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 
     21 import com.android.internal.R;
     22 import com.android.internal.os.BatteryStatsImpl;
     23 import com.android.internal.os.ProcessStats;
     24 import com.android.internal.widget.LockPatternUtils;
     25 import com.android.server.AttributeCache;
     26 import com.android.server.IntentResolver;
     27 import com.android.server.ProcessMap;
     28 import com.android.server.SystemServer;
     29 import com.android.server.Watchdog;
     30 import com.android.server.am.ActivityStack.ActivityState;
     31 import com.android.server.pm.UserManagerService;
     32 import com.android.server.wm.WindowManagerService;
     33 
     34 import dalvik.system.Zygote;
     35 
     36 import android.app.Activity;
     37 import android.app.ActivityManager;
     38 import android.app.ActivityManagerNative;
     39 import android.app.ActivityOptions;
     40 import android.app.ActivityThread;
     41 import android.app.AlertDialog;
     42 import android.app.AppGlobals;
     43 import android.app.ApplicationErrorReport;
     44 import android.app.Dialog;
     45 import android.app.IActivityController;
     46 import android.app.IApplicationThread;
     47 import android.app.IInstrumentationWatcher;
     48 import android.app.INotificationManager;
     49 import android.app.IProcessObserver;
     50 import android.app.IServiceConnection;
     51 import android.app.IStopUserCallback;
     52 import android.app.IThumbnailReceiver;
     53 import android.app.IUserSwitchObserver;
     54 import android.app.Instrumentation;
     55 import android.app.Notification;
     56 import android.app.NotificationManager;
     57 import android.app.PendingIntent;
     58 import android.app.backup.IBackupManager;
     59 import android.content.ActivityNotFoundException;
     60 import android.content.BroadcastReceiver;
     61 import android.content.ClipData;
     62 import android.content.ComponentCallbacks2;
     63 import android.content.ComponentName;
     64 import android.content.ContentProvider;
     65 import android.content.ContentResolver;
     66 import android.content.Context;
     67 import android.content.DialogInterface;
     68 import android.content.IContentProvider;
     69 import android.content.IIntentReceiver;
     70 import android.content.IIntentSender;
     71 import android.content.Intent;
     72 import android.content.IntentFilter;
     73 import android.content.IntentSender;
     74 import android.content.pm.ActivityInfo;
     75 import android.content.pm.ApplicationInfo;
     76 import android.content.pm.ConfigurationInfo;
     77 import android.content.pm.IPackageDataObserver;
     78 import android.content.pm.IPackageManager;
     79 import android.content.pm.InstrumentationInfo;
     80 import android.content.pm.PackageInfo;
     81 import android.content.pm.PackageManager;
     82 import android.content.pm.UserInfo;
     83 import android.content.pm.PackageManager.NameNotFoundException;
     84 import android.content.pm.PathPermission;
     85 import android.content.pm.ProviderInfo;
     86 import android.content.pm.ResolveInfo;
     87 import android.content.pm.ServiceInfo;
     88 import android.content.res.CompatibilityInfo;
     89 import android.content.res.Configuration;
     90 import android.graphics.Bitmap;
     91 import android.net.Proxy;
     92 import android.net.ProxyProperties;
     93 import android.net.Uri;
     94 import android.os.Binder;
     95 import android.os.Build;
     96 import android.os.Bundle;
     97 import android.os.Debug;
     98 import android.os.DropBoxManager;
     99 import android.os.Environment;
    100 import android.os.FileObserver;
    101 import android.os.FileUtils;
    102 import android.os.Handler;
    103 import android.os.IBinder;
    104 import android.os.IPermissionController;
    105 import android.os.IRemoteCallback;
    106 import android.os.IUserManager;
    107 import android.os.Looper;
    108 import android.os.Message;
    109 import android.os.Parcel;
    110 import android.os.ParcelFileDescriptor;
    111 import android.os.Process;
    112 import android.os.RemoteCallbackList;
    113 import android.os.RemoteException;
    114 import android.os.SELinux;
    115 import android.os.ServiceManager;
    116 import android.os.StrictMode;
    117 import android.os.SystemClock;
    118 import android.os.SystemProperties;
    119 import android.os.UserHandle;
    120 import android.provider.Settings;
    121 import android.text.format.Time;
    122 import android.util.EventLog;
    123 import android.util.Log;
    124 import android.util.Pair;
    125 import android.util.PrintWriterPrinter;
    126 import android.util.Slog;
    127 import android.util.SparseArray;
    128 import android.util.TimeUtils;
    129 import android.view.Gravity;
    130 import android.view.LayoutInflater;
    131 import android.view.View;
    132 import android.view.WindowManager;
    133 import android.view.WindowManagerPolicy;
    134 
    135 import java.io.BufferedInputStream;
    136 import java.io.BufferedOutputStream;
    137 import java.io.BufferedReader;
    138 import java.io.DataInputStream;
    139 import java.io.DataOutputStream;
    140 import java.io.File;
    141 import java.io.FileDescriptor;
    142 import java.io.FileInputStream;
    143 import java.io.FileNotFoundException;
    144 import java.io.FileOutputStream;
    145 import java.io.IOException;
    146 import java.io.InputStreamReader;
    147 import java.io.PrintWriter;
    148 import java.io.StringWriter;
    149 import java.lang.ref.WeakReference;
    150 import java.util.ArrayList;
    151 import java.util.Arrays;
    152 import java.util.Collections;
    153 import java.util.Comparator;
    154 import java.util.HashMap;
    155 import java.util.HashSet;
    156 import java.util.Iterator;
    157 import java.util.List;
    158 import java.util.Locale;
    159 import java.util.Map;
    160 import java.util.Set;
    161 import java.util.concurrent.atomic.AtomicBoolean;
    162 import java.util.concurrent.atomic.AtomicLong;
    163 
    164 public final class ActivityManagerService extends ActivityManagerNative
    165         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    166     private static final String USER_DATA_DIR = "/data/user/";
    167     static final String TAG = "ActivityManager";
    168     static final String TAG_MU = "ActivityManagerServiceMU";
    169     static final boolean DEBUG = false;
    170     static final boolean localLOGV = DEBUG;
    171     static final boolean DEBUG_SWITCH = localLOGV || false;
    172     static final boolean DEBUG_TASKS = localLOGV || false;
    173     static final boolean DEBUG_THUMBNAILS = localLOGV || false;
    174     static final boolean DEBUG_PAUSE = localLOGV || false;
    175     static final boolean DEBUG_OOM_ADJ = localLOGV || false;
    176     static final boolean DEBUG_TRANSITION = localLOGV || false;
    177     static final boolean DEBUG_BROADCAST = localLOGV || false;
    178     static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
    179     static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
    180     static final boolean DEBUG_SERVICE = localLOGV || false;
    181     static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
    182     static final boolean DEBUG_VISBILITY = localLOGV || false;
    183     static final boolean DEBUG_PROCESSES = localLOGV || false;
    184     static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
    185     static final boolean DEBUG_CLEANUP = localLOGV || false;
    186     static final boolean DEBUG_PROVIDER = localLOGV || false;
    187     static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
    188     static final boolean DEBUG_USER_LEAVING = localLOGV || false;
    189     static final boolean DEBUG_RESULTS = localLOGV || false;
    190     static final boolean DEBUG_BACKUP = localLOGV || false;
    191     static final boolean DEBUG_CONFIGURATION = localLOGV || false;
    192     static final boolean DEBUG_POWER = localLOGV || false;
    193     static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
    194     static final boolean DEBUG_MU = localLOGV || false;
    195     static final boolean VALIDATE_TOKENS = false;
    196     static final boolean SHOW_ACTIVITY_START_TIME = true;
    197 
    198     // Control over CPU and battery monitoring.
    199     static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
    200     static final boolean MONITOR_CPU_USAGE = true;
    201     static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
    202     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
    203     static final boolean MONITOR_THREAD_CPU_USAGE = false;
    204 
    205     // The flags that are set for all calls we make to the package manager.
    206     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
    207 
    208     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
    209 
    210     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
    211 
    212     // Maximum number of recent tasks that we can remember.
    213     static final int MAX_RECENT_TASKS = 20;
    214 
    215     // Amount of time after a call to stopAppSwitches() during which we will
    216     // prevent further untrusted switches from happening.
    217     static final long APP_SWITCH_DELAY_TIME = 5*1000;
    218 
    219     // How long we wait for a launched process to attach to the activity manager
    220     // before we decide it's never going to come up for real.
    221     static final int PROC_START_TIMEOUT = 10*1000;
    222 
    223     // How long we wait for a launched process to attach to the activity manager
    224     // before we decide it's never going to come up for real, when the process was
    225     // started with a wrapper for instrumentation (such as Valgrind) because it
    226     // could take much longer than usual.
    227     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
    228 
    229     // How long to wait after going idle before forcing apps to GC.
    230     static final int GC_TIMEOUT = 5*1000;
    231 
    232     // The minimum amount of time between successive GC requests for a process.
    233     static final int GC_MIN_INTERVAL = 60*1000;
    234 
    235     // The rate at which we check for apps using excessive power -- 15 mins.
    236     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
    237 
    238     // The minimum sample duration we will allow before deciding we have
    239     // enough data on wake locks to start killing things.
    240     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    241 
    242     // The minimum sample duration we will allow before deciding we have
    243     // enough data on CPU usage to start killing things.
    244     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    245 
    246     // How long we allow a receiver to run before giving up on it.
    247     static final int BROADCAST_FG_TIMEOUT = 10*1000;
    248     static final int BROADCAST_BG_TIMEOUT = 60*1000;
    249 
    250     // How long we wait until we timeout on key dispatching.
    251     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
    252 
    253     // How long we wait until we timeout on key dispatching during instrumentation.
    254     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
    255 
    256     // Amount of time we wait for observers to handle a user switch before
    257     // giving up on them and unfreezing the screen.
    258     static final int USER_SWITCH_TIMEOUT = 2*1000;
    259 
    260     // Maximum number of users we allow to be running at a time.
    261     static final int MAX_RUNNING_USERS = 3;
    262 
    263     static final int MY_PID = Process.myPid();
    264 
    265     static final String[] EMPTY_STRING_ARRAY = new String[0];
    266 
    267     public ActivityStack mMainStack;
    268 
    269     private final boolean mHeadless;
    270 
    271     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
    272     // default actuion automatically.  Important for devices without direct input
    273     // devices.
    274     private boolean mShowDialogs = true;
    275 
    276     /**
    277      * Description of a request to start a new activity, which has been held
    278      * due to app switches being disabled.
    279      */
    280     static class PendingActivityLaunch {
    281         ActivityRecord r;
    282         ActivityRecord sourceRecord;
    283         int startFlags;
    284     }
    285 
    286     final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
    287             = new ArrayList<PendingActivityLaunch>();
    288 
    289 
    290     BroadcastQueue mFgBroadcastQueue;
    291     BroadcastQueue mBgBroadcastQueue;
    292     // Convenient for easy iteration over the queues. Foreground is first
    293     // so that dispatch of foreground broadcasts gets precedence.
    294     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
    295 
    296     BroadcastQueue broadcastQueueForIntent(Intent intent) {
    297         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
    298         if (DEBUG_BACKGROUND_BROADCAST) {
    299             Slog.i(TAG, "Broadcast intent " + intent + " on "
    300                     + (isFg ? "foreground" : "background")
    301                     + " queue");
    302         }
    303         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
    304     }
    305 
    306     BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
    307         for (BroadcastQueue queue : mBroadcastQueues) {
    308             BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
    309             if (r != null) {
    310                 return r;
    311             }
    312         }
    313         return null;
    314     }
    315 
    316     /**
    317      * Activity we have told the window manager to have key focus.
    318      */
    319     ActivityRecord mFocusedActivity = null;
    320     /**
    321      * List of intents that were used to start the most recent tasks.
    322      */
    323     final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
    324 
    325     /**
    326      * Process management.
    327      */
    328     final ProcessList mProcessList = new ProcessList();
    329 
    330     /**
    331      * All of the applications we currently have running organized by name.
    332      * The keys are strings of the application package name (as
    333      * returned by the package manager), and the keys are ApplicationRecord
    334      * objects.
    335      */
    336     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
    337 
    338     /**
    339      * The currently running isolated processes.
    340      */
    341     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
    342 
    343     /**
    344      * Counter for assigning isolated process uids, to avoid frequently reusing the
    345      * same ones.
    346      */
    347     int mNextIsolatedProcessUid = 0;
    348 
    349     /**
    350      * The currently running heavy-weight process, if any.
    351      */
    352     ProcessRecord mHeavyWeightProcess = null;
    353 
    354     /**
    355      * The last time that various processes have crashed.
    356      */
    357     final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
    358 
    359     /**
    360      * Set of applications that we consider to be bad, and will reject
    361      * incoming broadcasts from (which the user has no control over).
    362      * Processes are added to this set when they have crashed twice within
    363      * a minimum amount of time; they are removed from it when they are
    364      * later restarted (hopefully due to some user action).  The value is the
    365      * time it was added to the list.
    366      */
    367     final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
    368 
    369     /**
    370      * All of the processes we currently have running organized by pid.
    371      * The keys are the pid running the application.
    372      *
    373      * <p>NOTE: This object is protected by its own lock, NOT the global
    374      * activity manager lock!
    375      */
    376     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
    377 
    378     /**
    379      * All of the processes that have been forced to be foreground.  The key
    380      * is the pid of the caller who requested it (we hold a death
    381      * link on it).
    382      */
    383     abstract class ForegroundToken implements IBinder.DeathRecipient {
    384         int pid;
    385         IBinder token;
    386     }
    387     final SparseArray<ForegroundToken> mForegroundProcesses
    388             = new SparseArray<ForegroundToken>();
    389 
    390     /**
    391      * List of records for processes that someone had tried to start before the
    392      * system was ready.  We don't start them at that point, but ensure they
    393      * are started by the time booting is complete.
    394      */
    395     final ArrayList<ProcessRecord> mProcessesOnHold
    396             = new ArrayList<ProcessRecord>();
    397 
    398     /**
    399      * List of persistent applications that are in the process
    400      * of being started.
    401      */
    402     final ArrayList<ProcessRecord> mPersistentStartingProcesses
    403             = new ArrayList<ProcessRecord>();
    404 
    405     /**
    406      * Processes that are being forcibly torn down.
    407      */
    408     final ArrayList<ProcessRecord> mRemovedProcesses
    409             = new ArrayList<ProcessRecord>();
    410 
    411     /**
    412      * List of running applications, sorted by recent usage.
    413      * The first entry in the list is the least recently used.
    414      * It contains ApplicationRecord objects.  This list does NOT include
    415      * any persistent application records (since we never want to exit them).
    416      */
    417     final ArrayList<ProcessRecord> mLruProcesses
    418             = new ArrayList<ProcessRecord>();
    419 
    420     /**
    421      * List of processes that should gc as soon as things are idle.
    422      */
    423     final ArrayList<ProcessRecord> mProcessesToGc
    424             = new ArrayList<ProcessRecord>();
    425 
    426     /**
    427      * This is the process holding what we currently consider to be
    428      * the "home" activity.
    429      */
    430     ProcessRecord mHomeProcess;
    431 
    432     /**
    433      * This is the process holding the activity the user last visited that
    434      * is in a different process from the one they are currently in.
    435      */
    436     ProcessRecord mPreviousProcess;
    437 
    438     /**
    439      * The time at which the previous process was last visible.
    440      */
    441     long mPreviousProcessVisibleTime;
    442 
    443     /**
    444      * Which uses have been started, so are allowed to run code.
    445      */
    446     final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
    447 
    448     /**
    449      * LRU list of history of current users.  Most recently current is at the end.
    450      */
    451     final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
    452 
    453     /**
    454      * Constant array of the users that are currently started.
    455      */
    456     int[] mStartedUserArray = new int[] { 0 };
    457 
    458     /**
    459      * Registered observers of the user switching mechanics.
    460      */
    461     final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
    462             = new RemoteCallbackList<IUserSwitchObserver>();
    463 
    464     /**
    465      * Currently active user switch.
    466      */
    467     Object mCurUserSwitchCallback;
    468 
    469     /**
    470      * Packages that the user has asked to have run in screen size
    471      * compatibility mode instead of filling the screen.
    472      */
    473     final CompatModePackages mCompatModePackages;
    474 
    475     /**
    476      * Set of PendingResultRecord objects that are currently active.
    477      */
    478     final HashSet mPendingResultRecords = new HashSet();
    479 
    480     /**
    481      * Set of IntentSenderRecord objects that are currently active.
    482      */
    483     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
    484             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
    485 
    486     /**
    487      * Fingerprints (hashCode()) of stack traces that we've
    488      * already logged DropBox entries for.  Guarded by itself.  If
    489      * something (rogue user app) forces this over
    490      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
    491      */
    492     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
    493     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
    494 
    495     /**
    496      * Strict Mode background batched logging state.
    497      *
    498      * The string buffer is guarded by itself, and its lock is also
    499      * used to determine if another batched write is already
    500      * in-flight.
    501      */
    502     private final StringBuilder mStrictModeBuffer = new StringBuilder();
    503 
    504     /**
    505      * Keeps track of all IIntentReceivers that have been registered for
    506      * broadcasts.  Hash keys are the receiver IBinder, hash value is
    507      * a ReceiverList.
    508      */
    509     final HashMap mRegisteredReceivers = new HashMap();
    510 
    511     /**
    512      * Resolver for broadcast intents to registered receivers.
    513      * Holds BroadcastFilter (subclass of IntentFilter).
    514      */
    515     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
    516             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
    517         @Override
    518         protected boolean allowFilterResult(
    519                 BroadcastFilter filter, List<BroadcastFilter> dest) {
    520             IBinder target = filter.receiverList.receiver.asBinder();
    521             for (int i=dest.size()-1; i>=0; i--) {
    522                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
    523                     return false;
    524                 }
    525             }
    526             return true;
    527         }
    528 
    529         @Override
    530         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
    531             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
    532                     || userId == filter.owningUserId) {
    533                 return super.newResult(filter, match, userId);
    534             }
    535             return null;
    536         }
    537 
    538         @Override
    539         protected BroadcastFilter[] newArray(int size) {
    540             return new BroadcastFilter[size];
    541         }
    542 
    543         @Override
    544         protected String packageForFilter(BroadcastFilter filter) {
    545             return filter.packageName;
    546         }
    547     };
    548 
    549     /**
    550      * State of all active sticky broadcasts per user.  Keys are the action of the
    551      * sticky Intent, values are an ArrayList of all broadcasted intents with
    552      * that action (which should usually be one).  The SparseArray is keyed
    553      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
    554      * for stickies that are sent to all users.
    555      */
    556     final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts =
    557             new SparseArray<HashMap<String, ArrayList<Intent>>>();
    558 
    559     final ActiveServices mServices;
    560 
    561     /**
    562      * Backup/restore process management
    563      */
    564     String mBackupAppName = null;
    565     BackupRecord mBackupTarget = null;
    566 
    567     /**
    568      * List of PendingThumbnailsRecord objects of clients who are still
    569      * waiting to receive all of the thumbnails for a task.
    570      */
    571     final ArrayList mPendingThumbnails = new ArrayList();
    572 
    573     /**
    574      * List of HistoryRecord objects that have been finished and must
    575      * still report back to a pending thumbnail receiver.
    576      */
    577     final ArrayList mCancelledThumbnails = new ArrayList();
    578 
    579     final ProviderMap mProviderMap;
    580 
    581     /**
    582      * List of content providers who have clients waiting for them.  The
    583      * application is currently being launched and the provider will be
    584      * removed from this list once it is published.
    585      */
    586     final ArrayList<ContentProviderRecord> mLaunchingProviders
    587             = new ArrayList<ContentProviderRecord>();
    588 
    589     /**
    590      * Global set of specific Uri permissions that have been granted.
    591      */
    592     final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
    593             = new SparseArray<HashMap<Uri, UriPermission>>();
    594 
    595     CoreSettingsObserver mCoreSettingsObserver;
    596 
    597     /**
    598      * Thread-local storage used to carry caller permissions over through
    599      * indirect content-provider access.
    600      * @see #ActivityManagerService.openContentUri()
    601      */
    602     private class Identity {
    603         public int pid;
    604         public int uid;
    605 
    606         Identity(int _pid, int _uid) {
    607             pid = _pid;
    608             uid = _uid;
    609         }
    610     }
    611 
    612     private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
    613 
    614     /**
    615      * All information we have collected about the runtime performance of
    616      * any user id that can impact battery performance.
    617      */
    618     final BatteryStatsService mBatteryStatsService;
    619 
    620     /**
    621      * information about component usage
    622      */
    623     final UsageStatsService mUsageStatsService;
    624 
    625     /**
    626      * Current configuration information.  HistoryRecord objects are given
    627      * a reference to this object to indicate which configuration they are
    628      * currently running in, so this object must be kept immutable.
    629      */
    630     Configuration mConfiguration = new Configuration();
    631 
    632     /**
    633      * Current sequencing integer of the configuration, for skipping old
    634      * configurations.
    635      */
    636     int mConfigurationSeq = 0;
    637 
    638     /**
    639      * Hardware-reported OpenGLES version.
    640      */
    641     final int GL_ES_VERSION;
    642 
    643     /**
    644      * List of initialization arguments to pass to all processes when binding applications to them.
    645      * For example, references to the commonly used services.
    646      */
    647     HashMap<String, IBinder> mAppBindArgs;
    648 
    649     /**
    650      * Temporary to avoid allocations.  Protected by main lock.
    651      */
    652     final StringBuilder mStringBuilder = new StringBuilder(256);
    653 
    654     /**
    655      * Used to control how we initialize the service.
    656      */
    657     boolean mStartRunning = false;
    658     ComponentName mTopComponent;
    659     String mTopAction;
    660     String mTopData;
    661     boolean mProcessesReady = false;
    662     boolean mSystemReady = false;
    663     boolean mBooting = false;
    664     boolean mWaitingUpdate = false;
    665     boolean mDidUpdate = false;
    666     boolean mOnBattery = false;
    667     boolean mLaunchWarningShown = false;
    668 
    669     Context mContext;
    670 
    671     int mFactoryTest;
    672 
    673     boolean mCheckedForSetup;
    674 
    675     /**
    676      * The time at which we will allow normal application switches again,
    677      * after a call to {@link #stopAppSwitches()}.
    678      */
    679     long mAppSwitchesAllowedTime;
    680 
    681     /**
    682      * This is set to true after the first switch after mAppSwitchesAllowedTime
    683      * is set; any switches after that will clear the time.
    684      */
    685     boolean mDidAppSwitch;
    686 
    687     /**
    688      * Last time (in realtime) at which we checked for power usage.
    689      */
    690     long mLastPowerCheckRealtime;
    691 
    692     /**
    693      * Last time (in uptime) at which we checked for power usage.
    694      */
    695     long mLastPowerCheckUptime;
    696 
    697     /**
    698      * Set while we are wanting to sleep, to prevent any
    699      * activities from being started/resumed.
    700      */
    701     boolean mSleeping = false;
    702 
    703     /**
    704      * State of external calls telling us if the device is asleep.
    705      */
    706     boolean mWentToSleep = false;
    707 
    708     /**
    709      * State of external call telling us if the lock screen is shown.
    710      */
    711     boolean mLockScreenShown = false;
    712 
    713     /**
    714      * Set if we are shutting down the system, similar to sleeping.
    715      */
    716     boolean mShuttingDown = false;
    717 
    718     /**
    719      * Task identifier that activities are currently being started
    720      * in.  Incremented each time a new task is created.
    721      * todo: Replace this with a TokenSpace class that generates non-repeating
    722      * integers that won't wrap.
    723      */
    724     int mCurTask = 1;
    725 
    726     /**
    727      * Current sequence id for oom_adj computation traversal.
    728      */
    729     int mAdjSeq = 0;
    730 
    731     /**
    732      * Current sequence id for process LRU updating.
    733      */
    734     int mLruSeq = 0;
    735 
    736     /**
    737      * Keep track of the non-hidden/empty process we last found, to help
    738      * determine how to distribute hidden/empty processes next time.
    739      */
    740     int mNumNonHiddenProcs = 0;
    741 
    742     /**
    743      * Keep track of the number of hidden procs, to balance oom adj
    744      * distribution between those and empty procs.
    745      */
    746     int mNumHiddenProcs = 0;
    747 
    748     /**
    749      * Keep track of the number of service processes we last found, to
    750      * determine on the next iteration which should be B services.
    751      */
    752     int mNumServiceProcs = 0;
    753     int mNewNumServiceProcs = 0;
    754 
    755     /**
    756      * System monitoring: number of processes that died since the last
    757      * N procs were started.
    758      */
    759     int[] mProcDeaths = new int[20];
    760 
    761     /**
    762      * This is set if we had to do a delayed dexopt of an app before launching
    763      * it, to increasing the ANR timeouts in that case.
    764      */
    765     boolean mDidDexOpt;
    766 
    767     String mDebugApp = null;
    768     boolean mWaitForDebugger = false;
    769     boolean mDebugTransient = false;
    770     String mOrigDebugApp = null;
    771     boolean mOrigWaitForDebugger = false;
    772     boolean mAlwaysFinishActivities = false;
    773     IActivityController mController = null;
    774     String mProfileApp = null;
    775     ProcessRecord mProfileProc = null;
    776     String mProfileFile;
    777     ParcelFileDescriptor mProfileFd;
    778     int mProfileType = 0;
    779     boolean mAutoStopProfiler = false;
    780     String mOpenGlTraceApp = null;
    781 
    782     static class ProcessChangeItem {
    783         static final int CHANGE_ACTIVITIES = 1<<0;
    784         static final int CHANGE_IMPORTANCE= 1<<1;
    785         int changes;
    786         int uid;
    787         int pid;
    788         int importance;
    789         boolean foregroundActivities;
    790     }
    791 
    792     final RemoteCallbackList<IProcessObserver> mProcessObservers
    793             = new RemoteCallbackList<IProcessObserver>();
    794     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
    795 
    796     final ArrayList<ProcessChangeItem> mPendingProcessChanges
    797             = new ArrayList<ProcessChangeItem>();
    798     final ArrayList<ProcessChangeItem> mAvailProcessChanges
    799             = new ArrayList<ProcessChangeItem>();
    800 
    801     /**
    802      * Callback of last caller to {@link #requestPss}.
    803      */
    804     Runnable mRequestPssCallback;
    805 
    806     /**
    807      * Remaining processes for which we are waiting results from the last
    808      * call to {@link #requestPss}.
    809      */
    810     final ArrayList<ProcessRecord> mRequestPssList
    811             = new ArrayList<ProcessRecord>();
    812 
    813     /**
    814      * Runtime statistics collection thread.  This object's lock is used to
    815      * protect all related state.
    816      */
    817     final Thread mProcessStatsThread;
    818 
    819     /**
    820      * Used to collect process stats when showing not responding dialog.
    821      * Protected by mProcessStatsThread.
    822      */
    823     final ProcessStats mProcessStats = new ProcessStats(
    824             MONITOR_THREAD_CPU_USAGE);
    825     final AtomicLong mLastCpuTime = new AtomicLong(0);
    826     final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
    827 
    828     long mLastWriteTime = 0;
    829 
    830     /**
    831      * Set to true after the system has finished booting.
    832      */
    833     boolean mBooted = false;
    834 
    835     int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
    836     int mProcessLimitOverride = -1;
    837 
    838     WindowManagerService mWindowManager;
    839 
    840     static ActivityManagerService mSelf;
    841     static ActivityThread mSystemThread;
    842 
    843     private int mCurrentUserId = 0;
    844     private int[] mCurrentUserArray = new int[] { 0 };
    845     private UserManagerService mUserManager;
    846 
    847     private final class AppDeathRecipient implements IBinder.DeathRecipient {
    848         final ProcessRecord mApp;
    849         final int mPid;
    850         final IApplicationThread mAppThread;
    851 
    852         AppDeathRecipient(ProcessRecord app, int pid,
    853                 IApplicationThread thread) {
    854             if (localLOGV) Slog.v(
    855                 TAG, "New death recipient " + this
    856                 + " for thread " + thread.asBinder());
    857             mApp = app;
    858             mPid = pid;
    859             mAppThread = thread;
    860         }
    861 
    862         public void binderDied() {
    863             if (localLOGV) Slog.v(
    864                 TAG, "Death received in " + this
    865                 + " for thread " + mAppThread.asBinder());
    866             synchronized(ActivityManagerService.this) {
    867                 appDiedLocked(mApp, mPid, mAppThread);
    868             }
    869         }
    870     }
    871 
    872     static final int SHOW_ERROR_MSG = 1;
    873     static final int SHOW_NOT_RESPONDING_MSG = 2;
    874     static final int SHOW_FACTORY_ERROR_MSG = 3;
    875     static final int UPDATE_CONFIGURATION_MSG = 4;
    876     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
    877     static final int WAIT_FOR_DEBUGGER_MSG = 6;
    878     static final int SERVICE_TIMEOUT_MSG = 12;
    879     static final int UPDATE_TIME_ZONE = 13;
    880     static final int SHOW_UID_ERROR_MSG = 14;
    881     static final int IM_FEELING_LUCKY_MSG = 15;
    882     static final int PROC_START_TIMEOUT_MSG = 20;
    883     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
    884     static final int KILL_APPLICATION_MSG = 22;
    885     static final int FINALIZE_PENDING_INTENT_MSG = 23;
    886     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
    887     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
    888     static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
    889     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
    890     static final int CLEAR_DNS_CACHE = 28;
    891     static final int UPDATE_HTTP_PROXY = 29;
    892     static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
    893     static final int DISPATCH_PROCESSES_CHANGED = 31;
    894     static final int DISPATCH_PROCESS_DIED = 32;
    895     static final int REPORT_MEM_USAGE = 33;
    896     static final int REPORT_USER_SWITCH_MSG = 34;
    897     static final int CONTINUE_USER_SWITCH_MSG = 35;
    898     static final int USER_SWITCH_TIMEOUT_MSG = 36;
    899 
    900     static final int FIRST_ACTIVITY_STACK_MSG = 100;
    901     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
    902     static final int FIRST_COMPAT_MODE_MSG = 300;
    903 
    904     AlertDialog mUidAlert;
    905     CompatModeDialog mCompatModeDialog;
    906     long mLastMemUsageReportTime = 0;
    907 
    908     final Handler mHandler = new Handler() {
    909         //public Handler() {
    910         //    if (localLOGV) Slog.v(TAG, "Handler started!");
    911         //}
    912 
    913         public void handleMessage(Message msg) {
    914             switch (msg.what) {
    915             case SHOW_ERROR_MSG: {
    916                 HashMap data = (HashMap) msg.obj;
    917                 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
    918                         Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
    919                 synchronized (ActivityManagerService.this) {
    920                     ProcessRecord proc = (ProcessRecord)data.get("app");
    921                     AppErrorResult res = (AppErrorResult) data.get("result");
    922                     if (proc != null && proc.crashDialog != null) {
    923                         Slog.e(TAG, "App already has crash dialog: " + proc);
    924                         if (res != null) {
    925                             res.set(0);
    926                         }
    927                         return;
    928                     }
    929                     if (!showBackground && UserHandle.getAppId(proc.uid)
    930                             >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
    931                             && proc.pid != MY_PID) {
    932                         Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
    933                         if (res != null) {
    934                             res.set(0);
    935                         }
    936                         return;
    937                     }
    938                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
    939                         Dialog d = new AppErrorDialog(mContext,
    940                                 ActivityManagerService.this, res, proc);
    941                         d.show();
    942                         proc.crashDialog = d;
    943                     } else {
    944                         // The device is asleep, so just pretend that the user
    945                         // saw a crash dialog and hit "force quit".
    946                         if (res != null) {
    947                             res.set(0);
    948                         }
    949                     }
    950                 }
    951 
    952                 ensureBootCompleted();
    953             } break;
    954             case SHOW_NOT_RESPONDING_MSG: {
    955                 synchronized (ActivityManagerService.this) {
    956                     HashMap data = (HashMap) msg.obj;
    957                     ProcessRecord proc = (ProcessRecord)data.get("app");
    958                     if (proc != null && proc.anrDialog != null) {
    959                         Slog.e(TAG, "App already has anr dialog: " + proc);
    960                         return;
    961                     }
    962 
    963                     Intent intent = new Intent("android.intent.action.ANR");
    964                     if (!mProcessesReady) {
    965                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
    966                                 | Intent.FLAG_RECEIVER_FOREGROUND);
    967                     }
    968                     broadcastIntentLocked(null, null, intent,
    969                             null, null, 0, null, null, null,
    970                             false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
    971 
    972                     if (mShowDialogs) {
    973                         Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
    974                                 mContext, proc, (ActivityRecord)data.get("activity"),
    975                                 msg.arg1 != 0);
    976                         d.show();
    977                         proc.anrDialog = d;
    978                     } else {
    979                         // Just kill the app if there is no dialog to be shown.
    980                         killAppAtUsersRequest(proc, null);
    981                     }
    982                 }
    983 
    984                 ensureBootCompleted();
    985             } break;
    986             case SHOW_STRICT_MODE_VIOLATION_MSG: {
    987                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
    988                 synchronized (ActivityManagerService.this) {
    989                     ProcessRecord proc = (ProcessRecord) data.get("app");
    990                     if (proc == null) {
    991                         Slog.e(TAG, "App not found when showing strict mode dialog.");
    992                         break;
    993                     }
    994                     if (proc.crashDialog != null) {
    995                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
    996                         return;
    997                     }
    998                     AppErrorResult res = (AppErrorResult) data.get("result");
    999                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
   1000                         Dialog d = new StrictModeViolationDialog(mContext,
   1001                                 ActivityManagerService.this, res, proc);
   1002                         d.show();
   1003                         proc.crashDialog = d;
   1004                     } else {
   1005                         // The device is asleep, so just pretend that the user
   1006                         // saw a crash dialog and hit "force quit".
   1007                         res.set(0);
   1008                     }
   1009                 }
   1010                 ensureBootCompleted();
   1011             } break;
   1012             case SHOW_FACTORY_ERROR_MSG: {
   1013                 Dialog d = new FactoryErrorDialog(
   1014                     mContext, msg.getData().getCharSequence("msg"));
   1015                 d.show();
   1016                 ensureBootCompleted();
   1017             } break;
   1018             case UPDATE_CONFIGURATION_MSG: {
   1019                 final ContentResolver resolver = mContext.getContentResolver();
   1020                 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
   1021             } break;
   1022             case GC_BACKGROUND_PROCESSES_MSG: {
   1023                 synchronized (ActivityManagerService.this) {
   1024                     performAppGcsIfAppropriateLocked();
   1025                 }
   1026             } break;
   1027             case WAIT_FOR_DEBUGGER_MSG: {
   1028                 synchronized (ActivityManagerService.this) {
   1029                     ProcessRecord app = (ProcessRecord)msg.obj;
   1030                     if (msg.arg1 != 0) {
   1031                         if (!app.waitedForDebugger) {
   1032                             Dialog d = new AppWaitingForDebuggerDialog(
   1033                                     ActivityManagerService.this,
   1034                                     mContext, app);
   1035                             app.waitDialog = d;
   1036                             app.waitedForDebugger = true;
   1037                             d.show();
   1038                         }
   1039                     } else {
   1040                         if (app.waitDialog != null) {
   1041                             app.waitDialog.dismiss();
   1042                             app.waitDialog = null;
   1043                         }
   1044                     }
   1045                 }
   1046             } break;
   1047             case SERVICE_TIMEOUT_MSG: {
   1048                 if (mDidDexOpt) {
   1049                     mDidDexOpt = false;
   1050                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   1051                     nmsg.obj = msg.obj;
   1052                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
   1053                     return;
   1054                 }
   1055                 mServices.serviceTimeout((ProcessRecord)msg.obj);
   1056             } break;
   1057             case UPDATE_TIME_ZONE: {
   1058                 synchronized (ActivityManagerService.this) {
   1059                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1060                         ProcessRecord r = mLruProcesses.get(i);
   1061                         if (r.thread != null) {
   1062                             try {
   1063                                 r.thread.updateTimeZone();
   1064                             } catch (RemoteException ex) {
   1065                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
   1066                             }
   1067                         }
   1068                     }
   1069                 }
   1070             } break;
   1071             case CLEAR_DNS_CACHE: {
   1072                 synchronized (ActivityManagerService.this) {
   1073                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1074                         ProcessRecord r = mLruProcesses.get(i);
   1075                         if (r.thread != null) {
   1076                             try {
   1077                                 r.thread.clearDnsCache();
   1078                             } catch (RemoteException ex) {
   1079                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
   1080                             }
   1081                         }
   1082                     }
   1083                 }
   1084             } break;
   1085             case UPDATE_HTTP_PROXY: {
   1086                 ProxyProperties proxy = (ProxyProperties)msg.obj;
   1087                 String host = "";
   1088                 String port = "";
   1089                 String exclList = "";
   1090                 if (proxy != null) {
   1091                     host = proxy.getHost();
   1092                     port = Integer.toString(proxy.getPort());
   1093                     exclList = proxy.getExclusionList();
   1094                 }
   1095                 synchronized (ActivityManagerService.this) {
   1096                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1097                         ProcessRecord r = mLruProcesses.get(i);
   1098                         if (r.thread != null) {
   1099                             try {
   1100                                 r.thread.setHttpProxy(host, port, exclList);
   1101                             } catch (RemoteException ex) {
   1102                                 Slog.w(TAG, "Failed to update http proxy for: " +
   1103                                         r.info.processName);
   1104                             }
   1105                         }
   1106                     }
   1107                 }
   1108             } break;
   1109             case SHOW_UID_ERROR_MSG: {
   1110                 String title = "System UIDs Inconsistent";
   1111                 String text = "UIDs on the system are inconsistent, you need to wipe your"
   1112                         + " data partition or your device will be unstable.";
   1113                 Log.e(TAG, title + ": " + text);
   1114                 if (mShowDialogs) {
   1115                     // XXX This is a temporary dialog, no need to localize.
   1116                     AlertDialog d = new BaseErrorDialog(mContext);
   1117                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
   1118                     d.setCancelable(false);
   1119                     d.setTitle(title);
   1120                     d.setMessage(text);
   1121                     d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
   1122                             mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
   1123                     mUidAlert = d;
   1124                     d.show();
   1125                 }
   1126             } break;
   1127             case IM_FEELING_LUCKY_MSG: {
   1128                 if (mUidAlert != null) {
   1129                     mUidAlert.dismiss();
   1130                     mUidAlert = null;
   1131                 }
   1132             } break;
   1133             case PROC_START_TIMEOUT_MSG: {
   1134                 if (mDidDexOpt) {
   1135                     mDidDexOpt = false;
   1136                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   1137                     nmsg.obj = msg.obj;
   1138                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
   1139                     return;
   1140                 }
   1141                 ProcessRecord app = (ProcessRecord)msg.obj;
   1142                 synchronized (ActivityManagerService.this) {
   1143                     processStartTimedOutLocked(app);
   1144                 }
   1145             } break;
   1146             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
   1147                 synchronized (ActivityManagerService.this) {
   1148                     doPendingActivityLaunchesLocked(true);
   1149                 }
   1150             } break;
   1151             case KILL_APPLICATION_MSG: {
   1152                 synchronized (ActivityManagerService.this) {
   1153                     int appid = msg.arg1;
   1154                     boolean restart = (msg.arg2 == 1);
   1155                     String pkg = (String) msg.obj;
   1156                     forceStopPackageLocked(pkg, appid, restart, false, true, false,
   1157                             UserHandle.USER_ALL);
   1158                 }
   1159             } break;
   1160             case FINALIZE_PENDING_INTENT_MSG: {
   1161                 ((PendingIntentRecord)msg.obj).completeFinalize();
   1162             } break;
   1163             case POST_HEAVY_NOTIFICATION_MSG: {
   1164                 INotificationManager inm = NotificationManager.getService();
   1165                 if (inm == null) {
   1166                     return;
   1167                 }
   1168 
   1169                 ActivityRecord root = (ActivityRecord)msg.obj;
   1170                 ProcessRecord process = root.app;
   1171                 if (process == null) {
   1172                     return;
   1173                 }
   1174 
   1175                 try {
   1176                     Context context = mContext.createPackageContext(process.info.packageName, 0);
   1177                     String text = mContext.getString(R.string.heavy_weight_notification,
   1178                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
   1179                     Notification notification = new Notification();
   1180                     notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
   1181                     notification.when = 0;
   1182                     notification.flags = Notification.FLAG_ONGOING_EVENT;
   1183                     notification.tickerText = text;
   1184                     notification.defaults = 0; // please be quiet
   1185                     notification.sound = null;
   1186                     notification.vibrate = null;
   1187                     notification.setLatestEventInfo(context, text,
   1188                             mContext.getText(R.string.heavy_weight_notification_detail),
   1189                             PendingIntent.getActivityAsUser(mContext, 0, root.intent,
   1190                                     PendingIntent.FLAG_CANCEL_CURRENT, null,
   1191                                     new UserHandle(root.userId)));
   1192 
   1193                     try {
   1194                         int[] outId = new int[1];
   1195                         inm.enqueueNotificationWithTag("android", null,
   1196                                 R.string.heavy_weight_notification,
   1197                                 notification, outId, root.userId);
   1198                     } catch (RuntimeException e) {
   1199                         Slog.w(ActivityManagerService.TAG,
   1200                                 "Error showing notification for heavy-weight app", e);
   1201                     } catch (RemoteException e) {
   1202                     }
   1203                 } catch (NameNotFoundException e) {
   1204                     Slog.w(TAG, "Unable to create context for heavy notification", e);
   1205                 }
   1206             } break;
   1207             case CANCEL_HEAVY_NOTIFICATION_MSG: {
   1208                 INotificationManager inm = NotificationManager.getService();
   1209                 if (inm == null) {
   1210                     return;
   1211                 }
   1212                 try {
   1213                     inm.cancelNotificationWithTag("android", null,
   1214                             R.string.heavy_weight_notification,  msg.arg1);
   1215                 } catch (RuntimeException e) {
   1216                     Slog.w(ActivityManagerService.TAG,
   1217                             "Error canceling notification for service", e);
   1218                 } catch (RemoteException e) {
   1219                 }
   1220             } break;
   1221             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
   1222                 synchronized (ActivityManagerService.this) {
   1223                     checkExcessivePowerUsageLocked(true);
   1224                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1225                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1226                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   1227                 }
   1228             } break;
   1229             case SHOW_COMPAT_MODE_DIALOG_MSG: {
   1230                 synchronized (ActivityManagerService.this) {
   1231                     ActivityRecord ar = (ActivityRecord)msg.obj;
   1232                     if (mCompatModeDialog != null) {
   1233                         if (mCompatModeDialog.mAppInfo.packageName.equals(
   1234                                 ar.info.applicationInfo.packageName)) {
   1235                             return;
   1236                         }
   1237                         mCompatModeDialog.dismiss();
   1238                         mCompatModeDialog = null;
   1239                     }
   1240                     if (ar != null && false) {
   1241                         if (mCompatModePackages.getPackageAskCompatModeLocked(
   1242                                 ar.packageName)) {
   1243                             int mode = mCompatModePackages.computeCompatModeLocked(
   1244                                     ar.info.applicationInfo);
   1245                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
   1246                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
   1247                                 mCompatModeDialog = new CompatModeDialog(
   1248                                         ActivityManagerService.this, mContext,
   1249                                         ar.info.applicationInfo);
   1250                                 mCompatModeDialog.show();
   1251                             }
   1252                         }
   1253                     }
   1254                 }
   1255                 break;
   1256             }
   1257             case DISPATCH_PROCESSES_CHANGED: {
   1258                 dispatchProcessesChanged();
   1259                 break;
   1260             }
   1261             case DISPATCH_PROCESS_DIED: {
   1262                 final int pid = msg.arg1;
   1263                 final int uid = msg.arg2;
   1264                 dispatchProcessDied(pid, uid);
   1265                 break;
   1266             }
   1267             case REPORT_MEM_USAGE: {
   1268                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   1269                 if (!isDebuggable) {
   1270                     return;
   1271                 }
   1272                 synchronized (ActivityManagerService.this) {
   1273                     long now = SystemClock.uptimeMillis();
   1274                     if (now < (mLastMemUsageReportTime+5*60*1000)) {
   1275                         // Don't report more than every 5 minutes to somewhat
   1276                         // avoid spamming.
   1277                         return;
   1278                     }
   1279                     mLastMemUsageReportTime = now;
   1280                 }
   1281                 Thread thread = new Thread() {
   1282                     @Override public void run() {
   1283                         StringBuilder dropBuilder = new StringBuilder(1024);
   1284                         StringBuilder logBuilder = new StringBuilder(1024);
   1285                         StringWriter oomSw = new StringWriter();
   1286                         PrintWriter oomPw = new PrintWriter(oomSw);
   1287                         StringWriter catSw = new StringWriter();
   1288                         PrintWriter catPw = new PrintWriter(catSw);
   1289                         String[] emptyArgs = new String[] { };
   1290                         StringBuilder tag = new StringBuilder(128);
   1291                         StringBuilder stack = new StringBuilder(128);
   1292                         tag.append("Low on memory -- ");
   1293                         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
   1294                                 tag, stack);
   1295                         dropBuilder.append(stack);
   1296                         dropBuilder.append('\n');
   1297                         dropBuilder.append('\n');
   1298                         String oomString = oomSw.toString();
   1299                         dropBuilder.append(oomString);
   1300                         dropBuilder.append('\n');
   1301                         logBuilder.append(oomString);
   1302                         try {
   1303                             java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
   1304                                     "procrank", });
   1305                             final InputStreamReader converter = new InputStreamReader(
   1306                                     proc.getInputStream());
   1307                             BufferedReader in = new BufferedReader(converter);
   1308                             String line;
   1309                             while (true) {
   1310                                 line = in.readLine();
   1311                                 if (line == null) {
   1312                                     break;
   1313                                 }
   1314                                 if (line.length() > 0) {
   1315                                     logBuilder.append(line);
   1316                                     logBuilder.append('\n');
   1317                                 }
   1318                                 dropBuilder.append(line);
   1319                                 dropBuilder.append('\n');
   1320                             }
   1321                             converter.close();
   1322                         } catch (IOException e) {
   1323                         }
   1324                         synchronized (ActivityManagerService.this) {
   1325                             catPw.println();
   1326                             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
   1327                             catPw.println();
   1328                             mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
   1329                                     false, false, null);
   1330                             catPw.println();
   1331                             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
   1332                         }
   1333                         dropBuilder.append(catSw.toString());
   1334                         addErrorToDropBox("lowmem", null, "system_server", null,
   1335                                 null, tag.toString(), dropBuilder.toString(), null, null);
   1336                         Slog.i(TAG, logBuilder.toString());
   1337                         synchronized (ActivityManagerService.this) {
   1338                             long now = SystemClock.uptimeMillis();
   1339                             if (mLastMemUsageReportTime < now) {
   1340                                 mLastMemUsageReportTime = now;
   1341                             }
   1342                         }
   1343                     }
   1344                 };
   1345                 thread.start();
   1346                 break;
   1347             }
   1348             case REPORT_USER_SWITCH_MSG: {
   1349                 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
   1350                 break;
   1351             }
   1352             case CONTINUE_USER_SWITCH_MSG: {
   1353                 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
   1354                 break;
   1355             }
   1356             case USER_SWITCH_TIMEOUT_MSG: {
   1357                 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
   1358                 break;
   1359             }
   1360             }
   1361         }
   1362     };
   1363 
   1364     public static void setSystemProcess() {
   1365         try {
   1366             ActivityManagerService m = mSelf;
   1367 
   1368             ServiceManager.addService("activity", m, true);
   1369             ServiceManager.addService("meminfo", new MemBinder(m));
   1370             ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
   1371             ServiceManager.addService("dbinfo", new DbBinder(m));
   1372             if (MONITOR_CPU_USAGE) {
   1373                 ServiceManager.addService("cpuinfo", new CpuBinder(m));
   1374             }
   1375             ServiceManager.addService("permission", new PermissionController(m));
   1376 
   1377             ApplicationInfo info =
   1378                 mSelf.mContext.getPackageManager().getApplicationInfo(
   1379                             "android", STOCK_PM_FLAGS);
   1380             mSystemThread.installSystemApplicationInfo(info);
   1381 
   1382             synchronized (mSelf) {
   1383                 ProcessRecord app = mSelf.newProcessRecordLocked(
   1384                         mSystemThread.getApplicationThread(), info,
   1385                         info.processName, false);
   1386                 app.persistent = true;
   1387                 app.pid = MY_PID;
   1388                 app.maxAdj = ProcessList.SYSTEM_ADJ;
   1389                 mSelf.mProcessNames.put(app.processName, app.uid, app);
   1390                 synchronized (mSelf.mPidsSelfLocked) {
   1391                     mSelf.mPidsSelfLocked.put(app.pid, app);
   1392                 }
   1393                 mSelf.updateLruProcessLocked(app, true);
   1394             }
   1395         } catch (PackageManager.NameNotFoundException e) {
   1396             throw new RuntimeException(
   1397                     "Unable to find android system package", e);
   1398         }
   1399     }
   1400 
   1401     public void setWindowManager(WindowManagerService wm) {
   1402         mWindowManager = wm;
   1403     }
   1404 
   1405     public static final Context main(int factoryTest) {
   1406         AThread thr = new AThread();
   1407         thr.start();
   1408 
   1409         synchronized (thr) {
   1410             while (thr.mService == null) {
   1411                 try {
   1412                     thr.wait();
   1413                 } catch (InterruptedException e) {
   1414                 }
   1415             }
   1416         }
   1417 
   1418         ActivityManagerService m = thr.mService;
   1419         mSelf = m;
   1420         ActivityThread at = ActivityThread.systemMain();
   1421         mSystemThread = at;
   1422         Context context = at.getSystemContext();
   1423         context.setTheme(android.R.style.Theme_Holo);
   1424         m.mContext = context;
   1425         m.mFactoryTest = factoryTest;
   1426         m.mMainStack = new ActivityStack(m, context, true);
   1427 
   1428         m.mBatteryStatsService.publish(context);
   1429         m.mUsageStatsService.publish(context);
   1430 
   1431         synchronized (thr) {
   1432             thr.mReady = true;
   1433             thr.notifyAll();
   1434         }
   1435 
   1436         m.startRunning(null, null, null, null);
   1437 
   1438         return context;
   1439     }
   1440 
   1441     public static ActivityManagerService self() {
   1442         return mSelf;
   1443     }
   1444 
   1445     static class AThread extends Thread {
   1446         ActivityManagerService mService;
   1447         boolean mReady = false;
   1448 
   1449         public AThread() {
   1450             super("ActivityManager");
   1451         }
   1452 
   1453         public void run() {
   1454             Looper.prepare();
   1455 
   1456             android.os.Process.setThreadPriority(
   1457                     android.os.Process.THREAD_PRIORITY_FOREGROUND);
   1458             android.os.Process.setCanSelfBackground(false);
   1459 
   1460             ActivityManagerService m = new ActivityManagerService();
   1461 
   1462             synchronized (this) {
   1463                 mService = m;
   1464                 notifyAll();
   1465             }
   1466 
   1467             synchronized (this) {
   1468                 while (!mReady) {
   1469                     try {
   1470                         wait();
   1471                     } catch (InterruptedException e) {
   1472                     }
   1473                 }
   1474             }
   1475 
   1476             // For debug builds, log event loop stalls to dropbox for analysis.
   1477             if (StrictMode.conditionallyEnableDebugLogging()) {
   1478                 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
   1479             }
   1480 
   1481             Looper.loop();
   1482         }
   1483     }
   1484 
   1485     static class MemBinder extends Binder {
   1486         ActivityManagerService mActivityManagerService;
   1487         MemBinder(ActivityManagerService activityManagerService) {
   1488             mActivityManagerService = activityManagerService;
   1489         }
   1490 
   1491         @Override
   1492         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1493             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1494                     != PackageManager.PERMISSION_GRANTED) {
   1495                 pw.println("Permission Denial: can't dump meminfo from from pid="
   1496                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1497                         + " without permission " + android.Manifest.permission.DUMP);
   1498                 return;
   1499             }
   1500 
   1501             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
   1502                     false, null, null, null);
   1503         }
   1504     }
   1505 
   1506     static class GraphicsBinder extends Binder {
   1507         ActivityManagerService mActivityManagerService;
   1508         GraphicsBinder(ActivityManagerService activityManagerService) {
   1509             mActivityManagerService = activityManagerService;
   1510         }
   1511 
   1512         @Override
   1513         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1514             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1515                     != PackageManager.PERMISSION_GRANTED) {
   1516                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
   1517                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1518                         + " without permission " + android.Manifest.permission.DUMP);
   1519                 return;
   1520             }
   1521 
   1522             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
   1523         }
   1524     }
   1525 
   1526     static class DbBinder extends Binder {
   1527         ActivityManagerService mActivityManagerService;
   1528         DbBinder(ActivityManagerService activityManagerService) {
   1529             mActivityManagerService = activityManagerService;
   1530         }
   1531 
   1532         @Override
   1533         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1534             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1535                     != PackageManager.PERMISSION_GRANTED) {
   1536                 pw.println("Permission Denial: can't dump dbinfo from from pid="
   1537                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1538                         + " without permission " + android.Manifest.permission.DUMP);
   1539                 return;
   1540             }
   1541 
   1542             mActivityManagerService.dumpDbInfo(fd, pw, args);
   1543         }
   1544     }
   1545 
   1546     static class CpuBinder extends Binder {
   1547         ActivityManagerService mActivityManagerService;
   1548         CpuBinder(ActivityManagerService activityManagerService) {
   1549             mActivityManagerService = activityManagerService;
   1550         }
   1551 
   1552         @Override
   1553         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1554             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1555                     != PackageManager.PERMISSION_GRANTED) {
   1556                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
   1557                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1558                         + " without permission " + android.Manifest.permission.DUMP);
   1559                 return;
   1560             }
   1561 
   1562             synchronized (mActivityManagerService.mProcessStatsThread) {
   1563                 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
   1564                 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
   1565                         SystemClock.uptimeMillis()));
   1566             }
   1567         }
   1568     }
   1569 
   1570     private ActivityManagerService() {
   1571         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
   1572 
   1573         mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
   1574         mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
   1575         mBroadcastQueues[0] = mFgBroadcastQueue;
   1576         mBroadcastQueues[1] = mBgBroadcastQueue;
   1577 
   1578         mServices = new ActiveServices(this);
   1579         mProviderMap = new ProviderMap(this);
   1580 
   1581         File dataDir = Environment.getDataDirectory();
   1582         File systemDir = new File(dataDir, "system");
   1583         systemDir.mkdirs();
   1584         mBatteryStatsService = new BatteryStatsService(new File(
   1585                 systemDir, "batterystats.bin").toString());
   1586         mBatteryStatsService.getActiveStatistics().readLocked();
   1587         mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
   1588         mOnBattery = DEBUG_POWER ? true
   1589                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
   1590         mBatteryStatsService.getActiveStatistics().setCallback(this);
   1591 
   1592         mUsageStatsService = new UsageStatsService(new File(
   1593                 systemDir, "usagestats").toString());
   1594         mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
   1595 
   1596         // User 0 is the first and only user that runs at boot.
   1597         mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
   1598         mUserLru.add(Integer.valueOf(0));
   1599         updateStartedUserArrayLocked();
   1600 
   1601         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
   1602             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
   1603 
   1604         mConfiguration.setToDefaults();
   1605         mConfiguration.setLocale(Locale.getDefault());
   1606 
   1607         mConfigurationSeq = mConfiguration.seq = 1;
   1608         mProcessStats.init();
   1609 
   1610         mCompatModePackages = new CompatModePackages(this, systemDir);
   1611 
   1612         // Add ourself to the Watchdog monitors.
   1613         Watchdog.getInstance().addMonitor(this);
   1614 
   1615         mProcessStatsThread = new Thread("ProcessStats") {
   1616             public void run() {
   1617                 while (true) {
   1618                     try {
   1619                         try {
   1620                             synchronized(this) {
   1621                                 final long now = SystemClock.uptimeMillis();
   1622                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
   1623                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
   1624                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
   1625                                 //        + ", write delay=" + nextWriteDelay);
   1626                                 if (nextWriteDelay < nextCpuDelay) {
   1627                                     nextCpuDelay = nextWriteDelay;
   1628                                 }
   1629                                 if (nextCpuDelay > 0) {
   1630                                     mProcessStatsMutexFree.set(true);
   1631                                     this.wait(nextCpuDelay);
   1632                                 }
   1633                             }
   1634                         } catch (InterruptedException e) {
   1635                         }
   1636                         updateCpuStatsNow();
   1637                     } catch (Exception e) {
   1638                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
   1639                     }
   1640                 }
   1641             }
   1642         };
   1643         mProcessStatsThread.start();
   1644     }
   1645 
   1646     @Override
   1647     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   1648             throws RemoteException {
   1649         if (code == SYSPROPS_TRANSACTION) {
   1650             // We need to tell all apps about the system property change.
   1651             ArrayList<IBinder> procs = new ArrayList<IBinder>();
   1652             synchronized(this) {
   1653                 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   1654                     final int NA = apps.size();
   1655                     for (int ia=0; ia<NA; ia++) {
   1656                         ProcessRecord app = apps.valueAt(ia);
   1657                         if (app.thread != null) {
   1658                             procs.add(app.thread.asBinder());
   1659                         }
   1660                     }
   1661                 }
   1662             }
   1663 
   1664             int N = procs.size();
   1665             for (int i=0; i<N; i++) {
   1666                 Parcel data2 = Parcel.obtain();
   1667                 try {
   1668                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
   1669                 } catch (RemoteException e) {
   1670                 }
   1671                 data2.recycle();
   1672             }
   1673         }
   1674         try {
   1675             return super.onTransact(code, data, reply, flags);
   1676         } catch (RuntimeException e) {
   1677             // The activity manager only throws security exceptions, so let's
   1678             // log all others.
   1679             if (!(e instanceof SecurityException)) {
   1680                 Slog.e(TAG, "Activity Manager Crash", e);
   1681             }
   1682             throw e;
   1683         }
   1684     }
   1685 
   1686     void updateCpuStats() {
   1687         final long now = SystemClock.uptimeMillis();
   1688         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
   1689             return;
   1690         }
   1691         if (mProcessStatsMutexFree.compareAndSet(true, false)) {
   1692             synchronized (mProcessStatsThread) {
   1693                 mProcessStatsThread.notify();
   1694             }
   1695         }
   1696     }
   1697 
   1698     void updateCpuStatsNow() {
   1699         synchronized (mProcessStatsThread) {
   1700             mProcessStatsMutexFree.set(false);
   1701             final long now = SystemClock.uptimeMillis();
   1702             boolean haveNewCpuStats = false;
   1703 
   1704             if (MONITOR_CPU_USAGE &&
   1705                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
   1706                 mLastCpuTime.set(now);
   1707                 haveNewCpuStats = true;
   1708                 mProcessStats.update();
   1709                 //Slog.i(TAG, mProcessStats.printCurrentState());
   1710                 //Slog.i(TAG, "Total CPU usage: "
   1711                 //        + mProcessStats.getTotalCpuPercent() + "%");
   1712 
   1713                 // Slog the cpu usage if the property is set.
   1714                 if ("true".equals(SystemProperties.get("events.cpu"))) {
   1715                     int user = mProcessStats.getLastUserTime();
   1716                     int system = mProcessStats.getLastSystemTime();
   1717                     int iowait = mProcessStats.getLastIoWaitTime();
   1718                     int irq = mProcessStats.getLastIrqTime();
   1719                     int softIrq = mProcessStats.getLastSoftIrqTime();
   1720                     int idle = mProcessStats.getLastIdleTime();
   1721 
   1722                     int total = user + system + iowait + irq + softIrq + idle;
   1723                     if (total == 0) total = 1;
   1724 
   1725                     EventLog.writeEvent(EventLogTags.CPU,
   1726                             ((user+system+iowait+irq+softIrq) * 100) / total,
   1727                             (user * 100) / total,
   1728                             (system * 100) / total,
   1729                             (iowait * 100) / total,
   1730                             (irq * 100) / total,
   1731                             (softIrq * 100) / total);
   1732                 }
   1733             }
   1734 
   1735             long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
   1736             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
   1737             synchronized(bstats) {
   1738                 synchronized(mPidsSelfLocked) {
   1739                     if (haveNewCpuStats) {
   1740                         if (mOnBattery) {
   1741                             int perc = bstats.startAddingCpuLocked();
   1742                             int totalUTime = 0;
   1743                             int totalSTime = 0;
   1744                             final int N = mProcessStats.countStats();
   1745                             for (int i=0; i<N; i++) {
   1746                                 ProcessStats.Stats st = mProcessStats.getStats(i);
   1747                                 if (!st.working) {
   1748                                     continue;
   1749                                 }
   1750                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
   1751                                 int otherUTime = (st.rel_utime*perc)/100;
   1752                                 int otherSTime = (st.rel_stime*perc)/100;
   1753                                 totalUTime += otherUTime;
   1754                                 totalSTime += otherSTime;
   1755                                 if (pr != null) {
   1756                                     BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
   1757                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
   1758                                             st.rel_stime-otherSTime);
   1759                                     ps.addSpeedStepTimes(cpuSpeedTimes);
   1760                                     pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
   1761                                 } else {
   1762                                     BatteryStatsImpl.Uid.Proc ps =
   1763                                             bstats.getProcessStatsLocked(st.name, st.pid);
   1764                                     if (ps != null) {
   1765                                         ps.addCpuTimeLocked(st.rel_utime-otherUTime,
   1766                                                 st.rel_stime-otherSTime);
   1767                                         ps.addSpeedStepTimes(cpuSpeedTimes);
   1768                                     }
   1769                                 }
   1770                             }
   1771                             bstats.finishAddingCpuLocked(perc, totalUTime,
   1772                                     totalSTime, cpuSpeedTimes);
   1773                         }
   1774                     }
   1775                 }
   1776 
   1777                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
   1778                     mLastWriteTime = now;
   1779                     mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
   1780                 }
   1781             }
   1782         }
   1783     }
   1784 
   1785     @Override
   1786     public void batteryNeedsCpuUpdate() {
   1787         updateCpuStatsNow();
   1788     }
   1789 
   1790     @Override
   1791     public void batteryPowerChanged(boolean onBattery) {
   1792         // When plugging in, update the CPU stats first before changing
   1793         // the plug state.
   1794         updateCpuStatsNow();
   1795         synchronized (this) {
   1796             synchronized(mPidsSelfLocked) {
   1797                 mOnBattery = DEBUG_POWER ? true : onBattery;
   1798             }
   1799         }
   1800     }
   1801 
   1802     /**
   1803      * Initialize the application bind args. These are passed to each
   1804      * process when the bindApplication() IPC is sent to the process. They're
   1805      * lazily setup to make sure the services are running when they're asked for.
   1806      */
   1807     private HashMap<String, IBinder> getCommonServicesLocked() {
   1808         if (mAppBindArgs == null) {
   1809             mAppBindArgs = new HashMap<String, IBinder>();
   1810 
   1811             // Setup the application init args
   1812             mAppBindArgs.put("package", ServiceManager.getService("package"));
   1813             mAppBindArgs.put("window", ServiceManager.getService("window"));
   1814             mAppBindArgs.put(Context.ALARM_SERVICE,
   1815                     ServiceManager.getService(Context.ALARM_SERVICE));
   1816         }
   1817         return mAppBindArgs;
   1818     }
   1819 
   1820     final void setFocusedActivityLocked(ActivityRecord r) {
   1821         if (mFocusedActivity != r) {
   1822             mFocusedActivity = r;
   1823             if (r != null) {
   1824                 mWindowManager.setFocusedApp(r.appToken, true);
   1825             }
   1826         }
   1827     }
   1828 
   1829     private final void updateLruProcessInternalLocked(ProcessRecord app, int bestPos) {
   1830         // put it on the LRU to keep track of when it should be exited.
   1831         int lrui = mLruProcesses.indexOf(app);
   1832         if (lrui >= 0) mLruProcesses.remove(lrui);
   1833 
   1834         int i = mLruProcesses.size()-1;
   1835         int skipTop = 0;
   1836 
   1837         app.lruSeq = mLruSeq;
   1838 
   1839         // compute the new weight for this process.
   1840         app.lastActivityTime = SystemClock.uptimeMillis();
   1841         if (app.activities.size() > 0) {
   1842             // If this process has activities, we more strongly want to keep
   1843             // it around.
   1844             app.lruWeight = app.lastActivityTime;
   1845         } else if (app.pubProviders.size() > 0) {
   1846             // If this process contains content providers, we want to keep
   1847             // it a little more strongly.
   1848             app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
   1849             // Also don't let it kick out the first few "real" hidden processes.
   1850             skipTop = ProcessList.MIN_HIDDEN_APPS;
   1851         } else {
   1852             // If this process doesn't have activities, we less strongly
   1853             // want to keep it around, and generally want to avoid getting
   1854             // in front of any very recently used activities.
   1855             app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
   1856             // Also don't let it kick out the first few "real" hidden processes.
   1857             skipTop = ProcessList.MIN_HIDDEN_APPS;
   1858         }
   1859 
   1860         while (i >= 0) {
   1861             ProcessRecord p = mLruProcesses.get(i);
   1862             // If this app shouldn't be in front of the first N background
   1863             // apps, then skip over that many that are currently hidden.
   1864             if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   1865                 skipTop--;
   1866             }
   1867             if (p.lruWeight <= app.lruWeight || i < bestPos) {
   1868                 mLruProcesses.add(i+1, app);
   1869                 break;
   1870             }
   1871             i--;
   1872         }
   1873         if (i < 0) {
   1874             mLruProcesses.add(0, app);
   1875         }
   1876 
   1877         // If the app is currently using a content provider or service,
   1878         // bump those processes as well.
   1879         if (app.connections.size() > 0) {
   1880             for (ConnectionRecord cr : app.connections) {
   1881                 if (cr.binding != null && cr.binding.service != null
   1882                         && cr.binding.service.app != null
   1883                         && cr.binding.service.app.lruSeq != mLruSeq) {
   1884                     updateLruProcessInternalLocked(cr.binding.service.app, i+1);
   1885                 }
   1886             }
   1887         }
   1888         for (int j=app.conProviders.size()-1; j>=0; j--) {
   1889             ContentProviderRecord cpr = app.conProviders.get(j).provider;
   1890             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
   1891                 updateLruProcessInternalLocked(cpr.proc, i+1);
   1892             }
   1893         }
   1894     }
   1895 
   1896     final void updateLruProcessLocked(ProcessRecord app,
   1897             boolean oomAdj) {
   1898         mLruSeq++;
   1899         updateLruProcessInternalLocked(app, 0);
   1900 
   1901         //Slog.i(TAG, "Putting proc to front: " + app.processName);
   1902         if (oomAdj) {
   1903             updateOomAdjLocked();
   1904         }
   1905     }
   1906 
   1907     final ProcessRecord getProcessRecordLocked(
   1908             String processName, int uid) {
   1909         if (uid == Process.SYSTEM_UID) {
   1910             // The system gets to run in any process.  If there are multiple
   1911             // processes with the same uid, just pick the first (this
   1912             // should never happen).
   1913             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
   1914                     processName);
   1915             if (procs == null) return null;
   1916             final int N = procs.size();
   1917             for (int i = 0; i < N; i++) {
   1918                 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
   1919             }
   1920         }
   1921         ProcessRecord proc = mProcessNames.get(processName, uid);
   1922         return proc;
   1923     }
   1924 
   1925     void ensurePackageDexOpt(String packageName) {
   1926         IPackageManager pm = AppGlobals.getPackageManager();
   1927         try {
   1928             if (pm.performDexOpt(packageName)) {
   1929                 mDidDexOpt = true;
   1930             }
   1931         } catch (RemoteException e) {
   1932         }
   1933     }
   1934 
   1935     boolean isNextTransitionForward() {
   1936         int transit = mWindowManager.getPendingAppTransition();
   1937         return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
   1938                 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
   1939                 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
   1940     }
   1941 
   1942     final ProcessRecord startProcessLocked(String processName,
   1943             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
   1944             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
   1945             boolean isolated) {
   1946         ProcessRecord app;
   1947         if (!isolated) {
   1948             app = getProcessRecordLocked(processName, info.uid);
   1949         } else {
   1950             // If this is an isolated process, it can't re-use an existing process.
   1951             app = null;
   1952         }
   1953         // We don't have to do anything more if:
   1954         // (1) There is an existing application record; and
   1955         // (2) The caller doesn't think it is dead, OR there is no thread
   1956         //     object attached to it so we know it couldn't have crashed; and
   1957         // (3) There is a pid assigned to it, so it is either starting or
   1958         //     already running.
   1959         if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
   1960                 + " app=" + app + " knownToBeDead=" + knownToBeDead
   1961                 + " thread=" + (app != null ? app.thread : null)
   1962                 + " pid=" + (app != null ? app.pid : -1));
   1963         if (app != null && app.pid > 0) {
   1964             if (!knownToBeDead || app.thread == null) {
   1965                 // We already have the app running, or are waiting for it to
   1966                 // come up (we have a pid but not yet its thread), so keep it.
   1967                 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
   1968                 // If this is a new package in the process, add the package to the list
   1969                 app.addPackage(info.packageName);
   1970                 return app;
   1971             } else {
   1972                 // An application record is attached to a previous process,
   1973                 // clean it up now.
   1974                 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
   1975                 handleAppDiedLocked(app, true, true);
   1976             }
   1977         }
   1978 
   1979         String hostingNameStr = hostingName != null
   1980                 ? hostingName.flattenToShortString() : null;
   1981 
   1982         if (!isolated) {
   1983             if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
   1984                 // If we are in the background, then check to see if this process
   1985                 // is bad.  If so, we will just silently fail.
   1986                 if (mBadProcesses.get(info.processName, info.uid) != null) {
   1987                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
   1988                             + "/" + info.processName);
   1989                     return null;
   1990                 }
   1991             } else {
   1992                 // When the user is explicitly starting a process, then clear its
   1993                 // crash count so that we won't make it bad until they see at
   1994                 // least one crash dialog again, and make the process good again
   1995                 // if it had been bad.
   1996                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
   1997                         + "/" + info.processName);
   1998                 mProcessCrashTimes.remove(info.processName, info.uid);
   1999                 if (mBadProcesses.get(info.processName, info.uid) != null) {
   2000                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
   2001                             UserHandle.getUserId(info.uid), info.uid,
   2002                             info.processName);
   2003                     mBadProcesses.remove(info.processName, info.uid);
   2004                     if (app != null) {
   2005                         app.bad = false;
   2006                     }
   2007                 }
   2008             }
   2009         }
   2010 
   2011         if (app == null) {
   2012             app = newProcessRecordLocked(null, info, processName, isolated);
   2013             if (app == null) {
   2014                 Slog.w(TAG, "Failed making new process record for "
   2015                         + processName + "/" + info.uid + " isolated=" + isolated);
   2016                 return null;
   2017             }
   2018             mProcessNames.put(processName, app.uid, app);
   2019             if (isolated) {
   2020                 mIsolatedProcesses.put(app.uid, app);
   2021             }
   2022         } else {
   2023             // If this is a new package in the process, add the package to the list
   2024             app.addPackage(info.packageName);
   2025         }
   2026 
   2027         // If the system is not ready yet, then hold off on starting this
   2028         // process until it is.
   2029         if (!mProcessesReady
   2030                 && !isAllowedWhileBooting(info)
   2031                 && !allowWhileBooting) {
   2032             if (!mProcessesOnHold.contains(app)) {
   2033                 mProcessesOnHold.add(app);
   2034             }
   2035             if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
   2036             return app;
   2037         }
   2038 
   2039         startProcessLocked(app, hostingType, hostingNameStr);
   2040         return (app.pid != 0) ? app : null;
   2041     }
   2042 
   2043     boolean isAllowedWhileBooting(ApplicationInfo ai) {
   2044         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
   2045     }
   2046 
   2047     private final void startProcessLocked(ProcessRecord app,
   2048             String hostingType, String hostingNameStr) {
   2049         if (app.pid > 0 && app.pid != MY_PID) {
   2050             synchronized (mPidsSelfLocked) {
   2051                 mPidsSelfLocked.remove(app.pid);
   2052                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   2053             }
   2054             app.setPid(0);
   2055         }
   2056 
   2057         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   2058                 "startProcessLocked removing on hold: " + app);
   2059         mProcessesOnHold.remove(app);
   2060 
   2061         updateCpuStats();
   2062 
   2063         System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
   2064         mProcDeaths[0] = 0;
   2065 
   2066         try {
   2067             int uid = app.uid;
   2068 
   2069             int[] gids = null;
   2070             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
   2071             if (!app.isolated) {
   2072                 int[] permGids = null;
   2073                 try {
   2074                     final PackageManager pm = mContext.getPackageManager();
   2075                     permGids = pm.getPackageGids(app.info.packageName);
   2076 
   2077                     if (Environment.isExternalStorageEmulated()) {
   2078                         if (pm.checkPermission(
   2079                                 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
   2080                                 app.info.packageName) == PERMISSION_GRANTED) {
   2081                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
   2082                         } else {
   2083                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
   2084                         }
   2085                     }
   2086                 } catch (PackageManager.NameNotFoundException e) {
   2087                     Slog.w(TAG, "Unable to retrieve gids", e);
   2088                 }
   2089 
   2090                 /*
   2091                  * Add shared application GID so applications can share some
   2092                  * resources like shared libraries
   2093                  */
   2094                 if (permGids == null) {
   2095                     gids = new int[1];
   2096                 } else {
   2097                     gids = new int[permGids.length + 1];
   2098                     System.arraycopy(permGids, 0, gids, 1, permGids.length);
   2099                 }
   2100                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
   2101             }
   2102             if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
   2103                 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
   2104                         && mTopComponent != null
   2105                         && app.processName.equals(mTopComponent.getPackageName())) {
   2106                     uid = 0;
   2107                 }
   2108                 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
   2109                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
   2110                     uid = 0;
   2111                 }
   2112             }
   2113             int debugFlags = 0;
   2114             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   2115                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
   2116                 // Also turn on CheckJNI for debuggable apps. It's quite
   2117                 // awkward to turn on otherwise.
   2118                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   2119             }
   2120             // Run the app in safe mode if its manifest requests so or the
   2121             // system is booted in safe mode.
   2122             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
   2123                 Zygote.systemInSafeMode == true) {
   2124                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
   2125             }
   2126             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
   2127                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   2128             }
   2129             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
   2130                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
   2131             }
   2132             if ("1".equals(SystemProperties.get("debug.assert"))) {
   2133                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
   2134             }
   2135 
   2136             // Start the process.  It will either succeed and return a result containing
   2137             // the PID of the new process, or else throw a RuntimeException.
   2138             Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
   2139                     app.processName, uid, uid, gids, debugFlags, mountExternal,
   2140                     app.info.targetSdkVersion, null, null);
   2141 
   2142             BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
   2143             synchronized (bs) {
   2144                 if (bs.isOnBattery()) {
   2145                     app.batteryStats.incStartsLocked();
   2146                 }
   2147             }
   2148 
   2149             EventLog.writeEvent(EventLogTags.AM_PROC_START,
   2150                     UserHandle.getUserId(uid), startResult.pid, uid,
   2151                     app.processName, hostingType,
   2152                     hostingNameStr != null ? hostingNameStr : "");
   2153 
   2154             if (app.persistent) {
   2155                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
   2156             }
   2157 
   2158             StringBuilder buf = mStringBuilder;
   2159             buf.setLength(0);
   2160             buf.append("Start proc ");
   2161             buf.append(app.processName);
   2162             buf.append(" for ");
   2163             buf.append(hostingType);
   2164             if (hostingNameStr != null) {
   2165                 buf.append(" ");
   2166                 buf.append(hostingNameStr);
   2167             }
   2168             buf.append(": pid=");
   2169             buf.append(startResult.pid);
   2170             buf.append(" uid=");
   2171             buf.append(uid);
   2172             buf.append(" gids={");
   2173             if (gids != null) {
   2174                 for (int gi=0; gi<gids.length; gi++) {
   2175                     if (gi != 0) buf.append(", ");
   2176                     buf.append(gids[gi]);
   2177 
   2178                 }
   2179             }
   2180             buf.append("}");
   2181             Slog.i(TAG, buf.toString());
   2182             app.setPid(startResult.pid);
   2183             app.usingWrapper = startResult.usingWrapper;
   2184             app.removed = false;
   2185             synchronized (mPidsSelfLocked) {
   2186                 this.mPidsSelfLocked.put(startResult.pid, app);
   2187                 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   2188                 msg.obj = app;
   2189                 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
   2190                         ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
   2191             }
   2192         } catch (RuntimeException e) {
   2193             // XXX do better error recovery.
   2194             app.setPid(0);
   2195             Slog.e(TAG, "Failure starting process " + app.processName, e);
   2196         }
   2197     }
   2198 
   2199     void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
   2200         if (resumed) {
   2201             mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
   2202         } else {
   2203             mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
   2204         }
   2205     }
   2206 
   2207     boolean startHomeActivityLocked(int userId) {
   2208         if (mHeadless) {
   2209             // Added because none of the other calls to ensureBootCompleted seem to fire
   2210             // when running headless.
   2211             ensureBootCompleted();
   2212             return false;
   2213         }
   2214 
   2215         if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
   2216                 && mTopAction == null) {
   2217             // We are running in factory test mode, but unable to find
   2218             // the factory test app, so just sit around displaying the
   2219             // error message and don't try to start anything.
   2220             return false;
   2221         }
   2222         Intent intent = new Intent(
   2223             mTopAction,
   2224             mTopData != null ? Uri.parse(mTopData) : null);
   2225         intent.setComponent(mTopComponent);
   2226         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   2227             intent.addCategory(Intent.CATEGORY_HOME);
   2228         }
   2229         ActivityInfo aInfo =
   2230             resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
   2231         if (aInfo != null) {
   2232             intent.setComponent(new ComponentName(
   2233                     aInfo.applicationInfo.packageName, aInfo.name));
   2234             // Don't do this if the home app is currently being
   2235             // instrumented.
   2236             aInfo = new ActivityInfo(aInfo);
   2237             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
   2238             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
   2239                     aInfo.applicationInfo.uid);
   2240             if (app == null || app.instrumentationClass == null) {
   2241                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
   2242                 mMainStack.startActivityLocked(null, intent, null, aInfo,
   2243                         null, null, 0, 0, 0, 0, null, false, null);
   2244             }
   2245         }
   2246 
   2247         return true;
   2248     }
   2249 
   2250     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
   2251         ActivityInfo ai = null;
   2252         ComponentName comp = intent.getComponent();
   2253         try {
   2254             if (comp != null) {
   2255                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
   2256             } else {
   2257                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
   2258                         intent,
   2259                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
   2260                             flags, userId);
   2261 
   2262                 if (info != null) {
   2263                     ai = info.activityInfo;
   2264                 }
   2265             }
   2266         } catch (RemoteException e) {
   2267             // ignore
   2268         }
   2269 
   2270         return ai;
   2271     }
   2272 
   2273     /**
   2274      * Starts the "new version setup screen" if appropriate.
   2275      */
   2276     void startSetupActivityLocked() {
   2277         // Only do this once per boot.
   2278         if (mCheckedForSetup) {
   2279             return;
   2280         }
   2281 
   2282         // We will show this screen if the current one is a different
   2283         // version than the last one shown, and we are not running in
   2284         // low-level factory test mode.
   2285         final ContentResolver resolver = mContext.getContentResolver();
   2286         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
   2287                 Settings.Global.getInt(resolver,
   2288                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
   2289             mCheckedForSetup = true;
   2290 
   2291             // See if we should be showing the platform update setup UI.
   2292             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
   2293             List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
   2294                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
   2295 
   2296             // We don't allow third party apps to replace this.
   2297             ResolveInfo ri = null;
   2298             for (int i=0; ris != null && i<ris.size(); i++) {
   2299                 if ((ris.get(i).activityInfo.applicationInfo.flags
   2300                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
   2301                     ri = ris.get(i);
   2302                     break;
   2303                 }
   2304             }
   2305 
   2306             if (ri != null) {
   2307                 String vers = ri.activityInfo.metaData != null
   2308                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
   2309                         : null;
   2310                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
   2311                     vers = ri.activityInfo.applicationInfo.metaData.getString(
   2312                             Intent.METADATA_SETUP_VERSION);
   2313                 }
   2314                 String lastVers = Settings.Secure.getString(
   2315                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
   2316                 if (vers != null && !vers.equals(lastVers)) {
   2317                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   2318                     intent.setComponent(new ComponentName(
   2319                             ri.activityInfo.packageName, ri.activityInfo.name));
   2320                     mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
   2321                             null, null, 0, 0, 0, 0, null, false, null);
   2322                 }
   2323             }
   2324         }
   2325     }
   2326 
   2327     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
   2328         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
   2329     }
   2330 
   2331     void enforceNotIsolatedCaller(String caller) {
   2332         if (UserHandle.isIsolated(Binder.getCallingUid())) {
   2333             throw new SecurityException("Isolated process not allowed to call " + caller);
   2334         }
   2335     }
   2336 
   2337     public int getFrontActivityScreenCompatMode() {
   2338         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
   2339         synchronized (this) {
   2340             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
   2341         }
   2342     }
   2343 
   2344     public void setFrontActivityScreenCompatMode(int mode) {
   2345         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   2346                 "setFrontActivityScreenCompatMode");
   2347         synchronized (this) {
   2348             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
   2349         }
   2350     }
   2351 
   2352     public int getPackageScreenCompatMode(String packageName) {
   2353         enforceNotIsolatedCaller("getPackageScreenCompatMode");
   2354         synchronized (this) {
   2355             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
   2356         }
   2357     }
   2358 
   2359     public void setPackageScreenCompatMode(String packageName, int mode) {
   2360         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   2361                 "setPackageScreenCompatMode");
   2362         synchronized (this) {
   2363             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
   2364         }
   2365     }
   2366 
   2367     public boolean getPackageAskScreenCompat(String packageName) {
   2368         enforceNotIsolatedCaller("getPackageAskScreenCompat");
   2369         synchronized (this) {
   2370             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
   2371         }
   2372     }
   2373 
   2374     public void setPackageAskScreenCompat(String packageName, boolean ask) {
   2375         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   2376                 "setPackageAskScreenCompat");
   2377         synchronized (this) {
   2378             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
   2379         }
   2380     }
   2381 
   2382     void reportResumedActivityLocked(ActivityRecord r) {
   2383         //Slog.i(TAG, "**** REPORT RESUME: " + r);
   2384         updateUsageStats(r, true);
   2385     }
   2386 
   2387     private void dispatchProcessesChanged() {
   2388         int N;
   2389         synchronized (this) {
   2390             N = mPendingProcessChanges.size();
   2391             if (mActiveProcessChanges.length < N) {
   2392                 mActiveProcessChanges = new ProcessChangeItem[N];
   2393             }
   2394             mPendingProcessChanges.toArray(mActiveProcessChanges);
   2395             mAvailProcessChanges.addAll(mPendingProcessChanges);
   2396             mPendingProcessChanges.clear();
   2397             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
   2398         }
   2399         int i = mProcessObservers.beginBroadcast();
   2400         while (i > 0) {
   2401             i--;
   2402             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   2403             if (observer != null) {
   2404                 try {
   2405                     for (int j=0; j<N; j++) {
   2406                         ProcessChangeItem item = mActiveProcessChanges[j];
   2407                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
   2408                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
   2409                                     + item.pid + " uid=" + item.uid + ": "
   2410                                     + item.foregroundActivities);
   2411                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
   2412                                     item.foregroundActivities);
   2413                         }
   2414                         if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
   2415                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
   2416                                     + item.pid + " uid=" + item.uid + ": " + item.importance);
   2417                             observer.onImportanceChanged(item.pid, item.uid,
   2418                                     item.importance);
   2419                         }
   2420                     }
   2421                 } catch (RemoteException e) {
   2422                 }
   2423             }
   2424         }
   2425         mProcessObservers.finishBroadcast();
   2426     }
   2427 
   2428     private void dispatchProcessDied(int pid, int uid) {
   2429         int i = mProcessObservers.beginBroadcast();
   2430         while (i > 0) {
   2431             i--;
   2432             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   2433             if (observer != null) {
   2434                 try {
   2435                     observer.onProcessDied(pid, uid);
   2436                 } catch (RemoteException e) {
   2437                 }
   2438             }
   2439         }
   2440         mProcessObservers.finishBroadcast();
   2441     }
   2442 
   2443     final void doPendingActivityLaunchesLocked(boolean doResume) {
   2444         final int N = mPendingActivityLaunches.size();
   2445         if (N <= 0) {
   2446             return;
   2447         }
   2448         for (int i=0; i<N; i++) {
   2449             PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
   2450             mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
   2451                     pal.startFlags, doResume && i == (N-1), null);
   2452         }
   2453         mPendingActivityLaunches.clear();
   2454     }
   2455 
   2456     public final int startActivity(IApplicationThread caller,
   2457             Intent intent, String resolvedType, IBinder resultTo,
   2458             String resultWho, int requestCode, int startFlags,
   2459             String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
   2460         return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
   2461                 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
   2462     }
   2463 
   2464     public final int startActivityAsUser(IApplicationThread caller,
   2465             Intent intent, String resolvedType, IBinder resultTo,
   2466             String resultWho, int requestCode, int startFlags,
   2467             String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
   2468         enforceNotIsolatedCaller("startActivity");
   2469         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   2470                 false, true, "startActivity", null);
   2471         return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
   2472                 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
   2473                 null, null, options, userId);
   2474     }
   2475 
   2476     public final WaitResult startActivityAndWait(IApplicationThread caller,
   2477             Intent intent, String resolvedType, IBinder resultTo,
   2478             String resultWho, int requestCode, int startFlags, String profileFile,
   2479             ParcelFileDescriptor profileFd, Bundle options, int userId) {
   2480         enforceNotIsolatedCaller("startActivityAndWait");
   2481         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   2482                 false, true, "startActivityAndWait", null);
   2483         WaitResult res = new WaitResult();
   2484         mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
   2485                 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
   2486                 res, null, options, UserHandle.getCallingUserId());
   2487         return res;
   2488     }
   2489 
   2490     public final int startActivityWithConfig(IApplicationThread caller,
   2491             Intent intent, String resolvedType, IBinder resultTo,
   2492             String resultWho, int requestCode, int startFlags, Configuration config,
   2493             Bundle options, int userId) {
   2494         enforceNotIsolatedCaller("startActivityWithConfig");
   2495         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   2496                 false, true, "startActivityWithConfig", null);
   2497         int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
   2498                 resultTo, resultWho, requestCode, startFlags,
   2499                 null, null, null, config, options, userId);
   2500         return ret;
   2501     }
   2502 
   2503     public int startActivityIntentSender(IApplicationThread caller,
   2504             IntentSender intent, Intent fillInIntent, String resolvedType,
   2505             IBinder resultTo, String resultWho, int requestCode,
   2506             int flagsMask, int flagsValues, Bundle options) {
   2507         enforceNotIsolatedCaller("startActivityIntentSender");
   2508         // Refuse possible leaked file descriptors
   2509         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
   2510             throw new IllegalArgumentException("File descriptors passed in Intent");
   2511         }
   2512 
   2513         IIntentSender sender = intent.getTarget();
   2514         if (!(sender instanceof PendingIntentRecord)) {
   2515             throw new IllegalArgumentException("Bad PendingIntent object");
   2516         }
   2517 
   2518         PendingIntentRecord pir = (PendingIntentRecord)sender;
   2519 
   2520         synchronized (this) {
   2521             // If this is coming from the currently resumed activity, it is
   2522             // effectively saying that app switches are allowed at this point.
   2523             if (mMainStack.mResumedActivity != null
   2524                     && mMainStack.mResumedActivity.info.applicationInfo.uid ==
   2525                             Binder.getCallingUid()) {
   2526                 mAppSwitchesAllowedTime = 0;
   2527             }
   2528         }
   2529         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
   2530                 resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
   2531         return ret;
   2532     }
   2533 
   2534     public boolean startNextMatchingActivity(IBinder callingActivity,
   2535             Intent intent, Bundle options) {
   2536         // Refuse possible leaked file descriptors
   2537         if (intent != null && intent.hasFileDescriptors() == true) {
   2538             throw new IllegalArgumentException("File descriptors passed in Intent");
   2539         }
   2540 
   2541         synchronized (this) {
   2542             ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
   2543             if (r == null) {
   2544                 ActivityOptions.abort(options);
   2545                 return false;
   2546             }
   2547             if (r.app == null || r.app.thread == null) {
   2548                 // The caller is not running...  d'oh!
   2549                 ActivityOptions.abort(options);
   2550                 return false;
   2551             }
   2552             intent = new Intent(intent);
   2553             // The caller is not allowed to change the data.
   2554             intent.setDataAndType(r.intent.getData(), r.intent.getType());
   2555             // And we are resetting to find the next component...
   2556             intent.setComponent(null);
   2557 
   2558             ActivityInfo aInfo = null;
   2559             try {
   2560                 List<ResolveInfo> resolves =
   2561                     AppGlobals.getPackageManager().queryIntentActivities(
   2562                             intent, r.resolvedType,
   2563                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
   2564                             UserHandle.getCallingUserId());
   2565 
   2566                 // Look for the original activity in the list...
   2567                 final int N = resolves != null ? resolves.size() : 0;
   2568                 for (int i=0; i<N; i++) {
   2569                     ResolveInfo rInfo = resolves.get(i);
   2570                     if (rInfo.activityInfo.packageName.equals(r.packageName)
   2571                             && rInfo.activityInfo.name.equals(r.info.name)) {
   2572                         // We found the current one...  the next matching is
   2573                         // after it.
   2574                         i++;
   2575                         if (i<N) {
   2576                             aInfo = resolves.get(i).activityInfo;
   2577                         }
   2578                         break;
   2579                     }
   2580                 }
   2581             } catch (RemoteException e) {
   2582             }
   2583 
   2584             if (aInfo == null) {
   2585                 // Nobody who is next!
   2586                 ActivityOptions.abort(options);
   2587                 return false;
   2588             }
   2589 
   2590             intent.setComponent(new ComponentName(
   2591                     aInfo.applicationInfo.packageName, aInfo.name));
   2592             intent.setFlags(intent.getFlags()&~(
   2593                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
   2594                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
   2595                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
   2596                     Intent.FLAG_ACTIVITY_NEW_TASK));
   2597 
   2598             // Okay now we need to start the new activity, replacing the
   2599             // currently running activity.  This is a little tricky because
   2600             // we want to start the new one as if the current one is finished,
   2601             // but not finish the current one first so that there is no flicker.
   2602             // And thus...
   2603             final boolean wasFinishing = r.finishing;
   2604             r.finishing = true;
   2605 
   2606             // Propagate reply information over to the new activity.
   2607             final ActivityRecord resultTo = r.resultTo;
   2608             final String resultWho = r.resultWho;
   2609             final int requestCode = r.requestCode;
   2610             r.resultTo = null;
   2611             if (resultTo != null) {
   2612                 resultTo.removeResultsLocked(r, resultWho, requestCode);
   2613             }
   2614 
   2615             final long origId = Binder.clearCallingIdentity();
   2616             int res = mMainStack.startActivityLocked(r.app.thread, intent,
   2617                     r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
   2618                     resultWho, requestCode, -1, r.launchedFromUid, 0,
   2619                     options, false, null);
   2620             Binder.restoreCallingIdentity(origId);
   2621 
   2622             r.finishing = wasFinishing;
   2623             if (res != ActivityManager.START_SUCCESS) {
   2624                 return false;
   2625             }
   2626             return true;
   2627         }
   2628     }
   2629 
   2630     final int startActivityInPackage(int uid,
   2631             Intent intent, String resolvedType, IBinder resultTo,
   2632             String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
   2633 
   2634         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   2635                 false, true, "startActivityInPackage", null);
   2636 
   2637         int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
   2638                 resultTo, resultWho, requestCode, startFlags,
   2639                 null, null, null, null, options, userId);
   2640         return ret;
   2641     }
   2642 
   2643     public final int startActivities(IApplicationThread caller,
   2644             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
   2645             int userId) {
   2646         enforceNotIsolatedCaller("startActivities");
   2647         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   2648                 false, true, "startActivity", null);
   2649         int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
   2650                 options, userId);
   2651         return ret;
   2652     }
   2653 
   2654     final int startActivitiesInPackage(int uid,
   2655             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
   2656             Bundle options, int userId) {
   2657 
   2658         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   2659                 false, true, "startActivityInPackage", null);
   2660         int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
   2661                 options, userId);
   2662         return ret;
   2663     }
   2664 
   2665     final void addRecentTaskLocked(TaskRecord task) {
   2666         int N = mRecentTasks.size();
   2667         // Quick case: check if the top-most recent task is the same.
   2668         if (N > 0 && mRecentTasks.get(0) == task) {
   2669             return;
   2670         }
   2671         // Remove any existing entries that are the same kind of task.
   2672         for (int i=0; i<N; i++) {
   2673             TaskRecord tr = mRecentTasks.get(i);
   2674             if (task.userId == tr.userId
   2675                     && ((task.affinity != null && task.affinity.equals(tr.affinity))
   2676                     || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
   2677                 mRecentTasks.remove(i);
   2678                 i--;
   2679                 N--;
   2680                 if (task.intent == null) {
   2681                     // If the new recent task we are adding is not fully
   2682                     // specified, then replace it with the existing recent task.
   2683                     task = tr;
   2684                 }
   2685             }
   2686         }
   2687         if (N >= MAX_RECENT_TASKS) {
   2688             mRecentTasks.remove(N-1);
   2689         }
   2690         mRecentTasks.add(0, task);
   2691     }
   2692 
   2693     public void setRequestedOrientation(IBinder token,
   2694             int requestedOrientation) {
   2695         synchronized (this) {
   2696             ActivityRecord r = mMainStack.isInStackLocked(token);
   2697             if (r == null) {
   2698                 return;
   2699             }
   2700             final long origId = Binder.clearCallingIdentity();
   2701             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
   2702             Configuration config = mWindowManager.updateOrientationFromAppTokens(
   2703                     mConfiguration,
   2704                     r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
   2705             if (config != null) {
   2706                 r.frozenBeforeDestroy = true;
   2707                 if (!updateConfigurationLocked(config, r, false, false)) {
   2708                     mMainStack.resumeTopActivityLocked(null);
   2709                 }
   2710             }
   2711             Binder.restoreCallingIdentity(origId);
   2712         }
   2713     }
   2714 
   2715     public int getRequestedOrientation(IBinder token) {
   2716         synchronized (this) {
   2717             ActivityRecord r = mMainStack.isInStackLocked(token);
   2718             if (r == null) {
   2719                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
   2720             }
   2721             return mWindowManager.getAppOrientation(r.appToken);
   2722         }
   2723     }
   2724 
   2725     /**
   2726      * This is the internal entry point for handling Activity.finish().
   2727      *
   2728      * @param token The Binder token referencing the Activity we want to finish.
   2729      * @param resultCode Result code, if any, from this Activity.
   2730      * @param resultData Result data (Intent), if any, from this Activity.
   2731      *
   2732      * @return Returns true if the activity successfully finished, or false if it is still running.
   2733      */
   2734     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
   2735         // Refuse possible leaked file descriptors
   2736         if (resultData != null && resultData.hasFileDescriptors() == true) {
   2737             throw new IllegalArgumentException("File descriptors passed in Intent");
   2738         }
   2739 
   2740         synchronized(this) {
   2741             if (mController != null) {
   2742                 // Find the first activity that is not finishing.
   2743                 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
   2744                 if (next != null) {
   2745                     // ask watcher if this is allowed
   2746                     boolean resumeOK = true;
   2747                     try {
   2748                         resumeOK = mController.activityResuming(next.packageName);
   2749                     } catch (RemoteException e) {
   2750                         mController = null;
   2751                     }
   2752 
   2753                     if (!resumeOK) {
   2754                         return false;
   2755                     }
   2756                 }
   2757             }
   2758             final long origId = Binder.clearCallingIdentity();
   2759             boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
   2760                     resultData, "app-request", true);
   2761             Binder.restoreCallingIdentity(origId);
   2762             return res;
   2763         }
   2764     }
   2765 
   2766     public final void finishHeavyWeightApp() {
   2767         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   2768                 != PackageManager.PERMISSION_GRANTED) {
   2769             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
   2770                     + Binder.getCallingPid()
   2771                     + ", uid=" + Binder.getCallingUid()
   2772                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   2773             Slog.w(TAG, msg);
   2774             throw new SecurityException(msg);
   2775         }
   2776 
   2777         synchronized(this) {
   2778             if (mHeavyWeightProcess == null) {
   2779                 return;
   2780             }
   2781 
   2782             ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
   2783                     mHeavyWeightProcess.activities);
   2784             for (int i=0; i<activities.size(); i++) {
   2785                 ActivityRecord r = activities.get(i);
   2786                 if (!r.finishing) {
   2787                     int index = mMainStack.indexOfTokenLocked(r.appToken);
   2788                     if (index >= 0) {
   2789                         mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
   2790                                 null, "finish-heavy", true);
   2791                     }
   2792                 }
   2793             }
   2794 
   2795             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   2796                     mHeavyWeightProcess.userId, 0));
   2797             mHeavyWeightProcess = null;
   2798         }
   2799     }
   2800 
   2801     public void crashApplication(int uid, int initialPid, String packageName,
   2802             String message) {
   2803         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   2804                 != PackageManager.PERMISSION_GRANTED) {
   2805             String msg = "Permission Denial: crashApplication() from pid="
   2806                     + Binder.getCallingPid()
   2807                     + ", uid=" + Binder.getCallingUid()
   2808                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   2809             Slog.w(TAG, msg);
   2810             throw new SecurityException(msg);
   2811         }
   2812 
   2813         synchronized(this) {
   2814             ProcessRecord proc = null;
   2815 
   2816             // Figure out which process to kill.  We don't trust that initialPid
   2817             // still has any relation to current pids, so must scan through the
   2818             // list.
   2819             synchronized (mPidsSelfLocked) {
   2820                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   2821                     ProcessRecord p = mPidsSelfLocked.valueAt(i);
   2822                     if (p.uid != uid) {
   2823                         continue;
   2824                     }
   2825                     if (p.pid == initialPid) {
   2826                         proc = p;
   2827                         break;
   2828                     }
   2829                     for (String str : p.pkgList) {
   2830                         if (str.equals(packageName)) {
   2831                             proc = p;
   2832                         }
   2833                     }
   2834                 }
   2835             }
   2836 
   2837             if (proc == null) {
   2838                 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
   2839                         + " initialPid=" + initialPid
   2840                         + " packageName=" + packageName);
   2841                 return;
   2842             }
   2843 
   2844             if (proc.thread != null) {
   2845                 if (proc.pid == Process.myPid()) {
   2846                     Log.w(TAG, "crashApplication: trying to crash self!");
   2847                     return;
   2848                 }
   2849                 long ident = Binder.clearCallingIdentity();
   2850                 try {
   2851                     proc.thread.scheduleCrash(message);
   2852                 } catch (RemoteException e) {
   2853                 }
   2854                 Binder.restoreCallingIdentity(ident);
   2855             }
   2856         }
   2857     }
   2858 
   2859     public final void finishSubActivity(IBinder token, String resultWho,
   2860             int requestCode) {
   2861         synchronized(this) {
   2862             final long origId = Binder.clearCallingIdentity();
   2863             mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
   2864             Binder.restoreCallingIdentity(origId);
   2865         }
   2866     }
   2867 
   2868     public boolean finishActivityAffinity(IBinder token) {
   2869         synchronized(this) {
   2870             final long origId = Binder.clearCallingIdentity();
   2871             boolean res = mMainStack.finishActivityAffinityLocked(token);
   2872             Binder.restoreCallingIdentity(origId);
   2873             return res;
   2874         }
   2875     }
   2876 
   2877     public boolean willActivityBeVisible(IBinder token) {
   2878         synchronized(this) {
   2879             int i;
   2880             for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
   2881                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   2882                 if (r.appToken == token) {
   2883                     return true;
   2884                 }
   2885                 if (r.fullscreen && !r.finishing) {
   2886                     return false;
   2887                 }
   2888             }
   2889             return true;
   2890         }
   2891     }
   2892 
   2893     public void overridePendingTransition(IBinder token, String packageName,
   2894             int enterAnim, int exitAnim) {
   2895         synchronized(this) {
   2896             ActivityRecord self = mMainStack.isInStackLocked(token);
   2897             if (self == null) {
   2898                 return;
   2899             }
   2900 
   2901             final long origId = Binder.clearCallingIdentity();
   2902 
   2903             if (self.state == ActivityState.RESUMED
   2904                     || self.state == ActivityState.PAUSING) {
   2905                 mWindowManager.overridePendingAppTransition(packageName,
   2906                         enterAnim, exitAnim, null);
   2907             }
   2908 
   2909             Binder.restoreCallingIdentity(origId);
   2910         }
   2911     }
   2912 
   2913     /**
   2914      * Main function for removing an existing process from the activity manager
   2915      * as a result of that process going away.  Clears out all connections
   2916      * to the process.
   2917      */
   2918     private final void handleAppDiedLocked(ProcessRecord app,
   2919             boolean restarting, boolean allowRestart) {
   2920         cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
   2921         if (!restarting) {
   2922             mLruProcesses.remove(app);
   2923         }
   2924 
   2925         if (mProfileProc == app) {
   2926             clearProfilerLocked();
   2927         }
   2928 
   2929         // Just in case...
   2930         if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
   2931             if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG,
   2932                     "App died while pausing: " + mMainStack.mPausingActivity);
   2933             mMainStack.mPausingActivity = null;
   2934         }
   2935         if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
   2936             mMainStack.mLastPausedActivity = null;
   2937         }
   2938 
   2939         // Remove this application's activities from active lists.
   2940         boolean hasVisibleActivities = mMainStack.removeHistoryRecordsForAppLocked(app);
   2941 
   2942         app.activities.clear();
   2943 
   2944         if (app.instrumentationClass != null) {
   2945             Slog.w(TAG, "Crash of app " + app.processName
   2946                   + " running instrumentation " + app.instrumentationClass);
   2947             Bundle info = new Bundle();
   2948             info.putString("shortMsg", "Process crashed.");
   2949             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
   2950         }
   2951 
   2952         if (!restarting) {
   2953             if (!mMainStack.resumeTopActivityLocked(null)) {
   2954                 // If there was nothing to resume, and we are not already
   2955                 // restarting this process, but there is a visible activity that
   2956                 // is hosted by the process...  then make sure all visible
   2957                 // activities are running, taking care of restarting this
   2958                 // process.
   2959                 if (hasVisibleActivities) {
   2960                     mMainStack.ensureActivitiesVisibleLocked(null, 0);
   2961                 }
   2962             }
   2963         }
   2964     }
   2965 
   2966     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
   2967         IBinder threadBinder = thread.asBinder();
   2968         // Find the application record.
   2969         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   2970             ProcessRecord rec = mLruProcesses.get(i);
   2971             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
   2972                 return i;
   2973             }
   2974         }
   2975         return -1;
   2976     }
   2977 
   2978     final ProcessRecord getRecordForAppLocked(
   2979             IApplicationThread thread) {
   2980         if (thread == null) {
   2981             return null;
   2982         }
   2983 
   2984         int appIndex = getLRURecordIndexForAppLocked(thread);
   2985         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
   2986     }
   2987 
   2988     final void appDiedLocked(ProcessRecord app, int pid,
   2989             IApplicationThread thread) {
   2990 
   2991         mProcDeaths[0]++;
   2992 
   2993         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   2994         synchronized (stats) {
   2995             stats.noteProcessDiedLocked(app.info.uid, pid);
   2996         }
   2997 
   2998         // Clean up already done if the process has been re-started.
   2999         if (app.pid == pid && app.thread != null &&
   3000                 app.thread.asBinder() == thread.asBinder()) {
   3001             if (!app.killedBackground) {
   3002                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   3003                         + ") has died.");
   3004             }
   3005             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
   3006             if (DEBUG_CLEANUP) Slog.v(
   3007                 TAG, "Dying app: " + app + ", pid: " + pid
   3008                 + ", thread: " + thread.asBinder());
   3009             boolean doLowMem = app.instrumentationClass == null;
   3010             handleAppDiedLocked(app, false, true);
   3011 
   3012             if (doLowMem) {
   3013                 // If there are no longer any background processes running,
   3014                 // and the app that died was not running instrumentation,
   3015                 // then tell everyone we are now low on memory.
   3016                 boolean haveBg = false;
   3017                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   3018                     ProcessRecord rec = mLruProcesses.get(i);
   3019                     if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   3020                         haveBg = true;
   3021                         break;
   3022                     }
   3023                 }
   3024 
   3025                 if (!haveBg) {
   3026                     EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
   3027                     long now = SystemClock.uptimeMillis();
   3028                     for (int i=mLruProcesses.size()-1; i>=0; i--) {
   3029                         ProcessRecord rec = mLruProcesses.get(i);
   3030                         if (rec != app && rec.thread != null &&
   3031                                 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
   3032                             // The low memory report is overriding any current
   3033                             // state for a GC request.  Make sure to do
   3034                             // heavy/important/visible/foreground processes first.
   3035                             if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   3036                                 rec.lastRequestedGc = 0;
   3037                             } else {
   3038                                 rec.lastRequestedGc = rec.lastLowMemory;
   3039                             }
   3040                             rec.reportLowMemory = true;
   3041                             rec.lastLowMemory = now;
   3042                             mProcessesToGc.remove(rec);
   3043                             addProcessToGcListLocked(rec);
   3044                         }
   3045                     }
   3046                     mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
   3047                     scheduleAppGcsLocked();
   3048                 }
   3049             }
   3050         } else if (app.pid != pid) {
   3051             // A new process has already been started.
   3052             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   3053                     + ") has died and restarted (pid " + app.pid + ").");
   3054             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
   3055         } else if (DEBUG_PROCESSES) {
   3056             Slog.d(TAG, "Received spurious death notification for thread "
   3057                     + thread.asBinder());
   3058         }
   3059     }
   3060 
   3061     /**
   3062      * If a stack trace dump file is configured, dump process stack traces.
   3063      * @param clearTraces causes the dump file to be erased prior to the new
   3064      *    traces being written, if true; when false, the new traces will be
   3065      *    appended to any existing file content.
   3066      * @param firstPids of dalvik VM processes to dump stack traces for first
   3067      * @param lastPids of dalvik VM processes to dump stack traces for last
   3068      * @param nativeProcs optional list of native process names to dump stack crawls
   3069      * @return file containing stack traces, or null if no dump file is configured
   3070      */
   3071     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
   3072             ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
   3073         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   3074         if (tracesPath == null || tracesPath.length() == 0) {
   3075             return null;
   3076         }
   3077 
   3078         File tracesFile = new File(tracesPath);
   3079         try {
   3080             File tracesDir = tracesFile.getParentFile();
   3081             if (!tracesDir.exists()) {
   3082                 tracesFile.mkdirs();
   3083                 if (!SELinux.restorecon(tracesDir)) {
   3084                     return null;
   3085                 }
   3086             }
   3087             FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
   3088 
   3089             if (clearTraces && tracesFile.exists()) tracesFile.delete();
   3090             tracesFile.createNewFile();
   3091             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   3092         } catch (IOException e) {
   3093             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
   3094             return null;
   3095         }
   3096 
   3097         dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
   3098         return tracesFile;
   3099     }
   3100 
   3101     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
   3102             ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
   3103         // Use a FileObserver to detect when traces finish writing.
   3104         // The order of traces is considered important to maintain for legibility.
   3105         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
   3106             public synchronized void onEvent(int event, String path) { notify(); }
   3107         };
   3108 
   3109         try {
   3110             observer.startWatching();
   3111 
   3112             // First collect all of the stacks of the most important pids.
   3113             if (firstPids != null) {
   3114                 try {
   3115                     int num = firstPids.size();
   3116                     for (int i = 0; i < num; i++) {
   3117                         synchronized (observer) {
   3118                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
   3119                             observer.wait(200);  // Wait for write-close, give up after 200msec
   3120                         }
   3121                     }
   3122                 } catch (InterruptedException e) {
   3123                     Log.wtf(TAG, e);
   3124                 }
   3125             }
   3126 
   3127             // Next measure CPU usage.
   3128             if (processStats != null) {
   3129                 processStats.init();
   3130                 System.gc();
   3131                 processStats.update();
   3132                 try {
   3133                     synchronized (processStats) {
   3134                         processStats.wait(500); // measure over 1/2 second.
   3135                     }
   3136                 } catch (InterruptedException e) {
   3137                 }
   3138                 processStats.update();
   3139 
   3140                 // We'll take the stack crawls of just the top apps using CPU.
   3141                 final int N = processStats.countWorkingStats();
   3142                 int numProcs = 0;
   3143                 for (int i=0; i<N && numProcs<5; i++) {
   3144                     ProcessStats.Stats stats = processStats.getWorkingStats(i);
   3145                     if (lastPids.indexOfKey(stats.pid) >= 0) {
   3146                         numProcs++;
   3147                         try {
   3148                             synchronized (observer) {
   3149                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
   3150                                 observer.wait(200);  // Wait for write-close, give up after 200msec
   3151                             }
   3152                         } catch (InterruptedException e) {
   3153                             Log.wtf(TAG, e);
   3154                         }
   3155 
   3156                     }
   3157                 }
   3158             }
   3159 
   3160         } finally {
   3161             observer.stopWatching();
   3162         }
   3163 
   3164         if (nativeProcs != null) {
   3165             int[] pids = Process.getPidsForCommands(nativeProcs);
   3166             if (pids != null) {
   3167                 for (int pid : pids) {
   3168                     Debug.dumpNativeBacktraceToFile(pid, tracesPath);
   3169                 }
   3170             }
   3171         }
   3172     }
   3173 
   3174     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
   3175         if (true || IS_USER_BUILD) {
   3176             return;
   3177         }
   3178         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   3179         if (tracesPath == null || tracesPath.length() == 0) {
   3180             return;
   3181         }
   3182 
   3183         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
   3184         StrictMode.allowThreadDiskWrites();
   3185         try {
   3186             final File tracesFile = new File(tracesPath);
   3187             final File tracesDir = tracesFile.getParentFile();
   3188             final File tracesTmp = new File(tracesDir, "__tmp__");
   3189             try {
   3190                 if (!tracesDir.exists()) {
   3191                     tracesFile.mkdirs();
   3192                     if (!SELinux.restorecon(tracesDir.getPath())) {
   3193                         return;
   3194                     }
   3195                 }
   3196                 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
   3197 
   3198                 if (tracesFile.exists()) {
   3199                     tracesTmp.delete();
   3200                     tracesFile.renameTo(tracesTmp);
   3201                 }
   3202                 StringBuilder sb = new StringBuilder();
   3203                 Time tobj = new Time();
   3204                 tobj.set(System.currentTimeMillis());
   3205                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
   3206                 sb.append(": ");
   3207                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
   3208                 sb.append(" since ");
   3209                 sb.append(msg);
   3210                 FileOutputStream fos = new FileOutputStream(tracesFile);
   3211                 fos.write(sb.toString().getBytes());
   3212                 if (app == null) {
   3213                     fos.write("\n*** No application process!".getBytes());
   3214                 }
   3215                 fos.close();
   3216                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   3217             } catch (IOException e) {
   3218                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
   3219                 return;
   3220             }
   3221 
   3222             if (app != null) {
   3223                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
   3224                 firstPids.add(app.pid);
   3225                 dumpStackTraces(tracesPath, firstPids, null, null, null);
   3226             }
   3227 
   3228             File lastTracesFile = null;
   3229             File curTracesFile = null;
   3230             for (int i=9; i>=0; i--) {
   3231                 String name = String.format("slow%02d.txt", i);
   3232                 curTracesFile = new File(tracesDir, name);
   3233                 if (curTracesFile.exists()) {
   3234                     if (lastTracesFile != null) {
   3235                         curTracesFile.renameTo(lastTracesFile);
   3236                     } else {
   3237                         curTracesFile.delete();
   3238                     }
   3239                 }
   3240                 lastTracesFile = curTracesFile;
   3241             }
   3242             tracesFile.renameTo(curTracesFile);
   3243             if (tracesTmp.exists()) {
   3244                 tracesTmp.renameTo(tracesFile);
   3245             }
   3246         } finally {
   3247             StrictMode.setThreadPolicy(oldPolicy);
   3248         }
   3249     }
   3250 
   3251     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
   3252             ActivityRecord parent, boolean aboveSystem, final String annotation) {
   3253         ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
   3254         SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
   3255 
   3256         if (mController != null) {
   3257             try {
   3258                 // 0 == continue, -1 = kill process immediately
   3259                 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
   3260                 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
   3261             } catch (RemoteException e) {
   3262                 mController = null;
   3263             }
   3264         }
   3265 
   3266         long anrTime = SystemClock.uptimeMillis();
   3267         if (MONITOR_CPU_USAGE) {
   3268             updateCpuStatsNow();
   3269         }
   3270 
   3271         synchronized (this) {
   3272             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
   3273             if (mShuttingDown) {
   3274                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
   3275                 return;
   3276             } else if (app.notResponding) {
   3277                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
   3278                 return;
   3279             } else if (app.crashing) {
   3280                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
   3281                 return;
   3282             }
   3283 
   3284             // In case we come through here for the same app before completing
   3285             // this one, mark as anring now so we will bail out.
   3286             app.notResponding = true;
   3287 
   3288             // Log the ANR to the event log.
   3289             EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
   3290                     app.processName, app.info.flags, annotation);
   3291 
   3292             // Dump thread traces as quickly as we can, starting with "interesting" processes.
   3293             firstPids.add(app.pid);
   3294 
   3295             int parentPid = app.pid;
   3296             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
   3297             if (parentPid != app.pid) firstPids.add(parentPid);
   3298 
   3299             if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
   3300 
   3301             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   3302                 ProcessRecord r = mLruProcesses.get(i);
   3303                 if (r != null && r.thread != null) {
   3304                     int pid = r.pid;
   3305                     if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
   3306                         if (r.persistent) {
   3307                             firstPids.add(pid);
   3308                         } else {
   3309                             lastPids.put(pid, Boolean.TRUE);
   3310                         }
   3311                     }
   3312                 }
   3313             }
   3314         }
   3315 
   3316         // Log the ANR to the main log.
   3317         StringBuilder info = new StringBuilder();
   3318         info.setLength(0);
   3319         info.append("ANR in ").append(app.processName);
   3320         if (activity != null && activity.shortComponentName != null) {
   3321             info.append(" (").append(activity.shortComponentName).append(")");
   3322         }
   3323         info.append("\n");
   3324         if (annotation != null) {
   3325             info.append("Reason: ").append(annotation).append("\n");
   3326         }
   3327         if (parent != null && parent != activity) {
   3328             info.append("Parent: ").append(parent.shortComponentName).append("\n");
   3329         }
   3330 
   3331         final ProcessStats processStats = new ProcessStats(true);
   3332 
   3333         File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
   3334 
   3335         String cpuInfo = null;
   3336         if (MONITOR_CPU_USAGE) {
   3337             updateCpuStatsNow();
   3338             synchronized (mProcessStatsThread) {
   3339                 cpuInfo = mProcessStats.printCurrentState(anrTime);
   3340             }
   3341             info.append(processStats.printCurrentLoad());
   3342             info.append(cpuInfo);
   3343         }
   3344 
   3345         info.append(processStats.printCurrentState(anrTime));
   3346 
   3347         Slog.e(TAG, info.toString());
   3348         if (tracesFile == null) {
   3349             // There is no trace file, so dump (only) the alleged culprit's threads to the log
   3350             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
   3351         }
   3352 
   3353         addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
   3354                 cpuInfo, tracesFile, null);
   3355 
   3356         if (mController != null) {
   3357             try {
   3358                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
   3359                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
   3360                 if (res != 0) {
   3361                     if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
   3362                     return;
   3363                 }
   3364             } catch (RemoteException e) {
   3365                 mController = null;
   3366             }
   3367         }
   3368 
   3369         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
   3370         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
   3371                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
   3372 
   3373         synchronized (this) {
   3374             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
   3375                 Slog.w(TAG, "Killing " + app + ": background ANR");
   3376                 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
   3377                         app.processName, app.setAdj, "background ANR");
   3378                 Process.killProcessQuiet(app.pid);
   3379                 return;
   3380             }
   3381 
   3382             // Set the app's notResponding state, and look up the errorReportReceiver
   3383             makeAppNotRespondingLocked(app,
   3384                     activity != null ? activity.shortComponentName : null,
   3385                     annotation != null ? "ANR " + annotation : "ANR",
   3386                     info.toString());
   3387 
   3388             // Bring up the infamous App Not Responding dialog
   3389             Message msg = Message.obtain();
   3390             HashMap map = new HashMap();
   3391             msg.what = SHOW_NOT_RESPONDING_MSG;
   3392             msg.obj = map;
   3393             msg.arg1 = aboveSystem ? 1 : 0;
   3394             map.put("app", app);
   3395             if (activity != null) {
   3396                 map.put("activity", activity);
   3397             }
   3398 
   3399             mHandler.sendMessage(msg);
   3400         }
   3401     }
   3402 
   3403     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
   3404         if (!mLaunchWarningShown) {
   3405             mLaunchWarningShown = true;
   3406             mHandler.post(new Runnable() {
   3407                 @Override
   3408                 public void run() {
   3409                     synchronized (ActivityManagerService.this) {
   3410                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
   3411                         d.show();
   3412                         mHandler.postDelayed(new Runnable() {
   3413                             @Override
   3414                             public void run() {
   3415                                 synchronized (ActivityManagerService.this) {
   3416                                     d.dismiss();
   3417                                     mLaunchWarningShown = false;
   3418                                 }
   3419                             }
   3420                         }, 4000);
   3421                     }
   3422                 }
   3423             });
   3424         }
   3425     }
   3426 
   3427     public boolean clearApplicationUserData(final String packageName,
   3428             final IPackageDataObserver observer, int userId) {
   3429         enforceNotIsolatedCaller("clearApplicationUserData");
   3430         int uid = Binder.getCallingUid();
   3431         int pid = Binder.getCallingPid();
   3432         userId = handleIncomingUser(pid, uid,
   3433                 userId, false, true, "clearApplicationUserData", null);
   3434         long callingId = Binder.clearCallingIdentity();
   3435         try {
   3436             IPackageManager pm = AppGlobals.getPackageManager();
   3437             int pkgUid = -1;
   3438             synchronized(this) {
   3439                 try {
   3440                     pkgUid = pm.getPackageUid(packageName, userId);
   3441                 } catch (RemoteException e) {
   3442                 }
   3443                 if (pkgUid == -1) {
   3444                     Slog.w(TAG, "Invalid packageName:" + packageName);
   3445                     return false;
   3446                 }
   3447                 if (uid == pkgUid || checkComponentPermission(
   3448                         android.Manifest.permission.CLEAR_APP_USER_DATA,
   3449                         pid, uid, -1, true)
   3450                         == PackageManager.PERMISSION_GRANTED) {
   3451                     forceStopPackageLocked(packageName, pkgUid);
   3452                 } else {
   3453                     throw new SecurityException(pid+" does not have permission:"+
   3454                             android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
   3455                                     "for process:"+packageName);
   3456                 }
   3457             }
   3458 
   3459             try {
   3460                 //clear application user data
   3461                 pm.clearApplicationUserData(packageName, observer, userId);
   3462                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
   3463                         Uri.fromParts("package", packageName, null));
   3464                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
   3465                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
   3466                         null, null, 0, null, null, null, false, false, userId);
   3467             } catch (RemoteException e) {
   3468             }
   3469         } finally {
   3470             Binder.restoreCallingIdentity(callingId);
   3471         }
   3472         return true;
   3473     }
   3474 
   3475     public void killBackgroundProcesses(final String packageName, int userId) {
   3476         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   3477                 != PackageManager.PERMISSION_GRANTED &&
   3478                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
   3479                         != PackageManager.PERMISSION_GRANTED) {
   3480             String msg = "Permission Denial: killBackgroundProcesses() from pid="
   3481                     + Binder.getCallingPid()
   3482                     + ", uid=" + Binder.getCallingUid()
   3483                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   3484             Slog.w(TAG, msg);
   3485             throw new SecurityException(msg);
   3486         }
   3487 
   3488         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   3489                 userId, true, true, "killBackgroundProcesses", null);
   3490         long callingId = Binder.clearCallingIdentity();
   3491         try {
   3492             IPackageManager pm = AppGlobals.getPackageManager();
   3493             synchronized(this) {
   3494                 int appId = -1;
   3495                 try {
   3496                     appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
   3497                 } catch (RemoteException e) {
   3498                 }
   3499                 if (appId == -1) {
   3500                     Slog.w(TAG, "Invalid packageName: " + packageName);
   3501                     return;
   3502                 }
   3503                 killPackageProcessesLocked(packageName, appId, userId,
   3504                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
   3505             }
   3506         } finally {
   3507             Binder.restoreCallingIdentity(callingId);
   3508         }
   3509     }
   3510 
   3511     public void killAllBackgroundProcesses() {
   3512         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   3513                 != PackageManager.PERMISSION_GRANTED) {
   3514             String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
   3515                     + Binder.getCallingPid()
   3516                     + ", uid=" + Binder.getCallingUid()
   3517                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   3518             Slog.w(TAG, msg);
   3519             throw new SecurityException(msg);
   3520         }
   3521 
   3522         long callingId = Binder.clearCallingIdentity();
   3523         try {
   3524             synchronized(this) {
   3525                 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   3526                 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   3527                     final int NA = apps.size();
   3528                     for (int ia=0; ia<NA; ia++) {
   3529                         ProcessRecord app = apps.valueAt(ia);
   3530                         if (app.persistent) {
   3531                             // we don't kill persistent processes
   3532                             continue;
   3533                         }
   3534                         if (app.removed) {
   3535                             procs.add(app);
   3536                         } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   3537                             app.removed = true;
   3538                             procs.add(app);
   3539                         }
   3540                     }
   3541                 }
   3542 
   3543                 int N = procs.size();
   3544                 for (int i=0; i<N; i++) {
   3545                     removeProcessLocked(procs.get(i), false, true, "kill all background");
   3546                 }
   3547             }
   3548         } finally {
   3549             Binder.restoreCallingIdentity(callingId);
   3550         }
   3551     }
   3552 
   3553     public void forceStopPackage(final String packageName, int userId) {
   3554         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   3555                 != PackageManager.PERMISSION_GRANTED) {
   3556             String msg = "Permission Denial: forceStopPackage() from pid="
   3557                     + Binder.getCallingPid()
   3558                     + ", uid=" + Binder.getCallingUid()
   3559                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   3560             Slog.w(TAG, msg);
   3561             throw new SecurityException(msg);
   3562         }
   3563         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   3564                 userId, true, true, "forceStopPackage", null);
   3565         long callingId = Binder.clearCallingIdentity();
   3566         try {
   3567             IPackageManager pm = AppGlobals.getPackageManager();
   3568             synchronized(this) {
   3569                 int[] users = userId == UserHandle.USER_ALL
   3570                         ? getUsersLocked() : new int[] { userId };
   3571                 for (int user : users) {
   3572                     int pkgUid = -1;
   3573                     try {
   3574                         pkgUid = pm.getPackageUid(packageName, user);
   3575                     } catch (RemoteException e) {
   3576                     }
   3577                     if (pkgUid == -1) {
   3578                         Slog.w(TAG, "Invalid packageName: " + packageName);
   3579                         continue;
   3580                     }
   3581                     try {
   3582                         pm.setPackageStoppedState(packageName, true, user);
   3583                     } catch (RemoteException e) {
   3584                     } catch (IllegalArgumentException e) {
   3585                         Slog.w(TAG, "Failed trying to unstop package "
   3586                                 + packageName + ": " + e);
   3587                     }
   3588                     if (isUserRunningLocked(user, false)) {
   3589                         forceStopPackageLocked(packageName, pkgUid);
   3590                     }
   3591                 }
   3592             }
   3593         } finally {
   3594             Binder.restoreCallingIdentity(callingId);
   3595         }
   3596     }
   3597 
   3598     /*
   3599      * The pkg name and app id have to be specified.
   3600      */
   3601     public void killApplicationWithAppId(String pkg, int appid) {
   3602         if (pkg == null) {
   3603             return;
   3604         }
   3605         // Make sure the uid is valid.
   3606         if (appid < 0) {
   3607             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
   3608             return;
   3609         }
   3610         int callerUid = Binder.getCallingUid();
   3611         // Only the system server can kill an application
   3612         if (callerUid == Process.SYSTEM_UID) {
   3613             // Post an aysnc message to kill the application
   3614             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
   3615             msg.arg1 = appid;
   3616             msg.arg2 = 0;
   3617             msg.obj = pkg;
   3618             mHandler.sendMessage(msg);
   3619         } else {
   3620             throw new SecurityException(callerUid + " cannot kill pkg: " +
   3621                     pkg);
   3622         }
   3623     }
   3624 
   3625     public void closeSystemDialogs(String reason) {
   3626         enforceNotIsolatedCaller("closeSystemDialogs");
   3627 
   3628         final int pid = Binder.getCallingPid();
   3629         final int uid = Binder.getCallingUid();
   3630         final long origId = Binder.clearCallingIdentity();
   3631         try {
   3632             synchronized (this) {
   3633                 // Only allow this from foreground processes, so that background
   3634                 // applications can't abuse it to prevent system UI from being shown.
   3635                 if (uid >= Process.FIRST_APPLICATION_UID) {
   3636                     ProcessRecord proc;
   3637                     synchronized (mPidsSelfLocked) {
   3638                         proc = mPidsSelfLocked.get(pid);
   3639                     }
   3640                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   3641                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
   3642                                 + " from background process " + proc);
   3643                         return;
   3644                     }
   3645                 }
   3646                 closeSystemDialogsLocked(reason);
   3647             }
   3648         } finally {
   3649             Binder.restoreCallingIdentity(origId);
   3650         }
   3651     }
   3652 
   3653     void closeSystemDialogsLocked(String reason) {
   3654         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
   3655         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   3656                 | Intent.FLAG_RECEIVER_FOREGROUND);
   3657         if (reason != null) {
   3658             intent.putExtra("reason", reason);
   3659         }
   3660         mWindowManager.closeSystemDialogs(reason);
   3661 
   3662         for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
   3663             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   3664             if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
   3665                 r.stack.finishActivityLocked(r, i,
   3666                         Activity.RESULT_CANCELED, null, "close-sys", true);
   3667             }
   3668         }
   3669 
   3670         broadcastIntentLocked(null, null, intent, null,
   3671                 null, 0, null, null, null, false, false, -1,
   3672                 Process.SYSTEM_UID, UserHandle.USER_ALL);
   3673     }
   3674 
   3675     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
   3676             throws RemoteException {
   3677         enforceNotIsolatedCaller("getProcessMemoryInfo");
   3678         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
   3679         for (int i=pids.length-1; i>=0; i--) {
   3680             infos[i] = new Debug.MemoryInfo();
   3681             Debug.getMemoryInfo(pids[i], infos[i]);
   3682         }
   3683         return infos;
   3684     }
   3685 
   3686     public long[] getProcessPss(int[] pids) throws RemoteException {
   3687         enforceNotIsolatedCaller("getProcessPss");
   3688         long[] pss = new long[pids.length];
   3689         for (int i=pids.length-1; i>=0; i--) {
   3690             pss[i] = Debug.getPss(pids[i]);
   3691         }
   3692         return pss;
   3693     }
   3694 
   3695     public void killApplicationProcess(String processName, int uid) {
   3696         if (processName == null) {
   3697             return;
   3698         }
   3699 
   3700         int callerUid = Binder.getCallingUid();
   3701         // Only the system server can kill an application
   3702         if (callerUid == Process.SYSTEM_UID) {
   3703             synchronized (this) {
   3704                 ProcessRecord app = getProcessRecordLocked(processName, uid);
   3705                 if (app != null && app.thread != null) {
   3706                     try {
   3707                         app.thread.scheduleSuicide();
   3708                     } catch (RemoteException e) {
   3709                         // If the other end already died, then our work here is done.
   3710                     }
   3711                 } else {
   3712                     Slog.w(TAG, "Process/uid not found attempting kill of "
   3713                             + processName + " / " + uid);
   3714                 }
   3715             }
   3716         } else {
   3717             throw new SecurityException(callerUid + " cannot kill app process: " +
   3718                     processName);
   3719         }
   3720     }
   3721 
   3722     private void forceStopPackageLocked(final String packageName, int uid) {
   3723         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
   3724                 false, true, false, UserHandle.getUserId(uid));
   3725         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
   3726                 Uri.fromParts("package", packageName, null));
   3727         if (!mProcessesReady) {
   3728             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   3729                     | Intent.FLAG_RECEIVER_FOREGROUND);
   3730         }
   3731         intent.putExtra(Intent.EXTRA_UID, uid);
   3732         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
   3733         broadcastIntentLocked(null, null, intent,
   3734                 null, null, 0, null, null, null,
   3735                 false, false,
   3736                 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
   3737     }
   3738 
   3739     private void forceStopUserLocked(int userId) {
   3740         forceStopPackageLocked(null, -1, false, false, true, false, userId);
   3741         Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
   3742         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   3743                 | Intent.FLAG_RECEIVER_FOREGROUND);
   3744         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   3745         broadcastIntentLocked(null, null, intent,
   3746                 null, null, 0, null, null, null,
   3747                 false, false,
   3748                 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   3749     }
   3750 
   3751     private final boolean killPackageProcessesLocked(String packageName, int appId,
   3752             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
   3753             boolean doit, boolean evenPersistent, String reason) {
   3754         ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   3755 
   3756         // Remove all processes this package may have touched: all with the
   3757         // same UID (except for the system or root user), and all whose name
   3758         // matches the package name.
   3759         final String procNamePrefix = packageName != null ? (packageName + ":") : null;
   3760         for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   3761             final int NA = apps.size();
   3762             for (int ia=0; ia<NA; ia++) {
   3763                 ProcessRecord app = apps.valueAt(ia);
   3764                 if (app.persistent && !evenPersistent) {
   3765                     // we don't kill persistent processes
   3766                     continue;
   3767                 }
   3768                 if (app.removed) {
   3769                     if (doit) {
   3770                         procs.add(app);
   3771                     }
   3772                     continue;
   3773                 }
   3774 
   3775                 // Skip process if it doesn't meet our oom adj requirement.
   3776                 if (app.setAdj < minOomAdj) {
   3777                     continue;
   3778                 }
   3779 
   3780                 // If no package is specified, we call all processes under the
   3781                 // give user id.
   3782                 if (packageName == null) {
   3783                     if (app.userId != userId) {
   3784                         continue;
   3785                     }
   3786                 // Package has been specified, we want to hit all processes
   3787                 // that match it.  We need to qualify this by the processes
   3788                 // that are running under the specified app and user ID.
   3789                 } else {
   3790                     if (UserHandle.getAppId(app.uid) != appId) {
   3791                         continue;
   3792                     }
   3793                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
   3794                         continue;
   3795                     }
   3796                     if (!app.pkgList.contains(packageName)) {
   3797                         continue;
   3798                     }
   3799                 }
   3800 
   3801                 // Process has passed all conditions, kill it!
   3802                 if (!doit) {
   3803                     return true;
   3804                 }
   3805                 app.removed = true;
   3806                 procs.add(app);
   3807             }
   3808         }
   3809 
   3810         int N = procs.size();
   3811         for (int i=0; i<N; i++) {
   3812             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
   3813         }
   3814         return N > 0;
   3815     }
   3816 
   3817     private final boolean forceStopPackageLocked(String name, int appId,
   3818             boolean callerWillRestart, boolean purgeCache, boolean doit,
   3819             boolean evenPersistent, int userId) {
   3820         int i;
   3821         int N;
   3822 
   3823         if (userId == UserHandle.USER_ALL && name == null) {
   3824             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
   3825         }
   3826 
   3827         if (appId < 0 && name != null) {
   3828             try {
   3829                 appId = UserHandle.getAppId(
   3830                         AppGlobals.getPackageManager().getPackageUid(name, 0));
   3831             } catch (RemoteException e) {
   3832             }
   3833         }
   3834 
   3835         if (doit) {
   3836             if (name != null) {
   3837                 Slog.i(TAG, "Force stopping package " + name + " appid=" + appId
   3838                         + " user=" + userId);
   3839             } else {
   3840                 Slog.i(TAG, "Force stopping user " + userId);
   3841             }
   3842 
   3843             Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
   3844             while (badApps.hasNext()) {
   3845                 SparseArray<Long> ba = badApps.next();
   3846                 for (i=ba.size()-1; i>=0; i--) {
   3847                     boolean remove = false;
   3848                     final int entUid = ba.keyAt(i);
   3849                     if (name != null) {
   3850                         if (userId == UserHandle.USER_ALL) {
   3851                             if (UserHandle.getAppId(entUid) == appId) {
   3852                                 remove = true;
   3853                             }
   3854                         } else {
   3855                             if (entUid == UserHandle.getUid(userId, appId)) {
   3856                                 remove = true;
   3857                             }
   3858                         }
   3859                     } else if (UserHandle.getUserId(entUid) == userId) {
   3860                         remove = true;
   3861                     }
   3862                     if (remove) {
   3863                         ba.removeAt(i);
   3864                     }
   3865                 }
   3866                 if (ba.size() == 0) {
   3867                     badApps.remove();
   3868                 }
   3869             }
   3870         }
   3871 
   3872         boolean didSomething = killPackageProcessesLocked(name, appId, userId,
   3873                 -100, callerWillRestart, false, doit, evenPersistent,
   3874                 name == null ? ("force stop user " + userId) : ("force stop " + name));
   3875 
   3876         TaskRecord lastTask = null;
   3877         for (i=0; i<mMainStack.mHistory.size(); i++) {
   3878             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   3879             final boolean samePackage = r.packageName.equals(name)
   3880                     || (name == null && r.userId == userId);
   3881             if ((userId == UserHandle.USER_ALL || r.userId == userId)
   3882                     && (samePackage || r.task == lastTask)
   3883                     && (r.app == null || evenPersistent || !r.app.persistent)) {
   3884                 if (!doit) {
   3885                     if (r.finishing) {
   3886                         // If this activity is just finishing, then it is not
   3887                         // interesting as far as something to stop.
   3888                         continue;
   3889                     }
   3890                     return true;
   3891                 }
   3892                 didSomething = true;
   3893                 Slog.i(TAG, "  Force finishing activity " + r);
   3894                 if (samePackage) {
   3895                     if (r.app != null) {
   3896                         r.app.removed = true;
   3897                     }
   3898                     r.app = null;
   3899                 }
   3900                 lastTask = r.task;
   3901                 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
   3902                         null, "force-stop", true)) {
   3903                     i--;
   3904                 }
   3905             }
   3906         }
   3907 
   3908         if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
   3909             if (!doit) {
   3910                 return true;
   3911             }
   3912             didSomething = true;
   3913         }
   3914 
   3915         if (name == null) {
   3916             // Remove all sticky broadcasts from this user.
   3917             mStickyBroadcasts.remove(userId);
   3918         }
   3919 
   3920         ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
   3921         if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
   3922                 userId, providers)) {
   3923             if (!doit) {
   3924                 return true;
   3925             }
   3926             didSomething = true;
   3927         }
   3928         N = providers.size();
   3929         for (i=0; i<N; i++) {
   3930             removeDyingProviderLocked(null, providers.get(i), true);
   3931         }
   3932 
   3933         if (name == null) {
   3934             // Remove pending intents.  For now we only do this when force
   3935             // stopping users, because we have some problems when doing this
   3936             // for packages -- app widgets are not currently cleaned up for
   3937             // such packages, so they can be left with bad pending intents.
   3938             if (mIntentSenderRecords.size() > 0) {
   3939                 Iterator<WeakReference<PendingIntentRecord>> it
   3940                         = mIntentSenderRecords.values().iterator();
   3941                 while (it.hasNext()) {
   3942                     WeakReference<PendingIntentRecord> wpir = it.next();
   3943                     if (wpir == null) {
   3944                         it.remove();
   3945                         continue;
   3946                     }
   3947                     PendingIntentRecord pir = wpir.get();
   3948                     if (pir == null) {
   3949                         it.remove();
   3950                         continue;
   3951                     }
   3952                     if (name == null) {
   3953                         // Stopping user, remove all objects for the user.
   3954                         if (pir.key.userId != userId) {
   3955                             // Not the same user, skip it.
   3956                             continue;
   3957                         }
   3958                     } else {
   3959                         if (UserHandle.getAppId(pir.uid) != appId) {
   3960                             // Different app id, skip it.
   3961                             continue;
   3962                         }
   3963                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
   3964                             // Different user, skip it.
   3965                             continue;
   3966                         }
   3967                         if (!pir.key.packageName.equals(name)) {
   3968                             // Different package, skip it.
   3969                             continue;
   3970                         }
   3971                     }
   3972                     if (!doit) {
   3973                         return true;
   3974                     }
   3975                     didSomething = true;
   3976                     it.remove();
   3977                     pir.canceled = true;
   3978                     if (pir.key.activity != null) {
   3979                         pir.key.activity.pendingResults.remove(pir.ref);
   3980                     }
   3981                 }
   3982             }
   3983         }
   3984 
   3985         if (doit) {
   3986             if (purgeCache && name != null) {
   3987                 AttributeCache ac = AttributeCache.instance();
   3988                 if (ac != null) {
   3989                     ac.removePackage(name);
   3990                 }
   3991             }
   3992             if (mBooted) {
   3993                 mMainStack.resumeTopActivityLocked(null);
   3994                 mMainStack.scheduleIdleLocked();
   3995             }
   3996         }
   3997 
   3998         return didSomething;
   3999     }
   4000 
   4001     private final boolean removeProcessLocked(ProcessRecord app,
   4002             boolean callerWillRestart, boolean allowRestart, String reason) {
   4003         final String name = app.processName;
   4004         final int uid = app.uid;
   4005         if (DEBUG_PROCESSES) Slog.d(
   4006             TAG, "Force removing proc " + app.toShortString() + " (" + name
   4007             + "/" + uid + ")");
   4008 
   4009         mProcessNames.remove(name, uid);
   4010         mIsolatedProcesses.remove(app.uid);
   4011         if (mHeavyWeightProcess == app) {
   4012             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   4013                     mHeavyWeightProcess.userId, 0));
   4014             mHeavyWeightProcess = null;
   4015         }
   4016         boolean needRestart = false;
   4017         if (app.pid > 0 && app.pid != MY_PID) {
   4018             int pid = app.pid;
   4019             synchronized (mPidsSelfLocked) {
   4020                 mPidsSelfLocked.remove(pid);
   4021                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   4022             }
   4023             Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
   4024             handleAppDiedLocked(app, true, allowRestart);
   4025             mLruProcesses.remove(app);
   4026             Process.killProcessQuiet(pid);
   4027 
   4028             if (app.persistent && !app.isolated) {
   4029                 if (!callerWillRestart) {
   4030                     addAppLocked(app.info, false);
   4031                 } else {
   4032                     needRestart = true;
   4033                 }
   4034             }
   4035         } else {
   4036             mRemovedProcesses.add(app);
   4037         }
   4038 
   4039         return needRestart;
   4040     }
   4041 
   4042     private final void processStartTimedOutLocked(ProcessRecord app) {
   4043         final int pid = app.pid;
   4044         boolean gone = false;
   4045         synchronized (mPidsSelfLocked) {
   4046             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
   4047             if (knownApp != null && knownApp.thread == null) {
   4048                 mPidsSelfLocked.remove(pid);
   4049                 gone = true;
   4050             }
   4051         }
   4052 
   4053         if (gone) {
   4054             Slog.w(TAG, "Process " + app + " failed to attach");
   4055             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
   4056                     pid, app.uid, app.processName);
   4057             mProcessNames.remove(app.processName, app.uid);
   4058             mIsolatedProcesses.remove(app.uid);
   4059             if (mHeavyWeightProcess == app) {
   4060                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   4061                         mHeavyWeightProcess.userId, 0));
   4062                 mHeavyWeightProcess = null;
   4063             }
   4064             // Take care of any launching providers waiting for this process.
   4065             checkAppInLaunchingProvidersLocked(app, true);
   4066             // Take care of any services that are waiting for the process.
   4067             mServices.processStartTimedOutLocked(app);
   4068             EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, pid,
   4069                     app.processName, app.setAdj, "start timeout");
   4070             Process.killProcessQuiet(pid);
   4071             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
   4072                 Slog.w(TAG, "Unattached app died before backup, skipping");
   4073                 try {
   4074                     IBackupManager bm = IBackupManager.Stub.asInterface(
   4075                             ServiceManager.getService(Context.BACKUP_SERVICE));
   4076                     bm.agentDisconnected(app.info.packageName);
   4077                 } catch (RemoteException e) {
   4078                     // Can't happen; the backup manager is local
   4079                 }
   4080             }
   4081             if (isPendingBroadcastProcessLocked(pid)) {
   4082                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   4083                 skipPendingBroadcastLocked(pid);
   4084             }
   4085         } else {
   4086             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
   4087         }
   4088     }
   4089 
   4090     private final boolean attachApplicationLocked(IApplicationThread thread,
   4091             int pid) {
   4092 
   4093         // Find the application record that is being attached...  either via
   4094         // the pid if we are running in multiple processes, or just pull the
   4095         // next app record if we are emulating process with anonymous threads.
   4096         ProcessRecord app;
   4097         if (pid != MY_PID && pid >= 0) {
   4098             synchronized (mPidsSelfLocked) {
   4099                 app = mPidsSelfLocked.get(pid);
   4100             }
   4101         } else {
   4102             app = null;
   4103         }
   4104 
   4105         if (app == null) {
   4106             Slog.w(TAG, "No pending application record for pid " + pid
   4107                     + " (IApplicationThread " + thread + "); dropping process");
   4108             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
   4109             if (pid > 0 && pid != MY_PID) {
   4110                 Process.killProcessQuiet(pid);
   4111             } else {
   4112                 try {
   4113                     thread.scheduleExit();
   4114                 } catch (Exception e) {
   4115                     // Ignore exceptions.
   4116                 }
   4117             }
   4118             return false;
   4119         }
   4120 
   4121         // If this application record is still attached to a previous
   4122         // process, clean it up now.
   4123         if (app.thread != null) {
   4124             handleAppDiedLocked(app, true, true);
   4125         }
   4126 
   4127         // Tell the process all about itself.
   4128 
   4129         if (localLOGV) Slog.v(
   4130                 TAG, "Binding process pid " + pid + " to record " + app);
   4131 
   4132         String processName = app.processName;
   4133         try {
   4134             AppDeathRecipient adr = new AppDeathRecipient(
   4135                     app, pid, thread);
   4136             thread.asBinder().linkToDeath(adr, 0);
   4137             app.deathRecipient = adr;
   4138         } catch (RemoteException e) {
   4139             app.resetPackageList();
   4140             startProcessLocked(app, "link fail", processName);
   4141             return false;
   4142         }
   4143 
   4144         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
   4145 
   4146         app.thread = thread;
   4147         app.curAdj = app.setAdj = -100;
   4148         app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
   4149         app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   4150         app.forcingToForeground = null;
   4151         app.foregroundServices = false;
   4152         app.hasShownUi = false;
   4153         app.debugging = false;
   4154 
   4155         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   4156 
   4157         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
   4158         List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
   4159 
   4160         if (!normalMode) {
   4161             Slog.i(TAG, "Launching preboot mode app: " + app);
   4162         }
   4163 
   4164         if (localLOGV) Slog.v(
   4165             TAG, "New app record " + app
   4166             + " thread=" + thread.asBinder() + " pid=" + pid);
   4167         try {
   4168             int testMode = IApplicationThread.DEBUG_OFF;
   4169             if (mDebugApp != null && mDebugApp.equals(processName)) {
   4170                 testMode = mWaitForDebugger
   4171                     ? IApplicationThread.DEBUG_WAIT
   4172                     : IApplicationThread.DEBUG_ON;
   4173                 app.debugging = true;
   4174                 if (mDebugTransient) {
   4175                     mDebugApp = mOrigDebugApp;
   4176                     mWaitForDebugger = mOrigWaitForDebugger;
   4177                 }
   4178             }
   4179             String profileFile = app.instrumentationProfileFile;
   4180             ParcelFileDescriptor profileFd = null;
   4181             boolean profileAutoStop = false;
   4182             if (mProfileApp != null && mProfileApp.equals(processName)) {
   4183                 mProfileProc = app;
   4184                 profileFile = mProfileFile;
   4185                 profileFd = mProfileFd;
   4186                 profileAutoStop = mAutoStopProfiler;
   4187             }
   4188             boolean enableOpenGlTrace = false;
   4189             if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
   4190                 enableOpenGlTrace = true;
   4191                 mOpenGlTraceApp = null;
   4192             }
   4193 
   4194             // If the app is being launched for restore or full backup, set it up specially
   4195             boolean isRestrictedBackupMode = false;
   4196             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
   4197                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
   4198                         || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
   4199                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
   4200             }
   4201 
   4202             ensurePackageDexOpt(app.instrumentationInfo != null
   4203                     ? app.instrumentationInfo.packageName
   4204                     : app.info.packageName);
   4205             if (app.instrumentationClass != null) {
   4206                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
   4207             }
   4208             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
   4209                     + processName + " with config " + mConfiguration);
   4210             ApplicationInfo appInfo = app.instrumentationInfo != null
   4211                     ? app.instrumentationInfo : app.info;
   4212             app.compat = compatibilityInfoForPackageLocked(appInfo);
   4213             if (profileFd != null) {
   4214                 profileFd = profileFd.dup();
   4215             }
   4216             thread.bindApplication(processName, appInfo, providers,
   4217                     app.instrumentationClass, profileFile, profileFd, profileAutoStop,
   4218                     app.instrumentationArguments, app.instrumentationWatcher, testMode,
   4219                     enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
   4220                     new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
   4221                     mCoreSettingsObserver.getCoreSettingsLocked());
   4222             updateLruProcessLocked(app, false);
   4223             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
   4224         } catch (Exception e) {
   4225             // todo: Yikes!  What should we do?  For now we will try to
   4226             // start another process, but that could easily get us in
   4227             // an infinite loop of restarting processes...
   4228             Slog.w(TAG, "Exception thrown during bind!", e);
   4229 
   4230             app.resetPackageList();
   4231             app.unlinkDeathRecipient();
   4232             startProcessLocked(app, "bind fail", processName);
   4233             return false;
   4234         }
   4235 
   4236         // Remove this record from the list of starting applications.
   4237         mPersistentStartingProcesses.remove(app);
   4238         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   4239                 "Attach application locked removing on hold: " + app);
   4240         mProcessesOnHold.remove(app);
   4241 
   4242         boolean badApp = false;
   4243         boolean didSomething = false;
   4244 
   4245         // See if the top visible activity is waiting to run in this process...
   4246         ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
   4247         if (hr != null && normalMode) {
   4248             if (hr.app == null && app.uid == hr.info.applicationInfo.uid
   4249                     && processName.equals(hr.processName)) {
   4250                 try {
   4251                     if (mHeadless) {
   4252                         Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
   4253                     } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
   4254                         didSomething = true;
   4255                     }
   4256                 } catch (Exception e) {
   4257                     Slog.w(TAG, "Exception in new application when starting activity "
   4258                           + hr.intent.getComponent().flattenToShortString(), e);
   4259                     badApp = true;
   4260                 }
   4261             } else {
   4262                 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
   4263             }
   4264         }
   4265 
   4266         // Find any services that should be running in this process...
   4267         if (!badApp) {
   4268             try {
   4269                 didSomething |= mServices.attachApplicationLocked(app, processName);
   4270             } catch (Exception e) {
   4271                 badApp = true;
   4272             }
   4273         }
   4274 
   4275         // Check if a next-broadcast receiver is in this process...
   4276         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
   4277             try {
   4278                 didSomething = sendPendingBroadcastsLocked(app);
   4279             } catch (Exception e) {
   4280                 // If the app died trying to launch the receiver we declare it 'bad'
   4281                 badApp = true;
   4282             }
   4283         }
   4284 
   4285         // Check whether the next backup agent is in this process...
   4286         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
   4287             if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
   4288             ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
   4289             try {
   4290                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
   4291                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
   4292                         mBackupTarget.backupMode);
   4293             } catch (Exception e) {
   4294                 Slog.w(TAG, "Exception scheduling backup agent creation: ");
   4295                 e.printStackTrace();
   4296             }
   4297         }
   4298 
   4299         if (badApp) {
   4300             // todo: Also need to kill application to deal with all
   4301             // kinds of exceptions.
   4302             handleAppDiedLocked(app, false, true);
   4303             return false;
   4304         }
   4305 
   4306         if (!didSomething) {
   4307             updateOomAdjLocked();
   4308         }
   4309 
   4310         return true;
   4311     }
   4312 
   4313     public final void attachApplication(IApplicationThread thread) {
   4314         synchronized (this) {
   4315             int callingPid = Binder.getCallingPid();
   4316             final long origId = Binder.clearCallingIdentity();
   4317             attachApplicationLocked(thread, callingPid);
   4318             Binder.restoreCallingIdentity(origId);
   4319         }
   4320     }
   4321 
   4322     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
   4323         final long origId = Binder.clearCallingIdentity();
   4324         ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
   4325         if (stopProfiling) {
   4326             synchronized (this) {
   4327                 if (mProfileProc == r.app) {
   4328                     if (mProfileFd != null) {
   4329                         try {
   4330                             mProfileFd.close();
   4331                         } catch (IOException e) {
   4332                         }
   4333                         clearProfilerLocked();
   4334                     }
   4335                 }
   4336             }
   4337         }
   4338         Binder.restoreCallingIdentity(origId);
   4339     }
   4340 
   4341     void enableScreenAfterBoot() {
   4342         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
   4343                 SystemClock.uptimeMillis());
   4344         mWindowManager.enableScreenAfterBoot();
   4345 
   4346         synchronized (this) {
   4347             updateEventDispatchingLocked();
   4348         }
   4349     }
   4350 
   4351     public void showBootMessage(final CharSequence msg, final boolean always) {
   4352         enforceNotIsolatedCaller("showBootMessage");
   4353         mWindowManager.showBootMessage(msg, always);
   4354     }
   4355 
   4356     public void dismissKeyguardOnNextActivity() {
   4357         enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
   4358         final long token = Binder.clearCallingIdentity();
   4359         try {
   4360             synchronized (this) {
   4361                 if (mLockScreenShown) {
   4362                     mLockScreenShown = false;
   4363                     comeOutOfSleepIfNeededLocked();
   4364                 }
   4365                 mMainStack.dismissKeyguardOnNextActivityLocked();
   4366             }
   4367         } finally {
   4368             Binder.restoreCallingIdentity(token);
   4369         }
   4370     }
   4371 
   4372     final void finishBooting() {
   4373         IntentFilter pkgFilter = new IntentFilter();
   4374         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
   4375         pkgFilter.addDataScheme("package");
   4376         mContext.registerReceiver(new BroadcastReceiver() {
   4377             @Override
   4378             public void onReceive(Context context, Intent intent) {
   4379                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
   4380                 if (pkgs != null) {
   4381                     for (String pkg : pkgs) {
   4382                         synchronized (ActivityManagerService.this) {
   4383                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
   4384                                 setResultCode(Activity.RESULT_OK);
   4385                                 return;
   4386                             }
   4387                         }
   4388                     }
   4389                 }
   4390             }
   4391         }, pkgFilter);
   4392 
   4393         synchronized (this) {
   4394             // Ensure that any processes we had put on hold are now started
   4395             // up.
   4396             final int NP = mProcessesOnHold.size();
   4397             if (NP > 0) {
   4398                 ArrayList<ProcessRecord> procs =
   4399                     new ArrayList<ProcessRecord>(mProcessesOnHold);
   4400                 for (int ip=0; ip<NP; ip++) {
   4401                     if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
   4402                             + procs.get(ip));
   4403                     startProcessLocked(procs.get(ip), "on-hold", null);
   4404                 }
   4405             }
   4406 
   4407             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   4408                 // Start looking for apps that are abusing wake locks.
   4409                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   4410                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   4411                 // Tell anyone interested that we are done booting!
   4412                 SystemProperties.set("sys.boot_completed", "1");
   4413                 SystemProperties.set("dev.bootcomplete", "1");
   4414                 for (int i=0; i<mStartedUsers.size(); i++) {
   4415                     UserStartedState uss = mStartedUsers.valueAt(i);
   4416                     if (uss.mState == UserStartedState.STATE_BOOTING) {
   4417                         uss.mState = UserStartedState.STATE_RUNNING;
   4418                         final int userId = mStartedUsers.keyAt(i);
   4419                         Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
   4420                         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   4421                         broadcastIntentLocked(null, null, intent,
   4422                                 null, null, 0, null, null,
   4423                                 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
   4424                                 false, false, MY_PID, Process.SYSTEM_UID, userId);
   4425                     }
   4426                 }
   4427             }
   4428         }
   4429     }
   4430 
   4431     final void ensureBootCompleted() {
   4432         boolean booting;
   4433         boolean enableScreen;
   4434         synchronized (this) {
   4435             booting = mBooting;
   4436             mBooting = false;
   4437             enableScreen = !mBooted;
   4438             mBooted = true;
   4439         }
   4440 
   4441         if (booting) {
   4442             finishBooting();
   4443         }
   4444 
   4445         if (enableScreen) {
   4446             enableScreenAfterBoot();
   4447         }
   4448     }
   4449 
   4450     public final void activityResumed(IBinder token) {
   4451         final long origId = Binder.clearCallingIdentity();
   4452         mMainStack.activityResumed(token);
   4453         Binder.restoreCallingIdentity(origId);
   4454     }
   4455 
   4456     public final void activityPaused(IBinder token) {
   4457         final long origId = Binder.clearCallingIdentity();
   4458         mMainStack.activityPaused(token, false);
   4459         Binder.restoreCallingIdentity(origId);
   4460     }
   4461 
   4462     public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
   4463             CharSequence description) {
   4464         if (localLOGV) Slog.v(
   4465             TAG, "Activity stopped: token=" + token);
   4466 
   4467         // Refuse possible leaked file descriptors
   4468         if (icicle != null && icicle.hasFileDescriptors()) {
   4469             throw new IllegalArgumentException("File descriptors passed in Bundle");
   4470         }
   4471 
   4472         ActivityRecord r = null;
   4473 
   4474         final long origId = Binder.clearCallingIdentity();
   4475 
   4476         synchronized (this) {
   4477             r = mMainStack.isInStackLocked(token);
   4478             if (r != null) {
   4479                 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
   4480             }
   4481         }
   4482 
   4483         if (r != null) {
   4484             sendPendingThumbnail(r, null, null, null, false);
   4485         }
   4486 
   4487         trimApplications();
   4488 
   4489         Binder.restoreCallingIdentity(origId);
   4490     }
   4491 
   4492     public final void activityDestroyed(IBinder token) {
   4493         if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
   4494         mMainStack.activityDestroyed(token);
   4495     }
   4496 
   4497     public String getCallingPackage(IBinder token) {
   4498         synchronized (this) {
   4499             ActivityRecord r = getCallingRecordLocked(token);
   4500             return r != null && r.app != null ? r.info.packageName : null;
   4501         }
   4502     }
   4503 
   4504     public ComponentName getCallingActivity(IBinder token) {
   4505         synchronized (this) {
   4506             ActivityRecord r = getCallingRecordLocked(token);
   4507             return r != null ? r.intent.getComponent() : null;
   4508         }
   4509     }
   4510 
   4511     private ActivityRecord getCallingRecordLocked(IBinder token) {
   4512         ActivityRecord r = mMainStack.isInStackLocked(token);
   4513         if (r == null) {
   4514             return null;
   4515         }
   4516         return r.resultTo;
   4517     }
   4518 
   4519     public ComponentName getActivityClassForToken(IBinder token) {
   4520         synchronized(this) {
   4521             ActivityRecord r = mMainStack.isInStackLocked(token);
   4522             if (r == null) {
   4523                 return null;
   4524             }
   4525             return r.intent.getComponent();
   4526         }
   4527     }
   4528 
   4529     public String getPackageForToken(IBinder token) {
   4530         synchronized(this) {
   4531             ActivityRecord r = mMainStack.isInStackLocked(token);
   4532             if (r == null) {
   4533                 return null;
   4534             }
   4535             return r.packageName;
   4536         }
   4537     }
   4538 
   4539     public IIntentSender getIntentSender(int type,
   4540             String packageName, IBinder token, String resultWho,
   4541             int requestCode, Intent[] intents, String[] resolvedTypes,
   4542             int flags, Bundle options, int userId) {
   4543         enforceNotIsolatedCaller("getIntentSender");
   4544         // Refuse possible leaked file descriptors
   4545         if (intents != null) {
   4546             if (intents.length < 1) {
   4547                 throw new IllegalArgumentException("Intents array length must be >= 1");
   4548             }
   4549             for (int i=0; i<intents.length; i++) {
   4550                 Intent intent = intents[i];
   4551                 if (intent != null) {
   4552                     if (intent.hasFileDescriptors()) {
   4553                         throw new IllegalArgumentException("File descriptors passed in Intent");
   4554                     }
   4555                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
   4556                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   4557                         throw new IllegalArgumentException(
   4558                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   4559                     }
   4560                     intents[i] = new Intent(intent);
   4561                 }
   4562             }
   4563             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
   4564                 throw new IllegalArgumentException(
   4565                         "Intent array length does not match resolvedTypes length");
   4566             }
   4567         }
   4568         if (options != null) {
   4569             if (options.hasFileDescriptors()) {
   4570                 throw new IllegalArgumentException("File descriptors passed in options");
   4571             }
   4572         }
   4573 
   4574         synchronized(this) {
   4575             int callingUid = Binder.getCallingUid();
   4576             int origUserId = userId;
   4577             userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
   4578                     type == ActivityManager.INTENT_SENDER_BROADCAST, false,
   4579                     "getIntentSender", null);
   4580             if (origUserId == UserHandle.USER_CURRENT) {
   4581                 // We don't want to evaluate this until the pending intent is
   4582                 // actually executed.  However, we do want to always do the
   4583                 // security checking for it above.
   4584                 userId = UserHandle.USER_CURRENT;
   4585             }
   4586             try {
   4587                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   4588                     int uid = AppGlobals.getPackageManager()
   4589                             .getPackageUid(packageName, UserHandle.getUserId(callingUid));
   4590                     if (!UserHandle.isSameApp(callingUid, uid)) {
   4591                         String msg = "Permission Denial: getIntentSender() from pid="
   4592                             + Binder.getCallingPid()
   4593                             + ", uid=" + Binder.getCallingUid()
   4594                             + ", (need uid=" + uid + ")"
   4595                             + " is not allowed to send as package " + packageName;
   4596                         Slog.w(TAG, msg);
   4597                         throw new SecurityException(msg);
   4598                     }
   4599                 }
   4600 
   4601                 return getIntentSenderLocked(type, packageName, callingUid, userId,
   4602                         token, resultWho, requestCode, intents, resolvedTypes, flags, options);
   4603 
   4604             } catch (RemoteException e) {
   4605                 throw new SecurityException(e);
   4606             }
   4607         }
   4608     }
   4609 
   4610     IIntentSender getIntentSenderLocked(int type, String packageName,
   4611             int callingUid, int userId, IBinder token, String resultWho,
   4612             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
   4613             Bundle options) {
   4614         if (DEBUG_MU)
   4615             Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
   4616         ActivityRecord activity = null;
   4617         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   4618             activity = mMainStack.isInStackLocked(token);
   4619             if (activity == null) {
   4620                 return null;
   4621             }
   4622             if (activity.finishing) {
   4623                 return null;
   4624             }
   4625         }
   4626 
   4627         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
   4628         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
   4629         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
   4630         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
   4631                 |PendingIntent.FLAG_UPDATE_CURRENT);
   4632 
   4633         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
   4634                 type, packageName, activity, resultWho,
   4635                 requestCode, intents, resolvedTypes, flags, options, userId);
   4636         WeakReference<PendingIntentRecord> ref;
   4637         ref = mIntentSenderRecords.get(key);
   4638         PendingIntentRecord rec = ref != null ? ref.get() : null;
   4639         if (rec != null) {
   4640             if (!cancelCurrent) {
   4641                 if (updateCurrent) {
   4642                     if (rec.key.requestIntent != null) {
   4643                         rec.key.requestIntent.replaceExtras(intents != null ?
   4644                                 intents[intents.length - 1] : null);
   4645                     }
   4646                     if (intents != null) {
   4647                         intents[intents.length-1] = rec.key.requestIntent;
   4648                         rec.key.allIntents = intents;
   4649                         rec.key.allResolvedTypes = resolvedTypes;
   4650                     } else {
   4651                         rec.key.allIntents = null;
   4652                         rec.key.allResolvedTypes = null;
   4653                     }
   4654                 }
   4655                 return rec;
   4656             }
   4657             rec.canceled = true;
   4658             mIntentSenderRecords.remove(key);
   4659         }
   4660         if (noCreate) {
   4661             return rec;
   4662         }
   4663         rec = new PendingIntentRecord(this, key, callingUid);
   4664         mIntentSenderRecords.put(key, rec.ref);
   4665         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   4666             if (activity.pendingResults == null) {
   4667                 activity.pendingResults
   4668                         = new HashSet<WeakReference<PendingIntentRecord>>();
   4669             }
   4670             activity.pendingResults.add(rec.ref);
   4671         }
   4672         return rec;
   4673     }
   4674 
   4675     public void cancelIntentSender(IIntentSender sender) {
   4676         if (!(sender instanceof PendingIntentRecord)) {
   4677             return;
   4678         }
   4679         synchronized(this) {
   4680             PendingIntentRecord rec = (PendingIntentRecord)sender;
   4681             try {
   4682                 int uid = AppGlobals.getPackageManager()
   4683                         .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
   4684                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
   4685                     String msg = "Permission Denial: cancelIntentSender() from pid="
   4686                         + Binder.getCallingPid()
   4687                         + ", uid=" + Binder.getCallingUid()
   4688                         + " is not allowed to cancel packges "
   4689                         + rec.key.packageName;
   4690                     Slog.w(TAG, msg);
   4691                     throw new SecurityException(msg);
   4692                 }
   4693             } catch (RemoteException e) {
   4694                 throw new SecurityException(e);
   4695             }
   4696             cancelIntentSenderLocked(rec, true);
   4697         }
   4698     }
   4699 
   4700     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
   4701         rec.canceled = true;
   4702         mIntentSenderRecords.remove(rec.key);
   4703         if (cleanActivity && rec.key.activity != null) {
   4704             rec.key.activity.pendingResults.remove(rec.ref);
   4705         }
   4706     }
   4707 
   4708     public String getPackageForIntentSender(IIntentSender pendingResult) {
   4709         if (!(pendingResult instanceof PendingIntentRecord)) {
   4710             return null;
   4711         }
   4712         try {
   4713             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   4714             return res.key.packageName;
   4715         } catch (ClassCastException e) {
   4716         }
   4717         return null;
   4718     }
   4719 
   4720     public int getUidForIntentSender(IIntentSender sender) {
   4721         if (sender instanceof PendingIntentRecord) {
   4722             try {
   4723                 PendingIntentRecord res = (PendingIntentRecord)sender;
   4724                 return res.uid;
   4725             } catch (ClassCastException e) {
   4726             }
   4727         }
   4728         return -1;
   4729     }
   4730 
   4731     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
   4732         if (!(pendingResult instanceof PendingIntentRecord)) {
   4733             return false;
   4734         }
   4735         try {
   4736             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   4737             if (res.key.allIntents == null) {
   4738                 return false;
   4739             }
   4740             for (int i=0; i<res.key.allIntents.length; i++) {
   4741                 Intent intent = res.key.allIntents[i];
   4742                 if (intent.getPackage() != null && intent.getComponent() != null) {
   4743                     return false;
   4744                 }
   4745             }
   4746             return true;
   4747         } catch (ClassCastException e) {
   4748         }
   4749         return false;
   4750     }
   4751 
   4752     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
   4753         if (!(pendingResult instanceof PendingIntentRecord)) {
   4754             return false;
   4755         }
   4756         try {
   4757             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   4758             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
   4759                 return true;
   4760             }
   4761             return false;
   4762         } catch (ClassCastException e) {
   4763         }
   4764         return false;
   4765     }
   4766 
   4767     public void setProcessLimit(int max) {
   4768         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   4769                 "setProcessLimit()");
   4770         synchronized (this) {
   4771             mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
   4772             mProcessLimitOverride = max;
   4773         }
   4774         trimApplications();
   4775     }
   4776 
   4777     public int getProcessLimit() {
   4778         synchronized (this) {
   4779             return mProcessLimitOverride;
   4780         }
   4781     }
   4782 
   4783     void foregroundTokenDied(ForegroundToken token) {
   4784         synchronized (ActivityManagerService.this) {
   4785             synchronized (mPidsSelfLocked) {
   4786                 ForegroundToken cur
   4787                     = mForegroundProcesses.get(token.pid);
   4788                 if (cur != token) {
   4789                     return;
   4790                 }
   4791                 mForegroundProcesses.remove(token.pid);
   4792                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
   4793                 if (pr == null) {
   4794                     return;
   4795                 }
   4796                 pr.forcingToForeground = null;
   4797                 pr.foregroundServices = false;
   4798             }
   4799             updateOomAdjLocked();
   4800         }
   4801     }
   4802 
   4803     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
   4804         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   4805                 "setProcessForeground()");
   4806         synchronized(this) {
   4807             boolean changed = false;
   4808 
   4809             synchronized (mPidsSelfLocked) {
   4810                 ProcessRecord pr = mPidsSelfLocked.get(pid);
   4811                 if (pr == null && isForeground) {
   4812                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
   4813                     return;
   4814                 }
   4815                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
   4816                 if (oldToken != null) {
   4817                     oldToken.token.unlinkToDeath(oldToken, 0);
   4818                     mForegroundProcesses.remove(pid);
   4819                     if (pr != null) {
   4820                         pr.forcingToForeground = null;
   4821                     }
   4822                     changed = true;
   4823                 }
   4824                 if (isForeground && token != null) {
   4825                     ForegroundToken newToken = new ForegroundToken() {
   4826                         public void binderDied() {
   4827                             foregroundTokenDied(this);
   4828                         }
   4829                     };
   4830                     newToken.pid = pid;
   4831                     newToken.token = token;
   4832                     try {
   4833                         token.linkToDeath(newToken, 0);
   4834                         mForegroundProcesses.put(pid, newToken);
   4835                         pr.forcingToForeground = token;
   4836                         changed = true;
   4837                     } catch (RemoteException e) {
   4838                         // If the process died while doing this, we will later
   4839                         // do the cleanup with the process death link.
   4840                     }
   4841                 }
   4842             }
   4843 
   4844             if (changed) {
   4845                 updateOomAdjLocked();
   4846             }
   4847         }
   4848     }
   4849 
   4850     // =========================================================
   4851     // PERMISSIONS
   4852     // =========================================================
   4853 
   4854     static class PermissionController extends IPermissionController.Stub {
   4855         ActivityManagerService mActivityManagerService;
   4856         PermissionController(ActivityManagerService activityManagerService) {
   4857             mActivityManagerService = activityManagerService;
   4858         }
   4859 
   4860         public boolean checkPermission(String permission, int pid, int uid) {
   4861             return mActivityManagerService.checkPermission(permission, pid,
   4862                     uid) == PackageManager.PERMISSION_GRANTED;
   4863         }
   4864     }
   4865 
   4866     /**
   4867      * This can be called with or without the global lock held.
   4868      */
   4869     int checkComponentPermission(String permission, int pid, int uid,
   4870             int owningUid, boolean exported) {
   4871         // We might be performing an operation on behalf of an indirect binder
   4872         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
   4873         // client identity accordingly before proceeding.
   4874         Identity tlsIdentity = sCallerIdentity.get();
   4875         if (tlsIdentity != null) {
   4876             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
   4877                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
   4878             uid = tlsIdentity.uid;
   4879             pid = tlsIdentity.pid;
   4880         }
   4881 
   4882         if (pid == MY_PID) {
   4883             return PackageManager.PERMISSION_GRANTED;
   4884         }
   4885 
   4886         return ActivityManager.checkComponentPermission(permission, uid,
   4887                 owningUid, exported);
   4888     }
   4889 
   4890     /**
   4891      * As the only public entry point for permissions checking, this method
   4892      * can enforce the semantic that requesting a check on a null global
   4893      * permission is automatically denied.  (Internally a null permission
   4894      * string is used when calling {@link #checkComponentPermission} in cases
   4895      * when only uid-based security is needed.)
   4896      *
   4897      * This can be called with or without the global lock held.
   4898      */
   4899     public int checkPermission(String permission, int pid, int uid) {
   4900         if (permission == null) {
   4901             return PackageManager.PERMISSION_DENIED;
   4902         }
   4903         return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
   4904     }
   4905 
   4906     /**
   4907      * Binder IPC calls go through the public entry point.
   4908      * This can be called with or without the global lock held.
   4909      */
   4910     int checkCallingPermission(String permission) {
   4911         return checkPermission(permission,
   4912                 Binder.getCallingPid(),
   4913                 UserHandle.getAppId(Binder.getCallingUid()));
   4914     }
   4915 
   4916     /**
   4917      * This can be called with or without the global lock held.
   4918      */
   4919     void enforceCallingPermission(String permission, String func) {
   4920         if (checkCallingPermission(permission)
   4921                 == PackageManager.PERMISSION_GRANTED) {
   4922             return;
   4923         }
   4924 
   4925         String msg = "Permission Denial: " + func + " from pid="
   4926                 + Binder.getCallingPid()
   4927                 + ", uid=" + Binder.getCallingUid()
   4928                 + " requires " + permission;
   4929         Slog.w(TAG, msg);
   4930         throw new SecurityException(msg);
   4931     }
   4932 
   4933     /**
   4934      * Determine if UID is holding permissions required to access {@link Uri} in
   4935      * the given {@link ProviderInfo}. Final permission checking is always done
   4936      * in {@link ContentProvider}.
   4937      */
   4938     private final boolean checkHoldingPermissionsLocked(
   4939             IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
   4940         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4941                 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
   4942 
   4943         if (pi.applicationInfo.uid == uid) {
   4944             return true;
   4945         } else if (!pi.exported) {
   4946             return false;
   4947         }
   4948 
   4949         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
   4950         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
   4951         try {
   4952             // check if target holds top-level <provider> permissions
   4953             if (!readMet && pi.readPermission != null
   4954                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
   4955                 readMet = true;
   4956             }
   4957             if (!writeMet && pi.writePermission != null
   4958                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
   4959                 writeMet = true;
   4960             }
   4961 
   4962             // track if unprotected read/write is allowed; any denied
   4963             // <path-permission> below removes this ability
   4964             boolean allowDefaultRead = pi.readPermission == null;
   4965             boolean allowDefaultWrite = pi.writePermission == null;
   4966 
   4967             // check if target holds any <path-permission> that match uri
   4968             final PathPermission[] pps = pi.pathPermissions;
   4969             if (pps != null) {
   4970                 final String path = uri.getPath();
   4971                 int i = pps.length;
   4972                 while (i > 0 && (!readMet || !writeMet)) {
   4973                     i--;
   4974                     PathPermission pp = pps[i];
   4975                     if (pp.match(path)) {
   4976                         if (!readMet) {
   4977                             final String pprperm = pp.getReadPermission();
   4978                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
   4979                                     + pprperm + " for " + pp.getPath()
   4980                                     + ": match=" + pp.match(path)
   4981                                     + " check=" + pm.checkUidPermission(pprperm, uid));
   4982                             if (pprperm != null) {
   4983                                 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
   4984                                     readMet = true;
   4985                                 } else {
   4986                                     allowDefaultRead = false;
   4987                                 }
   4988                             }
   4989                         }
   4990                         if (!writeMet) {
   4991                             final String ppwperm = pp.getWritePermission();
   4992                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
   4993                                     + ppwperm + " for " + pp.getPath()
   4994                                     + ": match=" + pp.match(path)
   4995                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
   4996                             if (ppwperm != null) {
   4997                                 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
   4998                                     writeMet = true;
   4999                                 } else {
   5000                                     allowDefaultWrite = false;
   5001                                 }
   5002                             }
   5003                         }
   5004                     }
   5005                 }
   5006             }
   5007 
   5008             // grant unprotected <provider> read/write, if not blocked by
   5009             // <path-permission> above
   5010             if (allowDefaultRead) readMet = true;
   5011             if (allowDefaultWrite) writeMet = true;
   5012 
   5013         } catch (RemoteException e) {
   5014             return false;
   5015         }
   5016 
   5017         return readMet && writeMet;
   5018     }
   5019 
   5020     private final boolean checkUriPermissionLocked(Uri uri, int uid,
   5021             int modeFlags) {
   5022         // Root gets to do everything.
   5023         if (uid == 0) {
   5024             return true;
   5025         }
   5026         HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   5027         if (perms == null) return false;
   5028         UriPermission perm = perms.get(uri);
   5029         if (perm == null) return false;
   5030         return (modeFlags&perm.modeFlags) == modeFlags;
   5031     }
   5032 
   5033     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
   5034         enforceNotIsolatedCaller("checkUriPermission");
   5035 
   5036         // Another redirected-binder-call permissions check as in
   5037         // {@link checkComponentPermission}.
   5038         Identity tlsIdentity = sCallerIdentity.get();
   5039         if (tlsIdentity != null) {
   5040             uid = tlsIdentity.uid;
   5041             pid = tlsIdentity.pid;
   5042         }
   5043 
   5044         // Our own process gets to do everything.
   5045         if (pid == MY_PID) {
   5046             return PackageManager.PERMISSION_GRANTED;
   5047         }
   5048         synchronized(this) {
   5049             return checkUriPermissionLocked(uri, uid, modeFlags)
   5050                     ? PackageManager.PERMISSION_GRANTED
   5051                     : PackageManager.PERMISSION_DENIED;
   5052         }
   5053     }
   5054 
   5055     /**
   5056      * Check if the targetPkg can be granted permission to access uri by
   5057      * the callingUid using the given modeFlags.  Throws a security exception
   5058      * if callingUid is not allowed to do this.  Returns the uid of the target
   5059      * if the URI permission grant should be performed; returns -1 if it is not
   5060      * needed (for example targetPkg already has permission to access the URI).
   5061      * If you already know the uid of the target, you can supply it in
   5062      * lastTargetUid else set that to -1.
   5063      */
   5064     int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
   5065             Uri uri, int modeFlags, int lastTargetUid) {
   5066         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   5067                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   5068         if (modeFlags == 0) {
   5069             return -1;
   5070         }
   5071 
   5072         if (targetPkg != null) {
   5073             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5074                     "Checking grant " + targetPkg + " permission to " + uri);
   5075         }
   5076 
   5077         final IPackageManager pm = AppGlobals.getPackageManager();
   5078 
   5079         // If this is not a content: uri, we can't do anything with it.
   5080         if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
   5081             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5082                     "Can't grant URI permission for non-content URI: " + uri);
   5083             return -1;
   5084         }
   5085 
   5086         String name = uri.getAuthority();
   5087         ProviderInfo pi = null;
   5088         ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
   5089                 UserHandle.getUserId(callingUid));
   5090         if (cpr != null) {
   5091             pi = cpr.info;
   5092         } else {
   5093             try {
   5094                 pi = pm.resolveContentProvider(name,
   5095                         PackageManager.GET_URI_PERMISSION_PATTERNS,
   5096                         UserHandle.getUserId(callingUid));
   5097             } catch (RemoteException ex) {
   5098             }
   5099         }
   5100         if (pi == null) {
   5101             Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
   5102             return -1;
   5103         }
   5104 
   5105         int targetUid = lastTargetUid;
   5106         if (targetUid < 0 && targetPkg != null) {
   5107             try {
   5108                 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
   5109                 if (targetUid < 0) {
   5110                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5111                             "Can't grant URI permission no uid for: " + targetPkg);
   5112                     return -1;
   5113                 }
   5114             } catch (RemoteException ex) {
   5115                 return -1;
   5116             }
   5117         }
   5118 
   5119         if (targetUid >= 0) {
   5120             // First...  does the target actually need this permission?
   5121             if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
   5122                 // No need to grant the target this permission.
   5123                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5124                         "Target " + targetPkg + " already has full permission to " + uri);
   5125                 return -1;
   5126             }
   5127         } else {
   5128             // First...  there is no target package, so can anyone access it?
   5129             boolean allowed = pi.exported;
   5130             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   5131                 if (pi.readPermission != null) {
   5132                     allowed = false;
   5133                 }
   5134             }
   5135             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   5136                 if (pi.writePermission != null) {
   5137                     allowed = false;
   5138                 }
   5139             }
   5140             if (allowed) {
   5141                 return -1;
   5142             }
   5143         }
   5144 
   5145         // Second...  is the provider allowing granting of URI permissions?
   5146         if (!pi.grantUriPermissions) {
   5147             throw new SecurityException("Provider " + pi.packageName
   5148                     + "/" + pi.name
   5149                     + " does not allow granting of Uri permissions (uri "
   5150                     + uri + ")");
   5151         }
   5152         if (pi.uriPermissionPatterns != null) {
   5153             final int N = pi.uriPermissionPatterns.length;
   5154             boolean allowed = false;
   5155             for (int i=0; i<N; i++) {
   5156                 if (pi.uriPermissionPatterns[i] != null
   5157                         && pi.uriPermissionPatterns[i].match(uri.getPath())) {
   5158                     allowed = true;
   5159                     break;
   5160                 }
   5161             }
   5162             if (!allowed) {
   5163                 throw new SecurityException("Provider " + pi.packageName
   5164                         + "/" + pi.name
   5165                         + " does not allow granting of permission to path of Uri "
   5166                         + uri);
   5167             }
   5168         }
   5169 
   5170         // Third...  does the caller itself have permission to access
   5171         // this uri?
   5172         if (callingUid != Process.myUid()) {
   5173             if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
   5174                 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
   5175                     throw new SecurityException("Uid " + callingUid
   5176                             + " does not have permission to uri " + uri);
   5177                 }
   5178             }
   5179         }
   5180 
   5181         return targetUid;
   5182     }
   5183 
   5184     public int checkGrantUriPermission(int callingUid, String targetPkg,
   5185             Uri uri, int modeFlags) {
   5186         enforceNotIsolatedCaller("checkGrantUriPermission");
   5187         synchronized(this) {
   5188             return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
   5189         }
   5190     }
   5191 
   5192     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
   5193             Uri uri, int modeFlags, UriPermissionOwner owner) {
   5194         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   5195                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   5196         if (modeFlags == 0) {
   5197             return;
   5198         }
   5199 
   5200         // So here we are: the caller has the assumed permission
   5201         // to the uri, and the target doesn't.  Let's now give this to
   5202         // the target.
   5203 
   5204         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5205                 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
   5206 
   5207         HashMap<Uri, UriPermission> targetUris
   5208                 = mGrantedUriPermissions.get(targetUid);
   5209         if (targetUris == null) {
   5210             targetUris = new HashMap<Uri, UriPermission>();
   5211             mGrantedUriPermissions.put(targetUid, targetUris);
   5212         }
   5213 
   5214         UriPermission perm = targetUris.get(uri);
   5215         if (perm == null) {
   5216             perm = new UriPermission(targetUid, uri);
   5217             targetUris.put(uri, perm);
   5218         }
   5219 
   5220         perm.modeFlags |= modeFlags;
   5221         if (owner == null) {
   5222             perm.globalModeFlags |= modeFlags;
   5223         } else {
   5224             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   5225                  perm.readOwners.add(owner);
   5226                  owner.addReadPermission(perm);
   5227             }
   5228             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   5229                  perm.writeOwners.add(owner);
   5230                  owner.addWritePermission(perm);
   5231             }
   5232         }
   5233     }
   5234 
   5235     void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
   5236             int modeFlags, UriPermissionOwner owner) {
   5237         if (targetPkg == null) {
   5238             throw new NullPointerException("targetPkg");
   5239         }
   5240 
   5241         int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
   5242         if (targetUid < 0) {
   5243             return;
   5244         }
   5245 
   5246         grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
   5247     }
   5248 
   5249     static class NeededUriGrants extends ArrayList<Uri> {
   5250         final String targetPkg;
   5251         final int targetUid;
   5252         final int flags;
   5253 
   5254         NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
   5255             targetPkg = _targetPkg;
   5256             targetUid = _targetUid;
   5257             flags = _flags;
   5258         }
   5259     }
   5260 
   5261     /**
   5262      * Like checkGrantUriPermissionLocked, but takes an Intent.
   5263      */
   5264     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
   5265             String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
   5266         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5267                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
   5268                 + " clip=" + (intent != null ? intent.getClipData() : null)
   5269                 + " from " + intent + "; flags=0x"
   5270                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
   5271 
   5272         if (targetPkg == null) {
   5273             throw new NullPointerException("targetPkg");
   5274         }
   5275 
   5276         if (intent == null) {
   5277             return null;
   5278         }
   5279         Uri data = intent.getData();
   5280         ClipData clip = intent.getClipData();
   5281         if (data == null && clip == null) {
   5282             return null;
   5283         }
   5284         if (data != null) {
   5285             int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
   5286                 mode, needed != null ? needed.targetUid : -1);
   5287             if (target > 0) {
   5288                 if (needed == null) {
   5289                     needed = new NeededUriGrants(targetPkg, target, mode);
   5290                 }
   5291                 needed.add(data);
   5292             }
   5293         }
   5294         if (clip != null) {
   5295             for (int i=0; i<clip.getItemCount(); i++) {
   5296                 Uri uri = clip.getItemAt(i).getUri();
   5297                 if (uri != null) {
   5298                     int target = -1;
   5299                     target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
   5300                             mode, needed != null ? needed.targetUid : -1);
   5301                     if (target > 0) {
   5302                         if (needed == null) {
   5303                             needed = new NeededUriGrants(targetPkg, target, mode);
   5304                         }
   5305                         needed.add(uri);
   5306                     }
   5307                 } else {
   5308                     Intent clipIntent = clip.getItemAt(i).getIntent();
   5309                     if (clipIntent != null) {
   5310                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
   5311                                 callingUid, targetPkg, clipIntent, mode, needed);
   5312                         if (newNeeded != null) {
   5313                             needed = newNeeded;
   5314                         }
   5315                     }
   5316                 }
   5317             }
   5318         }
   5319 
   5320         return needed;
   5321     }
   5322 
   5323     /**
   5324      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
   5325      */
   5326     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
   5327             UriPermissionOwner owner) {
   5328         if (needed != null) {
   5329             for (int i=0; i<needed.size(); i++) {
   5330                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
   5331                         needed.get(i), needed.flags, owner);
   5332             }
   5333         }
   5334     }
   5335 
   5336     void grantUriPermissionFromIntentLocked(int callingUid,
   5337             String targetPkg, Intent intent, UriPermissionOwner owner) {
   5338         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
   5339                 intent, intent != null ? intent.getFlags() : 0, null);
   5340         if (needed == null) {
   5341             return;
   5342         }
   5343 
   5344         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
   5345     }
   5346 
   5347     public void grantUriPermission(IApplicationThread caller, String targetPkg,
   5348             Uri uri, int modeFlags) {
   5349         enforceNotIsolatedCaller("grantUriPermission");
   5350         synchronized(this) {
   5351             final ProcessRecord r = getRecordForAppLocked(caller);
   5352             if (r == null) {
   5353                 throw new SecurityException("Unable to find app for caller "
   5354                         + caller
   5355                         + " when granting permission to uri " + uri);
   5356             }
   5357             if (targetPkg == null) {
   5358                 throw new IllegalArgumentException("null target");
   5359             }
   5360             if (uri == null) {
   5361                 throw new IllegalArgumentException("null uri");
   5362             }
   5363 
   5364             grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
   5365                     null);
   5366         }
   5367     }
   5368 
   5369     void removeUriPermissionIfNeededLocked(UriPermission perm) {
   5370         if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
   5371                 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
   5372             HashMap<Uri, UriPermission> perms
   5373                     = mGrantedUriPermissions.get(perm.uid);
   5374             if (perms != null) {
   5375                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5376                         "Removing " + perm.uid + " permission to " + perm.uri);
   5377                 perms.remove(perm.uri);
   5378                 if (perms.size() == 0) {
   5379                     mGrantedUriPermissions.remove(perm.uid);
   5380                 }
   5381             }
   5382         }
   5383     }
   5384 
   5385     private void revokeUriPermissionLocked(int callingUid, Uri uri,
   5386             int modeFlags) {
   5387         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   5388                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   5389         if (modeFlags == 0) {
   5390             return;
   5391         }
   5392 
   5393         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5394                 "Revoking all granted permissions to " + uri);
   5395 
   5396         final IPackageManager pm = AppGlobals.getPackageManager();
   5397 
   5398         final String authority = uri.getAuthority();
   5399         ProviderInfo pi = null;
   5400         int userId = UserHandle.getUserId(callingUid);
   5401         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
   5402         if (cpr != null) {
   5403             pi = cpr.info;
   5404         } else {
   5405             try {
   5406                 pi = pm.resolveContentProvider(authority,
   5407                         PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
   5408             } catch (RemoteException ex) {
   5409             }
   5410         }
   5411         if (pi == null) {
   5412             Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
   5413             return;
   5414         }
   5415 
   5416         // Does the caller have this permission on the URI?
   5417         if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
   5418             // Right now, if you are not the original owner of the permission,
   5419             // you are not allowed to revoke it.
   5420             //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
   5421                 throw new SecurityException("Uid " + callingUid
   5422                         + " does not have permission to uri " + uri);
   5423             //}
   5424         }
   5425 
   5426         // Go through all of the permissions and remove any that match.
   5427         final List<String> SEGMENTS = uri.getPathSegments();
   5428         if (SEGMENTS != null) {
   5429             final int NS = SEGMENTS.size();
   5430             int N = mGrantedUriPermissions.size();
   5431             for (int i=0; i<N; i++) {
   5432                 HashMap<Uri, UriPermission> perms
   5433                         = mGrantedUriPermissions.valueAt(i);
   5434                 Iterator<UriPermission> it = perms.values().iterator();
   5435             toploop:
   5436                 while (it.hasNext()) {
   5437                     UriPermission perm = it.next();
   5438                     Uri targetUri = perm.uri;
   5439                     if (!authority.equals(targetUri.getAuthority())) {
   5440                         continue;
   5441                     }
   5442                     List<String> targetSegments = targetUri.getPathSegments();
   5443                     if (targetSegments == null) {
   5444                         continue;
   5445                     }
   5446                     if (targetSegments.size() < NS) {
   5447                         continue;
   5448                     }
   5449                     for (int j=0; j<NS; j++) {
   5450                         if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
   5451                             continue toploop;
   5452                         }
   5453                     }
   5454                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5455                             "Revoking " + perm.uid + " permission to " + perm.uri);
   5456                     perm.clearModes(modeFlags);
   5457                     if (perm.modeFlags == 0) {
   5458                         it.remove();
   5459                     }
   5460                 }
   5461                 if (perms.size() == 0) {
   5462                     mGrantedUriPermissions.remove(
   5463                             mGrantedUriPermissions.keyAt(i));
   5464                     N--;
   5465                     i--;
   5466                 }
   5467             }
   5468         }
   5469     }
   5470 
   5471     public void revokeUriPermission(IApplicationThread caller, Uri uri,
   5472             int modeFlags) {
   5473         enforceNotIsolatedCaller("revokeUriPermission");
   5474         synchronized(this) {
   5475             final ProcessRecord r = getRecordForAppLocked(caller);
   5476             if (r == null) {
   5477                 throw new SecurityException("Unable to find app for caller "
   5478                         + caller
   5479                         + " when revoking permission to uri " + uri);
   5480             }
   5481             if (uri == null) {
   5482                 Slog.w(TAG, "revokeUriPermission: null uri");
   5483                 return;
   5484             }
   5485 
   5486             modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   5487                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   5488             if (modeFlags == 0) {
   5489                 return;
   5490             }
   5491 
   5492             final IPackageManager pm = AppGlobals.getPackageManager();
   5493 
   5494             final String authority = uri.getAuthority();
   5495             ProviderInfo pi = null;
   5496             ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
   5497             if (cpr != null) {
   5498                 pi = cpr.info;
   5499             } else {
   5500                 try {
   5501                     pi = pm.resolveContentProvider(authority,
   5502                             PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
   5503                 } catch (RemoteException ex) {
   5504                 }
   5505             }
   5506             if (pi == null) {
   5507                 Slog.w(TAG, "No content provider found for permission revoke: "
   5508                         + uri.toSafeString());
   5509                 return;
   5510             }
   5511 
   5512             revokeUriPermissionLocked(r.uid, uri, modeFlags);
   5513         }
   5514     }
   5515 
   5516     @Override
   5517     public IBinder newUriPermissionOwner(String name) {
   5518         enforceNotIsolatedCaller("newUriPermissionOwner");
   5519         synchronized(this) {
   5520             UriPermissionOwner owner = new UriPermissionOwner(this, name);
   5521             return owner.getExternalTokenLocked();
   5522         }
   5523     }
   5524 
   5525     @Override
   5526     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
   5527             Uri uri, int modeFlags) {
   5528         synchronized(this) {
   5529             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   5530             if (owner == null) {
   5531                 throw new IllegalArgumentException("Unknown owner: " + token);
   5532             }
   5533             if (fromUid != Binder.getCallingUid()) {
   5534                 if (Binder.getCallingUid() != Process.myUid()) {
   5535                     // Only system code can grant URI permissions on behalf
   5536                     // of other users.
   5537                     throw new SecurityException("nice try");
   5538                 }
   5539             }
   5540             if (targetPkg == null) {
   5541                 throw new IllegalArgumentException("null target");
   5542             }
   5543             if (uri == null) {
   5544                 throw new IllegalArgumentException("null uri");
   5545             }
   5546 
   5547             grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
   5548         }
   5549     }
   5550 
   5551     @Override
   5552     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
   5553         synchronized(this) {
   5554             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   5555             if (owner == null) {
   5556                 throw new IllegalArgumentException("Unknown owner: " + token);
   5557             }
   5558 
   5559             if (uri == null) {
   5560                 owner.removeUriPermissionsLocked(mode);
   5561             } else {
   5562                 owner.removeUriPermissionLocked(uri, mode);
   5563             }
   5564         }
   5565     }
   5566 
   5567     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
   5568         synchronized (this) {
   5569             ProcessRecord app =
   5570                 who != null ? getRecordForAppLocked(who) : null;
   5571             if (app == null) return;
   5572 
   5573             Message msg = Message.obtain();
   5574             msg.what = WAIT_FOR_DEBUGGER_MSG;
   5575             msg.obj = app;
   5576             msg.arg1 = waiting ? 1 : 0;
   5577             mHandler.sendMessage(msg);
   5578         }
   5579     }
   5580 
   5581     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
   5582         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
   5583         final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
   5584         outInfo.availMem = Process.getFreeMemory();
   5585         outInfo.totalMem = Process.getTotalMemory();
   5586         outInfo.threshold = homeAppMem;
   5587         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
   5588         outInfo.hiddenAppThreshold = hiddenAppMem;
   5589         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
   5590                 ProcessList.SERVICE_ADJ);
   5591         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
   5592                 ProcessList.VISIBLE_APP_ADJ);
   5593         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
   5594                 ProcessList.FOREGROUND_APP_ADJ);
   5595     }
   5596 
   5597     // =========================================================
   5598     // TASK MANAGEMENT
   5599     // =========================================================
   5600 
   5601     public List getTasks(int maxNum, int flags,
   5602                          IThumbnailReceiver receiver) {
   5603         ArrayList list = new ArrayList();
   5604 
   5605         PendingThumbnailsRecord pending = null;
   5606         IApplicationThread topThumbnail = null;
   5607         ActivityRecord topRecord = null;
   5608 
   5609         synchronized(this) {
   5610             if (localLOGV) Slog.v(
   5611                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
   5612                 + ", receiver=" + receiver);
   5613 
   5614             if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
   5615                     != PackageManager.PERMISSION_GRANTED) {
   5616                 if (receiver != null) {
   5617                     // If the caller wants to wait for pending thumbnails,
   5618                     // it ain't gonna get them.
   5619                     try {
   5620                         receiver.finished();
   5621                     } catch (RemoteException ex) {
   5622                     }
   5623                 }
   5624                 String msg = "Permission Denial: getTasks() from pid="
   5625                         + Binder.getCallingPid()
   5626                         + ", uid=" + Binder.getCallingUid()
   5627                         + " requires " + android.Manifest.permission.GET_TASKS;
   5628                 Slog.w(TAG, msg);
   5629                 throw new SecurityException(msg);
   5630             }
   5631 
   5632             int pos = mMainStack.mHistory.size()-1;
   5633             ActivityRecord next =
   5634                 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
   5635             ActivityRecord top = null;
   5636             TaskRecord curTask = null;
   5637             int numActivities = 0;
   5638             int numRunning = 0;
   5639             while (pos >= 0 && maxNum > 0) {
   5640                 final ActivityRecord r = next;
   5641                 pos--;
   5642                 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
   5643 
   5644                 // Initialize state for next task if needed.
   5645                 if (top == null ||
   5646                         (top.state == ActivityState.INITIALIZING
   5647                             && top.task == r.task)) {
   5648                     top = r;
   5649                     curTask = r.task;
   5650                     numActivities = numRunning = 0;
   5651                 }
   5652 
   5653                 // Add 'r' into the current task.
   5654                 numActivities++;
   5655                 if (r.app != null && r.app.thread != null) {
   5656                     numRunning++;
   5657                 }
   5658 
   5659                 if (localLOGV) Slog.v(
   5660                     TAG, r.intent.getComponent().flattenToShortString()
   5661                     + ": task=" + r.task);
   5662 
   5663                 // If the next one is a different task, generate a new
   5664                 // TaskInfo entry for what we have.
   5665                 if (next == null || next.task != curTask) {
   5666                     ActivityManager.RunningTaskInfo ci
   5667                             = new ActivityManager.RunningTaskInfo();
   5668                     ci.id = curTask.taskId;
   5669                     ci.baseActivity = r.intent.getComponent();
   5670                     ci.topActivity = top.intent.getComponent();
   5671                     if (top.thumbHolder != null) {
   5672                         ci.description = top.thumbHolder.lastDescription;
   5673                     }
   5674                     ci.numActivities = numActivities;
   5675                     ci.numRunning = numRunning;
   5676                     //System.out.println(
   5677                     //    "#" + maxNum + ": " + " descr=" + ci.description);
   5678                     if (ci.thumbnail == null && receiver != null) {
   5679                         if (localLOGV) Slog.v(
   5680                             TAG, "State=" + top.state + "Idle=" + top.idle
   5681                             + " app=" + top.app
   5682                             + " thr=" + (top.app != null ? top.app.thread : null));
   5683                         if (top.state == ActivityState.RESUMED
   5684                                 || top.state == ActivityState.PAUSING) {
   5685                             if (top.idle && top.app != null
   5686                                 && top.app.thread != null) {
   5687                                 topRecord = top;
   5688                                 topThumbnail = top.app.thread;
   5689                             } else {
   5690                                 top.thumbnailNeeded = true;
   5691                             }
   5692                         }
   5693                         if (pending == null) {
   5694                             pending = new PendingThumbnailsRecord(receiver);
   5695                         }
   5696                         pending.pendingRecords.add(top);
   5697                     }
   5698                     list.add(ci);
   5699                     maxNum--;
   5700                     top = null;
   5701                 }
   5702             }
   5703 
   5704             if (pending != null) {
   5705                 mPendingThumbnails.add(pending);
   5706             }
   5707         }
   5708 
   5709         if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
   5710 
   5711         if (topThumbnail != null) {
   5712             if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
   5713             try {
   5714                 topThumbnail.requestThumbnail(topRecord.appToken);
   5715             } catch (Exception e) {
   5716                 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
   5717                 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
   5718             }
   5719         }
   5720 
   5721         if (pending == null && receiver != null) {
   5722             // In this case all thumbnails were available and the client
   5723             // is being asked to be told when the remaining ones come in...
   5724             // which is unusually, since the top-most currently running
   5725             // activity should never have a canned thumbnail!  Oh well.
   5726             try {
   5727                 receiver.finished();
   5728             } catch (RemoteException ex) {
   5729             }
   5730         }
   5731 
   5732         return list;
   5733     }
   5734 
   5735     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
   5736             int flags, int userId) {
   5737         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   5738                 false, true, "getRecentTasks", null);
   5739 
   5740         synchronized (this) {
   5741             enforceCallingPermission(android.Manifest.permission.GET_TASKS,
   5742                     "getRecentTasks()");
   5743             final boolean detailed = checkCallingPermission(
   5744                     android.Manifest.permission.GET_DETAILED_TASKS)
   5745                     == PackageManager.PERMISSION_GRANTED;
   5746 
   5747             IPackageManager pm = AppGlobals.getPackageManager();
   5748 
   5749             final int N = mRecentTasks.size();
   5750             ArrayList<ActivityManager.RecentTaskInfo> res
   5751                     = new ArrayList<ActivityManager.RecentTaskInfo>(
   5752                             maxNum < N ? maxNum : N);
   5753             for (int i=0; i<N && maxNum > 0; i++) {
   5754                 TaskRecord tr = mRecentTasks.get(i);
   5755                 // Only add calling user's recent tasks
   5756                 if (tr.userId != userId) continue;
   5757                 // Return the entry if desired by the caller.  We always return
   5758                 // the first entry, because callers always expect this to be the
   5759                 // foreground app.  We may filter others if the caller has
   5760                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
   5761                 // we should exclude the entry.
   5762 
   5763                 if (i == 0
   5764                         || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
   5765                         || (tr.intent == null)
   5766                         || ((tr.intent.getFlags()
   5767                                 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
   5768                     ActivityManager.RecentTaskInfo rti
   5769                             = new ActivityManager.RecentTaskInfo();
   5770                     rti.id = tr.numActivities > 0 ? tr.taskId : -1;
   5771                     rti.persistentId = tr.taskId;
   5772                     rti.baseIntent = new Intent(
   5773                             tr.intent != null ? tr.intent : tr.affinityIntent);
   5774                     if (!detailed) {
   5775                         rti.baseIntent.replaceExtras((Bundle)null);
   5776                     }
   5777                     rti.origActivity = tr.origActivity;
   5778                     rti.description = tr.lastDescription;
   5779 
   5780                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
   5781                         // Check whether this activity is currently available.
   5782                         try {
   5783                             if (rti.origActivity != null) {
   5784                                 if (pm.getActivityInfo(rti.origActivity, 0, userId)
   5785                                         == null) {
   5786                                     continue;
   5787                                 }
   5788                             } else if (rti.baseIntent != null) {
   5789                                 if (pm.queryIntentActivities(rti.baseIntent,
   5790                                         null, 0, userId) == null) {
   5791                                     continue;
   5792                                 }
   5793                             }
   5794                         } catch (RemoteException e) {
   5795                             // Will never happen.
   5796                         }
   5797                     }
   5798 
   5799                     res.add(rti);
   5800                     maxNum--;
   5801                 }
   5802             }
   5803             return res;
   5804         }
   5805     }
   5806 
   5807     private TaskRecord taskForIdLocked(int id) {
   5808         final int N = mRecentTasks.size();
   5809         for (int i=0; i<N; i++) {
   5810             TaskRecord tr = mRecentTasks.get(i);
   5811             if (tr.taskId == id) {
   5812                 return tr;
   5813             }
   5814         }
   5815         return null;
   5816     }
   5817 
   5818     public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
   5819         synchronized (this) {
   5820             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
   5821                     "getTaskThumbnails()");
   5822             TaskRecord tr = taskForIdLocked(id);
   5823             if (tr != null) {
   5824                 return mMainStack.getTaskThumbnailsLocked(tr);
   5825             }
   5826         }
   5827         return null;
   5828     }
   5829 
   5830     public Bitmap getTaskTopThumbnail(int id) {
   5831         synchronized (this) {
   5832             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
   5833                     "getTaskTopThumbnail()");
   5834             TaskRecord tr = taskForIdLocked(id);
   5835             if (tr != null) {
   5836                 return mMainStack.getTaskTopThumbnailLocked(tr);
   5837             }
   5838         }
   5839         return null;
   5840     }
   5841 
   5842     public boolean removeSubTask(int taskId, int subTaskIndex) {
   5843         synchronized (this) {
   5844             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
   5845                     "removeSubTask()");
   5846             long ident = Binder.clearCallingIdentity();
   5847             try {
   5848                 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
   5849                         true) != null;
   5850             } finally {
   5851                 Binder.restoreCallingIdentity(ident);
   5852             }
   5853         }
   5854     }
   5855 
   5856     private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
   5857         final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
   5858         Intent baseIntent = new Intent(
   5859                 tr.intent != null ? tr.intent : tr.affinityIntent);
   5860         ComponentName component = baseIntent.getComponent();
   5861         if (component == null) {
   5862             Slog.w(TAG, "Now component for base intent of task: " + tr);
   5863             return;
   5864         }
   5865 
   5866         // Find any running services associated with this app.
   5867         mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
   5868 
   5869         if (killProcesses) {
   5870             // Find any running processes associated with this app.
   5871             final String pkg = component.getPackageName();
   5872             ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   5873             HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
   5874             for (SparseArray<ProcessRecord> uids : pmap.values()) {
   5875                 for (int i=0; i<uids.size(); i++) {
   5876                     ProcessRecord proc = uids.valueAt(i);
   5877                     if (proc.userId != tr.userId) {
   5878                         continue;
   5879                     }
   5880                     if (!proc.pkgList.contains(pkg)) {
   5881                         continue;
   5882                     }
   5883                     procs.add(proc);
   5884                 }
   5885             }
   5886 
   5887             // Kill the running processes.
   5888             for (int i=0; i<procs.size(); i++) {
   5889                 ProcessRecord pr = procs.get(i);
   5890                 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
   5891                     Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
   5892                     EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
   5893                             pr.processName, pr.setAdj, "remove task");
   5894                     pr.killedBackground = true;
   5895                     Process.killProcessQuiet(pr.pid);
   5896                 } else {
   5897                     pr.waitingToKill = "remove task";
   5898                 }
   5899             }
   5900         }
   5901     }
   5902 
   5903     public boolean removeTask(int taskId, int flags) {
   5904         synchronized (this) {
   5905             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
   5906                     "removeTask()");
   5907             long ident = Binder.clearCallingIdentity();
   5908             try {
   5909                 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
   5910                         false);
   5911                 if (r != null) {
   5912                     mRecentTasks.remove(r.task);
   5913                     cleanUpRemovedTaskLocked(r.task, flags);
   5914                     return true;
   5915                 } else {
   5916                     TaskRecord tr = null;
   5917                     int i=0;
   5918                     while (i < mRecentTasks.size()) {
   5919                         TaskRecord t = mRecentTasks.get(i);
   5920                         if (t.taskId == taskId) {
   5921                             tr = t;
   5922                             break;
   5923                         }
   5924                         i++;
   5925                     }
   5926                     if (tr != null) {
   5927                         if (tr.numActivities <= 0) {
   5928                             // Caller is just removing a recent task that is
   5929                             // not actively running.  That is easy!
   5930                             mRecentTasks.remove(i);
   5931                             cleanUpRemovedTaskLocked(tr, flags);
   5932                             return true;
   5933                         } else {
   5934                             Slog.w(TAG, "removeTask: task " + taskId
   5935                                     + " does not have activities to remove, "
   5936                                     + " but numActivities=" + tr.numActivities
   5937                                     + ": " + tr);
   5938                         }
   5939                     }
   5940                 }
   5941             } finally {
   5942                 Binder.restoreCallingIdentity(ident);
   5943             }
   5944         }
   5945         return false;
   5946     }
   5947 
   5948     private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
   5949         int j;
   5950         TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
   5951         TaskRecord jt = startTask;
   5952 
   5953         // First look backwards
   5954         for (j=startIndex-1; j>=0; j--) {
   5955             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
   5956             if (r.task != jt) {
   5957                 jt = r.task;
   5958                 if (affinity.equals(jt.affinity)) {
   5959                     return j;
   5960                 }
   5961             }
   5962         }
   5963 
   5964         // Now look forwards
   5965         final int N = mMainStack.mHistory.size();
   5966         jt = startTask;
   5967         for (j=startIndex+1; j<N; j++) {
   5968             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
   5969             if (r.task != jt) {
   5970                 if (affinity.equals(jt.affinity)) {
   5971                     return j;
   5972                 }
   5973                 jt = r.task;
   5974             }
   5975         }
   5976 
   5977         // Might it be at the top?
   5978         if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
   5979             return N-1;
   5980         }
   5981 
   5982         return -1;
   5983     }
   5984 
   5985     /**
   5986      * TODO: Add mController hook
   5987      */
   5988     public void moveTaskToFront(int task, int flags, Bundle options) {
   5989         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   5990                 "moveTaskToFront()");
   5991 
   5992         synchronized(this) {
   5993             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   5994                     Binder.getCallingUid(), "Task to front")) {
   5995                 ActivityOptions.abort(options);
   5996                 return;
   5997             }
   5998             final long origId = Binder.clearCallingIdentity();
   5999             try {
   6000                 TaskRecord tr = taskForIdLocked(task);
   6001                 if (tr != null) {
   6002                     if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
   6003                         mMainStack.mUserLeaving = true;
   6004                     }
   6005                     if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
   6006                         // Caller wants the home activity moved with it.  To accomplish this,
   6007                         // we'll just move the home task to the top first.
   6008                         mMainStack.moveHomeToFrontLocked();
   6009                     }
   6010                     mMainStack.moveTaskToFrontLocked(tr, null, options);
   6011                     return;
   6012                 }
   6013                 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
   6014                     ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
   6015                     if (hr.task.taskId == task) {
   6016                         if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
   6017                             mMainStack.mUserLeaving = true;
   6018                         }
   6019                         if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
   6020                             // Caller wants the home activity moved with it.  To accomplish this,
   6021                             // we'll just move the home task to the top first.
   6022                             mMainStack.moveHomeToFrontLocked();
   6023                         }
   6024                         mMainStack.moveTaskToFrontLocked(hr.task, null, options);
   6025                         return;
   6026                     }
   6027                 }
   6028             } finally {
   6029                 Binder.restoreCallingIdentity(origId);
   6030             }
   6031             ActivityOptions.abort(options);
   6032         }
   6033     }
   6034 
   6035     public void moveTaskToBack(int task) {
   6036         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   6037                 "moveTaskToBack()");
   6038 
   6039         synchronized(this) {
   6040             if (mMainStack.mResumedActivity != null
   6041                     && mMainStack.mResumedActivity.task.taskId == task) {
   6042                 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   6043                         Binder.getCallingUid(), "Task to back")) {
   6044                     return;
   6045                 }
   6046             }
   6047             final long origId = Binder.clearCallingIdentity();
   6048             mMainStack.moveTaskToBackLocked(task, null);
   6049             Binder.restoreCallingIdentity(origId);
   6050         }
   6051     }
   6052 
   6053     /**
   6054      * Moves an activity, and all of the other activities within the same task, to the bottom
   6055      * of the history stack.  The activity's order within the task is unchanged.
   6056      *
   6057      * @param token A reference to the activity we wish to move
   6058      * @param nonRoot If false then this only works if the activity is the root
   6059      *                of a task; if true it will work for any activity in a task.
   6060      * @return Returns true if the move completed, false if not.
   6061      */
   6062     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
   6063         enforceNotIsolatedCaller("moveActivityTaskToBack");
   6064         synchronized(this) {
   6065             final long origId = Binder.clearCallingIdentity();
   6066             int taskId = getTaskForActivityLocked(token, !nonRoot);
   6067             if (taskId >= 0) {
   6068                 return mMainStack.moveTaskToBackLocked(taskId, null);
   6069             }
   6070             Binder.restoreCallingIdentity(origId);
   6071         }
   6072         return false;
   6073     }
   6074 
   6075     public void moveTaskBackwards(int task) {
   6076         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   6077                 "moveTaskBackwards()");
   6078 
   6079         synchronized(this) {
   6080             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   6081                     Binder.getCallingUid(), "Task backwards")) {
   6082                 return;
   6083             }
   6084             final long origId = Binder.clearCallingIdentity();
   6085             moveTaskBackwardsLocked(task);
   6086             Binder.restoreCallingIdentity(origId);
   6087         }
   6088     }
   6089 
   6090     private final void moveTaskBackwardsLocked(int task) {
   6091         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
   6092     }
   6093 
   6094     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
   6095         synchronized(this) {
   6096             return getTaskForActivityLocked(token, onlyRoot);
   6097         }
   6098     }
   6099 
   6100     int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
   6101         final int N = mMainStack.mHistory.size();
   6102         TaskRecord lastTask = null;
   6103         for (int i=0; i<N; i++) {
   6104             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   6105             if (r.appToken == token) {
   6106                 if (!onlyRoot || lastTask != r.task) {
   6107                     return r.task.taskId;
   6108                 }
   6109                 return -1;
   6110             }
   6111             lastTask = r.task;
   6112         }
   6113 
   6114         return -1;
   6115     }
   6116 
   6117     // =========================================================
   6118     // THUMBNAILS
   6119     // =========================================================
   6120 
   6121     public void reportThumbnail(IBinder token,
   6122             Bitmap thumbnail, CharSequence description) {
   6123         //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
   6124         final long origId = Binder.clearCallingIdentity();
   6125         sendPendingThumbnail(null, token, thumbnail, description, true);
   6126         Binder.restoreCallingIdentity(origId);
   6127     }
   6128 
   6129     final void sendPendingThumbnail(ActivityRecord r, IBinder token,
   6130             Bitmap thumbnail, CharSequence description, boolean always) {
   6131         TaskRecord task = null;
   6132         ArrayList receivers = null;
   6133 
   6134         //System.out.println("Send pending thumbnail: " + r);
   6135 
   6136         synchronized(this) {
   6137             if (r == null) {
   6138                 r = mMainStack.isInStackLocked(token);
   6139                 if (r == null) {
   6140                     return;
   6141                 }
   6142             }
   6143             if (thumbnail == null && r.thumbHolder != null) {
   6144                 thumbnail = r.thumbHolder.lastThumbnail;
   6145                 description = r.thumbHolder.lastDescription;
   6146             }
   6147             if (thumbnail == null && !always) {
   6148                 // If there is no thumbnail, and this entry is not actually
   6149                 // going away, then abort for now and pick up the next
   6150                 // thumbnail we get.
   6151                 return;
   6152             }
   6153             task = r.task;
   6154 
   6155             int N = mPendingThumbnails.size();
   6156             int i=0;
   6157             while (i<N) {
   6158                 PendingThumbnailsRecord pr =
   6159                     (PendingThumbnailsRecord)mPendingThumbnails.get(i);
   6160                 //System.out.println("Looking in " + pr.pendingRecords);
   6161                 if (pr.pendingRecords.remove(r)) {
   6162                     if (receivers == null) {
   6163                         receivers = new ArrayList();
   6164                     }
   6165                     receivers.add(pr);
   6166                     if (pr.pendingRecords.size() == 0) {
   6167                         pr.finished = true;
   6168                         mPendingThumbnails.remove(i);
   6169                         N--;
   6170                         continue;
   6171                     }
   6172                 }
   6173                 i++;
   6174             }
   6175         }
   6176 
   6177         if (receivers != null) {
   6178             final int N = receivers.size();
   6179             for (int i=0; i<N; i++) {
   6180                 try {
   6181                     PendingThumbnailsRecord pr =
   6182                         (PendingThumbnailsRecord)receivers.get(i);
   6183                     pr.receiver.newThumbnail(
   6184                         task != null ? task.taskId : -1, thumbnail, description);
   6185                     if (pr.finished) {
   6186                         pr.receiver.finished();
   6187                     }
   6188                 } catch (Exception e) {
   6189                     Slog.w(TAG, "Exception thrown when sending thumbnail", e);
   6190                 }
   6191             }
   6192         }
   6193     }
   6194 
   6195     // =========================================================
   6196     // CONTENT PROVIDERS
   6197     // =========================================================
   6198 
   6199     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
   6200         List<ProviderInfo> providers = null;
   6201         try {
   6202             providers = AppGlobals.getPackageManager().
   6203                 queryContentProviders(app.processName, app.uid,
   6204                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
   6205         } catch (RemoteException ex) {
   6206         }
   6207         if (DEBUG_MU)
   6208             Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
   6209         int userId = app.userId;
   6210         if (providers != null) {
   6211             int N = providers.size();
   6212             for (int i=0; i<N; i++) {
   6213                 ProviderInfo cpi =
   6214                     (ProviderInfo)providers.get(i);
   6215                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
   6216                         cpi.name, cpi.flags);
   6217                 if (singleton && UserHandle.getUserId(app.uid) != 0) {
   6218                     // This is a singleton provider, but a user besides the
   6219                     // default user is asking to initialize a process it runs
   6220                     // in...  well, no, it doesn't actually run in this process,
   6221                     // it runs in the process of the default user.  Get rid of it.
   6222                     providers.remove(i);
   6223                     N--;
   6224                     continue;
   6225                 }
   6226 
   6227                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   6228                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
   6229                 if (cpr == null) {
   6230                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
   6231                     mProviderMap.putProviderByClass(comp, cpr);
   6232                 }
   6233                 if (DEBUG_MU)
   6234                     Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
   6235                 app.pubProviders.put(cpi.name, cpr);
   6236                 app.addPackage(cpi.applicationInfo.packageName);
   6237                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
   6238             }
   6239         }
   6240         return providers;
   6241     }
   6242 
   6243     /**
   6244      * Check if {@link ProcessRecord} has a possible chance at accessing the
   6245      * given {@link ProviderInfo}. Final permission checking is always done
   6246      * in {@link ContentProvider}.
   6247      */
   6248     private final String checkContentProviderPermissionLocked(
   6249             ProviderInfo cpi, ProcessRecord r) {
   6250         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
   6251         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
   6252         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
   6253                 cpi.applicationInfo.uid, cpi.exported)
   6254                 == PackageManager.PERMISSION_GRANTED) {
   6255             return null;
   6256         }
   6257         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
   6258                 cpi.applicationInfo.uid, cpi.exported)
   6259                 == PackageManager.PERMISSION_GRANTED) {
   6260             return null;
   6261         }
   6262 
   6263         PathPermission[] pps = cpi.pathPermissions;
   6264         if (pps != null) {
   6265             int i = pps.length;
   6266             while (i > 0) {
   6267                 i--;
   6268                 PathPermission pp = pps[i];
   6269                 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
   6270                         cpi.applicationInfo.uid, cpi.exported)
   6271                         == PackageManager.PERMISSION_GRANTED) {
   6272                     return null;
   6273                 }
   6274                 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
   6275                         cpi.applicationInfo.uid, cpi.exported)
   6276                         == PackageManager.PERMISSION_GRANTED) {
   6277                     return null;
   6278                 }
   6279             }
   6280         }
   6281 
   6282         HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   6283         if (perms != null) {
   6284             for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
   6285                 if (uri.getKey().getAuthority().equals(cpi.authority)) {
   6286                     return null;
   6287                 }
   6288             }
   6289         }
   6290 
   6291         String msg;
   6292         if (!cpi.exported) {
   6293             msg = "Permission Denial: opening provider " + cpi.name
   6294                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   6295                     + ", uid=" + callingUid + ") that is not exported from uid "
   6296                     + cpi.applicationInfo.uid;
   6297         } else {
   6298             msg = "Permission Denial: opening provider " + cpi.name
   6299                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   6300                     + ", uid=" + callingUid + ") requires "
   6301                     + cpi.readPermission + " or " + cpi.writePermission;
   6302         }
   6303         Slog.w(TAG, msg);
   6304         return msg;
   6305     }
   6306 
   6307     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
   6308             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   6309         if (r != null) {
   6310             for (int i=0; i<r.conProviders.size(); i++) {
   6311                 ContentProviderConnection conn = r.conProviders.get(i);
   6312                 if (conn.provider == cpr) {
   6313                     if (DEBUG_PROVIDER) Slog.v(TAG,
   6314                             "Adding provider requested by "
   6315                             + r.processName + " from process "
   6316                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   6317                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   6318                     if (stable) {
   6319                         conn.stableCount++;
   6320                         conn.numStableIncs++;
   6321                     } else {
   6322                         conn.unstableCount++;
   6323                         conn.numUnstableIncs++;
   6324                     }
   6325                     return conn;
   6326                 }
   6327             }
   6328             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
   6329             if (stable) {
   6330                 conn.stableCount = 1;
   6331                 conn.numStableIncs = 1;
   6332             } else {
   6333                 conn.unstableCount = 1;
   6334                 conn.numUnstableIncs = 1;
   6335             }
   6336             cpr.connections.add(conn);
   6337             r.conProviders.add(conn);
   6338             return conn;
   6339         }
   6340         cpr.addExternalProcessHandleLocked(externalProcessToken);
   6341         return null;
   6342     }
   6343 
   6344     boolean decProviderCountLocked(ContentProviderConnection conn,
   6345             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   6346         if (conn != null) {
   6347             cpr = conn.provider;
   6348             if (DEBUG_PROVIDER) Slog.v(TAG,
   6349                     "Removing provider requested by "
   6350                     + conn.client.processName + " from process "
   6351                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   6352                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   6353             if (stable) {
   6354                 conn.stableCount--;
   6355             } else {
   6356                 conn.unstableCount--;
   6357             }
   6358             if (conn.stableCount == 0 && conn.unstableCount == 0) {
   6359                 cpr.connections.remove(conn);
   6360                 conn.client.conProviders.remove(conn);
   6361                 return true;
   6362             }
   6363             return false;
   6364         }
   6365         cpr.removeExternalProcessHandleLocked(externalProcessToken);
   6366         return false;
   6367     }
   6368 
   6369     private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
   6370             String name, IBinder token, boolean stable, int userId) {
   6371         ContentProviderRecord cpr;
   6372         ContentProviderConnection conn = null;
   6373         ProviderInfo cpi = null;
   6374 
   6375         synchronized(this) {
   6376             ProcessRecord r = null;
   6377             if (caller != null) {
   6378                 r = getRecordForAppLocked(caller);
   6379                 if (r == null) {
   6380                     throw new SecurityException(
   6381                             "Unable to find app for caller " + caller
   6382                           + " (pid=" + Binder.getCallingPid()
   6383                           + ") when getting content provider " + name);
   6384                 }
   6385             }
   6386 
   6387             // First check if this content provider has been published...
   6388             cpr = mProviderMap.getProviderByName(name, userId);
   6389             boolean providerRunning = cpr != null;
   6390             if (providerRunning) {
   6391                 cpi = cpr.info;
   6392                 String msg;
   6393                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
   6394                     throw new SecurityException(msg);
   6395                 }
   6396 
   6397                 if (r != null && cpr.canRunHere(r)) {
   6398                     // This provider has been published or is in the process
   6399                     // of being published...  but it is also allowed to run
   6400                     // in the caller's process, so don't make a connection
   6401                     // and just let the caller instantiate its own instance.
   6402                     ContentProviderHolder holder = cpr.newHolder(null);
   6403                     // don't give caller the provider object, it needs
   6404                     // to make its own.
   6405                     holder.provider = null;
   6406                     return holder;
   6407                 }
   6408 
   6409                 final long origId = Binder.clearCallingIdentity();
   6410 
   6411                 // In this case the provider instance already exists, so we can
   6412                 // return it right away.
   6413                 conn = incProviderCountLocked(r, cpr, token, stable);
   6414                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
   6415                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   6416                         // If this is a perceptible app accessing the provider,
   6417                         // make sure to count it as being accessed and thus
   6418                         // back up on the LRU list.  This is good because
   6419                         // content providers are often expensive to start.
   6420                         updateLruProcessLocked(cpr.proc, false);
   6421                     }
   6422                 }
   6423 
   6424                 if (cpr.proc != null) {
   6425                     if (false) {
   6426                         if (cpr.name.flattenToShortString().equals(
   6427                                 "com.android.providers.calendar/.CalendarProvider2")) {
   6428                             Slog.v(TAG, "****************** KILLING "
   6429                                 + cpr.name.flattenToShortString());
   6430                             Process.killProcess(cpr.proc.pid);
   6431                         }
   6432                     }
   6433                     boolean success = updateOomAdjLocked(cpr.proc);
   6434                     if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
   6435                     // NOTE: there is still a race here where a signal could be
   6436                     // pending on the process even though we managed to update its
   6437                     // adj level.  Not sure what to do about this, but at least
   6438                     // the race is now smaller.
   6439                     if (!success) {
   6440                         // Uh oh...  it looks like the provider's process
   6441                         // has been killed on us.  We need to wait for a new
   6442                         // process to be started, and make sure its death
   6443                         // doesn't kill our process.
   6444                         Slog.i(TAG,
   6445                                 "Existing provider " + cpr.name.flattenToShortString()
   6446                                 + " is crashing; detaching " + r);
   6447                         boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
   6448                         appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
   6449                         if (!lastRef) {
   6450                             // This wasn't the last ref our process had on
   6451                             // the provider...  we have now been killed, bail.
   6452                             return null;
   6453                         }
   6454                         providerRunning = false;
   6455                         conn = null;
   6456                     }
   6457                 }
   6458 
   6459                 Binder.restoreCallingIdentity(origId);
   6460             }
   6461 
   6462             boolean singleton;
   6463             if (!providerRunning) {
   6464                 try {
   6465                     cpi = AppGlobals.getPackageManager().
   6466                         resolveContentProvider(name,
   6467                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
   6468                 } catch (RemoteException ex) {
   6469                 }
   6470                 if (cpi == null) {
   6471                     return null;
   6472                 }
   6473                 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
   6474                         cpi.name, cpi.flags);
   6475                 if (singleton) {
   6476                     userId = 0;
   6477                 }
   6478                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
   6479 
   6480                 String msg;
   6481                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
   6482                     throw new SecurityException(msg);
   6483                 }
   6484 
   6485                 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
   6486                         && !cpi.processName.equals("system")) {
   6487                     // If this content provider does not run in the system
   6488                     // process, and the system is not yet ready to run other
   6489                     // processes, then fail fast instead of hanging.
   6490                     throw new IllegalArgumentException(
   6491                             "Attempt to launch content provider before system ready");
   6492                 }
   6493 
   6494                 // Make sure that the user who owns this provider is started.  If not,
   6495                 // we don't want to allow it to run.
   6496                 if (mStartedUsers.get(userId) == null) {
   6497                     Slog.w(TAG, "Unable to launch app "
   6498                             + cpi.applicationInfo.packageName + "/"
   6499                             + cpi.applicationInfo.uid + " for provider "
   6500                             + name + ": user " + userId + " is stopped");
   6501                     return null;
   6502                 }
   6503 
   6504                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   6505                 cpr = mProviderMap.getProviderByClass(comp, userId);
   6506                 final boolean firstClass = cpr == null;
   6507                 if (firstClass) {
   6508                     try {
   6509                         ApplicationInfo ai =
   6510                             AppGlobals.getPackageManager().
   6511                                 getApplicationInfo(
   6512                                         cpi.applicationInfo.packageName,
   6513                                         STOCK_PM_FLAGS, userId);
   6514                         if (ai == null) {
   6515                             Slog.w(TAG, "No package info for content provider "
   6516                                     + cpi.name);
   6517                             return null;
   6518                         }
   6519                         ai = getAppInfoForUser(ai, userId);
   6520                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
   6521                     } catch (RemoteException ex) {
   6522                         // pm is in same process, this will never happen.
   6523                     }
   6524                 }
   6525 
   6526                 if (r != null && cpr.canRunHere(r)) {
   6527                     // If this is a multiprocess provider, then just return its
   6528                     // info and allow the caller to instantiate it.  Only do
   6529                     // this if the provider is the same user as the caller's
   6530                     // process, or can run as root (so can be in any process).
   6531                     return cpr.newHolder(null);
   6532                 }
   6533 
   6534                 if (DEBUG_PROVIDER) {
   6535                     RuntimeException e = new RuntimeException("here");
   6536                     Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
   6537                           + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
   6538                 }
   6539 
   6540                 // This is single process, and our app is now connecting to it.
   6541                 // See if we are already in the process of launching this
   6542                 // provider.
   6543                 final int N = mLaunchingProviders.size();
   6544                 int i;
   6545                 for (i=0; i<N; i++) {
   6546                     if (mLaunchingProviders.get(i) == cpr) {
   6547                         break;
   6548                     }
   6549                 }
   6550 
   6551                 // If the provider is not already being launched, then get it
   6552                 // started.
   6553                 if (i >= N) {
   6554                     final long origId = Binder.clearCallingIdentity();
   6555 
   6556                     try {
   6557                         // Content provider is now in use, its package can't be stopped.
   6558                         try {
   6559                             AppGlobals.getPackageManager().setPackageStoppedState(
   6560                                     cpr.appInfo.packageName, false, userId);
   6561                         } catch (RemoteException e) {
   6562                         } catch (IllegalArgumentException e) {
   6563                             Slog.w(TAG, "Failed trying to unstop package "
   6564                                     + cpr.appInfo.packageName + ": " + e);
   6565                         }
   6566 
   6567                         ProcessRecord proc = startProcessLocked(cpi.processName,
   6568                                 cpr.appInfo, false, 0, "content provider",
   6569                                 new ComponentName(cpi.applicationInfo.packageName,
   6570                                         cpi.name), false, false);
   6571                         if (proc == null) {
   6572                             Slog.w(TAG, "Unable to launch app "
   6573                                     + cpi.applicationInfo.packageName + "/"
   6574                                     + cpi.applicationInfo.uid + " for provider "
   6575                                     + name + ": process is bad");
   6576                             return null;
   6577                         }
   6578                         cpr.launchingApp = proc;
   6579                         mLaunchingProviders.add(cpr);
   6580                     } finally {
   6581                         Binder.restoreCallingIdentity(origId);
   6582                     }
   6583                 }
   6584 
   6585                 // Make sure the provider is published (the same provider class
   6586                 // may be published under multiple names).
   6587                 if (firstClass) {
   6588                     mProviderMap.putProviderByClass(comp, cpr);
   6589                 }
   6590 
   6591                 mProviderMap.putProviderByName(name, cpr);
   6592                 conn = incProviderCountLocked(r, cpr, token, stable);
   6593                 if (conn != null) {
   6594                     conn.waiting = true;
   6595                 }
   6596             }
   6597         }
   6598 
   6599         // Wait for the provider to be published...
   6600         synchronized (cpr) {
   6601             while (cpr.provider == null) {
   6602                 if (cpr.launchingApp == null) {
   6603                     Slog.w(TAG, "Unable to launch app "
   6604                             + cpi.applicationInfo.packageName + "/"
   6605                             + cpi.applicationInfo.uid + " for provider "
   6606                             + name + ": launching app became null");
   6607                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
   6608                             UserHandle.getUserId(cpi.applicationInfo.uid),
   6609                             cpi.applicationInfo.packageName,
   6610                             cpi.applicationInfo.uid, name);
   6611                     return null;
   6612                 }
   6613                 try {
   6614                     if (DEBUG_MU) {
   6615                         Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
   6616                                 + cpr.launchingApp);
   6617                     }
   6618                     if (conn != null) {
   6619                         conn.waiting = true;
   6620                     }
   6621                     cpr.wait();
   6622                 } catch (InterruptedException ex) {
   6623                 } finally {
   6624                     if (conn != null) {
   6625                         conn.waiting = false;
   6626                     }
   6627                 }
   6628             }
   6629         }
   6630         return cpr != null ? cpr.newHolder(conn) : null;
   6631     }
   6632 
   6633     public final ContentProviderHolder getContentProvider(
   6634             IApplicationThread caller, String name, int userId, boolean stable) {
   6635         enforceNotIsolatedCaller("getContentProvider");
   6636         if (caller == null) {
   6637             String msg = "null IApplicationThread when getting content provider "
   6638                     + name;
   6639             Slog.w(TAG, msg);
   6640             throw new SecurityException(msg);
   6641         }
   6642 
   6643         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   6644                 false, true, "getContentProvider", null);
   6645         return getContentProviderImpl(caller, name, null, stable, userId);
   6646     }
   6647 
   6648     public ContentProviderHolder getContentProviderExternal(
   6649             String name, int userId, IBinder token) {
   6650         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   6651             "Do not have permission in call getContentProviderExternal()");
   6652         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   6653                 false, true, "getContentProvider", null);
   6654         return getContentProviderExternalUnchecked(name, token, userId);
   6655     }
   6656 
   6657     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
   6658             IBinder token, int userId) {
   6659         return getContentProviderImpl(null, name, token, true, userId);
   6660     }
   6661 
   6662     /**
   6663      * Drop a content provider from a ProcessRecord's bookkeeping
   6664      * @param cpr
   6665      */
   6666     public void removeContentProvider(IBinder connection, boolean stable) {
   6667         enforceNotIsolatedCaller("removeContentProvider");
   6668         synchronized (this) {
   6669             ContentProviderConnection conn;
   6670             try {
   6671                 conn = (ContentProviderConnection)connection;
   6672             } catch (ClassCastException e) {
   6673                 String msg ="removeContentProvider: " + connection
   6674                         + " not a ContentProviderConnection";
   6675                 Slog.w(TAG, msg);
   6676                 throw new IllegalArgumentException(msg);
   6677             }
   6678             if (conn == null) {
   6679                 throw new NullPointerException("connection is null");
   6680             }
   6681             if (decProviderCountLocked(conn, null, null, stable)) {
   6682                 updateOomAdjLocked();
   6683             }
   6684         }
   6685     }
   6686 
   6687     public void removeContentProviderExternal(String name, IBinder token) {
   6688         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   6689             "Do not have permission in call removeContentProviderExternal()");
   6690         removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
   6691     }
   6692 
   6693     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
   6694         synchronized (this) {
   6695             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
   6696             if(cpr == null) {
   6697                 //remove from mProvidersByClass
   6698                 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
   6699                 return;
   6700             }
   6701 
   6702             //update content provider record entry info
   6703             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
   6704             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
   6705             if (localCpr.hasExternalProcessHandles()) {
   6706                 if (localCpr.removeExternalProcessHandleLocked(token)) {
   6707                     updateOomAdjLocked();
   6708                 } else {
   6709                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
   6710                             + " with no external reference for token: "
   6711                             + token + ".");
   6712                 }
   6713             } else {
   6714                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
   6715                         + " with no external references.");
   6716             }
   6717         }
   6718     }
   6719 
   6720     public final void publishContentProviders(IApplicationThread caller,
   6721             List<ContentProviderHolder> providers) {
   6722         if (providers == null) {
   6723             return;
   6724         }
   6725 
   6726         enforceNotIsolatedCaller("publishContentProviders");
   6727         synchronized (this) {
   6728             final ProcessRecord r = getRecordForAppLocked(caller);
   6729             if (DEBUG_MU)
   6730                 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
   6731             if (r == null) {
   6732                 throw new SecurityException(
   6733                         "Unable to find app for caller " + caller
   6734                       + " (pid=" + Binder.getCallingPid()
   6735                       + ") when publishing content providers");
   6736             }
   6737 
   6738             final long origId = Binder.clearCallingIdentity();
   6739 
   6740             final int N = providers.size();
   6741             for (int i=0; i<N; i++) {
   6742                 ContentProviderHolder src = providers.get(i);
   6743                 if (src == null || src.info == null || src.provider == null) {
   6744                     continue;
   6745                 }
   6746                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
   6747                 if (DEBUG_MU)
   6748                     Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
   6749                 if (dst != null) {
   6750                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
   6751                     mProviderMap.putProviderByClass(comp, dst);
   6752                     String names[] = dst.info.authority.split(";");
   6753                     for (int j = 0; j < names.length; j++) {
   6754                         mProviderMap.putProviderByName(names[j], dst);
   6755                     }
   6756 
   6757                     int NL = mLaunchingProviders.size();
   6758                     int j;
   6759                     for (j=0; j<NL; j++) {
   6760                         if (mLaunchingProviders.get(j) == dst) {
   6761                             mLaunchingProviders.remove(j);
   6762                             j--;
   6763                             NL--;
   6764                         }
   6765                     }
   6766                     synchronized (dst) {
   6767                         dst.provider = src.provider;
   6768                         dst.proc = r;
   6769                         dst.notifyAll();
   6770                     }
   6771                     updateOomAdjLocked(r);
   6772                 }
   6773             }
   6774 
   6775             Binder.restoreCallingIdentity(origId);
   6776         }
   6777     }
   6778 
   6779     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
   6780         ContentProviderConnection conn;
   6781         try {
   6782             conn = (ContentProviderConnection)connection;
   6783         } catch (ClassCastException e) {
   6784             String msg ="refContentProvider: " + connection
   6785                     + " not a ContentProviderConnection";
   6786             Slog.w(TAG, msg);
   6787             throw new IllegalArgumentException(msg);
   6788         }
   6789         if (conn == null) {
   6790             throw new NullPointerException("connection is null");
   6791         }
   6792 
   6793         synchronized (this) {
   6794             if (stable > 0) {
   6795                 conn.numStableIncs += stable;
   6796             }
   6797             stable = conn.stableCount + stable;
   6798             if (stable < 0) {
   6799                 throw new IllegalStateException("stableCount < 0: " + stable);
   6800             }
   6801 
   6802             if (unstable > 0) {
   6803                 conn.numUnstableIncs += unstable;
   6804             }
   6805             unstable = conn.unstableCount + unstable;
   6806             if (unstable < 0) {
   6807                 throw new IllegalStateException("unstableCount < 0: " + unstable);
   6808             }
   6809 
   6810             if ((stable+unstable) <= 0) {
   6811                 throw new IllegalStateException("ref counts can't go to zero here: stable="
   6812                         + stable + " unstable=" + unstable);
   6813             }
   6814             conn.stableCount = stable;
   6815             conn.unstableCount = unstable;
   6816             return !conn.dead;
   6817         }
   6818     }
   6819 
   6820     public void unstableProviderDied(IBinder connection) {
   6821         ContentProviderConnection conn;
   6822         try {
   6823             conn = (ContentProviderConnection)connection;
   6824         } catch (ClassCastException e) {
   6825             String msg ="refContentProvider: " + connection
   6826                     + " not a ContentProviderConnection";
   6827             Slog.w(TAG, msg);
   6828             throw new IllegalArgumentException(msg);
   6829         }
   6830         if (conn == null) {
   6831             throw new NullPointerException("connection is null");
   6832         }
   6833 
   6834         // Safely retrieve the content provider associated with the connection.
   6835         IContentProvider provider;
   6836         synchronized (this) {
   6837             provider = conn.provider.provider;
   6838         }
   6839 
   6840         if (provider == null) {
   6841             // Um, yeah, we're way ahead of you.
   6842             return;
   6843         }
   6844 
   6845         // Make sure the caller is being honest with us.
   6846         if (provider.asBinder().pingBinder()) {
   6847             // Er, no, still looks good to us.
   6848             synchronized (this) {
   6849                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
   6850                         + " says " + conn + " died, but we don't agree");
   6851                 return;
   6852             }
   6853         }
   6854 
   6855         // Well look at that!  It's dead!
   6856         synchronized (this) {
   6857             if (conn.provider.provider != provider) {
   6858                 // But something changed...  good enough.
   6859                 return;
   6860             }
   6861 
   6862             ProcessRecord proc = conn.provider.proc;
   6863             if (proc == null || proc.thread == null) {
   6864                 // Seems like the process is already cleaned up.
   6865                 return;
   6866             }
   6867 
   6868             // As far as we're concerned, this is just like receiving a
   6869             // death notification...  just a bit prematurely.
   6870             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
   6871                     + ") early provider death");
   6872             final long ident = Binder.clearCallingIdentity();
   6873             try {
   6874                 appDiedLocked(proc, proc.pid, proc.thread);
   6875             } finally {
   6876                 Binder.restoreCallingIdentity(ident);
   6877             }
   6878         }
   6879     }
   6880 
   6881     public static final void installSystemProviders() {
   6882         List<ProviderInfo> providers;
   6883         synchronized (mSelf) {
   6884             ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
   6885             providers = mSelf.generateApplicationProvidersLocked(app);
   6886             if (providers != null) {
   6887                 for (int i=providers.size()-1; i>=0; i--) {
   6888                     ProviderInfo pi = (ProviderInfo)providers.get(i);
   6889                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   6890                         Slog.w(TAG, "Not installing system proc provider " + pi.name
   6891                                 + ": not system .apk");
   6892                         providers.remove(i);
   6893                     }
   6894                 }
   6895             }
   6896         }
   6897         if (providers != null) {
   6898             mSystemThread.installSystemProviders(providers);
   6899         }
   6900 
   6901         mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
   6902 
   6903         mSelf.mUsageStatsService.monitorPackages();
   6904     }
   6905 
   6906     /**
   6907      * Allows app to retrieve the MIME type of a URI without having permission
   6908      * to access its content provider.
   6909      *
   6910      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
   6911      *
   6912      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
   6913      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
   6914      */
   6915     public String getProviderMimeType(Uri uri, int userId) {
   6916         enforceNotIsolatedCaller("getProviderMimeType");
   6917         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   6918                 userId, false, true, "getProviderMimeType", null);
   6919         final String name = uri.getAuthority();
   6920         final long ident = Binder.clearCallingIdentity();
   6921         ContentProviderHolder holder = null;
   6922 
   6923         try {
   6924             holder = getContentProviderExternalUnchecked(name, null, userId);
   6925             if (holder != null) {
   6926                 return holder.provider.getType(uri);
   6927             }
   6928         } catch (RemoteException e) {
   6929             Log.w(TAG, "Content provider dead retrieving " + uri, e);
   6930             return null;
   6931         } finally {
   6932             if (holder != null) {
   6933                 removeContentProviderExternalUnchecked(name, null, userId);
   6934             }
   6935             Binder.restoreCallingIdentity(ident);
   6936         }
   6937 
   6938         return null;
   6939     }
   6940 
   6941     // =========================================================
   6942     // GLOBAL MANAGEMENT
   6943     // =========================================================
   6944 
   6945     final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
   6946             ApplicationInfo info, String customProcess, boolean isolated) {
   6947         String proc = customProcess != null ? customProcess : info.processName;
   6948         BatteryStatsImpl.Uid.Proc ps = null;
   6949         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   6950         int uid = info.uid;
   6951         if (isolated) {
   6952             int userId = UserHandle.getUserId(uid);
   6953             int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
   6954             uid = 0;
   6955             while (true) {
   6956                 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
   6957                         || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
   6958                     mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
   6959                 }
   6960                 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
   6961                 mNextIsolatedProcessUid++;
   6962                 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
   6963                     // No process for this uid, use it.
   6964                     break;
   6965                 }
   6966                 stepsLeft--;
   6967                 if (stepsLeft <= 0) {
   6968                     return null;
   6969                 }
   6970             }
   6971         }
   6972         synchronized (stats) {
   6973             ps = stats.getProcessStatsLocked(info.uid, proc);
   6974         }
   6975         return new ProcessRecord(ps, thread, info, proc, uid);
   6976     }
   6977 
   6978     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
   6979         ProcessRecord app;
   6980         if (!isolated) {
   6981             app = getProcessRecordLocked(info.processName, info.uid);
   6982         } else {
   6983             app = null;
   6984         }
   6985 
   6986         if (app == null) {
   6987             app = newProcessRecordLocked(null, info, null, isolated);
   6988             mProcessNames.put(info.processName, app.uid, app);
   6989             if (isolated) {
   6990                 mIsolatedProcesses.put(app.uid, app);
   6991             }
   6992             updateLruProcessLocked(app, true);
   6993         }
   6994 
   6995         // This package really, really can not be stopped.
   6996         try {
   6997             AppGlobals.getPackageManager().setPackageStoppedState(
   6998                     info.packageName, false, UserHandle.getUserId(app.uid));
   6999         } catch (RemoteException e) {
   7000         } catch (IllegalArgumentException e) {
   7001             Slog.w(TAG, "Failed trying to unstop package "
   7002                     + info.packageName + ": " + e);
   7003         }
   7004 
   7005         if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
   7006                 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
   7007             app.persistent = true;
   7008             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
   7009         }
   7010         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
   7011             mPersistentStartingProcesses.add(app);
   7012             startProcessLocked(app, "added application", app.processName);
   7013         }
   7014 
   7015         return app;
   7016     }
   7017 
   7018     public void unhandledBack() {
   7019         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
   7020                 "unhandledBack()");
   7021 
   7022         synchronized(this) {
   7023             int count = mMainStack.mHistory.size();
   7024             if (DEBUG_SWITCH) Slog.d(
   7025                 TAG, "Performing unhandledBack(): stack size = " + count);
   7026             if (count > 1) {
   7027                 final long origId = Binder.clearCallingIdentity();
   7028                 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
   7029                         count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
   7030                 Binder.restoreCallingIdentity(origId);
   7031             }
   7032         }
   7033     }
   7034 
   7035     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
   7036         enforceNotIsolatedCaller("openContentUri");
   7037         final int userId = UserHandle.getCallingUserId();
   7038         String name = uri.getAuthority();
   7039         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
   7040         ParcelFileDescriptor pfd = null;
   7041         if (cph != null) {
   7042             // We record the binder invoker's uid in thread-local storage before
   7043             // going to the content provider to open the file.  Later, in the code
   7044             // that handles all permissions checks, we look for this uid and use
   7045             // that rather than the Activity Manager's own uid.  The effect is that
   7046             // we do the check against the caller's permissions even though it looks
   7047             // to the content provider like the Activity Manager itself is making
   7048             // the request.
   7049             sCallerIdentity.set(new Identity(
   7050                     Binder.getCallingPid(), Binder.getCallingUid()));
   7051             try {
   7052                 pfd = cph.provider.openFile(uri, "r");
   7053             } catch (FileNotFoundException e) {
   7054                 // do nothing; pfd will be returned null
   7055             } finally {
   7056                 // Ensure that whatever happens, we clean up the identity state
   7057                 sCallerIdentity.remove();
   7058             }
   7059 
   7060             // We've got the fd now, so we're done with the provider.
   7061             removeContentProviderExternalUnchecked(name, null, userId);
   7062         } else {
   7063             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
   7064         }
   7065         return pfd;
   7066     }
   7067 
   7068     // Actually is sleeping or shutting down or whatever else in the future
   7069     // is an inactive state.
   7070     public boolean isSleeping() {
   7071         return mSleeping || mShuttingDown;
   7072     }
   7073 
   7074     public void goingToSleep() {
   7075         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
   7076                 != PackageManager.PERMISSION_GRANTED) {
   7077             throw new SecurityException("Requires permission "
   7078                     + android.Manifest.permission.DEVICE_POWER);
   7079         }
   7080 
   7081         synchronized(this) {
   7082             mWentToSleep = true;
   7083             updateEventDispatchingLocked();
   7084 
   7085             if (!mSleeping) {
   7086                 mSleeping = true;
   7087                 mMainStack.stopIfSleepingLocked();
   7088 
   7089                 // Initialize the wake times of all processes.
   7090                 checkExcessivePowerUsageLocked(false);
   7091                 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   7092                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   7093                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   7094             }
   7095         }
   7096     }
   7097 
   7098     public boolean shutdown(int timeout) {
   7099         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
   7100                 != PackageManager.PERMISSION_GRANTED) {
   7101             throw new SecurityException("Requires permission "
   7102                     + android.Manifest.permission.SHUTDOWN);
   7103         }
   7104 
   7105         boolean timedout = false;
   7106 
   7107         synchronized(this) {
   7108             mShuttingDown = true;
   7109             updateEventDispatchingLocked();
   7110 
   7111             if (mMainStack.mResumedActivity != null) {
   7112                 mMainStack.stopIfSleepingLocked();
   7113                 final long endTime = System.currentTimeMillis() + timeout;
   7114                 while (mMainStack.mResumedActivity != null
   7115                         || mMainStack.mPausingActivity != null) {
   7116                     long delay = endTime - System.currentTimeMillis();
   7117                     if (delay <= 0) {
   7118                         Slog.w(TAG, "Activity manager shutdown timed out");
   7119                         timedout = true;
   7120                         break;
   7121                     }
   7122                     try {
   7123                         this.wait();
   7124                     } catch (InterruptedException e) {
   7125                     }
   7126                 }
   7127             }
   7128         }
   7129 
   7130         mUsageStatsService.shutdown();
   7131         mBatteryStatsService.shutdown();
   7132 
   7133         return timedout;
   7134     }
   7135 
   7136     public final void activitySlept(IBinder token) {
   7137         if (localLOGV) Slog.v(
   7138             TAG, "Activity slept: token=" + token);
   7139 
   7140         ActivityRecord r = null;
   7141 
   7142         final long origId = Binder.clearCallingIdentity();
   7143 
   7144         synchronized (this) {
   7145             r = mMainStack.isInStackLocked(token);
   7146             if (r != null) {
   7147                 mMainStack.activitySleptLocked(r);
   7148             }
   7149         }
   7150 
   7151         Binder.restoreCallingIdentity(origId);
   7152     }
   7153 
   7154     private void comeOutOfSleepIfNeededLocked() {
   7155         if (!mWentToSleep && !mLockScreenShown) {
   7156             if (mSleeping) {
   7157                 mSleeping = false;
   7158                 mMainStack.awakeFromSleepingLocked();
   7159                 mMainStack.resumeTopActivityLocked(null);
   7160             }
   7161         }
   7162     }
   7163 
   7164     public void wakingUp() {
   7165         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
   7166                 != PackageManager.PERMISSION_GRANTED) {
   7167             throw new SecurityException("Requires permission "
   7168                     + android.Manifest.permission.DEVICE_POWER);
   7169         }
   7170 
   7171         synchronized(this) {
   7172             mWentToSleep = false;
   7173             updateEventDispatchingLocked();
   7174             comeOutOfSleepIfNeededLocked();
   7175         }
   7176     }
   7177 
   7178     private void updateEventDispatchingLocked() {
   7179         mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
   7180     }
   7181 
   7182     public void setLockScreenShown(boolean shown) {
   7183         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
   7184                 != PackageManager.PERMISSION_GRANTED) {
   7185             throw new SecurityException("Requires permission "
   7186                     + android.Manifest.permission.DEVICE_POWER);
   7187         }
   7188 
   7189         synchronized(this) {
   7190             mLockScreenShown = shown;
   7191             comeOutOfSleepIfNeededLocked();
   7192         }
   7193     }
   7194 
   7195     public void stopAppSwitches() {
   7196         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   7197                 != PackageManager.PERMISSION_GRANTED) {
   7198             throw new SecurityException("Requires permission "
   7199                     + android.Manifest.permission.STOP_APP_SWITCHES);
   7200         }
   7201 
   7202         synchronized(this) {
   7203             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
   7204                     + APP_SWITCH_DELAY_TIME;
   7205             mDidAppSwitch = false;
   7206             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   7207             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   7208             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
   7209         }
   7210     }
   7211 
   7212     public void resumeAppSwitches() {
   7213         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   7214                 != PackageManager.PERMISSION_GRANTED) {
   7215             throw new SecurityException("Requires permission "
   7216                     + android.Manifest.permission.STOP_APP_SWITCHES);
   7217         }
   7218 
   7219         synchronized(this) {
   7220             // Note that we don't execute any pending app switches... we will
   7221             // let those wait until either the timeout, or the next start
   7222             // activity request.
   7223             mAppSwitchesAllowedTime = 0;
   7224         }
   7225     }
   7226 
   7227     boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
   7228             String name) {
   7229         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
   7230             return true;
   7231         }
   7232 
   7233         final int perm = checkComponentPermission(
   7234                 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
   7235                 callingUid, -1, true);
   7236         if (perm == PackageManager.PERMISSION_GRANTED) {
   7237             return true;
   7238         }
   7239 
   7240         Slog.w(TAG, name + " request from " + callingUid + " stopped");
   7241         return false;
   7242     }
   7243 
   7244     public void setDebugApp(String packageName, boolean waitForDebugger,
   7245             boolean persistent) {
   7246         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
   7247                 "setDebugApp()");
   7248 
   7249         // Note that this is not really thread safe if there are multiple
   7250         // callers into it at the same time, but that's not a situation we
   7251         // care about.
   7252         if (persistent) {
   7253             final ContentResolver resolver = mContext.getContentResolver();
   7254             Settings.Global.putString(
   7255                 resolver, Settings.Global.DEBUG_APP,
   7256                 packageName);
   7257             Settings.Global.putInt(
   7258                 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
   7259                 waitForDebugger ? 1 : 0);
   7260         }
   7261 
   7262         synchronized (this) {
   7263             if (!persistent) {
   7264                 mOrigDebugApp = mDebugApp;
   7265                 mOrigWaitForDebugger = mWaitForDebugger;
   7266             }
   7267             mDebugApp = packageName;
   7268             mWaitForDebugger = waitForDebugger;
   7269             mDebugTransient = !persistent;
   7270             if (packageName != null) {
   7271                 final long origId = Binder.clearCallingIdentity();
   7272                 forceStopPackageLocked(packageName, -1, false, false, true, true,
   7273                         UserHandle.USER_ALL);
   7274                 Binder.restoreCallingIdentity(origId);
   7275             }
   7276         }
   7277     }
   7278 
   7279     void setOpenGlTraceApp(ApplicationInfo app, String processName) {
   7280         synchronized (this) {
   7281             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   7282             if (!isDebuggable) {
   7283                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   7284                     throw new SecurityException("Process not debuggable: " + app.packageName);
   7285                 }
   7286             }
   7287 
   7288             mOpenGlTraceApp = processName;
   7289         }
   7290     }
   7291 
   7292     void setProfileApp(ApplicationInfo app, String processName, String profileFile,
   7293             ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
   7294         synchronized (this) {
   7295             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   7296             if (!isDebuggable) {
   7297                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   7298                     throw new SecurityException("Process not debuggable: " + app.packageName);
   7299                 }
   7300             }
   7301             mProfileApp = processName;
   7302             mProfileFile = profileFile;
   7303             if (mProfileFd != null) {
   7304                 try {
   7305                     mProfileFd.close();
   7306                 } catch (IOException e) {
   7307                 }
   7308                 mProfileFd = null;
   7309             }
   7310             mProfileFd = profileFd;
   7311             mProfileType = 0;
   7312             mAutoStopProfiler = autoStopProfiler;
   7313         }
   7314     }
   7315 
   7316     public void setAlwaysFinish(boolean enabled) {
   7317         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
   7318                 "setAlwaysFinish()");
   7319 
   7320         Settings.Global.putInt(
   7321                 mContext.getContentResolver(),
   7322                 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
   7323 
   7324         synchronized (this) {
   7325             mAlwaysFinishActivities = enabled;
   7326         }
   7327     }
   7328 
   7329     public void setActivityController(IActivityController controller) {
   7330         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   7331                 "setActivityController()");
   7332         synchronized (this) {
   7333             mController = controller;
   7334         }
   7335     }
   7336 
   7337     public boolean isUserAMonkey() {
   7338         // For now the fact that there is a controller implies
   7339         // we have a monkey.
   7340         synchronized (this) {
   7341             return mController != null;
   7342         }
   7343     }
   7344 
   7345     public void requestBugReport() {
   7346         // No permission check because this can't do anything harmful --
   7347         // it will just eventually cause the user to be presented with
   7348         // a UI to select where the bug report goes.
   7349         SystemProperties.set("ctl.start", "bugreport");
   7350     }
   7351 
   7352     public long inputDispatchingTimedOut(int pid, boolean aboveSystem) {
   7353         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
   7354                 != PackageManager.PERMISSION_GRANTED) {
   7355             throw new SecurityException("Requires permission "
   7356                     + android.Manifest.permission.FILTER_EVENTS);
   7357         }
   7358 
   7359         ProcessRecord proc;
   7360 
   7361         // TODO: Unify this code with ActivityRecord.keyDispatchingTimedOut().
   7362         synchronized (this) {
   7363             synchronized (mPidsSelfLocked) {
   7364                 proc = mPidsSelfLocked.get(pid);
   7365             }
   7366             if (proc != null) {
   7367                 if (proc.debugging) {
   7368                     return -1;
   7369                 }
   7370 
   7371                 if (mDidDexOpt) {
   7372                     // Give more time since we were dexopting.
   7373                     mDidDexOpt = false;
   7374                     return -1;
   7375                 }
   7376 
   7377                 if (proc.instrumentationClass != null) {
   7378                     Bundle info = new Bundle();
   7379                     info.putString("shortMsg", "keyDispatchingTimedOut");
   7380                     info.putString("longMsg", "Timed out while dispatching key event");
   7381                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
   7382                     proc = null;
   7383                 }
   7384             }
   7385         }
   7386 
   7387         if (proc != null) {
   7388             appNotResponding(proc, null, null, aboveSystem, "keyDispatchingTimedOut");
   7389             if (proc.instrumentationClass != null || proc.usingWrapper) {
   7390                 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
   7391             }
   7392         }
   7393 
   7394         return KEY_DISPATCHING_TIMEOUT;
   7395     }
   7396 
   7397     public void registerProcessObserver(IProcessObserver observer) {
   7398         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   7399                 "registerProcessObserver()");
   7400         synchronized (this) {
   7401             mProcessObservers.register(observer);
   7402         }
   7403     }
   7404 
   7405     public void unregisterProcessObserver(IProcessObserver observer) {
   7406         synchronized (this) {
   7407             mProcessObservers.unregister(observer);
   7408         }
   7409     }
   7410 
   7411     public void setImmersive(IBinder token, boolean immersive) {
   7412         synchronized(this) {
   7413             ActivityRecord r = mMainStack.isInStackLocked(token);
   7414             if (r == null) {
   7415                 throw new IllegalArgumentException();
   7416             }
   7417             r.immersive = immersive;
   7418         }
   7419     }
   7420 
   7421     public boolean isImmersive(IBinder token) {
   7422         synchronized (this) {
   7423             ActivityRecord r = mMainStack.isInStackLocked(token);
   7424             if (r == null) {
   7425                 throw new IllegalArgumentException();
   7426             }
   7427             return r.immersive;
   7428         }
   7429     }
   7430 
   7431     public boolean isTopActivityImmersive() {
   7432         enforceNotIsolatedCaller("startActivity");
   7433         synchronized (this) {
   7434             ActivityRecord r = mMainStack.topRunningActivityLocked(null);
   7435             return (r != null) ? r.immersive : false;
   7436         }
   7437     }
   7438 
   7439     public final void enterSafeMode() {
   7440         synchronized(this) {
   7441             // It only makes sense to do this before the system is ready
   7442             // and started launching other packages.
   7443             if (!mSystemReady) {
   7444                 try {
   7445                     AppGlobals.getPackageManager().enterSafeMode();
   7446                 } catch (RemoteException e) {
   7447                 }
   7448             }
   7449         }
   7450     }
   7451 
   7452     public final void showSafeModeOverlay() {
   7453         View v = LayoutInflater.from(mContext).inflate(
   7454                 com.android.internal.R.layout.safe_mode, null);
   7455         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
   7456         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
   7457         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
   7458         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
   7459         lp.gravity = Gravity.BOTTOM | Gravity.START;
   7460         lp.format = v.getBackground().getOpacity();
   7461         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
   7462                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
   7463         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
   7464         ((WindowManager)mContext.getSystemService(
   7465                 Context.WINDOW_SERVICE)).addView(v, lp);
   7466     }
   7467 
   7468     public void noteWakeupAlarm(IIntentSender sender) {
   7469         if (!(sender instanceof PendingIntentRecord)) {
   7470             return;
   7471         }
   7472         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   7473         synchronized (stats) {
   7474             if (mBatteryStatsService.isOnBattery()) {
   7475                 mBatteryStatsService.enforceCallingPermission();
   7476                 PendingIntentRecord rec = (PendingIntentRecord)sender;
   7477                 int MY_UID = Binder.getCallingUid();
   7478                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
   7479                 BatteryStatsImpl.Uid.Pkg pkg =
   7480                     stats.getPackageStatsLocked(uid, rec.key.packageName);
   7481                 pkg.incWakeupsLocked();
   7482             }
   7483         }
   7484     }
   7485 
   7486     public boolean killPids(int[] pids, String pReason, boolean secure) {
   7487         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   7488             throw new SecurityException("killPids only available to the system");
   7489         }
   7490         String reason = (pReason == null) ? "Unknown" : pReason;
   7491         // XXX Note: don't acquire main activity lock here, because the window
   7492         // manager calls in with its locks held.
   7493 
   7494         boolean killed = false;
   7495         synchronized (mPidsSelfLocked) {
   7496             int[] types = new int[pids.length];
   7497             int worstType = 0;
   7498             for (int i=0; i<pids.length; i++) {
   7499                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   7500                 if (proc != null) {
   7501                     int type = proc.setAdj;
   7502                     types[i] = type;
   7503                     if (type > worstType) {
   7504                         worstType = type;
   7505                     }
   7506                 }
   7507             }
   7508 
   7509             // If the worst oom_adj is somewhere in the hidden proc LRU range,
   7510             // then constrain it so we will kill all hidden procs.
   7511             if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
   7512                     && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
   7513                 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
   7514             }
   7515 
   7516             // If this is not a secure call, don't let it kill processes that
   7517             // are important.
   7518             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
   7519                 worstType = ProcessList.SERVICE_ADJ;
   7520             }
   7521 
   7522             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
   7523             for (int i=0; i<pids.length; i++) {
   7524                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   7525                 if (proc == null) {
   7526                     continue;
   7527                 }
   7528                 int adj = proc.setAdj;
   7529                 if (adj >= worstType && !proc.killedBackground) {
   7530                     Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
   7531                     EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, proc.pid,
   7532                             proc.processName, adj, reason);
   7533                     killed = true;
   7534                     proc.killedBackground = true;
   7535                     Process.killProcessQuiet(pids[i]);
   7536                 }
   7537             }
   7538         }
   7539         return killed;
   7540     }
   7541 
   7542     @Override
   7543     public boolean killProcessesBelowForeground(String reason) {
   7544         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   7545             throw new SecurityException("killProcessesBelowForeground() only available to system");
   7546         }
   7547 
   7548         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
   7549     }
   7550 
   7551     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
   7552         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   7553             throw new SecurityException("killProcessesBelowAdj() only available to system");
   7554         }
   7555 
   7556         boolean killed = false;
   7557         synchronized (mPidsSelfLocked) {
   7558             final int size = mPidsSelfLocked.size();
   7559             for (int i = 0; i < size; i++) {
   7560                 final int pid = mPidsSelfLocked.keyAt(i);
   7561                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   7562                 if (proc == null) continue;
   7563 
   7564                 final int adj = proc.setAdj;
   7565                 if (adj > belowAdj && !proc.killedBackground) {
   7566                     Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
   7567                     EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId,
   7568                             proc.pid, proc.processName, adj, reason);
   7569                     killed = true;
   7570                     proc.killedBackground = true;
   7571                     Process.killProcessQuiet(pid);
   7572                 }
   7573             }
   7574         }
   7575         return killed;
   7576     }
   7577 
   7578     public final void startRunning(String pkg, String cls, String action,
   7579             String data) {
   7580         synchronized(this) {
   7581             if (mStartRunning) {
   7582                 return;
   7583             }
   7584             mStartRunning = true;
   7585             mTopComponent = pkg != null && cls != null
   7586                     ? new ComponentName(pkg, cls) : null;
   7587             mTopAction = action != null ? action : Intent.ACTION_MAIN;
   7588             mTopData = data;
   7589             if (!mSystemReady) {
   7590                 return;
   7591             }
   7592         }
   7593 
   7594         systemReady(null);
   7595     }
   7596 
   7597     private void retrieveSettings() {
   7598         final ContentResolver resolver = mContext.getContentResolver();
   7599         String debugApp = Settings.Global.getString(
   7600             resolver, Settings.Global.DEBUG_APP);
   7601         boolean waitForDebugger = Settings.Global.getInt(
   7602             resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
   7603         boolean alwaysFinishActivities = Settings.Global.getInt(
   7604             resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
   7605 
   7606         Configuration configuration = new Configuration();
   7607         Settings.System.getConfiguration(resolver, configuration);
   7608 
   7609         synchronized (this) {
   7610             mDebugApp = mOrigDebugApp = debugApp;
   7611             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
   7612             mAlwaysFinishActivities = alwaysFinishActivities;
   7613             // This happens before any activities are started, so we can
   7614             // change mConfiguration in-place.
   7615             updateConfigurationLocked(configuration, null, false, true);
   7616             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
   7617         }
   7618     }
   7619 
   7620     public boolean testIsSystemReady() {
   7621         // no need to synchronize(this) just to read & return the value
   7622         return mSystemReady;
   7623     }
   7624 
   7625     private static File getCalledPreBootReceiversFile() {
   7626         File dataDir = Environment.getDataDirectory();
   7627         File systemDir = new File(dataDir, "system");
   7628         File fname = new File(systemDir, "called_pre_boots.dat");
   7629         return fname;
   7630     }
   7631 
   7632     static final int LAST_DONE_VERSION = 10000;
   7633 
   7634     private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
   7635         ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
   7636         File file = getCalledPreBootReceiversFile();
   7637         FileInputStream fis = null;
   7638         try {
   7639             fis = new FileInputStream(file);
   7640             DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
   7641             int fvers = dis.readInt();
   7642             if (fvers == LAST_DONE_VERSION) {
   7643                 String vers = dis.readUTF();
   7644                 String codename = dis.readUTF();
   7645                 String build = dis.readUTF();
   7646                 if (android.os.Build.VERSION.RELEASE.equals(vers)
   7647                         && android.os.Build.VERSION.CODENAME.equals(codename)
   7648                         && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
   7649                     int num = dis.readInt();
   7650                     while (num > 0) {
   7651                         num--;
   7652                         String pkg = dis.readUTF();
   7653                         String cls = dis.readUTF();
   7654                         lastDoneReceivers.add(new ComponentName(pkg, cls));
   7655                     }
   7656                 }
   7657             }
   7658         } catch (FileNotFoundException e) {
   7659         } catch (IOException e) {
   7660             Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
   7661         } finally {
   7662             if (fis != null) {
   7663                 try {
   7664                     fis.close();
   7665                 } catch (IOException e) {
   7666                 }
   7667             }
   7668         }
   7669         return lastDoneReceivers;
   7670     }
   7671 
   7672     private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
   7673         File file = getCalledPreBootReceiversFile();
   7674         FileOutputStream fos = null;
   7675         DataOutputStream dos = null;
   7676         try {
   7677             Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
   7678             fos = new FileOutputStream(file);
   7679             dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
   7680             dos.writeInt(LAST_DONE_VERSION);
   7681             dos.writeUTF(android.os.Build.VERSION.RELEASE);
   7682             dos.writeUTF(android.os.Build.VERSION.CODENAME);
   7683             dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
   7684             dos.writeInt(list.size());
   7685             for (int i=0; i<list.size(); i++) {
   7686                 dos.writeUTF(list.get(i).getPackageName());
   7687                 dos.writeUTF(list.get(i).getClassName());
   7688             }
   7689         } catch (IOException e) {
   7690             Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
   7691             file.delete();
   7692         } finally {
   7693             FileUtils.sync(fos);
   7694             if (dos != null) {
   7695                 try {
   7696                     dos.close();
   7697                 } catch (IOException e) {
   7698                     // TODO Auto-generated catch block
   7699                     e.printStackTrace();
   7700                 }
   7701             }
   7702         }
   7703     }
   7704 
   7705     public void systemReady(final Runnable goingCallback) {
   7706         synchronized(this) {
   7707             if (mSystemReady) {
   7708                 if (goingCallback != null) goingCallback.run();
   7709                 return;
   7710             }
   7711 
   7712             // Check to see if there are any update receivers to run.
   7713             if (!mDidUpdate) {
   7714                 if (mWaitingUpdate) {
   7715                     return;
   7716                 }
   7717                 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
   7718                 List<ResolveInfo> ris = null;
   7719                 try {
   7720                     ris = AppGlobals.getPackageManager().queryIntentReceivers(
   7721                             intent, null, 0, 0);
   7722                 } catch (RemoteException e) {
   7723                 }
   7724                 if (ris != null) {
   7725                     for (int i=ris.size()-1; i>=0; i--) {
   7726                         if ((ris.get(i).activityInfo.applicationInfo.flags
   7727                                 &ApplicationInfo.FLAG_SYSTEM) == 0) {
   7728                             ris.remove(i);
   7729                         }
   7730                     }
   7731                     intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
   7732 
   7733                     ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
   7734 
   7735                     final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
   7736                     for (int i=0; i<ris.size(); i++) {
   7737                         ActivityInfo ai = ris.get(i).activityInfo;
   7738                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
   7739                         if (lastDoneReceivers.contains(comp)) {
   7740                             ris.remove(i);
   7741                             i--;
   7742                         }
   7743                     }
   7744 
   7745                     final int[] users = getUsersLocked();
   7746                     for (int i=0; i<ris.size(); i++) {
   7747                         ActivityInfo ai = ris.get(i).activityInfo;
   7748                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
   7749                         doneReceivers.add(comp);
   7750                         intent.setComponent(comp);
   7751                         for (int j=0; j<users.length; j++) {
   7752                             IIntentReceiver finisher = null;
   7753                             if (i == ris.size()-1 && j == users.length-1) {
   7754                                 finisher = new IIntentReceiver.Stub() {
   7755                                     public void performReceive(Intent intent, int resultCode,
   7756                                             String data, Bundle extras, boolean ordered,
   7757                                             boolean sticky, int sendingUser) {
   7758                                         // The raw IIntentReceiver interface is called
   7759                                         // with the AM lock held, so redispatch to
   7760                                         // execute our code without the lock.
   7761                                         mHandler.post(new Runnable() {
   7762                                             public void run() {
   7763                                                 synchronized (ActivityManagerService.this) {
   7764                                                     mDidUpdate = true;
   7765                                                 }
   7766                                                 writeLastDonePreBootReceivers(doneReceivers);
   7767                                                 showBootMessage(mContext.getText(
   7768                                                         R.string.android_upgrading_complete),
   7769                                                         false);
   7770                                                 systemReady(goingCallback);
   7771                                             }
   7772                                         });
   7773                                     }
   7774                                 };
   7775                             }
   7776                             Slog.i(TAG, "Sending system update to " + intent.getComponent()
   7777                                     + " for user " + users[j]);
   7778                             broadcastIntentLocked(null, null, intent, null, finisher,
   7779                                     0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
   7780                                     users[j]);
   7781                             if (finisher != null) {
   7782                                 mWaitingUpdate = true;
   7783                             }
   7784                         }
   7785                     }
   7786                 }
   7787                 if (mWaitingUpdate) {
   7788                     return;
   7789                 }
   7790                 mDidUpdate = true;
   7791             }
   7792 
   7793             mSystemReady = true;
   7794             if (!mStartRunning) {
   7795                 return;
   7796             }
   7797         }
   7798 
   7799         ArrayList<ProcessRecord> procsToKill = null;
   7800         synchronized(mPidsSelfLocked) {
   7801             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
   7802                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   7803                 if (!isAllowedWhileBooting(proc.info)){
   7804                     if (procsToKill == null) {
   7805                         procsToKill = new ArrayList<ProcessRecord>();
   7806                     }
   7807                     procsToKill.add(proc);
   7808                 }
   7809             }
   7810         }
   7811 
   7812         synchronized(this) {
   7813             if (procsToKill != null) {
   7814                 for (int i=procsToKill.size()-1; i>=0; i--) {
   7815                     ProcessRecord proc = procsToKill.get(i);
   7816                     Slog.i(TAG, "Removing system update proc: " + proc);
   7817                     removeProcessLocked(proc, true, false, "system update done");
   7818                 }
   7819             }
   7820 
   7821             // Now that we have cleaned up any update processes, we
   7822             // are ready to start launching real processes and know that
   7823             // we won't trample on them any more.
   7824             mProcessesReady = true;
   7825         }
   7826 
   7827         Slog.i(TAG, "System now ready");
   7828         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
   7829             SystemClock.uptimeMillis());
   7830 
   7831         synchronized(this) {
   7832             // Make sure we have no pre-ready processes sitting around.
   7833 
   7834             if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
   7835                 ResolveInfo ri = mContext.getPackageManager()
   7836                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
   7837                                 STOCK_PM_FLAGS);
   7838                 CharSequence errorMsg = null;
   7839                 if (ri != null) {
   7840                     ActivityInfo ai = ri.activityInfo;
   7841                     ApplicationInfo app = ai.applicationInfo;
   7842                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   7843                         mTopAction = Intent.ACTION_FACTORY_TEST;
   7844                         mTopData = null;
   7845                         mTopComponent = new ComponentName(app.packageName,
   7846                                 ai.name);
   7847                     } else {
   7848                         errorMsg = mContext.getResources().getText(
   7849                                 com.android.internal.R.string.factorytest_not_system);
   7850                     }
   7851                 } else {
   7852                     errorMsg = mContext.getResources().getText(
   7853                             com.android.internal.R.string.factorytest_no_action);
   7854                 }
   7855                 if (errorMsg != null) {
   7856                     mTopAction = null;
   7857                     mTopData = null;
   7858                     mTopComponent = null;
   7859                     Message msg = Message.obtain();
   7860                     msg.what = SHOW_FACTORY_ERROR_MSG;
   7861                     msg.getData().putCharSequence("msg", errorMsg);
   7862                     mHandler.sendMessage(msg);
   7863                 }
   7864             }
   7865         }
   7866 
   7867         retrieveSettings();
   7868 
   7869         if (goingCallback != null) goingCallback.run();
   7870 
   7871         synchronized (this) {
   7872             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   7873                 try {
   7874                     List apps = AppGlobals.getPackageManager().
   7875                         getPersistentApplications(STOCK_PM_FLAGS);
   7876                     if (apps != null) {
   7877                         int N = apps.size();
   7878                         int i;
   7879                         for (i=0; i<N; i++) {
   7880                             ApplicationInfo info
   7881                                 = (ApplicationInfo)apps.get(i);
   7882                             if (info != null &&
   7883                                     !info.packageName.equals("android")) {
   7884                                 addAppLocked(info, false);
   7885                             }
   7886                         }
   7887                     }
   7888                 } catch (RemoteException ex) {
   7889                     // pm is in same process, this will never happen.
   7890                 }
   7891             }
   7892 
   7893             // Start up initial activity.
   7894             mBooting = true;
   7895 
   7896             try {
   7897                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
   7898                     Message msg = Message.obtain();
   7899                     msg.what = SHOW_UID_ERROR_MSG;
   7900                     mHandler.sendMessage(msg);
   7901                 }
   7902             } catch (RemoteException e) {
   7903             }
   7904 
   7905             long ident = Binder.clearCallingIdentity();
   7906             try {
   7907                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
   7908                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   7909                         | Intent.FLAG_RECEIVER_FOREGROUND);
   7910                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
   7911                 broadcastIntentLocked(null, null, intent,
   7912                         null, null, 0, null, null, null,
   7913                         false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
   7914                 intent = new Intent(Intent.ACTION_USER_STARTING);
   7915                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   7916                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
   7917                 broadcastIntentLocked(null, null, intent,
   7918                         null, new IIntentReceiver.Stub() {
   7919                             @Override
   7920                             public void performReceive(Intent intent, int resultCode, String data,
   7921                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
   7922                                     throws RemoteException {
   7923                             }
   7924                         }, 0, null, null,
   7925                         android.Manifest.permission.INTERACT_ACROSS_USERS,
   7926                         false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   7927             } finally {
   7928                 Binder.restoreCallingIdentity(ident);
   7929             }
   7930             mMainStack.resumeTopActivityLocked(null);
   7931             sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
   7932         }
   7933     }
   7934 
   7935     private boolean makeAppCrashingLocked(ProcessRecord app,
   7936             String shortMsg, String longMsg, String stackTrace) {
   7937         app.crashing = true;
   7938         app.crashingReport = generateProcessError(app,
   7939                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
   7940         startAppProblemLocked(app);
   7941         app.stopFreezingAllLocked();
   7942         return handleAppCrashLocked(app);
   7943     }
   7944 
   7945     private void makeAppNotRespondingLocked(ProcessRecord app,
   7946             String activity, String shortMsg, String longMsg) {
   7947         app.notResponding = true;
   7948         app.notRespondingReport = generateProcessError(app,
   7949                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
   7950                 activity, shortMsg, longMsg, null);
   7951         startAppProblemLocked(app);
   7952         app.stopFreezingAllLocked();
   7953     }
   7954 
   7955     /**
   7956      * Generate a process error record, suitable for attachment to a ProcessRecord.
   7957      *
   7958      * @param app The ProcessRecord in which the error occurred.
   7959      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
   7960      *                      ActivityManager.AppErrorStateInfo
   7961      * @param activity The activity associated with the crash, if known.
   7962      * @param shortMsg Short message describing the crash.
   7963      * @param longMsg Long message describing the crash.
   7964      * @param stackTrace Full crash stack trace, may be null.
   7965      *
   7966      * @return Returns a fully-formed AppErrorStateInfo record.
   7967      */
   7968     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
   7969             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
   7970         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
   7971 
   7972         report.condition = condition;
   7973         report.processName = app.processName;
   7974         report.pid = app.pid;
   7975         report.uid = app.info.uid;
   7976         report.tag = activity;
   7977         report.shortMsg = shortMsg;
   7978         report.longMsg = longMsg;
   7979         report.stackTrace = stackTrace;
   7980 
   7981         return report;
   7982     }
   7983 
   7984     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
   7985         synchronized (this) {
   7986             app.crashing = false;
   7987             app.crashingReport = null;
   7988             app.notResponding = false;
   7989             app.notRespondingReport = null;
   7990             if (app.anrDialog == fromDialog) {
   7991                 app.anrDialog = null;
   7992             }
   7993             if (app.waitDialog == fromDialog) {
   7994                 app.waitDialog = null;
   7995             }
   7996             if (app.pid > 0 && app.pid != MY_PID) {
   7997                 handleAppCrashLocked(app);
   7998                 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
   7999                 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
   8000                         app.processName, app.setAdj, "user's request after error");
   8001                 Process.killProcessQuiet(app.pid);
   8002             }
   8003         }
   8004     }
   8005 
   8006     private boolean handleAppCrashLocked(ProcessRecord app) {
   8007         if (mHeadless) {
   8008             Log.e(TAG, "handleAppCrashLocked: " + app.processName);
   8009             return false;
   8010         }
   8011         long now = SystemClock.uptimeMillis();
   8012 
   8013         Long crashTime;
   8014         if (!app.isolated) {
   8015             crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
   8016         } else {
   8017             crashTime = null;
   8018         }
   8019         if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
   8020             // This process loses!
   8021             Slog.w(TAG, "Process " + app.info.processName
   8022                     + " has crashed too many times: killing!");
   8023             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
   8024                     app.userId, app.info.processName, app.uid);
   8025             for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
   8026                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   8027                 if (r.app == app) {
   8028                     Slog.w(TAG, "  Force finishing activity "
   8029                         + r.intent.getComponent().flattenToShortString());
   8030                     r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
   8031                             null, "crashed", false);
   8032                 }
   8033             }
   8034             if (!app.persistent) {
   8035                 // We don't want to start this process again until the user
   8036                 // explicitly does so...  but for persistent process, we really
   8037                 // need to keep it running.  If a persistent process is actually
   8038                 // repeatedly crashing, then badness for everyone.
   8039                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
   8040                         app.info.processName);
   8041                 if (!app.isolated) {
   8042                     // XXX We don't have a way to mark isolated processes
   8043                     // as bad, since they don't have a peristent identity.
   8044                     mBadProcesses.put(app.info.processName, app.uid, now);
   8045                     mProcessCrashTimes.remove(app.info.processName, app.uid);
   8046                 }
   8047                 app.bad = true;
   8048                 app.removed = true;
   8049                 // Don't let services in this process be restarted and potentially
   8050                 // annoy the user repeatedly.  Unless it is persistent, since those
   8051                 // processes run critical code.
   8052                 removeProcessLocked(app, false, false, "crash");
   8053                 mMainStack.resumeTopActivityLocked(null);
   8054                 return false;
   8055             }
   8056             mMainStack.resumeTopActivityLocked(null);
   8057         } else {
   8058             ActivityRecord r = mMainStack.topRunningActivityLocked(null);
   8059             if (r != null && r.app == app) {
   8060                 // If the top running activity is from this crashing
   8061                 // process, then terminate it to avoid getting in a loop.
   8062                 Slog.w(TAG, "  Force finishing activity "
   8063                         + r.intent.getComponent().flattenToShortString());
   8064                 int index = mMainStack.indexOfActivityLocked(r);
   8065                 r.stack.finishActivityLocked(r, index,
   8066                         Activity.RESULT_CANCELED, null, "crashed", false);
   8067                 // Also terminate any activities below it that aren't yet
   8068                 // stopped, to avoid a situation where one will get
   8069                 // re-start our crashing activity once it gets resumed again.
   8070                 index--;
   8071                 if (index >= 0) {
   8072                     r = (ActivityRecord)mMainStack.mHistory.get(index);
   8073                     if (r.state == ActivityState.RESUMED
   8074                             || r.state == ActivityState.PAUSING
   8075                             || r.state == ActivityState.PAUSED) {
   8076                         if (!r.isHomeActivity || mHomeProcess != r.app) {
   8077                             Slog.w(TAG, "  Force finishing activity "
   8078                                     + r.intent.getComponent().flattenToShortString());
   8079                             r.stack.finishActivityLocked(r, index,
   8080                                     Activity.RESULT_CANCELED, null, "crashed", false);
   8081                         }
   8082                     }
   8083                 }
   8084             }
   8085         }
   8086 
   8087         // Bump up the crash count of any services currently running in the proc.
   8088         if (app.services.size() != 0) {
   8089             // Any services running in the application need to be placed
   8090             // back in the pending list.
   8091             Iterator<ServiceRecord> it = app.services.iterator();
   8092             while (it.hasNext()) {
   8093                 ServiceRecord sr = it.next();
   8094                 sr.crashCount++;
   8095             }
   8096         }
   8097 
   8098         // If the crashing process is what we consider to be the "home process" and it has been
   8099         // replaced by a third-party app, clear the package preferred activities from packages
   8100         // with a home activity running in the process to prevent a repeatedly crashing app
   8101         // from blocking the user to manually clear the list.
   8102         if (app == mHomeProcess && mHomeProcess.activities.size() > 0
   8103                     && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
   8104             Iterator it = mHomeProcess.activities.iterator();
   8105             while (it.hasNext()) {
   8106                 ActivityRecord r = (ActivityRecord)it.next();
   8107                 if (r.isHomeActivity) {
   8108                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
   8109                     try {
   8110                         ActivityThread.getPackageManager()
   8111                                 .clearPackagePreferredActivities(r.packageName);
   8112                     } catch (RemoteException c) {
   8113                         // pm is in same process, this will never happen.
   8114                     }
   8115                 }
   8116             }
   8117         }
   8118 
   8119         if (!app.isolated) {
   8120             // XXX Can't keep track of crash times for isolated processes,
   8121             // because they don't have a perisistent identity.
   8122             mProcessCrashTimes.put(app.info.processName, app.uid, now);
   8123         }
   8124 
   8125         return true;
   8126     }
   8127 
   8128     void startAppProblemLocked(ProcessRecord app) {
   8129         if (app.userId == mCurrentUserId) {
   8130             app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
   8131                     mContext, app.info.packageName, app.info.flags);
   8132         } else {
   8133             // If this app is not running under the current user, then we
   8134             // can't give it a report button because that would require
   8135             // launching the report UI under a different user.
   8136             app.errorReportReceiver = null;
   8137         }
   8138         skipCurrentReceiverLocked(app);
   8139     }
   8140 
   8141     void skipCurrentReceiverLocked(ProcessRecord app) {
   8142         for (BroadcastQueue queue : mBroadcastQueues) {
   8143             queue.skipCurrentReceiverLocked(app);
   8144         }
   8145     }
   8146 
   8147     /**
   8148      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
   8149      * The application process will exit immediately after this call returns.
   8150      * @param app object of the crashing app, null for the system server
   8151      * @param crashInfo describing the exception
   8152      */
   8153     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
   8154         ProcessRecord r = findAppProcess(app, "Crash");
   8155         final String processName = app == null ? "system_server"
   8156                 : (r == null ? "unknown" : r.processName);
   8157 
   8158         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
   8159                 UserHandle.getUserId(Binder.getCallingUid()), processName,
   8160                 r == null ? -1 : r.info.flags,
   8161                 crashInfo.exceptionClassName,
   8162                 crashInfo.exceptionMessage,
   8163                 crashInfo.throwFileName,
   8164                 crashInfo.throwLineNumber);
   8165 
   8166         addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
   8167 
   8168         crashApplication(r, crashInfo);
   8169     }
   8170 
   8171     public void handleApplicationStrictModeViolation(
   8172             IBinder app,
   8173             int violationMask,
   8174             StrictMode.ViolationInfo info) {
   8175         ProcessRecord r = findAppProcess(app, "StrictMode");
   8176         if (r == null) {
   8177             return;
   8178         }
   8179 
   8180         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
   8181             Integer stackFingerprint = info.hashCode();
   8182             boolean logIt = true;
   8183             synchronized (mAlreadyLoggedViolatedStacks) {
   8184                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
   8185                     logIt = false;
   8186                     // TODO: sub-sample into EventLog for these, with
   8187                     // the info.durationMillis?  Then we'd get
   8188                     // the relative pain numbers, without logging all
   8189                     // the stack traces repeatedly.  We'd want to do
   8190                     // likewise in the client code, which also does
   8191                     // dup suppression, before the Binder call.
   8192                 } else {
   8193                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
   8194                         mAlreadyLoggedViolatedStacks.clear();
   8195                     }
   8196                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
   8197                 }
   8198             }
   8199             if (logIt) {
   8200                 logStrictModeViolationToDropBox(r, info);
   8201             }
   8202         }
   8203 
   8204         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
   8205             AppErrorResult result = new AppErrorResult();
   8206             synchronized (this) {
   8207                 final long origId = Binder.clearCallingIdentity();
   8208 
   8209                 Message msg = Message.obtain();
   8210                 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
   8211                 HashMap<String, Object> data = new HashMap<String, Object>();
   8212                 data.put("result", result);
   8213                 data.put("app", r);
   8214                 data.put("violationMask", violationMask);
   8215                 data.put("info", info);
   8216                 msg.obj = data;
   8217                 mHandler.sendMessage(msg);
   8218 
   8219                 Binder.restoreCallingIdentity(origId);
   8220             }
   8221             int res = result.get();
   8222             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
   8223         }
   8224     }
   8225 
   8226     // Depending on the policy in effect, there could be a bunch of
   8227     // these in quick succession so we try to batch these together to
   8228     // minimize disk writes, number of dropbox entries, and maximize
   8229     // compression, by having more fewer, larger records.
   8230     private void logStrictModeViolationToDropBox(
   8231             ProcessRecord process,
   8232             StrictMode.ViolationInfo info) {
   8233         if (info == null) {
   8234             return;
   8235         }
   8236         final boolean isSystemApp = process == null ||
   8237                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
   8238                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
   8239         final String processName = process == null ? "unknown" : process.processName;
   8240         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
   8241         final DropBoxManager dbox = (DropBoxManager)
   8242                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   8243 
   8244         // Exit early if the dropbox isn't configured to accept this report type.
   8245         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   8246 
   8247         boolean bufferWasEmpty;
   8248         boolean needsFlush;
   8249         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
   8250         synchronized (sb) {
   8251             bufferWasEmpty = sb.length() == 0;
   8252             appendDropBoxProcessHeaders(process, processName, sb);
   8253             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   8254             sb.append("System-App: ").append(isSystemApp).append("\n");
   8255             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
   8256             if (info.violationNumThisLoop != 0) {
   8257                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
   8258             }
   8259             if (info.numAnimationsRunning != 0) {
   8260                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
   8261             }
   8262             if (info.broadcastIntentAction != null) {
   8263                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
   8264             }
   8265             if (info.durationMillis != -1) {
   8266                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
   8267             }
   8268             if (info.numInstances != -1) {
   8269                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
   8270             }
   8271             if (info.tags != null) {
   8272                 for (String tag : info.tags) {
   8273                     sb.append("Span-Tag: ").append(tag).append("\n");
   8274                 }
   8275             }
   8276             sb.append("\n");
   8277             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
   8278                 sb.append(info.crashInfo.stackTrace);
   8279             }
   8280             sb.append("\n");
   8281 
   8282             // Only buffer up to ~64k.  Various logging bits truncate
   8283             // things at 128k.
   8284             needsFlush = (sb.length() > 64 * 1024);
   8285         }
   8286 
   8287         // Flush immediately if the buffer's grown too large, or this
   8288         // is a non-system app.  Non-system apps are isolated with a
   8289         // different tag & policy and not batched.
   8290         //
   8291         // Batching is useful during internal testing with
   8292         // StrictMode settings turned up high.  Without batching,
   8293         // thousands of separate files could be created on boot.
   8294         if (!isSystemApp || needsFlush) {
   8295             new Thread("Error dump: " + dropboxTag) {
   8296                 @Override
   8297                 public void run() {
   8298                     String report;
   8299                     synchronized (sb) {
   8300                         report = sb.toString();
   8301                         sb.delete(0, sb.length());
   8302                         sb.trimToSize();
   8303                     }
   8304                     if (report.length() != 0) {
   8305                         dbox.addText(dropboxTag, report);
   8306                     }
   8307                 }
   8308             }.start();
   8309             return;
   8310         }
   8311 
   8312         // System app batching:
   8313         if (!bufferWasEmpty) {
   8314             // An existing dropbox-writing thread is outstanding, so
   8315             // we don't need to start it up.  The existing thread will
   8316             // catch the buffer appends we just did.
   8317             return;
   8318         }
   8319 
   8320         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
   8321         // (After this point, we shouldn't access AMS internal data structures.)
   8322         new Thread("Error dump: " + dropboxTag) {
   8323             @Override
   8324             public void run() {
   8325                 // 5 second sleep to let stacks arrive and be batched together
   8326                 try {
   8327                     Thread.sleep(5000);  // 5 seconds
   8328                 } catch (InterruptedException e) {}
   8329 
   8330                 String errorReport;
   8331                 synchronized (mStrictModeBuffer) {
   8332                     errorReport = mStrictModeBuffer.toString();
   8333                     if (errorReport.length() == 0) {
   8334                         return;
   8335                     }
   8336                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
   8337                     mStrictModeBuffer.trimToSize();
   8338                 }
   8339                 dbox.addText(dropboxTag, errorReport);
   8340             }
   8341         }.start();
   8342     }
   8343 
   8344     /**
   8345      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
   8346      * @param app object of the crashing app, null for the system server
   8347      * @param tag reported by the caller
   8348      * @param crashInfo describing the context of the error
   8349      * @return true if the process should exit immediately (WTF is fatal)
   8350      */
   8351     public boolean handleApplicationWtf(IBinder app, String tag,
   8352             ApplicationErrorReport.CrashInfo crashInfo) {
   8353         ProcessRecord r = findAppProcess(app, "WTF");
   8354         final String processName = app == null ? "system_server"
   8355                 : (r == null ? "unknown" : r.processName);
   8356 
   8357         EventLog.writeEvent(EventLogTags.AM_WTF,
   8358                 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
   8359                 processName,
   8360                 r == null ? -1 : r.info.flags,
   8361                 tag, crashInfo.exceptionMessage);
   8362 
   8363         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
   8364 
   8365         if (r != null && r.pid != Process.myPid() &&
   8366                 Settings.Global.getInt(mContext.getContentResolver(),
   8367                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
   8368             crashApplication(r, crashInfo);
   8369             return true;
   8370         } else {
   8371             return false;
   8372         }
   8373     }
   8374 
   8375     /**
   8376      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
   8377      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
   8378      */
   8379     private ProcessRecord findAppProcess(IBinder app, String reason) {
   8380         if (app == null) {
   8381             return null;
   8382         }
   8383 
   8384         synchronized (this) {
   8385             for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   8386                 final int NA = apps.size();
   8387                 for (int ia=0; ia<NA; ia++) {
   8388                     ProcessRecord p = apps.valueAt(ia);
   8389                     if (p.thread != null && p.thread.asBinder() == app) {
   8390                         return p;
   8391                     }
   8392                 }
   8393             }
   8394 
   8395             Slog.w(TAG, "Can't find mystery application for " + reason
   8396                     + " from pid=" + Binder.getCallingPid()
   8397                     + " uid=" + Binder.getCallingUid() + ": " + app);
   8398             return null;
   8399         }
   8400     }
   8401 
   8402     /**
   8403      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
   8404      * to append various headers to the dropbox log text.
   8405      */
   8406     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
   8407             StringBuilder sb) {
   8408         // Watchdog thread ends up invoking this function (with
   8409         // a null ProcessRecord) to add the stack file to dropbox.
   8410         // Do not acquire a lock on this (am) in such cases, as it
   8411         // could cause a potential deadlock, if and when watchdog
   8412         // is invoked due to unavailability of lock on am and it
   8413         // would prevent watchdog from killing system_server.
   8414         if (process == null) {
   8415             sb.append("Process: ").append(processName).append("\n");
   8416             return;
   8417         }
   8418         // Note: ProcessRecord 'process' is guarded by the service
   8419         // instance.  (notably process.pkgList, which could otherwise change
   8420         // concurrently during execution of this method)
   8421         synchronized (this) {
   8422             sb.append("Process: ").append(processName).append("\n");
   8423             int flags = process.info.flags;
   8424             IPackageManager pm = AppGlobals.getPackageManager();
   8425             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
   8426             for (String pkg : process.pkgList) {
   8427                 sb.append("Package: ").append(pkg);
   8428                 try {
   8429                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
   8430                     if (pi != null) {
   8431                         sb.append(" v").append(pi.versionCode);
   8432                         if (pi.versionName != null) {
   8433                             sb.append(" (").append(pi.versionName).append(")");
   8434                         }
   8435                     }
   8436                 } catch (RemoteException e) {
   8437                     Slog.e(TAG, "Error getting package info: " + pkg, e);
   8438                 }
   8439                 sb.append("\n");
   8440             }
   8441         }
   8442     }
   8443 
   8444     private static String processClass(ProcessRecord process) {
   8445         if (process == null || process.pid == MY_PID) {
   8446             return "system_server";
   8447         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   8448             return "system_app";
   8449         } else {
   8450             return "data_app";
   8451         }
   8452     }
   8453 
   8454     /**
   8455      * Write a description of an error (crash, WTF, ANR) to the drop box.
   8456      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
   8457      * @param process which caused the error, null means the system server
   8458      * @param activity which triggered the error, null if unknown
   8459      * @param parent activity related to the error, null if unknown
   8460      * @param subject line related to the error, null if absent
   8461      * @param report in long form describing the error, null if absent
   8462      * @param logFile to include in the report, null if none
   8463      * @param crashInfo giving an application stack trace, null if absent
   8464      */
   8465     public void addErrorToDropBox(String eventType,
   8466             ProcessRecord process, String processName, ActivityRecord activity,
   8467             ActivityRecord parent, String subject,
   8468             final String report, final File logFile,
   8469             final ApplicationErrorReport.CrashInfo crashInfo) {
   8470         // NOTE -- this must never acquire the ActivityManagerService lock,
   8471         // otherwise the watchdog may be prevented from resetting the system.
   8472 
   8473         final String dropboxTag = processClass(process) + "_" + eventType;
   8474         final DropBoxManager dbox = (DropBoxManager)
   8475                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   8476 
   8477         // Exit early if the dropbox isn't configured to accept this report type.
   8478         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   8479 
   8480         final StringBuilder sb = new StringBuilder(1024);
   8481         appendDropBoxProcessHeaders(process, processName, sb);
   8482         if (activity != null) {
   8483             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
   8484         }
   8485         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
   8486             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
   8487         }
   8488         if (parent != null && parent != activity) {
   8489             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
   8490         }
   8491         if (subject != null) {
   8492             sb.append("Subject: ").append(subject).append("\n");
   8493         }
   8494         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   8495         if (Debug.isDebuggerConnected()) {
   8496             sb.append("Debugger: Connected\n");
   8497         }
   8498         sb.append("\n");
   8499 
   8500         // Do the rest in a worker thread to avoid blocking the caller on I/O
   8501         // (After this point, we shouldn't access AMS internal data structures.)
   8502         Thread worker = new Thread("Error dump: " + dropboxTag) {
   8503             @Override
   8504             public void run() {
   8505                 if (report != null) {
   8506                     sb.append(report);
   8507                 }
   8508                 if (logFile != null) {
   8509                     try {
   8510                         sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
   8511                     } catch (IOException e) {
   8512                         Slog.e(TAG, "Error reading " + logFile, e);
   8513                     }
   8514                 }
   8515                 if (crashInfo != null && crashInfo.stackTrace != null) {
   8516                     sb.append(crashInfo.stackTrace);
   8517                 }
   8518 
   8519                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
   8520                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
   8521                 if (lines > 0) {
   8522                     sb.append("\n");
   8523 
   8524                     // Merge several logcat streams, and take the last N lines
   8525                     InputStreamReader input = null;
   8526                     try {
   8527                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
   8528                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
   8529                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
   8530 
   8531                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
   8532                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
   8533                         input = new InputStreamReader(logcat.getInputStream());
   8534 
   8535                         int num;
   8536                         char[] buf = new char[8192];
   8537                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
   8538                     } catch (IOException e) {
   8539                         Slog.e(TAG, "Error running logcat", e);
   8540                     } finally {
   8541                         if (input != null) try { input.close(); } catch (IOException e) {}
   8542                     }
   8543                 }
   8544 
   8545                 dbox.addText(dropboxTag, sb.toString());
   8546             }
   8547         };
   8548 
   8549         if (process == null) {
   8550             // If process is null, we are being called from some internal code
   8551             // and may be about to die -- run this synchronously.
   8552             worker.run();
   8553         } else {
   8554             worker.start();
   8555         }
   8556     }
   8557 
   8558     /**
   8559      * Bring up the "unexpected error" dialog box for a crashing app.
   8560      * Deal with edge cases (intercepts from instrumented applications,
   8561      * ActivityController, error intent receivers, that sort of thing).
   8562      * @param r the application crashing
   8563      * @param crashInfo describing the failure
   8564      */
   8565     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
   8566         long timeMillis = System.currentTimeMillis();
   8567         String shortMsg = crashInfo.exceptionClassName;
   8568         String longMsg = crashInfo.exceptionMessage;
   8569         String stackTrace = crashInfo.stackTrace;
   8570         if (shortMsg != null && longMsg != null) {
   8571             longMsg = shortMsg + ": " + longMsg;
   8572         } else if (shortMsg != null) {
   8573             longMsg = shortMsg;
   8574         }
   8575 
   8576         AppErrorResult result = new AppErrorResult();
   8577         synchronized (this) {
   8578             if (mController != null) {
   8579                 try {
   8580                     String name = r != null ? r.processName : null;
   8581                     int pid = r != null ? r.pid : Binder.getCallingPid();
   8582                     if (!mController.appCrashed(name, pid,
   8583                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
   8584                         Slog.w(TAG, "Force-killing crashed app " + name
   8585                                 + " at watcher's request");
   8586                         Process.killProcess(pid);
   8587                         return;
   8588                     }
   8589                 } catch (RemoteException e) {
   8590                     mController = null;
   8591                 }
   8592             }
   8593 
   8594             final long origId = Binder.clearCallingIdentity();
   8595 
   8596             // If this process is running instrumentation, finish it.
   8597             if (r != null && r.instrumentationClass != null) {
   8598                 Slog.w(TAG, "Error in app " + r.processName
   8599                       + " running instrumentation " + r.instrumentationClass + ":");
   8600                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
   8601                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
   8602                 Bundle info = new Bundle();
   8603                 info.putString("shortMsg", shortMsg);
   8604                 info.putString("longMsg", longMsg);
   8605                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
   8606                 Binder.restoreCallingIdentity(origId);
   8607                 return;
   8608             }
   8609 
   8610             // If we can't identify the process or it's already exceeded its crash quota,
   8611             // quit right away without showing a crash dialog.
   8612             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
   8613                 Binder.restoreCallingIdentity(origId);
   8614                 return;
   8615             }
   8616 
   8617             Message msg = Message.obtain();
   8618             msg.what = SHOW_ERROR_MSG;
   8619             HashMap data = new HashMap();
   8620             data.put("result", result);
   8621             data.put("app", r);
   8622             msg.obj = data;
   8623             mHandler.sendMessage(msg);
   8624 
   8625             Binder.restoreCallingIdentity(origId);
   8626         }
   8627 
   8628         int res = result.get();
   8629 
   8630         Intent appErrorIntent = null;
   8631         synchronized (this) {
   8632             if (r != null && !r.isolated) {
   8633                 // XXX Can't keep track of crash time for isolated processes,
   8634                 // since they don't have a persistent identity.
   8635                 mProcessCrashTimes.put(r.info.processName, r.uid,
   8636                         SystemClock.uptimeMillis());
   8637             }
   8638             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
   8639                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
   8640             }
   8641         }
   8642 
   8643         if (appErrorIntent != null) {
   8644             try {
   8645                 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
   8646             } catch (ActivityNotFoundException e) {
   8647                 Slog.w(TAG, "bug report receiver dissappeared", e);
   8648             }
   8649         }
   8650     }
   8651 
   8652     Intent createAppErrorIntentLocked(ProcessRecord r,
   8653             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   8654         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
   8655         if (report == null) {
   8656             return null;
   8657         }
   8658         Intent result = new Intent(Intent.ACTION_APP_ERROR);
   8659         result.setComponent(r.errorReportReceiver);
   8660         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
   8661         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   8662         return result;
   8663     }
   8664 
   8665     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
   8666             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   8667         if (r.errorReportReceiver == null) {
   8668             return null;
   8669         }
   8670 
   8671         if (!r.crashing && !r.notResponding) {
   8672             return null;
   8673         }
   8674 
   8675         ApplicationErrorReport report = new ApplicationErrorReport();
   8676         report.packageName = r.info.packageName;
   8677         report.installerPackageName = r.errorReportReceiver.getPackageName();
   8678         report.processName = r.processName;
   8679         report.time = timeMillis;
   8680         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   8681 
   8682         if (r.crashing) {
   8683             report.type = ApplicationErrorReport.TYPE_CRASH;
   8684             report.crashInfo = crashInfo;
   8685         } else if (r.notResponding) {
   8686             report.type = ApplicationErrorReport.TYPE_ANR;
   8687             report.anrInfo = new ApplicationErrorReport.AnrInfo();
   8688 
   8689             report.anrInfo.activity = r.notRespondingReport.tag;
   8690             report.anrInfo.cause = r.notRespondingReport.shortMsg;
   8691             report.anrInfo.info = r.notRespondingReport.longMsg;
   8692         }
   8693 
   8694         return report;
   8695     }
   8696 
   8697     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
   8698         enforceNotIsolatedCaller("getProcessesInErrorState");
   8699         // assume our apps are happy - lazy create the list
   8700         List<ActivityManager.ProcessErrorStateInfo> errList = null;
   8701 
   8702         final boolean allUsers = ActivityManager.checkUidPermission(
   8703                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   8704                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
   8705         int userId = UserHandle.getUserId(Binder.getCallingUid());
   8706 
   8707         synchronized (this) {
   8708 
   8709             // iterate across all processes
   8710             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   8711                 ProcessRecord app = mLruProcesses.get(i);
   8712                 if (!allUsers && app.userId != userId) {
   8713                     continue;
   8714                 }
   8715                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
   8716                     // This one's in trouble, so we'll generate a report for it
   8717                     // crashes are higher priority (in case there's a crash *and* an anr)
   8718                     ActivityManager.ProcessErrorStateInfo report = null;
   8719                     if (app.crashing) {
   8720                         report = app.crashingReport;
   8721                     } else if (app.notResponding) {
   8722                         report = app.notRespondingReport;
   8723                     }
   8724 
   8725                     if (report != null) {
   8726                         if (errList == null) {
   8727                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
   8728                         }
   8729                         errList.add(report);
   8730                     } else {
   8731                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
   8732                                 " crashing = " + app.crashing +
   8733                                 " notResponding = " + app.notResponding);
   8734                     }
   8735                 }
   8736             }
   8737         }
   8738 
   8739         return errList;
   8740     }
   8741 
   8742     static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
   8743         if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   8744             if (currApp != null) {
   8745                 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
   8746             }
   8747             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   8748         } else if (adj >= ProcessList.SERVICE_B_ADJ) {
   8749             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   8750         } else if (adj >= ProcessList.HOME_APP_ADJ) {
   8751             if (currApp != null) {
   8752                 currApp.lru = 0;
   8753             }
   8754             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   8755         } else if (adj >= ProcessList.SERVICE_ADJ) {
   8756             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   8757         } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   8758             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
   8759         } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   8760             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
   8761         } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
   8762             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
   8763         } else {
   8764             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
   8765         }
   8766     }
   8767 
   8768     private void fillInProcMemInfo(ProcessRecord app,
   8769             ActivityManager.RunningAppProcessInfo outInfo) {
   8770         outInfo.pid = app.pid;
   8771         outInfo.uid = app.info.uid;
   8772         if (mHeavyWeightProcess == app) {
   8773             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
   8774         }
   8775         if (app.persistent) {
   8776             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
   8777         }
   8778         if (app.hasActivities) {
   8779             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
   8780         }
   8781         outInfo.lastTrimLevel = app.trimMemoryLevel;
   8782         int adj = app.curAdj;
   8783         outInfo.importance = oomAdjToImportance(adj, outInfo);
   8784         outInfo.importanceReasonCode = app.adjTypeCode;
   8785     }
   8786 
   8787     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
   8788         enforceNotIsolatedCaller("getRunningAppProcesses");
   8789         // Lazy instantiation of list
   8790         List<ActivityManager.RunningAppProcessInfo> runList = null;
   8791         final boolean allUsers = ActivityManager.checkUidPermission(
   8792                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   8793                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
   8794         int userId = UserHandle.getUserId(Binder.getCallingUid());
   8795         synchronized (this) {
   8796             // Iterate across all processes
   8797             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   8798                 ProcessRecord app = mLruProcesses.get(i);
   8799                 if (!allUsers && app.userId != userId) {
   8800                     continue;
   8801                 }
   8802                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
   8803                     // Generate process state info for running application
   8804                     ActivityManager.RunningAppProcessInfo currApp =
   8805                         new ActivityManager.RunningAppProcessInfo(app.processName,
   8806                                 app.pid, app.getPackageList());
   8807                     fillInProcMemInfo(app, currApp);
   8808                     if (app.adjSource instanceof ProcessRecord) {
   8809                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
   8810                         currApp.importanceReasonImportance = oomAdjToImportance(
   8811                                 app.adjSourceOom, null);
   8812                     } else if (app.adjSource instanceof ActivityRecord) {
   8813                         ActivityRecord r = (ActivityRecord)app.adjSource;
   8814                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
   8815                     }
   8816                     if (app.adjTarget instanceof ComponentName) {
   8817                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
   8818                     }
   8819                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
   8820                     //        + " lru=" + currApp.lru);
   8821                     if (runList == null) {
   8822                         runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
   8823                     }
   8824                     runList.add(currApp);
   8825                 }
   8826             }
   8827         }
   8828         return runList;
   8829     }
   8830 
   8831     public List<ApplicationInfo> getRunningExternalApplications() {
   8832         enforceNotIsolatedCaller("getRunningExternalApplications");
   8833         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
   8834         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
   8835         if (runningApps != null && runningApps.size() > 0) {
   8836             Set<String> extList = new HashSet<String>();
   8837             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
   8838                 if (app.pkgList != null) {
   8839                     for (String pkg : app.pkgList) {
   8840                         extList.add(pkg);
   8841                     }
   8842                 }
   8843             }
   8844             IPackageManager pm = AppGlobals.getPackageManager();
   8845             for (String pkg : extList) {
   8846                 try {
   8847                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
   8848                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
   8849                         retList.add(info);
   8850                     }
   8851                 } catch (RemoteException e) {
   8852                 }
   8853             }
   8854         }
   8855         return retList;
   8856     }
   8857 
   8858     @Override
   8859     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
   8860         enforceNotIsolatedCaller("getMyMemoryState");
   8861         synchronized (this) {
   8862             ProcessRecord proc;
   8863             synchronized (mPidsSelfLocked) {
   8864                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
   8865             }
   8866             fillInProcMemInfo(proc, outInfo);
   8867         }
   8868     }
   8869 
   8870     @Override
   8871     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   8872         if (checkCallingPermission(android.Manifest.permission.DUMP)
   8873                 != PackageManager.PERMISSION_GRANTED) {
   8874             pw.println("Permission Denial: can't dump ActivityManager from from pid="
   8875                     + Binder.getCallingPid()
   8876                     + ", uid=" + Binder.getCallingUid()
   8877                     + " without permission "
   8878                     + android.Manifest.permission.DUMP);
   8879             return;
   8880         }
   8881 
   8882         boolean dumpAll = false;
   8883         boolean dumpClient = false;
   8884         String dumpPackage = null;
   8885 
   8886         int opti = 0;
   8887         while (opti < args.length) {
   8888             String opt = args[opti];
   8889             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   8890                 break;
   8891             }
   8892             opti++;
   8893             if ("-a".equals(opt)) {
   8894                 dumpAll = true;
   8895             } else if ("-c".equals(opt)) {
   8896                 dumpClient = true;
   8897             } else if ("-h".equals(opt)) {
   8898                 pw.println("Activity manager dump options:");
   8899                 pw.println("  [-a] [-c] [-h] [cmd] ...");
   8900                 pw.println("  cmd may be one of:");
   8901                 pw.println("    a[ctivities]: activity stack state");
   8902                 pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
   8903                 pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
   8904                 pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
   8905                 pw.println("    o[om]: out of memory management");
   8906                 pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
   8907                 pw.println("    provider [COMP_SPEC]: provider client-side state");
   8908                 pw.println("    s[ervices] [COMP_SPEC ...]: service state");
   8909                 pw.println("    service [COMP_SPEC]: service client-side state");
   8910                 pw.println("    package [PACKAGE_NAME]: all state related to given package");
   8911                 pw.println("    all: dump all activities");
   8912                 pw.println("    top: dump the top activity");
   8913                 pw.println("  cmd may also be a COMP_SPEC to dump activities.");
   8914                 pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
   8915                 pw.println("    a partial substring in a component name, a");
   8916                 pw.println("    hex object identifier.");
   8917                 pw.println("  -a: include all available server state.");
   8918                 pw.println("  -c: include client state.");
   8919                 return;
   8920             } else {
   8921                 pw.println("Unknown argument: " + opt + "; use -h for help");
   8922             }
   8923         }
   8924 
   8925         long origId = Binder.clearCallingIdentity();
   8926         boolean more = false;
   8927         // Is the caller requesting to dump a particular piece of data?
   8928         if (opti < args.length) {
   8929             String cmd = args[opti];
   8930             opti++;
   8931             if ("activities".equals(cmd) || "a".equals(cmd)) {
   8932                 synchronized (this) {
   8933                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
   8934                 }
   8935             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
   8936                 String[] newArgs;
   8937                 String name;
   8938                 if (opti >= args.length) {
   8939                     name = null;
   8940                     newArgs = EMPTY_STRING_ARRAY;
   8941                 } else {
   8942                     name = args[opti];
   8943                     opti++;
   8944                     newArgs = new String[args.length - opti];
   8945                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   8946                             args.length - opti);
   8947                 }
   8948                 synchronized (this) {
   8949                     dumpBroadcastsLocked(fd, pw, args, opti, true, name);
   8950                 }
   8951             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
   8952                 String[] newArgs;
   8953                 String name;
   8954                 if (opti >= args.length) {
   8955                     name = null;
   8956                     newArgs = EMPTY_STRING_ARRAY;
   8957                 } else {
   8958                     name = args[opti];
   8959                     opti++;
   8960                     newArgs = new String[args.length - opti];
   8961                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   8962                             args.length - opti);
   8963                 }
   8964                 synchronized (this) {
   8965                     dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
   8966                 }
   8967             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
   8968                 String[] newArgs;
   8969                 String name;
   8970                 if (opti >= args.length) {
   8971                     name = null;
   8972                     newArgs = EMPTY_STRING_ARRAY;
   8973                 } else {
   8974                     name = args[opti];
   8975                     opti++;
   8976                     newArgs = new String[args.length - opti];
   8977                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   8978                             args.length - opti);
   8979                 }
   8980                 synchronized (this) {
   8981                     dumpProcessesLocked(fd, pw, args, opti, true, name);
   8982                 }
   8983             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
   8984                 synchronized (this) {
   8985                     dumpOomLocked(fd, pw, args, opti, true);
   8986                 }
   8987             } else if ("provider".equals(cmd)) {
   8988                 String[] newArgs;
   8989                 String name;
   8990                 if (opti >= args.length) {
   8991                     name = null;
   8992                     newArgs = EMPTY_STRING_ARRAY;
   8993                 } else {
   8994                     name = args[opti];
   8995                     opti++;
   8996                     newArgs = new String[args.length - opti];
   8997                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   8998                 }
   8999                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
   9000                     pw.println("No providers match: " + name);
   9001                     pw.println("Use -h for help.");
   9002                 }
   9003             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
   9004                 synchronized (this) {
   9005                     dumpProvidersLocked(fd, pw, args, opti, true, null);
   9006                 }
   9007             } else if ("service".equals(cmd)) {
   9008                 String[] newArgs;
   9009                 String name;
   9010                 if (opti >= args.length) {
   9011                     name = null;
   9012                     newArgs = EMPTY_STRING_ARRAY;
   9013                 } else {
   9014                     name = args[opti];
   9015                     opti++;
   9016                     newArgs = new String[args.length - opti];
   9017                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   9018                             args.length - opti);
   9019                 }
   9020                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
   9021                     pw.println("No services match: " + name);
   9022                     pw.println("Use -h for help.");
   9023                 }
   9024             } else if ("package".equals(cmd)) {
   9025                 String[] newArgs;
   9026                 if (opti >= args.length) {
   9027                     pw.println("package: no package name specified");
   9028                     pw.println("Use -h for help.");
   9029                 } else {
   9030                     dumpPackage = args[opti];
   9031                     opti++;
   9032                     newArgs = new String[args.length - opti];
   9033                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   9034                             args.length - opti);
   9035                     args = newArgs;
   9036                     opti = 0;
   9037                     more = true;
   9038                 }
   9039             } else if ("services".equals(cmd) || "s".equals(cmd)) {
   9040                 synchronized (this) {
   9041                     mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
   9042                 }
   9043             } else {
   9044                 // Dumping a single activity?
   9045                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
   9046                     pw.println("Bad activity command, or no activities match: " + cmd);
   9047                     pw.println("Use -h for help.");
   9048                 }
   9049             }
   9050             if (!more) {
   9051                 Binder.restoreCallingIdentity(origId);
   9052                 return;
   9053             }
   9054         }
   9055 
   9056         // No piece of data specified, dump everything.
   9057         synchronized (this) {
   9058             boolean needSep;
   9059             needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   9060             if (needSep) {
   9061                 pw.println(" ");
   9062             }
   9063             if (dumpAll) {
   9064                 pw.println("-------------------------------------------------------------------------------");
   9065             }
   9066             needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   9067             if (needSep) {
   9068                 pw.println(" ");
   9069             }
   9070             if (dumpAll) {
   9071                 pw.println("-------------------------------------------------------------------------------");
   9072             }
   9073             needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   9074             if (needSep) {
   9075                 pw.println(" ");
   9076             }
   9077             if (dumpAll) {
   9078                 pw.println("-------------------------------------------------------------------------------");
   9079             }
   9080             needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   9081             if (needSep) {
   9082                 pw.println(" ");
   9083             }
   9084             if (dumpAll) {
   9085                 pw.println("-------------------------------------------------------------------------------");
   9086             }
   9087             needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   9088             if (needSep) {
   9089                 pw.println(" ");
   9090             }
   9091             if (dumpAll) {
   9092                 pw.println("-------------------------------------------------------------------------------");
   9093             }
   9094             dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   9095         }
   9096         Binder.restoreCallingIdentity(origId);
   9097     }
   9098 
   9099     boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   9100             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   9101         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
   9102         pw.println("  Main stack:");
   9103         dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
   9104                 dumpPackage);
   9105         pw.println(" ");
   9106         pw.println("  Running activities (most recent first):");
   9107         dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
   9108                 dumpPackage);
   9109         if (mMainStack.mWaitingVisibleActivities.size() > 0) {
   9110             pw.println(" ");
   9111             pw.println("  Activities waiting for another to become visible:");
   9112             dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
   9113                     !dumpAll, false, dumpPackage);
   9114         }
   9115         if (mMainStack.mStoppingActivities.size() > 0) {
   9116             pw.println(" ");
   9117             pw.println("  Activities waiting to stop:");
   9118             dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
   9119                     !dumpAll, false, dumpPackage);
   9120         }
   9121         if (mMainStack.mGoingToSleepActivities.size() > 0) {
   9122             pw.println(" ");
   9123             pw.println("  Activities waiting to sleep:");
   9124             dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
   9125                     !dumpAll, false, dumpPackage);
   9126         }
   9127         if (mMainStack.mFinishingActivities.size() > 0) {
   9128             pw.println(" ");
   9129             pw.println("  Activities waiting to finish:");
   9130             dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
   9131                     !dumpAll, false, dumpPackage);
   9132         }
   9133 
   9134         pw.println(" ");
   9135         if (mMainStack.mPausingActivity != null) {
   9136             pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
   9137         }
   9138         pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
   9139         pw.println("  mFocusedActivity: " + mFocusedActivity);
   9140         if (dumpAll) {
   9141             pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
   9142             pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
   9143             pw.println("  mDismissKeyguardOnNextActivity: "
   9144                     + mMainStack.mDismissKeyguardOnNextActivity);
   9145         }
   9146 
   9147         if (mRecentTasks.size() > 0) {
   9148             pw.println();
   9149             pw.println("  Recent tasks:");
   9150 
   9151             final int N = mRecentTasks.size();
   9152             for (int i=0; i<N; i++) {
   9153                 TaskRecord tr = mRecentTasks.get(i);
   9154                 if (dumpPackage != null) {
   9155                     if (tr.realActivity == null ||
   9156                             !dumpPackage.equals(tr.realActivity)) {
   9157                         continue;
   9158                     }
   9159                 }
   9160                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
   9161                         pw.println(tr);
   9162                 if (dumpAll) {
   9163                     mRecentTasks.get(i).dump(pw, "    ");
   9164                 }
   9165             }
   9166         }
   9167 
   9168         if (dumpAll) {
   9169             pw.println(" ");
   9170             pw.println("  mCurTask: " + mCurTask);
   9171         }
   9172 
   9173         return true;
   9174     }
   9175 
   9176     boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   9177             int opti, boolean dumpAll, String dumpPackage) {
   9178         boolean needSep = false;
   9179         int numPers = 0;
   9180 
   9181         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
   9182 
   9183         if (dumpAll) {
   9184             for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
   9185                 final int NA = procs.size();
   9186                 for (int ia=0; ia<NA; ia++) {
   9187                     ProcessRecord r = procs.valueAt(ia);
   9188                     if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   9189                         continue;
   9190                     }
   9191                     if (!needSep) {
   9192                         pw.println("  All known processes:");
   9193                         needSep = true;
   9194                     }
   9195                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
   9196                         pw.print(" UID "); pw.print(procs.keyAt(ia));
   9197                         pw.print(" "); pw.println(r);
   9198                     r.dump(pw, "    ");
   9199                     if (r.persistent) {
   9200                         numPers++;
   9201                     }
   9202                 }
   9203             }
   9204         }
   9205 
   9206         if (mIsolatedProcesses.size() > 0) {
   9207             if (needSep) pw.println(" ");
   9208             needSep = true;
   9209             pw.println("  Isolated process list (sorted by uid):");
   9210             for (int i=0; i<mIsolatedProcesses.size(); i++) {
   9211                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
   9212                 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   9213                     continue;
   9214                 }
   9215                 pw.println(String.format("%sIsolated #%2d: %s",
   9216                         "    ", i, r.toString()));
   9217             }
   9218         }
   9219 
   9220         if (mLruProcesses.size() > 0) {
   9221             if (needSep) pw.println(" ");
   9222             needSep = true;
   9223             pw.println("  Process LRU list (sorted by oom_adj):");
   9224             dumpProcessOomList(pw, this, mLruProcesses, "    ",
   9225                     "Proc", "PERS", false, dumpPackage);
   9226             needSep = true;
   9227         }
   9228 
   9229         if (dumpAll) {
   9230             synchronized (mPidsSelfLocked) {
   9231                 boolean printed = false;
   9232                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   9233                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
   9234                     if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   9235                         continue;
   9236                     }
   9237                     if (!printed) {
   9238                         if (needSep) pw.println(" ");
   9239                         needSep = true;
   9240                         pw.println("  PID mappings:");
   9241                         printed = true;
   9242                     }
   9243                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
   9244                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
   9245                 }
   9246             }
   9247         }
   9248 
   9249         if (mForegroundProcesses.size() > 0) {
   9250             synchronized (mPidsSelfLocked) {
   9251                 boolean printed = false;
   9252                 for (int i=0; i<mForegroundProcesses.size(); i++) {
   9253                     ProcessRecord r = mPidsSelfLocked.get(
   9254                             mForegroundProcesses.valueAt(i).pid);
   9255                     if (dumpPackage != null && (r == null
   9256                             || !dumpPackage.equals(r.info.packageName))) {
   9257                         continue;
   9258                     }
   9259                     if (!printed) {
   9260                         if (needSep) pw.println(" ");
   9261                         needSep = true;
   9262                         pw.println("  Foreground Processes:");
   9263                         printed = true;
   9264                     }
   9265                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
   9266                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
   9267                 }
   9268             }
   9269         }
   9270 
   9271         if (mPersistentStartingProcesses.size() > 0) {
   9272             if (needSep) pw.println(" ");
   9273             needSep = true;
   9274             pw.println("  Persisent processes that are starting:");
   9275             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
   9276                     "Starting Norm", "Restarting PERS", dumpPackage);
   9277         }
   9278 
   9279         if (mRemovedProcesses.size() > 0) {
   9280             if (needSep) pw.println(" ");
   9281             needSep = true;
   9282             pw.println("  Processes that are being removed:");
   9283             dumpProcessList(pw, this, mRemovedProcesses, "    ",
   9284                     "Removed Norm", "Removed PERS", dumpPackage);
   9285         }
   9286 
   9287         if (mProcessesOnHold.size() > 0) {
   9288             if (needSep) pw.println(" ");
   9289             needSep = true;
   9290             pw.println("  Processes that are on old until the system is ready:");
   9291             dumpProcessList(pw, this, mProcessesOnHold, "    ",
   9292                     "OnHold Norm", "OnHold PERS", dumpPackage);
   9293         }
   9294 
   9295         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
   9296 
   9297         if (mProcessCrashTimes.getMap().size() > 0) {
   9298             boolean printed = false;
   9299             long now = SystemClock.uptimeMillis();
   9300             for (Map.Entry<String, SparseArray<Long>> procs
   9301                     : mProcessCrashTimes.getMap().entrySet()) {
   9302                 String pname = procs.getKey();
   9303                 SparseArray<Long> uids = procs.getValue();
   9304                 final int N = uids.size();
   9305                 for (int i=0; i<N; i++) {
   9306                     int puid = uids.keyAt(i);
   9307                     ProcessRecord r = mProcessNames.get(pname, puid);
   9308                     if (dumpPackage != null && (r == null
   9309                             || !dumpPackage.equals(r.info.packageName))) {
   9310                         continue;
   9311                     }
   9312                     if (!printed) {
   9313                         if (needSep) pw.println(" ");
   9314                         needSep = true;
   9315                         pw.println("  Time since processes crashed:");
   9316                         printed = true;
   9317                     }
   9318                     pw.print("    Process "); pw.print(pname);
   9319                             pw.print(" uid "); pw.print(puid);
   9320                             pw.print(": last crashed ");
   9321                             TimeUtils.formatDuration(now-uids.valueAt(i), pw);
   9322                             pw.println(" ago");
   9323                 }
   9324             }
   9325         }
   9326 
   9327         if (mBadProcesses.getMap().size() > 0) {
   9328             boolean printed = false;
   9329             for (Map.Entry<String, SparseArray<Long>> procs
   9330                     : mBadProcesses.getMap().entrySet()) {
   9331                 String pname = procs.getKey();
   9332                 SparseArray<Long> uids = procs.getValue();
   9333                 final int N = uids.size();
   9334                 for (int i=0; i<N; i++) {
   9335                     int puid = uids.keyAt(i);
   9336                     ProcessRecord r = mProcessNames.get(pname, puid);
   9337                     if (dumpPackage != null && (r == null
   9338                             || !dumpPackage.equals(r.info.packageName))) {
   9339                         continue;
   9340                     }
   9341                     if (!printed) {
   9342                         if (needSep) pw.println(" ");
   9343                         needSep = true;
   9344                         pw.println("  Bad processes:");
   9345                     }
   9346                     pw.print("    Bad process "); pw.print(pname);
   9347                             pw.print(" uid "); pw.print(puid);
   9348                             pw.print(": crashed at time ");
   9349                             pw.println(uids.valueAt(i));
   9350                 }
   9351             }
   9352         }
   9353 
   9354         pw.println();
   9355         pw.println("  mStartedUsers:");
   9356         for (int i=0; i<mStartedUsers.size(); i++) {
   9357             UserStartedState uss = mStartedUsers.valueAt(i);
   9358             pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
   9359                     pw.print(": "); uss.dump("", pw);
   9360         }
   9361         pw.print("  mStartedUserArray: [");
   9362         for (int i=0; i<mStartedUserArray.length; i++) {
   9363             if (i > 0) pw.print(", ");
   9364             pw.print(mStartedUserArray[i]);
   9365         }
   9366         pw.println("]");
   9367         pw.print("  mUserLru: [");
   9368         for (int i=0; i<mUserLru.size(); i++) {
   9369             if (i > 0) pw.print(", ");
   9370             pw.print(mUserLru.get(i));
   9371         }
   9372         pw.println("]");
   9373         if (dumpAll) {
   9374             pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
   9375         }
   9376         pw.println("  mHomeProcess: " + mHomeProcess);
   9377         pw.println("  mPreviousProcess: " + mPreviousProcess);
   9378         if (dumpAll) {
   9379             StringBuilder sb = new StringBuilder(128);
   9380             sb.append("  mPreviousProcessVisibleTime: ");
   9381             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
   9382             pw.println(sb);
   9383         }
   9384         if (mHeavyWeightProcess != null) {
   9385             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   9386         }
   9387         pw.println("  mConfiguration: " + mConfiguration);
   9388         if (dumpAll) {
   9389             pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
   9390             if (mCompatModePackages.getPackages().size() > 0) {
   9391                 boolean printed = false;
   9392                 for (Map.Entry<String, Integer> entry
   9393                         : mCompatModePackages.getPackages().entrySet()) {
   9394                     String pkg = entry.getKey();
   9395                     int mode = entry.getValue();
   9396                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
   9397                         continue;
   9398                     }
   9399                     if (!printed) {
   9400                         pw.println("  mScreenCompatPackages:");
   9401                         printed = true;
   9402                     }
   9403                     pw.print("    "); pw.print(pkg); pw.print(": ");
   9404                             pw.print(mode); pw.println();
   9405                 }
   9406             }
   9407         }
   9408         if (mSleeping || mWentToSleep || mLockScreenShown) {
   9409             pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
   9410                     + " mLockScreenShown " + mLockScreenShown);
   9411         }
   9412         if (mShuttingDown) {
   9413             pw.println("  mShuttingDown=" + mShuttingDown);
   9414         }
   9415         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
   9416                 || mOrigWaitForDebugger) {
   9417             pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
   9418                     + " mDebugTransient=" + mDebugTransient
   9419                     + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
   9420         }
   9421         if (mOpenGlTraceApp != null) {
   9422             pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
   9423         }
   9424         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
   9425                 || mProfileFd != null) {
   9426             pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
   9427             pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
   9428             pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
   9429                     + mAutoStopProfiler);
   9430         }
   9431         if (mAlwaysFinishActivities || mController != null) {
   9432             pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
   9433                     + " mController=" + mController);
   9434         }
   9435         if (dumpAll) {
   9436             pw.println("  Total persistent processes: " + numPers);
   9437             pw.println("  mStartRunning=" + mStartRunning
   9438                     + " mProcessesReady=" + mProcessesReady
   9439                     + " mSystemReady=" + mSystemReady);
   9440             pw.println("  mBooting=" + mBooting
   9441                     + " mBooted=" + mBooted
   9442                     + " mFactoryTest=" + mFactoryTest);
   9443             pw.print("  mLastPowerCheckRealtime=");
   9444                     TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
   9445                     pw.println("");
   9446             pw.print("  mLastPowerCheckUptime=");
   9447                     TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
   9448                     pw.println("");
   9449             pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
   9450             pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
   9451             pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
   9452             pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
   9453                     + " mNumHiddenProcs=" + mNumHiddenProcs
   9454                     + " mNumServiceProcs=" + mNumServiceProcs
   9455                     + " mNewNumServiceProcs=" + mNewNumServiceProcs);
   9456         }
   9457 
   9458         return true;
   9459     }
   9460 
   9461     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
   9462             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
   9463         if (mProcessesToGc.size() > 0) {
   9464             boolean printed = false;
   9465             long now = SystemClock.uptimeMillis();
   9466             for (int i=0; i<mProcessesToGc.size(); i++) {
   9467                 ProcessRecord proc = mProcessesToGc.get(i);
   9468                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
   9469                     continue;
   9470                 }
   9471                 if (!printed) {
   9472                     if (needSep) pw.println(" ");
   9473                     needSep = true;
   9474                     pw.println("  Processes that are waiting to GC:");
   9475                     printed = true;
   9476                 }
   9477                 pw.print("    Process "); pw.println(proc);
   9478                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
   9479                         pw.print(", last gced=");
   9480                         pw.print(now-proc.lastRequestedGc);
   9481                         pw.print(" ms ago, last lowMem=");
   9482                         pw.print(now-proc.lastLowMemory);
   9483                         pw.println(" ms ago");
   9484 
   9485             }
   9486         }
   9487         return needSep;
   9488     }
   9489 
   9490     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   9491             int opti, boolean dumpAll) {
   9492         boolean needSep = false;
   9493 
   9494         if (mLruProcesses.size() > 0) {
   9495             if (needSep) pw.println(" ");
   9496             needSep = true;
   9497             pw.println("  OOM levels:");
   9498             pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
   9499             pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
   9500             pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
   9501             pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
   9502             pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
   9503             pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
   9504             pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
   9505             pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
   9506             pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
   9507             pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
   9508             pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
   9509             pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
   9510             pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
   9511 
   9512             if (needSep) pw.println(" ");
   9513             needSep = true;
   9514             pw.println("  Process OOM control:");
   9515             dumpProcessOomList(pw, this, mLruProcesses, "    ",
   9516                     "Proc", "PERS", true, null);
   9517             needSep = true;
   9518         }
   9519 
   9520         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
   9521 
   9522         pw.println();
   9523         pw.println("  mHomeProcess: " + mHomeProcess);
   9524         pw.println("  mPreviousProcess: " + mPreviousProcess);
   9525         if (mHeavyWeightProcess != null) {
   9526             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   9527         }
   9528 
   9529         return true;
   9530     }
   9531 
   9532     /**
   9533      * There are three ways to call this:
   9534      *  - no provider specified: dump all the providers
   9535      *  - a flattened component name that matched an existing provider was specified as the
   9536      *    first arg: dump that one provider
   9537      *  - the first arg isn't the flattened component name of an existing provider:
   9538      *    dump all providers whose component contains the first arg as a substring
   9539      */
   9540     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   9541             int opti, boolean dumpAll) {
   9542         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
   9543     }
   9544 
   9545     static class ItemMatcher {
   9546         ArrayList<ComponentName> components;
   9547         ArrayList<String> strings;
   9548         ArrayList<Integer> objects;
   9549         boolean all;
   9550 
   9551         ItemMatcher() {
   9552             all = true;
   9553         }
   9554 
   9555         void build(String name) {
   9556             ComponentName componentName = ComponentName.unflattenFromString(name);
   9557             if (componentName != null) {
   9558                 if (components == null) {
   9559                     components = new ArrayList<ComponentName>();
   9560                 }
   9561                 components.add(componentName);
   9562                 all = false;
   9563             } else {
   9564                 int objectId = 0;
   9565                 // Not a '/' separated full component name; maybe an object ID?
   9566                 try {
   9567                     objectId = Integer.parseInt(name, 16);
   9568                     if (objects == null) {
   9569                         objects = new ArrayList<Integer>();
   9570                     }
   9571                     objects.add(objectId);
   9572                     all = false;
   9573                 } catch (RuntimeException e) {
   9574                     // Not an integer; just do string match.
   9575                     if (strings == null) {
   9576                         strings = new ArrayList<String>();
   9577                     }
   9578                     strings.add(name);
   9579                     all = false;
   9580                 }
   9581             }
   9582         }
   9583 
   9584         int build(String[] args, int opti) {
   9585             for (; opti<args.length; opti++) {
   9586                 String name = args[opti];
   9587                 if ("--".equals(name)) {
   9588                     return opti+1;
   9589                 }
   9590                 build(name);
   9591             }
   9592             return opti;
   9593         }
   9594 
   9595         boolean match(Object object, ComponentName comp) {
   9596             if (all) {
   9597                 return true;
   9598             }
   9599             if (components != null) {
   9600                 for (int i=0; i<components.size(); i++) {
   9601                     if (components.get(i).equals(comp)) {
   9602                         return true;
   9603                     }
   9604                 }
   9605             }
   9606             if (objects != null) {
   9607                 for (int i=0; i<objects.size(); i++) {
   9608                     if (System.identityHashCode(object) == objects.get(i)) {
   9609                         return true;
   9610                     }
   9611                 }
   9612             }
   9613             if (strings != null) {
   9614                 String flat = comp.flattenToString();
   9615                 for (int i=0; i<strings.size(); i++) {
   9616                     if (flat.contains(strings.get(i))) {
   9617                         return true;
   9618                     }
   9619                 }
   9620             }
   9621             return false;
   9622         }
   9623     }
   9624 
   9625     /**
   9626      * There are three things that cmd can be:
   9627      *  - a flattened component name that matches an existing activity
   9628      *  - the cmd arg isn't the flattened component name of an existing activity:
   9629      *    dump all activity whose component contains the cmd as a substring
   9630      *  - A hex number of the ActivityRecord object instance.
   9631      */
   9632     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   9633             int opti, boolean dumpAll) {
   9634         ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
   9635 
   9636         if ("all".equals(name)) {
   9637             synchronized (this) {
   9638                 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
   9639                     activities.add(r1);
   9640                 }
   9641             }
   9642         } else if ("top".equals(name)) {
   9643             synchronized (this) {
   9644                 final int N = mMainStack.mHistory.size();
   9645                 if (N > 0) {
   9646                     activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
   9647                 }
   9648             }
   9649         } else {
   9650             ItemMatcher matcher = new ItemMatcher();
   9651             matcher.build(name);
   9652 
   9653             synchronized (this) {
   9654                 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
   9655                     if (matcher.match(r1, r1.intent.getComponent())) {
   9656                         activities.add(r1);
   9657                     }
   9658                 }
   9659             }
   9660         }
   9661 
   9662         if (activities.size() <= 0) {
   9663             return false;
   9664         }
   9665 
   9666         String[] newArgs = new String[args.length - opti];
   9667         if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   9668 
   9669         TaskRecord lastTask = null;
   9670         boolean needSep = false;
   9671         for (int i=activities.size()-1; i>=0; i--) {
   9672             ActivityRecord r = (ActivityRecord)activities.get(i);
   9673             if (needSep) {
   9674                 pw.println();
   9675             }
   9676             needSep = true;
   9677             synchronized (this) {
   9678                 if (lastTask != r.task) {
   9679                     lastTask = r.task;
   9680                     pw.print("TASK "); pw.print(lastTask.affinity);
   9681                             pw.print(" id="); pw.println(lastTask.taskId);
   9682                     if (dumpAll) {
   9683                         lastTask.dump(pw, "  ");
   9684                     }
   9685                 }
   9686             }
   9687             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
   9688         }
   9689         return true;
   9690     }
   9691 
   9692     /**
   9693      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
   9694      * there is a thread associated with the activity.
   9695      */
   9696     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
   9697             final ActivityRecord r, String[] args, boolean dumpAll) {
   9698         String innerPrefix = prefix + "  ";
   9699         synchronized (this) {
   9700             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
   9701                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
   9702                     pw.print(" pid=");
   9703                     if (r.app != null) pw.println(r.app.pid);
   9704                     else pw.println("(not running)");
   9705             if (dumpAll) {
   9706                 r.dump(pw, innerPrefix);
   9707             }
   9708         }
   9709         if (r.app != null && r.app.thread != null) {
   9710             // flush anything that is already in the PrintWriter since the thread is going
   9711             // to write to the file descriptor directly
   9712             pw.flush();
   9713             try {
   9714                 TransferPipe tp = new TransferPipe();
   9715                 try {
   9716                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
   9717                             r.appToken, innerPrefix, args);
   9718                     tp.go(fd);
   9719                 } finally {
   9720                     tp.kill();
   9721                 }
   9722             } catch (IOException e) {
   9723                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   9724             } catch (RemoteException e) {
   9725                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   9726             }
   9727         }
   9728     }
   9729 
   9730     boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   9731             int opti, boolean dumpAll, String dumpPackage) {
   9732         boolean needSep = false;
   9733         boolean onlyHistory = false;
   9734 
   9735         if ("history".equals(dumpPackage)) {
   9736             if (opti < args.length && "-s".equals(args[opti])) {
   9737                 dumpAll = false;
   9738             }
   9739             onlyHistory = true;
   9740             dumpPackage = null;
   9741         }
   9742 
   9743         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
   9744         if (!onlyHistory && dumpAll) {
   9745             if (mRegisteredReceivers.size() > 0) {
   9746                 boolean printed = false;
   9747                 Iterator it = mRegisteredReceivers.values().iterator();
   9748                 while (it.hasNext()) {
   9749                     ReceiverList r = (ReceiverList)it.next();
   9750                     if (dumpPackage != null && (r.app == null ||
   9751                             !dumpPackage.equals(r.app.info.packageName))) {
   9752                         continue;
   9753                     }
   9754                     if (!printed) {
   9755                         pw.println("  Registered Receivers:");
   9756                         needSep = true;
   9757                         printed = true;
   9758                     }
   9759                     pw.print("  * "); pw.println(r);
   9760                     r.dump(pw, "    ");
   9761                 }
   9762             }
   9763 
   9764             if (mReceiverResolver.dump(pw, needSep ?
   9765                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
   9766                     "    ", dumpPackage, false)) {
   9767                 needSep = true;
   9768             }
   9769         }
   9770 
   9771         for (BroadcastQueue q : mBroadcastQueues) {
   9772             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
   9773         }
   9774 
   9775         needSep = true;
   9776 
   9777         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
   9778             for (int user=0; user<mStickyBroadcasts.size(); user++) {
   9779                 if (needSep) {
   9780                     pw.println();
   9781                 }
   9782                 needSep = true;
   9783                 pw.print("  Sticky broadcasts for user ");
   9784                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
   9785                 StringBuilder sb = new StringBuilder(128);
   9786                 for (Map.Entry<String, ArrayList<Intent>> ent
   9787                         : mStickyBroadcasts.valueAt(user).entrySet()) {
   9788                     pw.print("  * Sticky action "); pw.print(ent.getKey());
   9789                     if (dumpAll) {
   9790                         pw.println(":");
   9791                         ArrayList<Intent> intents = ent.getValue();
   9792                         final int N = intents.size();
   9793                         for (int i=0; i<N; i++) {
   9794                             sb.setLength(0);
   9795                             sb.append("    Intent: ");
   9796                             intents.get(i).toShortString(sb, false, true, false, false);
   9797                             pw.println(sb.toString());
   9798                             Bundle bundle = intents.get(i).getExtras();
   9799                             if (bundle != null) {
   9800                                 pw.print("      ");
   9801                                 pw.println(bundle.toString());
   9802                             }
   9803                         }
   9804                     } else {
   9805                         pw.println("");
   9806                     }
   9807                 }
   9808             }
   9809         }
   9810 
   9811         if (!onlyHistory && dumpAll) {
   9812             pw.println();
   9813             for (BroadcastQueue queue : mBroadcastQueues) {
   9814                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
   9815                         + queue.mBroadcastsScheduled);
   9816             }
   9817             pw.println("  mHandler:");
   9818             mHandler.dump(new PrintWriterPrinter(pw), "    ");
   9819             needSep = true;
   9820         }
   9821 
   9822         return needSep;
   9823     }
   9824 
   9825     boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   9826             int opti, boolean dumpAll, String dumpPackage) {
   9827         boolean needSep = true;
   9828 
   9829         ItemMatcher matcher = new ItemMatcher();
   9830         matcher.build(args, opti);
   9831 
   9832         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
   9833 
   9834         mProviderMap.dumpProvidersLocked(pw, dumpAll);
   9835 
   9836         if (mLaunchingProviders.size() > 0) {
   9837             boolean printed = false;
   9838             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
   9839                 ContentProviderRecord r = mLaunchingProviders.get(i);
   9840                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
   9841                     continue;
   9842                 }
   9843                 if (!printed) {
   9844                     if (needSep) pw.println(" ");
   9845                     needSep = true;
   9846                     pw.println("  Launching content providers:");
   9847                     printed = true;
   9848                 }
   9849                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
   9850                         pw.println(r);
   9851             }
   9852         }
   9853 
   9854         if (mGrantedUriPermissions.size() > 0) {
   9855             if (needSep) pw.println();
   9856             needSep = true;
   9857             pw.println("Granted Uri Permissions:");
   9858             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
   9859                 int uid = mGrantedUriPermissions.keyAt(i);
   9860                 HashMap<Uri, UriPermission> perms
   9861                         = mGrantedUriPermissions.valueAt(i);
   9862                 pw.print("  * UID "); pw.print(uid);
   9863                         pw.println(" holds:");
   9864                 for (UriPermission perm : perms.values()) {
   9865                     pw.print("    "); pw.println(perm);
   9866                     if (dumpAll) {
   9867                         perm.dump(pw, "      ");
   9868                     }
   9869                 }
   9870             }
   9871             needSep = true;
   9872         }
   9873 
   9874         return needSep;
   9875     }
   9876 
   9877     boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   9878             int opti, boolean dumpAll, String dumpPackage) {
   9879         boolean needSep = false;
   9880 
   9881         if (mIntentSenderRecords.size() > 0) {
   9882             boolean printed = false;
   9883             Iterator<WeakReference<PendingIntentRecord>> it
   9884                     = mIntentSenderRecords.values().iterator();
   9885             while (it.hasNext()) {
   9886                 WeakReference<PendingIntentRecord> ref = it.next();
   9887                 PendingIntentRecord rec = ref != null ? ref.get(): null;
   9888                 if (dumpPackage != null && (rec == null
   9889                         || !dumpPackage.equals(rec.key.packageName))) {
   9890                     continue;
   9891                 }
   9892                 if (!printed) {
   9893                     pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
   9894                     printed = true;
   9895                 }
   9896                 needSep = true;
   9897                 if (rec != null) {
   9898                     pw.print("  * "); pw.println(rec);
   9899                     if (dumpAll) {
   9900                         rec.dump(pw, "    ");
   9901                     }
   9902                 } else {
   9903                     pw.print("  * "); pw.println(ref);
   9904                 }
   9905             }
   9906         }
   9907 
   9908         return needSep;
   9909     }
   9910 
   9911     private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
   9912             String prefix, String label, boolean complete, boolean brief, boolean client,
   9913             String dumpPackage) {
   9914         TaskRecord lastTask = null;
   9915         boolean needNL = false;
   9916         final String innerPrefix = prefix + "      ";
   9917         final String[] args = new String[0];
   9918         for (int i=list.size()-1; i>=0; i--) {
   9919             final ActivityRecord r = (ActivityRecord)list.get(i);
   9920             if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
   9921                 continue;
   9922             }
   9923             final boolean full = !brief && (complete || !r.isInHistory());
   9924             if (needNL) {
   9925                 pw.println(" ");
   9926                 needNL = false;
   9927             }
   9928             if (lastTask != r.task) {
   9929                 lastTask = r.task;
   9930                 pw.print(prefix);
   9931                 pw.print(full ? "* " : "  ");
   9932                 pw.println(lastTask);
   9933                 if (full) {
   9934                     lastTask.dump(pw, prefix + "  ");
   9935                 } else if (complete) {
   9936                     // Complete + brief == give a summary.  Isn't that obvious?!?
   9937                     if (lastTask.intent != null) {
   9938                         pw.print(prefix); pw.print("  ");
   9939                                 pw.println(lastTask.intent.toInsecureStringWithClip());
   9940                     }
   9941                 }
   9942             }
   9943             pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
   9944             pw.print(" #"); pw.print(i); pw.print(": ");
   9945             pw.println(r);
   9946             if (full) {
   9947                 r.dump(pw, innerPrefix);
   9948             } else if (complete) {
   9949                 // Complete + brief == give a summary.  Isn't that obvious?!?
   9950                 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
   9951                 if (r.app != null) {
   9952                     pw.print(innerPrefix); pw.println(r.app);
   9953                 }
   9954             }
   9955             if (client && r.app != null && r.app.thread != null) {
   9956                 // flush anything that is already in the PrintWriter since the thread is going
   9957                 // to write to the file descriptor directly
   9958                 pw.flush();
   9959                 try {
   9960                     TransferPipe tp = new TransferPipe();
   9961                     try {
   9962                         r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
   9963                                 r.appToken, innerPrefix, args);
   9964                         // Short timeout, since blocking here can
   9965                         // deadlock with the application.
   9966                         tp.go(fd, 2000);
   9967                     } finally {
   9968                         tp.kill();
   9969                     }
   9970                 } catch (IOException e) {
   9971                     pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   9972                 } catch (RemoteException e) {
   9973                     pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   9974                 }
   9975                 needNL = true;
   9976             }
   9977         }
   9978     }
   9979 
   9980     private static String buildOomTag(String prefix, String space, int val, int base) {
   9981         if (val == base) {
   9982             if (space == null) return prefix;
   9983             return prefix + "  ";
   9984         }
   9985         return prefix + "+" + Integer.toString(val-base);
   9986     }
   9987 
   9988     private static final int dumpProcessList(PrintWriter pw,
   9989             ActivityManagerService service, List list,
   9990             String prefix, String normalLabel, String persistentLabel,
   9991             String dumpPackage) {
   9992         int numPers = 0;
   9993         final int N = list.size()-1;
   9994         for (int i=N; i>=0; i--) {
   9995             ProcessRecord r = (ProcessRecord)list.get(i);
   9996             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   9997                 continue;
   9998             }
   9999             pw.println(String.format("%s%s #%2d: %s",
   10000                     prefix, (r.persistent ? persistentLabel : normalLabel),
   10001                     i, r.toString()));
   10002             if (r.persistent) {
   10003                 numPers++;
   10004             }
   10005         }
   10006         return numPers;
   10007     }
   10008 
   10009     private static final boolean dumpProcessOomList(PrintWriter pw,
   10010             ActivityManagerService service, List<ProcessRecord> origList,
   10011             String prefix, String normalLabel, String persistentLabel,
   10012             boolean inclDetails, String dumpPackage) {
   10013 
   10014         ArrayList<Pair<ProcessRecord, Integer>> list
   10015                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
   10016         for (int i=0; i<origList.size(); i++) {
   10017             ProcessRecord r = origList.get(i);
   10018             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   10019                 continue;
   10020             }
   10021             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
   10022         }
   10023 
   10024         if (list.size() <= 0) {
   10025             return false;
   10026         }
   10027 
   10028         Comparator<Pair<ProcessRecord, Integer>> comparator
   10029                 = new Comparator<Pair<ProcessRecord, Integer>>() {
   10030             @Override
   10031             public int compare(Pair<ProcessRecord, Integer> object1,
   10032                     Pair<ProcessRecord, Integer> object2) {
   10033                 if (object1.first.setAdj != object2.first.setAdj) {
   10034                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
   10035                 }
   10036                 if (object1.second.intValue() != object2.second.intValue()) {
   10037                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
   10038                 }
   10039                 return 0;
   10040             }
   10041         };
   10042 
   10043         Collections.sort(list, comparator);
   10044 
   10045         final long curRealtime = SystemClock.elapsedRealtime();
   10046         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
   10047         final long curUptime = SystemClock.uptimeMillis();
   10048         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
   10049 
   10050         for (int i=list.size()-1; i>=0; i--) {
   10051             ProcessRecord r = list.get(i).first;
   10052             String oomAdj;
   10053             if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   10054                 oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
   10055             } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
   10056                 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
   10057             } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
   10058                 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
   10059             } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
   10060                 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
   10061             } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
   10062                 oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
   10063             } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
   10064                 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
   10065             } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   10066                 oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
   10067             } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   10068                 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
   10069             } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
   10070                 oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
   10071             } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
   10072                 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
   10073             } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
   10074                 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
   10075             } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
   10076                 oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
   10077             } else {
   10078                 oomAdj = Integer.toString(r.setAdj);
   10079             }
   10080             String schedGroup;
   10081             switch (r.setSchedGroup) {
   10082                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
   10083                     schedGroup = "B";
   10084                     break;
   10085                 case Process.THREAD_GROUP_DEFAULT:
   10086                     schedGroup = "F";
   10087                     break;
   10088                 default:
   10089                     schedGroup = Integer.toString(r.setSchedGroup);
   10090                     break;
   10091             }
   10092             String foreground;
   10093             if (r.foregroundActivities) {
   10094                 foreground = "A";
   10095             } else if (r.foregroundServices) {
   10096                 foreground = "S";
   10097             } else {
   10098                 foreground = " ";
   10099             }
   10100             pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
   10101                     prefix, (r.persistent ? persistentLabel : normalLabel),
   10102                     (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
   10103                     foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
   10104             if (r.adjSource != null || r.adjTarget != null) {
   10105                 pw.print(prefix);
   10106                 pw.print("    ");
   10107                 if (r.adjTarget instanceof ComponentName) {
   10108                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
   10109                 } else if (r.adjTarget != null) {
   10110                     pw.print(r.adjTarget.toString());
   10111                 } else {
   10112                     pw.print("{null}");
   10113                 }
   10114                 pw.print("<=");
   10115                 if (r.adjSource instanceof ProcessRecord) {
   10116                     pw.print("Proc{");
   10117                     pw.print(((ProcessRecord)r.adjSource).toShortString());
   10118                     pw.println("}");
   10119                 } else if (r.adjSource != null) {
   10120                     pw.println(r.adjSource.toString());
   10121                 } else {
   10122                     pw.println("{null}");
   10123                 }
   10124             }
   10125             if (inclDetails) {
   10126                 pw.print(prefix);
   10127                 pw.print("    ");
   10128                 pw.print("oom: max="); pw.print(r.maxAdj);
   10129                 pw.print(" hidden="); pw.print(r.hiddenAdj);
   10130                 pw.print(" client="); pw.print(r.clientHiddenAdj);
   10131                 pw.print(" empty="); pw.print(r.emptyAdj);
   10132                 pw.print(" curRaw="); pw.print(r.curRawAdj);
   10133                 pw.print(" setRaw="); pw.print(r.setRawAdj);
   10134                 pw.print(" cur="); pw.print(r.curAdj);
   10135                 pw.print(" set="); pw.println(r.setAdj);
   10136                 pw.print(prefix);
   10137                 pw.print("    ");
   10138                 pw.print("keeping="); pw.print(r.keeping);
   10139                 pw.print(" hidden="); pw.print(r.hidden);
   10140                 pw.print(" empty="); pw.print(r.empty);
   10141                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
   10142 
   10143                 if (!r.keeping) {
   10144                     if (r.lastWakeTime != 0) {
   10145                         long wtime;
   10146                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
   10147                         synchronized (stats) {
   10148                             wtime = stats.getProcessWakeTime(r.info.uid,
   10149                                     r.pid, curRealtime);
   10150                         }
   10151                         long timeUsed = wtime - r.lastWakeTime;
   10152                         pw.print(prefix);
   10153                         pw.print("    ");
   10154                         pw.print("keep awake over ");
   10155                         TimeUtils.formatDuration(realtimeSince, pw);
   10156                         pw.print(" used ");
   10157                         TimeUtils.formatDuration(timeUsed, pw);
   10158                         pw.print(" (");
   10159                         pw.print((timeUsed*100)/realtimeSince);
   10160                         pw.println("%)");
   10161                     }
   10162                     if (r.lastCpuTime != 0) {
   10163                         long timeUsed = r.curCpuTime - r.lastCpuTime;
   10164                         pw.print(prefix);
   10165                         pw.print("    ");
   10166                         pw.print("run cpu over ");
   10167                         TimeUtils.formatDuration(uptimeSince, pw);
   10168                         pw.print(" used ");
   10169                         TimeUtils.formatDuration(timeUsed, pw);
   10170                         pw.print(" (");
   10171                         pw.print((timeUsed*100)/uptimeSince);
   10172                         pw.println("%)");
   10173                     }
   10174                 }
   10175             }
   10176         }
   10177         return true;
   10178     }
   10179 
   10180     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
   10181         ArrayList<ProcessRecord> procs;
   10182         synchronized (this) {
   10183             if (args != null && args.length > start
   10184                     && args[start].charAt(0) != '-') {
   10185                 procs = new ArrayList<ProcessRecord>();
   10186                 int pid = -1;
   10187                 try {
   10188                     pid = Integer.parseInt(args[start]);
   10189                 } catch (NumberFormatException e) {
   10190 
   10191                 }
   10192                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   10193                     ProcessRecord proc = mLruProcesses.get(i);
   10194                     if (proc.pid == pid) {
   10195                         procs.add(proc);
   10196                     } else if (proc.processName.equals(args[start])) {
   10197                         procs.add(proc);
   10198                     }
   10199                 }
   10200                 if (procs.size() <= 0) {
   10201                     pw.println("No process found for: " + args[start]);
   10202                     return null;
   10203                 }
   10204             } else {
   10205                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
   10206             }
   10207         }
   10208         return procs;
   10209     }
   10210 
   10211     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
   10212             PrintWriter pw, String[] args) {
   10213         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
   10214         if (procs == null) {
   10215             return;
   10216         }
   10217 
   10218         long uptime = SystemClock.uptimeMillis();
   10219         long realtime = SystemClock.elapsedRealtime();
   10220         pw.println("Applications Graphics Acceleration Info:");
   10221         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   10222 
   10223         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   10224             ProcessRecord r = procs.get(i);
   10225             if (r.thread != null) {
   10226                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
   10227                 pw.flush();
   10228                 try {
   10229                     TransferPipe tp = new TransferPipe();
   10230                     try {
   10231                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
   10232                         tp.go(fd);
   10233                     } finally {
   10234                         tp.kill();
   10235                     }
   10236                 } catch (IOException e) {
   10237                     pw.println("Failure while dumping the app: " + r);
   10238                     pw.flush();
   10239                 } catch (RemoteException e) {
   10240                     pw.println("Got a RemoteException while dumping the app " + r);
   10241                     pw.flush();
   10242                 }
   10243             }
   10244         }
   10245     }
   10246 
   10247     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
   10248         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
   10249         if (procs == null) {
   10250             return;
   10251         }
   10252 
   10253         pw.println("Applications Database Info:");
   10254 
   10255         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   10256             ProcessRecord r = procs.get(i);
   10257             if (r.thread != null) {
   10258                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
   10259                 pw.flush();
   10260                 try {
   10261                     TransferPipe tp = new TransferPipe();
   10262                     try {
   10263                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
   10264                         tp.go(fd);
   10265                     } finally {
   10266                         tp.kill();
   10267                     }
   10268                 } catch (IOException e) {
   10269                     pw.println("Failure while dumping the app: " + r);
   10270                     pw.flush();
   10271                 } catch (RemoteException e) {
   10272                     pw.println("Got a RemoteException while dumping the app " + r);
   10273                     pw.flush();
   10274                 }
   10275             }
   10276         }
   10277     }
   10278 
   10279     final static class MemItem {
   10280         final String label;
   10281         final String shortLabel;
   10282         final long pss;
   10283         final int id;
   10284         ArrayList<MemItem> subitems;
   10285 
   10286         public MemItem(String _label, String _shortLabel, long _pss, int _id) {
   10287             label = _label;
   10288             shortLabel = _shortLabel;
   10289             pss = _pss;
   10290             id = _id;
   10291         }
   10292     }
   10293 
   10294     static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
   10295             boolean sort) {
   10296         if (sort) {
   10297             Collections.sort(items, new Comparator<MemItem>() {
   10298                 @Override
   10299                 public int compare(MemItem lhs, MemItem rhs) {
   10300                     if (lhs.pss < rhs.pss) {
   10301                         return 1;
   10302                     } else if (lhs.pss > rhs.pss) {
   10303                         return -1;
   10304                     }
   10305                     return 0;
   10306                 }
   10307             });
   10308         }
   10309 
   10310         for (int i=0; i<items.size(); i++) {
   10311             MemItem mi = items.get(i);
   10312             pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
   10313             if (mi.subitems != null) {
   10314                 dumpMemItems(pw, prefix + "           ", mi.subitems, true);
   10315             }
   10316         }
   10317     }
   10318 
   10319     // These are in KB.
   10320     static final long[] DUMP_MEM_BUCKETS = new long[] {
   10321         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
   10322         120*1024, 160*1024, 200*1024,
   10323         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
   10324         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
   10325     };
   10326 
   10327     static final void appendMemBucket(StringBuilder out, long memKB, String label,
   10328             boolean stackLike) {
   10329         int start = label.lastIndexOf('.');
   10330         if (start >= 0) start++;
   10331         else start = 0;
   10332         int end = label.length();
   10333         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
   10334             if (DUMP_MEM_BUCKETS[i] >= memKB) {
   10335                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
   10336                 out.append(bucket);
   10337                 out.append(stackLike ? "MB." : "MB ");
   10338                 out.append(label, start, end);
   10339                 return;
   10340             }
   10341         }
   10342         out.append(memKB/1024);
   10343         out.append(stackLike ? "MB." : "MB ");
   10344         out.append(label, start, end);
   10345     }
   10346 
   10347     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
   10348             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
   10349             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
   10350             ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
   10351             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
   10352     };
   10353     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
   10354             "System", "Persistent", "Foreground",
   10355             "Visible", "Perceptible", "Heavy Weight",
   10356             "Backup", "A Services", "Home", "Previous",
   10357             "B Services", "Background"
   10358     };
   10359 
   10360     final void dumpApplicationMemoryUsage(FileDescriptor fd,
   10361             PrintWriter pw, String prefix, String[] args, boolean brief,
   10362             PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
   10363         boolean dumpAll = false;
   10364         boolean oomOnly = false;
   10365 
   10366         int opti = 0;
   10367         while (opti < args.length) {
   10368             String opt = args[opti];
   10369             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   10370                 break;
   10371             }
   10372             opti++;
   10373             if ("-a".equals(opt)) {
   10374                 dumpAll = true;
   10375             } else if ("--oom".equals(opt)) {
   10376                 oomOnly = true;
   10377             } else if ("-h".equals(opt)) {
   10378                 pw.println("meminfo dump options: [-a] [--oom] [process]");
   10379                 pw.println("  -a: include all available information for each process.");
   10380                 pw.println("  --oom: only show processes organized by oom adj.");
   10381                 pw.println("If [process] is specified it can be the name or ");
   10382                 pw.println("pid of a specific process to dump.");
   10383                 return;
   10384             } else {
   10385                 pw.println("Unknown argument: " + opt + "; use -h for help");
   10386             }
   10387         }
   10388 
   10389         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
   10390         if (procs == null) {
   10391             return;
   10392         }
   10393 
   10394         final boolean isCheckinRequest = scanArgs(args, "--checkin");
   10395         long uptime = SystemClock.uptimeMillis();
   10396         long realtime = SystemClock.elapsedRealtime();
   10397 
   10398         if (procs.size() == 1 || isCheckinRequest) {
   10399             dumpAll = true;
   10400         }
   10401 
   10402         if (isCheckinRequest) {
   10403             // short checkin version
   10404             pw.println(uptime + "," + realtime);
   10405             pw.flush();
   10406         } else {
   10407             pw.println("Applications Memory Usage (kB):");
   10408             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   10409         }
   10410 
   10411         String[] innerArgs = new String[args.length-opti];
   10412         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
   10413 
   10414         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
   10415         long nativePss=0, dalvikPss=0, otherPss=0;
   10416         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
   10417 
   10418         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
   10419         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
   10420                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
   10421 
   10422         long totalPss = 0;
   10423 
   10424         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   10425             ProcessRecord r = procs.get(i);
   10426             if (r.thread != null) {
   10427                 if (!isCheckinRequest && dumpAll) {
   10428                     pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
   10429                     pw.flush();
   10430                 }
   10431                 Debug.MemoryInfo mi = null;
   10432                 if (dumpAll) {
   10433                     try {
   10434                         mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
   10435                     } catch (RemoteException e) {
   10436                         if (!isCheckinRequest) {
   10437                             pw.println("Got RemoteException!");
   10438                             pw.flush();
   10439                         }
   10440                     }
   10441                 } else {
   10442                     mi = new Debug.MemoryInfo();
   10443                     Debug.getMemoryInfo(r.pid, mi);
   10444                 }
   10445 
   10446                 if (!isCheckinRequest && mi != null) {
   10447                     long myTotalPss = mi.getTotalPss();
   10448                     totalPss += myTotalPss;
   10449                     MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
   10450                             r.processName, myTotalPss, 0);
   10451                     procMems.add(pssItem);
   10452 
   10453                     nativePss += mi.nativePss;
   10454                     dalvikPss += mi.dalvikPss;
   10455                     otherPss += mi.otherPss;
   10456                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   10457                         long mem = mi.getOtherPss(j);
   10458                         miscPss[j] += mem;
   10459                         otherPss -= mem;
   10460                     }
   10461 
   10462                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
   10463                         if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
   10464                                 || oomIndex == (oomPss.length-1)) {
   10465                             oomPss[oomIndex] += myTotalPss;
   10466                             if (oomProcs[oomIndex] == null) {
   10467                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
   10468                             }
   10469                             oomProcs[oomIndex].add(pssItem);
   10470                             break;
   10471                         }
   10472                     }
   10473                 }
   10474             }
   10475         }
   10476 
   10477         if (!isCheckinRequest && procs.size() > 1) {
   10478             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
   10479 
   10480             catMems.add(new MemItem("Native", "Native", nativePss, -1));
   10481             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
   10482             catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
   10483             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   10484                 String label = Debug.MemoryInfo.getOtherLabel(j);
   10485                 catMems.add(new MemItem(label, label, miscPss[j], j));
   10486             }
   10487 
   10488             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
   10489             for (int j=0; j<oomPss.length; j++) {
   10490                 if (oomPss[j] != 0) {
   10491                     String label = DUMP_MEM_OOM_LABEL[j];
   10492                     MemItem item = new MemItem(label, label, oomPss[j],
   10493                             DUMP_MEM_OOM_ADJ[j]);
   10494                     item.subitems = oomProcs[j];
   10495                     oomMems.add(item);
   10496                 }
   10497             }
   10498 
   10499             if (outTag != null || outStack != null) {
   10500                 if (outTag != null) {
   10501                     appendMemBucket(outTag, totalPss, "total", false);
   10502                 }
   10503                 if (outStack != null) {
   10504                     appendMemBucket(outStack, totalPss, "total", true);
   10505                 }
   10506                 boolean firstLine = true;
   10507                 for (int i=0; i<oomMems.size(); i++) {
   10508                     MemItem miCat = oomMems.get(i);
   10509                     if (miCat.subitems == null || miCat.subitems.size() < 1) {
   10510                         continue;
   10511                     }
   10512                     if (miCat.id < ProcessList.SERVICE_ADJ
   10513                             || miCat.id == ProcessList.HOME_APP_ADJ
   10514                             || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
   10515                         if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
   10516                             outTag.append(" / ");
   10517                         }
   10518                         if (outStack != null) {
   10519                             if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
   10520                                 if (firstLine) {
   10521                                     outStack.append(":");
   10522                                     firstLine = false;
   10523                                 }
   10524                                 outStack.append("\n\t at ");
   10525                             } else {
   10526                                 outStack.append("$");
   10527                             }
   10528                         }
   10529                         for (int j=0; j<miCat.subitems.size(); j++) {
   10530                             MemItem mi = miCat.subitems.get(j);
   10531                             if (j > 0) {
   10532                                 if (outTag != null) {
   10533                                     outTag.append(" ");
   10534                                 }
   10535                                 if (outStack != null) {
   10536                                     outStack.append("$");
   10537                                 }
   10538                             }
   10539                             if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
   10540                                 appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
   10541                             }
   10542                             if (outStack != null) {
   10543                                 appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
   10544                             }
   10545                         }
   10546                         if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
   10547                             outStack.append("(");
   10548                             for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
   10549                                 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
   10550                                     outStack.append(DUMP_MEM_OOM_LABEL[k]);
   10551                                     outStack.append(":");
   10552                                     outStack.append(DUMP_MEM_OOM_ADJ[k]);
   10553                                 }
   10554                             }
   10555                             outStack.append(")");
   10556                         }
   10557                     }
   10558                 }
   10559             }
   10560 
   10561             if (!brief && !oomOnly) {
   10562                 pw.println();
   10563                 pw.println("Total PSS by process:");
   10564                 dumpMemItems(pw, "  ", procMems, true);
   10565                 pw.println();
   10566             }
   10567             pw.println("Total PSS by OOM adjustment:");
   10568             dumpMemItems(pw, "  ", oomMems, false);
   10569             if (!oomOnly) {
   10570                 PrintWriter out = categoryPw != null ? categoryPw : pw;
   10571                 out.println();
   10572                 out.println("Total PSS by category:");
   10573                 dumpMemItems(out, "  ", catMems, true);
   10574             }
   10575             pw.println();
   10576             pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
   10577             final int[] SINGLE_LONG_FORMAT = new int[] {
   10578                 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
   10579             };
   10580             long[] longOut = new long[1];
   10581             Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
   10582                     SINGLE_LONG_FORMAT, null, longOut, null);
   10583             long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   10584             longOut[0] = 0;
   10585             Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
   10586                     SINGLE_LONG_FORMAT, null, longOut, null);
   10587             long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   10588             longOut[0] = 0;
   10589             Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
   10590                     SINGLE_LONG_FORMAT, null, longOut, null);
   10591             long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   10592             longOut[0] = 0;
   10593             Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
   10594                     SINGLE_LONG_FORMAT, null, longOut, null);
   10595             long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   10596             pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
   10597                     pw.print(shared); pw.println(" kB");
   10598             pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
   10599                     pw.print(voltile); pw.println(" kB volatile");
   10600         }
   10601     }
   10602 
   10603     /**
   10604      * Searches array of arguments for the specified string
   10605      * @param args array of argument strings
   10606      * @param value value to search for
   10607      * @return true if the value is contained in the array
   10608      */
   10609     private static boolean scanArgs(String[] args, String value) {
   10610         if (args != null) {
   10611             for (String arg : args) {
   10612                 if (value.equals(arg)) {
   10613                     return true;
   10614                 }
   10615             }
   10616         }
   10617         return false;
   10618     }
   10619 
   10620     private final boolean removeDyingProviderLocked(ProcessRecord proc,
   10621             ContentProviderRecord cpr, boolean always) {
   10622         final boolean inLaunching = mLaunchingProviders.contains(cpr);
   10623 
   10624         if (!inLaunching || always) {
   10625             synchronized (cpr) {
   10626                 cpr.launchingApp = null;
   10627                 cpr.notifyAll();
   10628             }
   10629             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
   10630             String names[] = cpr.info.authority.split(";");
   10631             for (int j = 0; j < names.length; j++) {
   10632                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
   10633             }
   10634         }
   10635 
   10636         for (int i=0; i<cpr.connections.size(); i++) {
   10637             ContentProviderConnection conn = cpr.connections.get(i);
   10638             if (conn.waiting) {
   10639                 // If this connection is waiting for the provider, then we don't
   10640                 // need to mess with its process unless we are always removing
   10641                 // or for some reason the provider is not currently launching.
   10642                 if (inLaunching && !always) {
   10643                     continue;
   10644                 }
   10645             }
   10646             ProcessRecord capp = conn.client;
   10647             conn.dead = true;
   10648             if (conn.stableCount > 0) {
   10649                 if (!capp.persistent && capp.thread != null
   10650                         && capp.pid != 0
   10651                         && capp.pid != MY_PID) {
   10652                     Slog.i(TAG, "Kill " + capp.processName
   10653                             + " (pid " + capp.pid + "): provider " + cpr.info.name
   10654                             + " in dying process " + (proc != null ? proc.processName : "??"));
   10655                     EventLog.writeEvent(EventLogTags.AM_KILL, capp.userId, capp.pid,
   10656                             capp.processName, capp.setAdj, "dying provider "
   10657                                     + cpr.name.toShortString());
   10658                     Process.killProcessQuiet(capp.pid);
   10659                 }
   10660             } else if (capp.thread != null && conn.provider.provider != null) {
   10661                 try {
   10662                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
   10663                 } catch (RemoteException e) {
   10664                 }
   10665                 // In the protocol here, we don't expect the client to correctly
   10666                 // clean up this connection, we'll just remove it.
   10667                 cpr.connections.remove(i);
   10668                 conn.client.conProviders.remove(conn);
   10669             }
   10670         }
   10671 
   10672         if (inLaunching && always) {
   10673             mLaunchingProviders.remove(cpr);
   10674         }
   10675         return inLaunching;
   10676     }
   10677 
   10678     /**
   10679      * Main code for cleaning up a process when it has gone away.  This is
   10680      * called both as a result of the process dying, or directly when stopping
   10681      * a process when running in single process mode.
   10682      */
   10683     private final void cleanUpApplicationRecordLocked(ProcessRecord app,
   10684             boolean restarting, boolean allowRestart, int index) {
   10685         if (index >= 0) {
   10686             mLruProcesses.remove(index);
   10687         }
   10688 
   10689         mProcessesToGc.remove(app);
   10690 
   10691         // Dismiss any open dialogs.
   10692         if (app.crashDialog != null) {
   10693             app.crashDialog.dismiss();
   10694             app.crashDialog = null;
   10695         }
   10696         if (app.anrDialog != null) {
   10697             app.anrDialog.dismiss();
   10698             app.anrDialog = null;
   10699         }
   10700         if (app.waitDialog != null) {
   10701             app.waitDialog.dismiss();
   10702             app.waitDialog = null;
   10703         }
   10704 
   10705         app.crashing = false;
   10706         app.notResponding = false;
   10707 
   10708         app.resetPackageList();
   10709         app.unlinkDeathRecipient();
   10710         app.thread = null;
   10711         app.forcingToForeground = null;
   10712         app.foregroundServices = false;
   10713         app.foregroundActivities = false;
   10714         app.hasShownUi = false;
   10715         app.hasAboveClient = false;
   10716 
   10717         mServices.killServicesLocked(app, allowRestart);
   10718 
   10719         boolean restart = false;
   10720 
   10721         // Remove published content providers.
   10722         if (!app.pubProviders.isEmpty()) {
   10723             Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
   10724             while (it.hasNext()) {
   10725                 ContentProviderRecord cpr = it.next();
   10726 
   10727                 final boolean always = app.bad || !allowRestart;
   10728                 if (removeDyingProviderLocked(app, cpr, always) || always) {
   10729                     // We left the provider in the launching list, need to
   10730                     // restart it.
   10731                     restart = true;
   10732                 }
   10733 
   10734                 cpr.provider = null;
   10735                 cpr.proc = null;
   10736             }
   10737             app.pubProviders.clear();
   10738         }
   10739 
   10740         // Take care of any launching providers waiting for this process.
   10741         if (checkAppInLaunchingProvidersLocked(app, false)) {
   10742             restart = true;
   10743         }
   10744 
   10745         // Unregister from connected content providers.
   10746         if (!app.conProviders.isEmpty()) {
   10747             for (int i=0; i<app.conProviders.size(); i++) {
   10748                 ContentProviderConnection conn = app.conProviders.get(i);
   10749                 conn.provider.connections.remove(conn);
   10750             }
   10751             app.conProviders.clear();
   10752         }
   10753 
   10754         // At this point there may be remaining entries in mLaunchingProviders
   10755         // where we were the only one waiting, so they are no longer of use.
   10756         // Look for these and clean up if found.
   10757         // XXX Commented out for now.  Trying to figure out a way to reproduce
   10758         // the actual situation to identify what is actually going on.
   10759         if (false) {
   10760             for (int i=0; i<mLaunchingProviders.size(); i++) {
   10761                 ContentProviderRecord cpr = (ContentProviderRecord)
   10762                         mLaunchingProviders.get(i);
   10763                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
   10764                     synchronized (cpr) {
   10765                         cpr.launchingApp = null;
   10766                         cpr.notifyAll();
   10767                     }
   10768                 }
   10769             }
   10770         }
   10771 
   10772         skipCurrentReceiverLocked(app);
   10773 
   10774         // Unregister any receivers.
   10775         if (app.receivers.size() > 0) {
   10776             Iterator<ReceiverList> it = app.receivers.iterator();
   10777             while (it.hasNext()) {
   10778                 removeReceiverLocked(it.next());
   10779             }
   10780             app.receivers.clear();
   10781         }
   10782 
   10783         // If the app is undergoing backup, tell the backup manager about it
   10784         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
   10785             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
   10786                     + mBackupTarget.appInfo + " died during backup");
   10787             try {
   10788                 IBackupManager bm = IBackupManager.Stub.asInterface(
   10789                         ServiceManager.getService(Context.BACKUP_SERVICE));
   10790                 bm.agentDisconnected(app.info.packageName);
   10791             } catch (RemoteException e) {
   10792                 // can't happen; backup manager is local
   10793             }
   10794         }
   10795 
   10796         for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
   10797             ProcessChangeItem item = mPendingProcessChanges.get(i);
   10798             if (item.pid == app.pid) {
   10799                 mPendingProcessChanges.remove(i);
   10800                 mAvailProcessChanges.add(item);
   10801             }
   10802         }
   10803         mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
   10804 
   10805         // If the caller is restarting this app, then leave it in its
   10806         // current lists and let the caller take care of it.
   10807         if (restarting) {
   10808             return;
   10809         }
   10810 
   10811         if (!app.persistent || app.isolated) {
   10812             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
   10813                     "Removing non-persistent process during cleanup: " + app);
   10814             mProcessNames.remove(app.processName, app.uid);
   10815             mIsolatedProcesses.remove(app.uid);
   10816             if (mHeavyWeightProcess == app) {
   10817                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   10818                         mHeavyWeightProcess.userId, 0));
   10819                 mHeavyWeightProcess = null;
   10820             }
   10821         } else if (!app.removed) {
   10822             // This app is persistent, so we need to keep its record around.
   10823             // If it is not already on the pending app list, add it there
   10824             // and start a new process for it.
   10825             if (mPersistentStartingProcesses.indexOf(app) < 0) {
   10826                 mPersistentStartingProcesses.add(app);
   10827                 restart = true;
   10828             }
   10829         }
   10830         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
   10831                 "Clean-up removing on hold: " + app);
   10832         mProcessesOnHold.remove(app);
   10833 
   10834         if (app == mHomeProcess) {
   10835             mHomeProcess = null;
   10836         }
   10837         if (app == mPreviousProcess) {
   10838             mPreviousProcess = null;
   10839         }
   10840 
   10841         if (restart && !app.isolated) {
   10842             // We have components that still need to be running in the
   10843             // process, so re-launch it.
   10844             mProcessNames.put(app.processName, app.uid, app);
   10845             startProcessLocked(app, "restart", app.processName);
   10846         } else if (app.pid > 0 && app.pid != MY_PID) {
   10847             // Goodbye!
   10848             synchronized (mPidsSelfLocked) {
   10849                 mPidsSelfLocked.remove(app.pid);
   10850                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   10851             }
   10852             app.setPid(0);
   10853         }
   10854     }
   10855 
   10856     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
   10857         // Look through the content providers we are waiting to have launched,
   10858         // and if any run in this process then either schedule a restart of
   10859         // the process or kill the client waiting for it if this process has
   10860         // gone bad.
   10861         int NL = mLaunchingProviders.size();
   10862         boolean restart = false;
   10863         for (int i=0; i<NL; i++) {
   10864             ContentProviderRecord cpr = mLaunchingProviders.get(i);
   10865             if (cpr.launchingApp == app) {
   10866                 if (!alwaysBad && !app.bad) {
   10867                     restart = true;
   10868                 } else {
   10869                     removeDyingProviderLocked(app, cpr, true);
   10870                     // cpr should have been removed from mLaunchingProviders
   10871                     NL = mLaunchingProviders.size();
   10872                     i--;
   10873                 }
   10874             }
   10875         }
   10876         return restart;
   10877     }
   10878 
   10879     // =========================================================
   10880     // SERVICES
   10881     // =========================================================
   10882 
   10883     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
   10884             int flags) {
   10885         enforceNotIsolatedCaller("getServices");
   10886         synchronized (this) {
   10887             return mServices.getRunningServiceInfoLocked(maxNum, flags);
   10888         }
   10889     }
   10890 
   10891     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
   10892         enforceNotIsolatedCaller("getRunningServiceControlPanel");
   10893         synchronized (this) {
   10894             return mServices.getRunningServiceControlPanelLocked(name);
   10895         }
   10896     }
   10897 
   10898     public ComponentName startService(IApplicationThread caller, Intent service,
   10899             String resolvedType, int userId) {
   10900         enforceNotIsolatedCaller("startService");
   10901         // Refuse possible leaked file descriptors
   10902         if (service != null && service.hasFileDescriptors() == true) {
   10903             throw new IllegalArgumentException("File descriptors passed in Intent");
   10904         }
   10905 
   10906         if (DEBUG_SERVICE)
   10907             Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
   10908         synchronized(this) {
   10909             final int callingPid = Binder.getCallingPid();
   10910             final int callingUid = Binder.getCallingUid();
   10911             checkValidCaller(callingUid, userId);
   10912             final long origId = Binder.clearCallingIdentity();
   10913             ComponentName res = mServices.startServiceLocked(caller, service,
   10914                     resolvedType, callingPid, callingUid, userId);
   10915             Binder.restoreCallingIdentity(origId);
   10916             return res;
   10917         }
   10918     }
   10919 
   10920     ComponentName startServiceInPackage(int uid,
   10921             Intent service, String resolvedType, int userId) {
   10922         synchronized(this) {
   10923             if (DEBUG_SERVICE)
   10924                 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
   10925             final long origId = Binder.clearCallingIdentity();
   10926             ComponentName res = mServices.startServiceLocked(null, service,
   10927                     resolvedType, -1, uid, userId);
   10928             Binder.restoreCallingIdentity(origId);
   10929             return res;
   10930         }
   10931     }
   10932 
   10933     public int stopService(IApplicationThread caller, Intent service,
   10934             String resolvedType, int userId) {
   10935         enforceNotIsolatedCaller("stopService");
   10936         // Refuse possible leaked file descriptors
   10937         if (service != null && service.hasFileDescriptors() == true) {
   10938             throw new IllegalArgumentException("File descriptors passed in Intent");
   10939         }
   10940 
   10941         checkValidCaller(Binder.getCallingUid(), userId);
   10942 
   10943         synchronized(this) {
   10944             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
   10945         }
   10946     }
   10947 
   10948     public IBinder peekService(Intent service, String resolvedType) {
   10949         enforceNotIsolatedCaller("peekService");
   10950         // Refuse possible leaked file descriptors
   10951         if (service != null && service.hasFileDescriptors() == true) {
   10952             throw new IllegalArgumentException("File descriptors passed in Intent");
   10953         }
   10954         synchronized(this) {
   10955             return mServices.peekServiceLocked(service, resolvedType);
   10956         }
   10957     }
   10958 
   10959     public boolean stopServiceToken(ComponentName className, IBinder token,
   10960             int startId) {
   10961         synchronized(this) {
   10962             return mServices.stopServiceTokenLocked(className, token, startId);
   10963         }
   10964     }
   10965 
   10966     public void setServiceForeground(ComponentName className, IBinder token,
   10967             int id, Notification notification, boolean removeNotification) {
   10968         synchronized(this) {
   10969             mServices.setServiceForegroundLocked(className, token, id, notification,
   10970                     removeNotification);
   10971         }
   10972     }
   10973 
   10974     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
   10975             boolean requireFull, String name, String callerPackage) {
   10976         final int callingUserId = UserHandle.getUserId(callingUid);
   10977         if (callingUserId != userId) {
   10978             if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   10979                 if ((requireFull || checkComponentPermission(
   10980                         android.Manifest.permission.INTERACT_ACROSS_USERS,
   10981                         callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
   10982                         && checkComponentPermission(
   10983                                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   10984                                 callingPid, callingUid, -1, true)
   10985                                 != PackageManager.PERMISSION_GRANTED) {
   10986                     if (userId == UserHandle.USER_CURRENT_OR_SELF) {
   10987                         // In this case, they would like to just execute as their
   10988                         // owner user instead of failing.
   10989                         userId = callingUserId;
   10990                     } else {
   10991                         StringBuilder builder = new StringBuilder(128);
   10992                         builder.append("Permission Denial: ");
   10993                         builder.append(name);
   10994                         if (callerPackage != null) {
   10995                             builder.append(" from ");
   10996                             builder.append(callerPackage);
   10997                         }
   10998                         builder.append(" asks to run as user ");
   10999                         builder.append(userId);
   11000                         builder.append(" but is calling from user ");
   11001                         builder.append(UserHandle.getUserId(callingUid));
   11002                         builder.append("; this requires ");
   11003                         builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
   11004                         if (!requireFull) {
   11005                             builder.append(" or ");
   11006                             builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
   11007                         }
   11008                         String msg = builder.toString();
   11009                         Slog.w(TAG, msg);
   11010                         throw new SecurityException(msg);
   11011                     }
   11012                 }
   11013             }
   11014             if (userId == UserHandle.USER_CURRENT
   11015                     || userId == UserHandle.USER_CURRENT_OR_SELF) {
   11016                 // Note that we may be accessing this outside of a lock...
   11017                 // shouldn't be a big deal, if this is being called outside
   11018                 // of a locked context there is intrinsically a race with
   11019                 // the value the caller will receive and someone else changing it.
   11020                 userId = mCurrentUserId;
   11021             }
   11022             if (!allowAll && userId < 0) {
   11023                 throw new IllegalArgumentException(
   11024                         "Call does not support special user #" + userId);
   11025             }
   11026         }
   11027         return userId;
   11028     }
   11029 
   11030     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
   11031             String className, int flags) {
   11032         boolean result = false;
   11033         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
   11034             if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
   11035                 if (ActivityManager.checkUidPermission(
   11036                         android.Manifest.permission.INTERACT_ACROSS_USERS,
   11037                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
   11038                     ComponentName comp = new ComponentName(aInfo.packageName, className);
   11039                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
   11040                             + " requests FLAG_SINGLE_USER, but app does not hold "
   11041                             + android.Manifest.permission.INTERACT_ACROSS_USERS;
   11042                     Slog.w(TAG, msg);
   11043                     throw new SecurityException(msg);
   11044                 }
   11045                 result = true;
   11046             }
   11047         } else if (componentProcessName == aInfo.packageName) {
   11048             result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
   11049         } else if ("system".equals(componentProcessName)) {
   11050             result = true;
   11051         }
   11052         if (DEBUG_MU) {
   11053             Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
   11054                     + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
   11055         }
   11056         return result;
   11057     }
   11058 
   11059     public int bindService(IApplicationThread caller, IBinder token,
   11060             Intent service, String resolvedType,
   11061             IServiceConnection connection, int flags, int userId) {
   11062         enforceNotIsolatedCaller("bindService");
   11063         // Refuse possible leaked file descriptors
   11064         if (service != null && service.hasFileDescriptors() == true) {
   11065             throw new IllegalArgumentException("File descriptors passed in Intent");
   11066         }
   11067 
   11068         synchronized(this) {
   11069             return mServices.bindServiceLocked(caller, token, service, resolvedType,
   11070                     connection, flags, userId);
   11071         }
   11072     }
   11073 
   11074     public boolean unbindService(IServiceConnection connection) {
   11075         synchronized (this) {
   11076             return mServices.unbindServiceLocked(connection);
   11077         }
   11078     }
   11079 
   11080     public void publishService(IBinder token, Intent intent, IBinder service) {
   11081         // Refuse possible leaked file descriptors
   11082         if (intent != null && intent.hasFileDescriptors() == true) {
   11083             throw new IllegalArgumentException("File descriptors passed in Intent");
   11084         }
   11085 
   11086         synchronized(this) {
   11087             if (!(token instanceof ServiceRecord)) {
   11088                 throw new IllegalArgumentException("Invalid service token");
   11089             }
   11090             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
   11091         }
   11092     }
   11093 
   11094     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
   11095         // Refuse possible leaked file descriptors
   11096         if (intent != null && intent.hasFileDescriptors() == true) {
   11097             throw new IllegalArgumentException("File descriptors passed in Intent");
   11098         }
   11099 
   11100         synchronized(this) {
   11101             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
   11102         }
   11103     }
   11104 
   11105     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
   11106         synchronized(this) {
   11107             if (!(token instanceof ServiceRecord)) {
   11108                 throw new IllegalArgumentException("Invalid service token");
   11109             }
   11110             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
   11111         }
   11112     }
   11113 
   11114     // =========================================================
   11115     // BACKUP AND RESTORE
   11116     // =========================================================
   11117 
   11118     // Cause the target app to be launched if necessary and its backup agent
   11119     // instantiated.  The backup agent will invoke backupAgentCreated() on the
   11120     // activity manager to announce its creation.
   11121     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
   11122         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
   11123         enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
   11124 
   11125         synchronized(this) {
   11126             // !!! TODO: currently no check here that we're already bound
   11127             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   11128             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   11129             synchronized (stats) {
   11130                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
   11131             }
   11132 
   11133             // Backup agent is now in use, its package can't be stopped.
   11134             try {
   11135                 AppGlobals.getPackageManager().setPackageStoppedState(
   11136                         app.packageName, false, UserHandle.getUserId(app.uid));
   11137             } catch (RemoteException e) {
   11138             } catch (IllegalArgumentException e) {
   11139                 Slog.w(TAG, "Failed trying to unstop package "
   11140                         + app.packageName + ": " + e);
   11141             }
   11142 
   11143             BackupRecord r = new BackupRecord(ss, app, backupMode);
   11144             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
   11145                     ? new ComponentName(app.packageName, app.backupAgentName)
   11146                     : new ComponentName("android", "FullBackupAgent");
   11147             // startProcessLocked() returns existing proc's record if it's already running
   11148             ProcessRecord proc = startProcessLocked(app.processName, app,
   11149                     false, 0, "backup", hostingName, false, false);
   11150             if (proc == null) {
   11151                 Slog.e(TAG, "Unable to start backup agent process " + r);
   11152                 return false;
   11153             }
   11154 
   11155             r.app = proc;
   11156             mBackupTarget = r;
   11157             mBackupAppName = app.packageName;
   11158 
   11159             // Try not to kill the process during backup
   11160             updateOomAdjLocked(proc);
   11161 
   11162             // If the process is already attached, schedule the creation of the backup agent now.
   11163             // If it is not yet live, this will be done when it attaches to the framework.
   11164             if (proc.thread != null) {
   11165                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
   11166                 try {
   11167                     proc.thread.scheduleCreateBackupAgent(app,
   11168                             compatibilityInfoForPackageLocked(app), backupMode);
   11169                 } catch (RemoteException e) {
   11170                     // Will time out on the backup manager side
   11171                 }
   11172             } else {
   11173                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
   11174             }
   11175             // Invariants: at this point, the target app process exists and the application
   11176             // is either already running or in the process of coming up.  mBackupTarget and
   11177             // mBackupAppName describe the app, so that when it binds back to the AM we
   11178             // know that it's scheduled for a backup-agent operation.
   11179         }
   11180 
   11181         return true;
   11182     }
   11183 
   11184     @Override
   11185     public void clearPendingBackup() {
   11186         if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
   11187         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
   11188 
   11189         synchronized (this) {
   11190             mBackupTarget = null;
   11191             mBackupAppName = null;
   11192         }
   11193     }
   11194 
   11195     // A backup agent has just come up
   11196     public void backupAgentCreated(String agentPackageName, IBinder agent) {
   11197         if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
   11198                 + " = " + agent);
   11199 
   11200         synchronized(this) {
   11201             if (!agentPackageName.equals(mBackupAppName)) {
   11202                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
   11203                 return;
   11204             }
   11205         }
   11206 
   11207         long oldIdent = Binder.clearCallingIdentity();
   11208         try {
   11209             IBackupManager bm = IBackupManager.Stub.asInterface(
   11210                     ServiceManager.getService(Context.BACKUP_SERVICE));
   11211             bm.agentConnected(agentPackageName, agent);
   11212         } catch (RemoteException e) {
   11213             // can't happen; the backup manager service is local
   11214         } catch (Exception e) {
   11215             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
   11216             e.printStackTrace();
   11217         } finally {
   11218             Binder.restoreCallingIdentity(oldIdent);
   11219         }
   11220     }
   11221 
   11222     // done with this agent
   11223     public void unbindBackupAgent(ApplicationInfo appInfo) {
   11224         if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
   11225         if (appInfo == null) {
   11226             Slog.w(TAG, "unbind backup agent for null app");
   11227             return;
   11228         }
   11229 
   11230         synchronized(this) {
   11231             try {
   11232                 if (mBackupAppName == null) {
   11233                     Slog.w(TAG, "Unbinding backup agent with no active backup");
   11234                     return;
   11235                 }
   11236 
   11237                 if (!mBackupAppName.equals(appInfo.packageName)) {
   11238                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
   11239                     return;
   11240                 }
   11241 
   11242                 // Not backing this app up any more; reset its OOM adjustment
   11243                 final ProcessRecord proc = mBackupTarget.app;
   11244                 updateOomAdjLocked(proc);
   11245 
   11246                 // If the app crashed during backup, 'thread' will be null here
   11247                 if (proc.thread != null) {
   11248                     try {
   11249                         proc.thread.scheduleDestroyBackupAgent(appInfo,
   11250                                 compatibilityInfoForPackageLocked(appInfo));
   11251                     } catch (Exception e) {
   11252                         Slog.e(TAG, "Exception when unbinding backup agent:");
   11253                         e.printStackTrace();
   11254                     }
   11255                 }
   11256             } finally {
   11257                 mBackupTarget = null;
   11258                 mBackupAppName = null;
   11259             }
   11260         }
   11261     }
   11262     // =========================================================
   11263     // BROADCASTS
   11264     // =========================================================
   11265 
   11266     private final List getStickiesLocked(String action, IntentFilter filter,
   11267             List cur, int userId) {
   11268         final ContentResolver resolver = mContext.getContentResolver();
   11269         HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   11270         if (stickies == null) {
   11271             return cur;
   11272         }
   11273         final ArrayList<Intent> list = stickies.get(action);
   11274         if (list == null) {
   11275             return cur;
   11276         }
   11277         int N = list.size();
   11278         for (int i=0; i<N; i++) {
   11279             Intent intent = list.get(i);
   11280             if (filter.match(resolver, intent, true, TAG) >= 0) {
   11281                 if (cur == null) {
   11282                     cur = new ArrayList<Intent>();
   11283                 }
   11284                 cur.add(intent);
   11285             }
   11286         }
   11287         return cur;
   11288     }
   11289 
   11290     boolean isPendingBroadcastProcessLocked(int pid) {
   11291         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
   11292                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
   11293     }
   11294 
   11295     void skipPendingBroadcastLocked(int pid) {
   11296             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   11297             for (BroadcastQueue queue : mBroadcastQueues) {
   11298                 queue.skipPendingBroadcastLocked(pid);
   11299             }
   11300     }
   11301 
   11302     // The app just attached; send any pending broadcasts that it should receive
   11303     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
   11304         boolean didSomething = false;
   11305         for (BroadcastQueue queue : mBroadcastQueues) {
   11306             didSomething |= queue.sendPendingBroadcastsLocked(app);
   11307         }
   11308         return didSomething;
   11309     }
   11310 
   11311     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
   11312             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
   11313         enforceNotIsolatedCaller("registerReceiver");
   11314         int callingUid;
   11315         int callingPid;
   11316         synchronized(this) {
   11317             ProcessRecord callerApp = null;
   11318             if (caller != null) {
   11319                 callerApp = getRecordForAppLocked(caller);
   11320                 if (callerApp == null) {
   11321                     throw new SecurityException(
   11322                             "Unable to find app for caller " + caller
   11323                             + " (pid=" + Binder.getCallingPid()
   11324                             + ") when registering receiver " + receiver);
   11325                 }
   11326                 if (callerApp.info.uid != Process.SYSTEM_UID &&
   11327                         !callerApp.pkgList.contains(callerPackage)) {
   11328                     throw new SecurityException("Given caller package " + callerPackage
   11329                             + " is not running in process " + callerApp);
   11330                 }
   11331                 callingUid = callerApp.info.uid;
   11332                 callingPid = callerApp.pid;
   11333             } else {
   11334                 callerPackage = null;
   11335                 callingUid = Binder.getCallingUid();
   11336                 callingPid = Binder.getCallingPid();
   11337             }
   11338 
   11339             userId = this.handleIncomingUser(callingPid, callingUid, userId,
   11340                     true, true, "registerReceiver", callerPackage);
   11341 
   11342             List allSticky = null;
   11343 
   11344             // Look for any matching sticky broadcasts...
   11345             Iterator actions = filter.actionsIterator();
   11346             if (actions != null) {
   11347                 while (actions.hasNext()) {
   11348                     String action = (String)actions.next();
   11349                     allSticky = getStickiesLocked(action, filter, allSticky,
   11350                             UserHandle.USER_ALL);
   11351                     allSticky = getStickiesLocked(action, filter, allSticky,
   11352                             UserHandle.getUserId(callingUid));
   11353                 }
   11354             } else {
   11355                 allSticky = getStickiesLocked(null, filter, allSticky,
   11356                         UserHandle.USER_ALL);
   11357                 allSticky = getStickiesLocked(null, filter, allSticky,
   11358                         UserHandle.getUserId(callingUid));
   11359             }
   11360 
   11361             // The first sticky in the list is returned directly back to
   11362             // the client.
   11363             Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
   11364 
   11365             if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
   11366                     + ": " + sticky);
   11367 
   11368             if (receiver == null) {
   11369                 return sticky;
   11370             }
   11371 
   11372             ReceiverList rl
   11373                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   11374             if (rl == null) {
   11375                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
   11376                         userId, receiver);
   11377                 if (rl.app != null) {
   11378                     rl.app.receivers.add(rl);
   11379                 } else {
   11380                     try {
   11381                         receiver.asBinder().linkToDeath(rl, 0);
   11382                     } catch (RemoteException e) {
   11383                         return sticky;
   11384                     }
   11385                     rl.linkedToDeath = true;
   11386                 }
   11387                 mRegisteredReceivers.put(receiver.asBinder(), rl);
   11388             } else if (rl.uid != callingUid) {
   11389                 throw new IllegalArgumentException(
   11390                         "Receiver requested to register for uid " + callingUid
   11391                         + " was previously registered for uid " + rl.uid);
   11392             } else if (rl.pid != callingPid) {
   11393                 throw new IllegalArgumentException(
   11394                         "Receiver requested to register for pid " + callingPid
   11395                         + " was previously registered for pid " + rl.pid);
   11396             } else if (rl.userId != userId) {
   11397                 throw new IllegalArgumentException(
   11398                         "Receiver requested to register for user " + userId
   11399                         + " was previously registered for user " + rl.userId);
   11400             }
   11401             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
   11402                     permission, callingUid, userId);
   11403             rl.add(bf);
   11404             if (!bf.debugCheck()) {
   11405                 Slog.w(TAG, "==> For Dynamic broadast");
   11406             }
   11407             mReceiverResolver.addFilter(bf);
   11408 
   11409             // Enqueue broadcasts for all existing stickies that match
   11410             // this filter.
   11411             if (allSticky != null) {
   11412                 ArrayList receivers = new ArrayList();
   11413                 receivers.add(bf);
   11414 
   11415                 int N = allSticky.size();
   11416                 for (int i=0; i<N; i++) {
   11417                     Intent intent = (Intent)allSticky.get(i);
   11418                     BroadcastQueue queue = broadcastQueueForIntent(intent);
   11419                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
   11420                             null, -1, -1, null, receivers, null, 0, null, null,
   11421                             false, true, true, -1);
   11422                     queue.enqueueParallelBroadcastLocked(r);
   11423                     queue.scheduleBroadcastsLocked();
   11424                 }
   11425             }
   11426 
   11427             return sticky;
   11428         }
   11429     }
   11430 
   11431     public void unregisterReceiver(IIntentReceiver receiver) {
   11432         if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
   11433 
   11434         final long origId = Binder.clearCallingIdentity();
   11435         try {
   11436             boolean doTrim = false;
   11437 
   11438             synchronized(this) {
   11439                 ReceiverList rl
   11440                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   11441                 if (rl != null) {
   11442                     if (rl.curBroadcast != null) {
   11443                         BroadcastRecord r = rl.curBroadcast;
   11444                         final boolean doNext = finishReceiverLocked(
   11445                                 receiver.asBinder(), r.resultCode, r.resultData,
   11446                                 r.resultExtras, r.resultAbort, true);
   11447                         if (doNext) {
   11448                             doTrim = true;
   11449                             r.queue.processNextBroadcast(false);
   11450                         }
   11451                     }
   11452 
   11453                     if (rl.app != null) {
   11454                         rl.app.receivers.remove(rl);
   11455                     }
   11456                     removeReceiverLocked(rl);
   11457                     if (rl.linkedToDeath) {
   11458                         rl.linkedToDeath = false;
   11459                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
   11460                     }
   11461                 }
   11462             }
   11463 
   11464             // If we actually concluded any broadcasts, we might now be able
   11465             // to trim the recipients' apps from our working set
   11466             if (doTrim) {
   11467                 trimApplications();
   11468                 return;
   11469             }
   11470 
   11471         } finally {
   11472             Binder.restoreCallingIdentity(origId);
   11473         }
   11474     }
   11475 
   11476     void removeReceiverLocked(ReceiverList rl) {
   11477         mRegisteredReceivers.remove(rl.receiver.asBinder());
   11478         int N = rl.size();
   11479         for (int i=0; i<N; i++) {
   11480             mReceiverResolver.removeFilter(rl.get(i));
   11481         }
   11482     }
   11483 
   11484     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
   11485         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   11486             ProcessRecord r = mLruProcesses.get(i);
   11487             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
   11488                 try {
   11489                     r.thread.dispatchPackageBroadcast(cmd, packages);
   11490                 } catch (RemoteException ex) {
   11491                 }
   11492             }
   11493         }
   11494     }
   11495 
   11496     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
   11497             int[] users) {
   11498         List<ResolveInfo> receivers = null;
   11499         try {
   11500             HashSet<ComponentName> singleUserReceivers = null;
   11501             boolean scannedFirstReceivers = false;
   11502             for (int user : users) {
   11503                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
   11504                         .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
   11505                 if (user != 0 && newReceivers != null) {
   11506                     // If this is not the primary user, we need to check for
   11507                     // any receivers that should be filtered out.
   11508                     for (int i=0; i<newReceivers.size(); i++) {
   11509                         ResolveInfo ri = newReceivers.get(i);
   11510                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
   11511                             newReceivers.remove(i);
   11512                             i--;
   11513                         }
   11514                     }
   11515                 }
   11516                 if (newReceivers != null && newReceivers.size() == 0) {
   11517                     newReceivers = null;
   11518                 }
   11519                 if (receivers == null) {
   11520                     receivers = newReceivers;
   11521                 } else if (newReceivers != null) {
   11522                     // We need to concatenate the additional receivers
   11523                     // found with what we have do far.  This would be easy,
   11524                     // but we also need to de-dup any receivers that are
   11525                     // singleUser.
   11526                     if (!scannedFirstReceivers) {
   11527                         // Collect any single user receivers we had already retrieved.
   11528                         scannedFirstReceivers = true;
   11529                         for (int i=0; i<receivers.size(); i++) {
   11530                             ResolveInfo ri = receivers.get(i);
   11531                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   11532                                 ComponentName cn = new ComponentName(
   11533                                         ri.activityInfo.packageName, ri.activityInfo.name);
   11534                                 if (singleUserReceivers == null) {
   11535                                     singleUserReceivers = new HashSet<ComponentName>();
   11536                                 }
   11537                                 singleUserReceivers.add(cn);
   11538                             }
   11539                         }
   11540                     }
   11541                     // Add the new results to the existing results, tracking
   11542                     // and de-dupping single user receivers.
   11543                     for (int i=0; i<newReceivers.size(); i++) {
   11544                         ResolveInfo ri = newReceivers.get(i);
   11545                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   11546                             ComponentName cn = new ComponentName(
   11547                                     ri.activityInfo.packageName, ri.activityInfo.name);
   11548                             if (singleUserReceivers == null) {
   11549                                 singleUserReceivers = new HashSet<ComponentName>();
   11550                             }
   11551                             if (!singleUserReceivers.contains(cn)) {
   11552                                 singleUserReceivers.add(cn);
   11553                                 receivers.add(ri);
   11554                             }
   11555                         } else {
   11556                             receivers.add(ri);
   11557                         }
   11558                     }
   11559                 }
   11560             }
   11561         } catch (RemoteException ex) {
   11562             // pm is in same process, this will never happen.
   11563         }
   11564         return receivers;
   11565     }
   11566 
   11567     private final int broadcastIntentLocked(ProcessRecord callerApp,
   11568             String callerPackage, Intent intent, String resolvedType,
   11569             IIntentReceiver resultTo, int resultCode, String resultData,
   11570             Bundle map, String requiredPermission,
   11571             boolean ordered, boolean sticky, int callingPid, int callingUid,
   11572             int userId) {
   11573         intent = new Intent(intent);
   11574 
   11575         // By default broadcasts do not go to stopped apps.
   11576         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
   11577 
   11578         if (DEBUG_BROADCAST_LIGHT) Slog.v(
   11579             TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
   11580             + " ordered=" + ordered + " userid=" + userId);
   11581         if ((resultTo != null) && !ordered) {
   11582             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
   11583         }
   11584 
   11585         userId = handleIncomingUser(callingPid, callingUid, userId,
   11586                 true, false, "broadcast", callerPackage);
   11587 
   11588         // Make sure that the user who is receiving this broadcast is started.
   11589         // If not, we will just skip it.
   11590         if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
   11591             if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
   11592                     & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
   11593                 Slog.w(TAG, "Skipping broadcast of " + intent
   11594                         + ": user " + userId + " is stopped");
   11595                 return ActivityManager.BROADCAST_SUCCESS;
   11596             }
   11597         }
   11598 
   11599         /*
   11600          * Prevent non-system code (defined here to be non-persistent
   11601          * processes) from sending protected broadcasts.
   11602          */
   11603         int callingAppId = UserHandle.getAppId(callingUid);
   11604         if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
   11605             || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
   11606             callingUid == 0) {
   11607             // Always okay.
   11608         } else if (callerApp == null || !callerApp.persistent) {
   11609             try {
   11610                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
   11611                         intent.getAction())) {
   11612                     String msg = "Permission Denial: not allowed to send broadcast "
   11613                             + intent.getAction() + " from pid="
   11614                             + callingPid + ", uid=" + callingUid;
   11615                     Slog.w(TAG, msg);
   11616                     throw new SecurityException(msg);
   11617                 }
   11618             } catch (RemoteException e) {
   11619                 Slog.w(TAG, "Remote exception", e);
   11620                 return ActivityManager.BROADCAST_SUCCESS;
   11621             }
   11622         }
   11623 
   11624         // Handle special intents: if this broadcast is from the package
   11625         // manager about a package being removed, we need to remove all of
   11626         // its activities from the history stack.
   11627         final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
   11628                 intent.getAction());
   11629         if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
   11630                 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
   11631                 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
   11632                 || uidRemoved) {
   11633             if (checkComponentPermission(
   11634                     android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
   11635                     callingPid, callingUid, -1, true)
   11636                     == PackageManager.PERMISSION_GRANTED) {
   11637                 if (uidRemoved) {
   11638                     final Bundle intentExtras = intent.getExtras();
   11639                     final int uid = intentExtras != null
   11640                             ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
   11641                     if (uid >= 0) {
   11642                         BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
   11643                         synchronized (bs) {
   11644                             bs.removeUidStatsLocked(uid);
   11645                         }
   11646                     }
   11647                 } else {
   11648                     // If resources are unavailable just force stop all
   11649                     // those packages and flush the attribute cache as well.
   11650                     if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
   11651                         String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   11652                         if (list != null && (list.length > 0)) {
   11653                             for (String pkg : list) {
   11654                                 forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
   11655                             }
   11656                             sendPackageBroadcastLocked(
   11657                                     IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
   11658                         }
   11659                     } else {
   11660                         Uri data = intent.getData();
   11661                         String ssp;
   11662                         if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   11663                             if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
   11664                                 forceStopPackageLocked(ssp,
   11665                                         intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
   11666                                         false, userId);
   11667                             }
   11668                             if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
   11669                                 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
   11670                                         new String[] {ssp}, userId);
   11671                             }
   11672                         }
   11673                     }
   11674                 }
   11675             } else {
   11676                 String msg = "Permission Denial: " + intent.getAction()
   11677                         + " broadcast from " + callerPackage + " (pid=" + callingPid
   11678                         + ", uid=" + callingUid + ")"
   11679                         + " requires "
   11680                         + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
   11681                 Slog.w(TAG, msg);
   11682                 throw new SecurityException(msg);
   11683             }
   11684 
   11685         // Special case for adding a package: by default turn on compatibility
   11686         // mode.
   11687         } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
   11688             Uri data = intent.getData();
   11689             String ssp;
   11690             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   11691                 mCompatModePackages.handlePackageAddedLocked(ssp,
   11692                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
   11693             }
   11694         }
   11695 
   11696         /*
   11697          * If this is the time zone changed action, queue up a message that will reset the timezone
   11698          * of all currently running processes. This message will get queued up before the broadcast
   11699          * happens.
   11700          */
   11701         if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
   11702             mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
   11703         }
   11704 
   11705         if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
   11706             mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
   11707         }
   11708 
   11709         if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
   11710             ProxyProperties proxy = intent.getParcelableExtra("proxy");
   11711             mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
   11712         }
   11713 
   11714         // Add to the sticky list if requested.
   11715         if (sticky) {
   11716             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
   11717                     callingPid, callingUid)
   11718                     != PackageManager.PERMISSION_GRANTED) {
   11719                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
   11720                         + callingPid + ", uid=" + callingUid
   11721                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   11722                 Slog.w(TAG, msg);
   11723                 throw new SecurityException(msg);
   11724             }
   11725             if (requiredPermission != null) {
   11726                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
   11727                         + " and enforce permission " + requiredPermission);
   11728                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
   11729             }
   11730             if (intent.getComponent() != null) {
   11731                 throw new SecurityException(
   11732                         "Sticky broadcasts can't target a specific component");
   11733             }
   11734             // We use userId directly here, since the "all" target is maintained
   11735             // as a separate set of sticky broadcasts.
   11736             if (userId != UserHandle.USER_ALL) {
   11737                 // But first, if this is not a broadcast to all users, then
   11738                 // make sure it doesn't conflict with an existing broadcast to
   11739                 // all users.
   11740                 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
   11741                         UserHandle.USER_ALL);
   11742                 if (stickies != null) {
   11743                     ArrayList<Intent> list = stickies.get(intent.getAction());
   11744                     if (list != null) {
   11745                         int N = list.size();
   11746                         int i;
   11747                         for (i=0; i<N; i++) {
   11748                             if (intent.filterEquals(list.get(i))) {
   11749                                 throw new IllegalArgumentException(
   11750                                         "Sticky broadcast " + intent + " for user "
   11751                                         + userId + " conflicts with existing global broadcast");
   11752                             }
   11753                         }
   11754                     }
   11755                 }
   11756             }
   11757             HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   11758             if (stickies == null) {
   11759                 stickies = new HashMap<String, ArrayList<Intent>>();
   11760                 mStickyBroadcasts.put(userId, stickies);
   11761             }
   11762             ArrayList<Intent> list = stickies.get(intent.getAction());
   11763             if (list == null) {
   11764                 list = new ArrayList<Intent>();
   11765                 stickies.put(intent.getAction(), list);
   11766             }
   11767             int N = list.size();
   11768             int i;
   11769             for (i=0; i<N; i++) {
   11770                 if (intent.filterEquals(list.get(i))) {
   11771                     // This sticky already exists, replace it.
   11772                     list.set(i, new Intent(intent));
   11773                     break;
   11774                 }
   11775             }
   11776             if (i >= N) {
   11777                 list.add(new Intent(intent));
   11778             }
   11779         }
   11780 
   11781         int[] users;
   11782         if (userId == UserHandle.USER_ALL) {
   11783             // Caller wants broadcast to go to all started users.
   11784             users = mStartedUserArray;
   11785         } else {
   11786             // Caller wants broadcast to go to one specific user.
   11787             users = new int[] {userId};
   11788         }
   11789 
   11790         // Figure out who all will receive this broadcast.
   11791         List receivers = null;
   11792         List<BroadcastFilter> registeredReceivers = null;
   11793         // Need to resolve the intent to interested receivers...
   11794         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
   11795                  == 0) {
   11796             receivers = collectReceiverComponents(intent, resolvedType, users);
   11797         }
   11798         if (intent.getComponent() == null) {
   11799             registeredReceivers = mReceiverResolver.queryIntent(intent,
   11800                     resolvedType, false, userId);
   11801         }
   11802 
   11803         final boolean replacePending =
   11804                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
   11805 
   11806         if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
   11807                 + " replacePending=" + replacePending);
   11808 
   11809         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
   11810         if (!ordered && NR > 0) {
   11811             // If we are not serializing this broadcast, then send the
   11812             // registered receivers separately so they don't wait for the
   11813             // components to be launched.
   11814             final BroadcastQueue queue = broadcastQueueForIntent(intent);
   11815             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   11816                     callerPackage, callingPid, callingUid, requiredPermission,
   11817                     registeredReceivers, resultTo, resultCode, resultData, map,
   11818                     ordered, sticky, false, userId);
   11819             if (DEBUG_BROADCAST) Slog.v(
   11820                     TAG, "Enqueueing parallel broadcast " + r);
   11821             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
   11822             if (!replaced) {
   11823                 queue.enqueueParallelBroadcastLocked(r);
   11824                 queue.scheduleBroadcastsLocked();
   11825             }
   11826             registeredReceivers = null;
   11827             NR = 0;
   11828         }
   11829 
   11830         // Merge into one list.
   11831         int ir = 0;
   11832         if (receivers != null) {
   11833             // A special case for PACKAGE_ADDED: do not allow the package
   11834             // being added to see this broadcast.  This prevents them from
   11835             // using this as a back door to get run as soon as they are
   11836             // installed.  Maybe in the future we want to have a special install
   11837             // broadcast or such for apps, but we'd like to deliberately make
   11838             // this decision.
   11839             String skipPackages[] = null;
   11840             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
   11841                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
   11842                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
   11843                 Uri data = intent.getData();
   11844                 if (data != null) {
   11845                     String pkgName = data.getSchemeSpecificPart();
   11846                     if (pkgName != null) {
   11847                         skipPackages = new String[] { pkgName };
   11848                     }
   11849                 }
   11850             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
   11851                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   11852             }
   11853             if (skipPackages != null && (skipPackages.length > 0)) {
   11854                 for (String skipPackage : skipPackages) {
   11855                     if (skipPackage != null) {
   11856                         int NT = receivers.size();
   11857                         for (int it=0; it<NT; it++) {
   11858                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
   11859                             if (curt.activityInfo.packageName.equals(skipPackage)) {
   11860                                 receivers.remove(it);
   11861                                 it--;
   11862                                 NT--;
   11863                             }
   11864                         }
   11865                     }
   11866                 }
   11867             }
   11868 
   11869             int NT = receivers != null ? receivers.size() : 0;
   11870             int it = 0;
   11871             ResolveInfo curt = null;
   11872             BroadcastFilter curr = null;
   11873             while (it < NT && ir < NR) {
   11874                 if (curt == null) {
   11875                     curt = (ResolveInfo)receivers.get(it);
   11876                 }
   11877                 if (curr == null) {
   11878                     curr = registeredReceivers.get(ir);
   11879                 }
   11880                 if (curr.getPriority() >= curt.priority) {
   11881                     // Insert this broadcast record into the final list.
   11882                     receivers.add(it, curr);
   11883                     ir++;
   11884                     curr = null;
   11885                     it++;
   11886                     NT++;
   11887                 } else {
   11888                     // Skip to the next ResolveInfo in the final list.
   11889                     it++;
   11890                     curt = null;
   11891                 }
   11892             }
   11893         }
   11894         while (ir < NR) {
   11895             if (receivers == null) {
   11896                 receivers = new ArrayList();
   11897             }
   11898             receivers.add(registeredReceivers.get(ir));
   11899             ir++;
   11900         }
   11901 
   11902         if ((receivers != null && receivers.size() > 0)
   11903                 || resultTo != null) {
   11904             BroadcastQueue queue = broadcastQueueForIntent(intent);
   11905             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   11906                     callerPackage, callingPid, callingUid, requiredPermission,
   11907                     receivers, resultTo, resultCode, resultData, map, ordered,
   11908                     sticky, false, userId);
   11909             if (DEBUG_BROADCAST) Slog.v(
   11910                     TAG, "Enqueueing ordered broadcast " + r
   11911                     + ": prev had " + queue.mOrderedBroadcasts.size());
   11912             if (DEBUG_BROADCAST) {
   11913                 int seq = r.intent.getIntExtra("seq", -1);
   11914                 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
   11915             }
   11916             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
   11917             if (!replaced) {
   11918                 queue.enqueueOrderedBroadcastLocked(r);
   11919                 queue.scheduleBroadcastsLocked();
   11920             }
   11921         }
   11922 
   11923         return ActivityManager.BROADCAST_SUCCESS;
   11924     }
   11925 
   11926     final Intent verifyBroadcastLocked(Intent intent) {
   11927         // Refuse possible leaked file descriptors
   11928         if (intent != null && intent.hasFileDescriptors() == true) {
   11929             throw new IllegalArgumentException("File descriptors passed in Intent");
   11930         }
   11931 
   11932         int flags = intent.getFlags();
   11933 
   11934         if (!mProcessesReady) {
   11935             // if the caller really truly claims to know what they're doing, go
   11936             // ahead and allow the broadcast without launching any receivers
   11937             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
   11938                 intent = new Intent(intent);
   11939                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   11940             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
   11941                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
   11942                         + " before boot completion");
   11943                 throw new IllegalStateException("Cannot broadcast before boot completed");
   11944             }
   11945         }
   11946 
   11947         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   11948             throw new IllegalArgumentException(
   11949                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   11950         }
   11951 
   11952         return intent;
   11953     }
   11954 
   11955     public final int broadcastIntent(IApplicationThread caller,
   11956             Intent intent, String resolvedType, IIntentReceiver resultTo,
   11957             int resultCode, String resultData, Bundle map,
   11958             String requiredPermission, boolean serialized, boolean sticky, int userId) {
   11959         enforceNotIsolatedCaller("broadcastIntent");
   11960         synchronized(this) {
   11961             intent = verifyBroadcastLocked(intent);
   11962 
   11963             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   11964             final int callingPid = Binder.getCallingPid();
   11965             final int callingUid = Binder.getCallingUid();
   11966             final long origId = Binder.clearCallingIdentity();
   11967             int res = broadcastIntentLocked(callerApp,
   11968                     callerApp != null ? callerApp.info.packageName : null,
   11969                     intent, resolvedType, resultTo,
   11970                     resultCode, resultData, map, requiredPermission, serialized, sticky,
   11971                     callingPid, callingUid, userId);
   11972             Binder.restoreCallingIdentity(origId);
   11973             return res;
   11974         }
   11975     }
   11976 
   11977     int broadcastIntentInPackage(String packageName, int uid,
   11978             Intent intent, String resolvedType, IIntentReceiver resultTo,
   11979             int resultCode, String resultData, Bundle map,
   11980             String requiredPermission, boolean serialized, boolean sticky, int userId) {
   11981         synchronized(this) {
   11982             intent = verifyBroadcastLocked(intent);
   11983 
   11984             final long origId = Binder.clearCallingIdentity();
   11985             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
   11986                     resultTo, resultCode, resultData, map, requiredPermission,
   11987                     serialized, sticky, -1, uid, userId);
   11988             Binder.restoreCallingIdentity(origId);
   11989             return res;
   11990         }
   11991     }
   11992 
   11993     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
   11994         // Refuse possible leaked file descriptors
   11995         if (intent != null && intent.hasFileDescriptors() == true) {
   11996             throw new IllegalArgumentException("File descriptors passed in Intent");
   11997         }
   11998 
   11999         userId = handleIncomingUser(Binder.getCallingPid(),
   12000                 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
   12001 
   12002         synchronized(this) {
   12003             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
   12004                     != PackageManager.PERMISSION_GRANTED) {
   12005                 String msg = "Permission Denial: unbroadcastIntent() from pid="
   12006                         + Binder.getCallingPid()
   12007                         + ", uid=" + Binder.getCallingUid()
   12008                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   12009                 Slog.w(TAG, msg);
   12010                 throw new SecurityException(msg);
   12011             }
   12012             HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   12013             if (stickies != null) {
   12014                 ArrayList<Intent> list = stickies.get(intent.getAction());
   12015                 if (list != null) {
   12016                     int N = list.size();
   12017                     int i;
   12018                     for (i=0; i<N; i++) {
   12019                         if (intent.filterEquals(list.get(i))) {
   12020                             list.remove(i);
   12021                             break;
   12022                         }
   12023                     }
   12024                     if (list.size() <= 0) {
   12025                         stickies.remove(intent.getAction());
   12026                     }
   12027                 }
   12028                 if (stickies.size() <= 0) {
   12029                     mStickyBroadcasts.remove(userId);
   12030                 }
   12031             }
   12032         }
   12033     }
   12034 
   12035     private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
   12036             String resultData, Bundle resultExtras, boolean resultAbort,
   12037             boolean explicit) {
   12038         final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
   12039         if (r == null) {
   12040             Slog.w(TAG, "finishReceiver called but not found on queue");
   12041             return false;
   12042         }
   12043 
   12044         return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
   12045                 explicit);
   12046     }
   12047 
   12048     public void finishReceiver(IBinder who, int resultCode, String resultData,
   12049             Bundle resultExtras, boolean resultAbort) {
   12050         if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
   12051 
   12052         // Refuse possible leaked file descriptors
   12053         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
   12054             throw new IllegalArgumentException("File descriptors passed in Bundle");
   12055         }
   12056 
   12057         final long origId = Binder.clearCallingIdentity();
   12058         try {
   12059             boolean doNext = false;
   12060             BroadcastRecord r = null;
   12061 
   12062             synchronized(this) {
   12063                 r = broadcastRecordForReceiverLocked(who);
   12064                 if (r != null) {
   12065                     doNext = r.queue.finishReceiverLocked(r, resultCode,
   12066                         resultData, resultExtras, resultAbort, true);
   12067                 }
   12068             }
   12069 
   12070             if (doNext) {
   12071                 r.queue.processNextBroadcast(false);
   12072             }
   12073             trimApplications();
   12074         } finally {
   12075             Binder.restoreCallingIdentity(origId);
   12076         }
   12077     }
   12078 
   12079     // =========================================================
   12080     // INSTRUMENTATION
   12081     // =========================================================
   12082 
   12083     public boolean startInstrumentation(ComponentName className,
   12084             String profileFile, int flags, Bundle arguments,
   12085             IInstrumentationWatcher watcher, int userId) {
   12086         enforceNotIsolatedCaller("startInstrumentation");
   12087         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   12088                 userId, false, true, "startInstrumentation", null);
   12089         // Refuse possible leaked file descriptors
   12090         if (arguments != null && arguments.hasFileDescriptors()) {
   12091             throw new IllegalArgumentException("File descriptors passed in Bundle");
   12092         }
   12093 
   12094         synchronized(this) {
   12095             InstrumentationInfo ii = null;
   12096             ApplicationInfo ai = null;
   12097             try {
   12098                 ii = mContext.getPackageManager().getInstrumentationInfo(
   12099                     className, STOCK_PM_FLAGS);
   12100                 ai = AppGlobals.getPackageManager().getApplicationInfo(
   12101                         ii.targetPackage, STOCK_PM_FLAGS, userId);
   12102             } catch (PackageManager.NameNotFoundException e) {
   12103             } catch (RemoteException e) {
   12104             }
   12105             if (ii == null) {
   12106                 reportStartInstrumentationFailure(watcher, className,
   12107                         "Unable to find instrumentation info for: " + className);
   12108                 return false;
   12109             }
   12110             if (ai == null) {
   12111                 reportStartInstrumentationFailure(watcher, className,
   12112                         "Unable to find instrumentation target package: " + ii.targetPackage);
   12113                 return false;
   12114             }
   12115 
   12116             int match = mContext.getPackageManager().checkSignatures(
   12117                     ii.targetPackage, ii.packageName);
   12118             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
   12119                 String msg = "Permission Denial: starting instrumentation "
   12120                         + className + " from pid="
   12121                         + Binder.getCallingPid()
   12122                         + ", uid=" + Binder.getCallingPid()
   12123                         + " not allowed because package " + ii.packageName
   12124                         + " does not have a signature matching the target "
   12125                         + ii.targetPackage;
   12126                 reportStartInstrumentationFailure(watcher, className, msg);
   12127                 throw new SecurityException(msg);
   12128             }
   12129 
   12130             final long origId = Binder.clearCallingIdentity();
   12131             // Instrumentation can kill and relaunch even persistent processes
   12132             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
   12133             ProcessRecord app = addAppLocked(ai, false);
   12134             app.instrumentationClass = className;
   12135             app.instrumentationInfo = ai;
   12136             app.instrumentationProfileFile = profileFile;
   12137             app.instrumentationArguments = arguments;
   12138             app.instrumentationWatcher = watcher;
   12139             app.instrumentationResultClass = className;
   12140             Binder.restoreCallingIdentity(origId);
   12141         }
   12142 
   12143         return true;
   12144     }
   12145 
   12146     /**
   12147      * Report errors that occur while attempting to start Instrumentation.  Always writes the
   12148      * error to the logs, but if somebody is watching, send the report there too.  This enables
   12149      * the "am" command to report errors with more information.
   12150      *
   12151      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
   12152      * @param cn The component name of the instrumentation.
   12153      * @param report The error report.
   12154      */
   12155     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
   12156             ComponentName cn, String report) {
   12157         Slog.w(TAG, report);
   12158         try {
   12159             if (watcher != null) {
   12160                 Bundle results = new Bundle();
   12161                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
   12162                 results.putString("Error", report);
   12163                 watcher.instrumentationStatus(cn, -1, results);
   12164             }
   12165         } catch (RemoteException e) {
   12166             Slog.w(TAG, e);
   12167         }
   12168     }
   12169 
   12170     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
   12171         if (app.instrumentationWatcher != null) {
   12172             try {
   12173                 // NOTE:  IInstrumentationWatcher *must* be oneway here
   12174                 app.instrumentationWatcher.instrumentationFinished(
   12175                     app.instrumentationClass,
   12176                     resultCode,
   12177                     results);
   12178             } catch (RemoteException e) {
   12179             }
   12180         }
   12181         app.instrumentationWatcher = null;
   12182         app.instrumentationClass = null;
   12183         app.instrumentationInfo = null;
   12184         app.instrumentationProfileFile = null;
   12185         app.instrumentationArguments = null;
   12186 
   12187         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
   12188     }
   12189 
   12190     public void finishInstrumentation(IApplicationThread target,
   12191             int resultCode, Bundle results) {
   12192         int userId = UserHandle.getCallingUserId();
   12193         // Refuse possible leaked file descriptors
   12194         if (results != null && results.hasFileDescriptors()) {
   12195             throw new IllegalArgumentException("File descriptors passed in Intent");
   12196         }
   12197 
   12198         synchronized(this) {
   12199             ProcessRecord app = getRecordForAppLocked(target);
   12200             if (app == null) {
   12201                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
   12202                 return;
   12203             }
   12204             final long origId = Binder.clearCallingIdentity();
   12205             finishInstrumentationLocked(app, resultCode, results);
   12206             Binder.restoreCallingIdentity(origId);
   12207         }
   12208     }
   12209 
   12210     // =========================================================
   12211     // CONFIGURATION
   12212     // =========================================================
   12213 
   12214     public ConfigurationInfo getDeviceConfigurationInfo() {
   12215         ConfigurationInfo config = new ConfigurationInfo();
   12216         synchronized (this) {
   12217             config.reqTouchScreen = mConfiguration.touchscreen;
   12218             config.reqKeyboardType = mConfiguration.keyboard;
   12219             config.reqNavigation = mConfiguration.navigation;
   12220             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
   12221                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
   12222                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
   12223             }
   12224             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
   12225                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
   12226                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
   12227             }
   12228             config.reqGlEsVersion = GL_ES_VERSION;
   12229         }
   12230         return config;
   12231     }
   12232 
   12233     public Configuration getConfiguration() {
   12234         Configuration ci;
   12235         synchronized(this) {
   12236             ci = new Configuration(mConfiguration);
   12237         }
   12238         return ci;
   12239     }
   12240 
   12241     public void updatePersistentConfiguration(Configuration values) {
   12242         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   12243                 "updateConfiguration()");
   12244         enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
   12245                 "updateConfiguration()");
   12246         if (values == null) {
   12247             throw new NullPointerException("Configuration must not be null");
   12248         }
   12249 
   12250         synchronized(this) {
   12251             final long origId = Binder.clearCallingIdentity();
   12252             updateConfigurationLocked(values, null, true, false);
   12253             Binder.restoreCallingIdentity(origId);
   12254         }
   12255     }
   12256 
   12257     public void updateConfiguration(Configuration values) {
   12258         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   12259                 "updateConfiguration()");
   12260 
   12261         synchronized(this) {
   12262             if (values == null && mWindowManager != null) {
   12263                 // sentinel: fetch the current configuration from the window manager
   12264                 values = mWindowManager.computeNewConfiguration();
   12265             }
   12266 
   12267             if (mWindowManager != null) {
   12268                 mProcessList.applyDisplaySize(mWindowManager);
   12269             }
   12270 
   12271             final long origId = Binder.clearCallingIdentity();
   12272             if (values != null) {
   12273                 Settings.System.clearConfiguration(values);
   12274             }
   12275             updateConfigurationLocked(values, null, false, false);
   12276             Binder.restoreCallingIdentity(origId);
   12277         }
   12278     }
   12279 
   12280     /**
   12281      * Do either or both things: (1) change the current configuration, and (2)
   12282      * make sure the given activity is running with the (now) current
   12283      * configuration.  Returns true if the activity has been left running, or
   12284      * false if <var>starting</var> is being destroyed to match the new
   12285      * configuration.
   12286      * @param persistent TODO
   12287      */
   12288     boolean updateConfigurationLocked(Configuration values,
   12289             ActivityRecord starting, boolean persistent, boolean initLocale) {
   12290         // do nothing if we are headless
   12291         if (mHeadless) return true;
   12292 
   12293         int changes = 0;
   12294 
   12295         boolean kept = true;
   12296 
   12297         if (values != null) {
   12298             Configuration newConfig = new Configuration(mConfiguration);
   12299             changes = newConfig.updateFrom(values);
   12300             if (changes != 0) {
   12301                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
   12302                     Slog.i(TAG, "Updating configuration to: " + values);
   12303                 }
   12304 
   12305                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
   12306 
   12307                 if (values.locale != null && !initLocale) {
   12308                     saveLocaleLocked(values.locale,
   12309                                      !values.locale.equals(mConfiguration.locale),
   12310                                      values.userSetLocale);
   12311                 }
   12312 
   12313                 mConfigurationSeq++;
   12314                 if (mConfigurationSeq <= 0) {
   12315                     mConfigurationSeq = 1;
   12316                 }
   12317                 newConfig.seq = mConfigurationSeq;
   12318                 mConfiguration = newConfig;
   12319                 Slog.i(TAG, "Config changed: " + newConfig);
   12320 
   12321                 final Configuration configCopy = new Configuration(mConfiguration);
   12322 
   12323                 // TODO: If our config changes, should we auto dismiss any currently
   12324                 // showing dialogs?
   12325                 mShowDialogs = shouldShowDialogs(newConfig);
   12326 
   12327                 AttributeCache ac = AttributeCache.instance();
   12328                 if (ac != null) {
   12329                     ac.updateConfiguration(configCopy);
   12330                 }
   12331 
   12332                 // Make sure all resources in our process are updated
   12333                 // right now, so that anyone who is going to retrieve
   12334                 // resource values after we return will be sure to get
   12335                 // the new ones.  This is especially important during
   12336                 // boot, where the first config change needs to guarantee
   12337                 // all resources have that config before following boot
   12338                 // code is executed.
   12339                 mSystemThread.applyConfigurationToResources(configCopy);
   12340 
   12341                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
   12342                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
   12343                     msg.obj = new Configuration(configCopy);
   12344                     mHandler.sendMessage(msg);
   12345                 }
   12346 
   12347                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   12348                     ProcessRecord app = mLruProcesses.get(i);
   12349                     try {
   12350                         if (app.thread != null) {
   12351                             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
   12352                                     + app.processName + " new config " + mConfiguration);
   12353                             app.thread.scheduleConfigurationChanged(configCopy);
   12354                         }
   12355                     } catch (Exception e) {
   12356                     }
   12357                 }
   12358                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
   12359                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   12360                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
   12361                         | Intent.FLAG_RECEIVER_FOREGROUND);
   12362                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
   12363                         null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   12364                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
   12365                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
   12366                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   12367                     broadcastIntentLocked(null, null, intent,
   12368                             null, null, 0, null, null,
   12369                             null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   12370                 }
   12371             }
   12372         }
   12373 
   12374         if (changes != 0 && starting == null) {
   12375             // If the configuration changed, and the caller is not already
   12376             // in the process of starting an activity, then find the top
   12377             // activity to check if its configuration needs to change.
   12378             starting = mMainStack.topRunningActivityLocked(null);
   12379         }
   12380 
   12381         if (starting != null) {
   12382             kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
   12383             // And we need to make sure at this point that all other activities
   12384             // are made visible with the correct configuration.
   12385             mMainStack.ensureActivitiesVisibleLocked(starting, changes);
   12386         }
   12387 
   12388         if (values != null && mWindowManager != null) {
   12389             mWindowManager.setNewConfiguration(mConfiguration);
   12390         }
   12391 
   12392         return kept;
   12393     }
   12394 
   12395     /**
   12396      * Decide based on the configuration whether we should shouw the ANR,
   12397      * crash, etc dialogs.  The idea is that if there is no affordnace to
   12398      * press the on-screen buttons, we shouldn't show the dialog.
   12399      *
   12400      * A thought: SystemUI might also want to get told about this, the Power
   12401      * dialog / global actions also might want different behaviors.
   12402      */
   12403     private static final boolean shouldShowDialogs(Configuration config) {
   12404         return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
   12405                 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
   12406     }
   12407 
   12408     /**
   12409      * Save the locale.  You must be inside a synchronized (this) block.
   12410      */
   12411     private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
   12412         if(isDiff) {
   12413             SystemProperties.set("user.language", l.getLanguage());
   12414             SystemProperties.set("user.region", l.getCountry());
   12415         }
   12416 
   12417         if(isPersist) {
   12418             SystemProperties.set("persist.sys.language", l.getLanguage());
   12419             SystemProperties.set("persist.sys.country", l.getCountry());
   12420             SystemProperties.set("persist.sys.localevar", l.getVariant());
   12421         }
   12422     }
   12423 
   12424     @Override
   12425     public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
   12426         ActivityRecord srec = ActivityRecord.forToken(token);
   12427         return srec != null && srec.task.affinity != null &&
   12428                 srec.task.affinity.equals(destAffinity);
   12429     }
   12430 
   12431     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
   12432             Intent resultData) {
   12433         ComponentName dest = destIntent.getComponent();
   12434 
   12435         synchronized (this) {
   12436             ActivityRecord srec = ActivityRecord.forToken(token);
   12437             if (srec == null) {
   12438                 return false;
   12439             }
   12440             ArrayList<ActivityRecord> history = srec.stack.mHistory;
   12441             final int start = history.indexOf(srec);
   12442             if (start < 0) {
   12443                 // Current activity is not in history stack; do nothing.
   12444                 return false;
   12445             }
   12446             int finishTo = start - 1;
   12447             ActivityRecord parent = null;
   12448             boolean foundParentInTask = false;
   12449             if (dest != null) {
   12450                 TaskRecord tr = srec.task;
   12451                 for (int i = start - 1; i >= 0; i--) {
   12452                     ActivityRecord r = history.get(i);
   12453                     if (tr != r.task) {
   12454                         // Couldn't find parent in the same task; stop at the one above this.
   12455                         // (Root of current task; in-app "home" behavior)
   12456                         // Always at least finish the current activity.
   12457                         finishTo = Math.min(start - 1, i + 1);
   12458                         parent = history.get(finishTo);
   12459                         break;
   12460                     } else if (r.info.packageName.equals(dest.getPackageName()) &&
   12461                             r.info.name.equals(dest.getClassName())) {
   12462                         finishTo = i;
   12463                         parent = r;
   12464                         foundParentInTask = true;
   12465                         break;
   12466                     }
   12467                 }
   12468             }
   12469 
   12470             if (mController != null) {
   12471                 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
   12472                 if (next != null) {
   12473                     // ask watcher if this is allowed
   12474                     boolean resumeOK = true;
   12475                     try {
   12476                         resumeOK = mController.activityResuming(next.packageName);
   12477                     } catch (RemoteException e) {
   12478                         mController = null;
   12479                     }
   12480 
   12481                     if (!resumeOK) {
   12482                         return false;
   12483                     }
   12484                 }
   12485             }
   12486             final long origId = Binder.clearCallingIdentity();
   12487             for (int i = start; i > finishTo; i--) {
   12488                 ActivityRecord r = history.get(i);
   12489                 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
   12490                         "navigate-up", true);
   12491                 // Only return the supplied result for the first activity finished
   12492                 resultCode = Activity.RESULT_CANCELED;
   12493                 resultData = null;
   12494             }
   12495 
   12496             if (parent != null && foundParentInTask) {
   12497                 final int parentLaunchMode = parent.info.launchMode;
   12498                 final int destIntentFlags = destIntent.getFlags();
   12499                 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
   12500                         parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
   12501                         parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
   12502                         (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
   12503                     parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
   12504                 } else {
   12505                     try {
   12506                         ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
   12507                                 destIntent.getComponent(), 0, srec.userId);
   12508                         int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
   12509                                 null, aInfo, parent.appToken, null,
   12510                                 0, -1, parent.launchedFromUid, 0, null, true, null);
   12511                         foundParentInTask = res == ActivityManager.START_SUCCESS;
   12512                     } catch (RemoteException e) {
   12513                         foundParentInTask = false;
   12514                     }
   12515                     mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
   12516                             resultData, "navigate-up", true);
   12517                 }
   12518             }
   12519             Binder.restoreCallingIdentity(origId);
   12520             return foundParentInTask;
   12521         }
   12522     }
   12523 
   12524     public int getLaunchedFromUid(IBinder activityToken) {
   12525         ActivityRecord srec = ActivityRecord.forToken(activityToken);
   12526         if (srec == null) {
   12527             return -1;
   12528         }
   12529         return srec.launchedFromUid;
   12530     }
   12531 
   12532     // =========================================================
   12533     // LIFETIME MANAGEMENT
   12534     // =========================================================
   12535 
   12536     // Returns which broadcast queue the app is the current [or imminent] receiver
   12537     // on, or 'null' if the app is not an active broadcast recipient.
   12538     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
   12539         BroadcastRecord r = app.curReceiver;
   12540         if (r != null) {
   12541             return r.queue;
   12542         }
   12543 
   12544         // It's not the current receiver, but it might be starting up to become one
   12545         synchronized (this) {
   12546             for (BroadcastQueue queue : mBroadcastQueues) {
   12547                 r = queue.mPendingBroadcast;
   12548                 if (r != null && r.curApp == app) {
   12549                     // found it; report which queue it's in
   12550                     return queue;
   12551                 }
   12552             }
   12553         }
   12554 
   12555         return null;
   12556     }
   12557 
   12558     private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj,
   12559             int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
   12560         if (mAdjSeq == app.adjSeq) {
   12561             // This adjustment has already been computed.  If we are calling
   12562             // from the top, we may have already computed our adjustment with
   12563             // an earlier hidden adjustment that isn't really for us... if
   12564             // so, use the new hidden adjustment.
   12565             if (!recursed && app.hidden) {
   12566                 if (app.hasActivities) {
   12567                     app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
   12568                 } else if (app.hasClientActivities) {
   12569                     app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj;
   12570                 } else {
   12571                     app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj;
   12572                 }
   12573             }
   12574             return app.curRawAdj;
   12575         }
   12576 
   12577         if (app.thread == null) {
   12578             app.adjSeq = mAdjSeq;
   12579             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   12580             return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
   12581         }
   12582 
   12583         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
   12584         app.adjSource = null;
   12585         app.adjTarget = null;
   12586         app.empty = false;
   12587         app.hidden = false;
   12588         app.hasClientActivities = false;
   12589 
   12590         final int activitiesSize = app.activities.size();
   12591 
   12592         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   12593             // The max adjustment doesn't allow this app to be anything
   12594             // below foreground, so it is not worth doing work for it.
   12595             app.adjType = "fixed";
   12596             app.adjSeq = mAdjSeq;
   12597             app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
   12598             app.hasActivities = false;
   12599             app.foregroundActivities = false;
   12600             app.keeping = true;
   12601             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
   12602             // System process can do UI, and when they do we want to have
   12603             // them trim their memory after the user leaves the UI.  To
   12604             // facilitate this, here we need to determine whether or not it
   12605             // is currently showing UI.
   12606             app.systemNoUi = true;
   12607             if (app == TOP_APP) {
   12608                 app.systemNoUi = false;
   12609                 app.hasActivities = true;
   12610             } else if (activitiesSize > 0) {
   12611                 for (int j = 0; j < activitiesSize; j++) {
   12612                     final ActivityRecord r = app.activities.get(j);
   12613                     if (r.visible) {
   12614                         app.systemNoUi = false;
   12615                     }
   12616                     if (r.app == app) {
   12617                         app.hasActivities = true;
   12618                     }
   12619                 }
   12620             }
   12621             return (app.curAdj=app.maxAdj);
   12622         }
   12623 
   12624         app.keeping = false;
   12625         app.systemNoUi = false;
   12626         app.hasActivities = false;
   12627 
   12628         // Determine the importance of the process, starting with most
   12629         // important to least, and assign an appropriate OOM adjustment.
   12630         int adj;
   12631         int schedGroup;
   12632         boolean foregroundActivities = false;
   12633         boolean interesting = false;
   12634         BroadcastQueue queue;
   12635         if (app == TOP_APP) {
   12636             // The last app on the list is the foreground app.
   12637             adj = ProcessList.FOREGROUND_APP_ADJ;
   12638             schedGroup = Process.THREAD_GROUP_DEFAULT;
   12639             app.adjType = "top-activity";
   12640             foregroundActivities = true;
   12641             interesting = true;
   12642             app.hasActivities = true;
   12643         } else if (app.instrumentationClass != null) {
   12644             // Don't want to kill running instrumentation.
   12645             adj = ProcessList.FOREGROUND_APP_ADJ;
   12646             schedGroup = Process.THREAD_GROUP_DEFAULT;
   12647             app.adjType = "instrumentation";
   12648             interesting = true;
   12649         } else if ((queue = isReceivingBroadcast(app)) != null) {
   12650             // An app that is currently receiving a broadcast also
   12651             // counts as being in the foreground for OOM killer purposes.
   12652             // It's placed in a sched group based on the nature of the
   12653             // broadcast as reflected by which queue it's active in.
   12654             adj = ProcessList.FOREGROUND_APP_ADJ;
   12655             schedGroup = (queue == mFgBroadcastQueue)
   12656                     ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
   12657             app.adjType = "broadcast";
   12658         } else if (app.executingServices.size() > 0) {
   12659             // An app that is currently executing a service callback also
   12660             // counts as being in the foreground.
   12661             adj = ProcessList.FOREGROUND_APP_ADJ;
   12662             schedGroup = Process.THREAD_GROUP_DEFAULT;
   12663             app.adjType = "exec-service";
   12664         } else {
   12665             // Assume process is hidden (has activities); we will correct
   12666             // later if this is not the case.
   12667             adj = hiddenAdj;
   12668             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   12669             app.hidden = true;
   12670             app.adjType = "bg-act";
   12671         }
   12672 
   12673         boolean hasStoppingActivities = false;
   12674 
   12675         // Examine all activities if not already foreground.
   12676         if (!foregroundActivities && activitiesSize > 0) {
   12677             for (int j = 0; j < activitiesSize; j++) {
   12678                 final ActivityRecord r = app.activities.get(j);
   12679                 if (r.visible) {
   12680                     // App has a visible activity; only upgrade adjustment.
   12681                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   12682                         adj = ProcessList.VISIBLE_APP_ADJ;
   12683                         app.adjType = "visible";
   12684                     }
   12685                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   12686                     app.hidden = false;
   12687                     app.hasActivities = true;
   12688                     foregroundActivities = true;
   12689                     break;
   12690                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
   12691                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   12692                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   12693                         app.adjType = "pausing";
   12694                     }
   12695                     app.hidden = false;
   12696                     foregroundActivities = true;
   12697                 } else if (r.state == ActivityState.STOPPING) {
   12698                     // We will apply the actual adjustment later, because
   12699                     // we want to allow this process to immediately go through
   12700                     // any memory trimming that is in effect.
   12701                     app.hidden = false;
   12702                     foregroundActivities = true;
   12703                     hasStoppingActivities = true;
   12704                 }
   12705                 if (r.app == app) {
   12706                     app.hasActivities = true;
   12707                 }
   12708             }
   12709         }
   12710 
   12711         if (adj == hiddenAdj && !app.hasActivities) {
   12712             if (app.hasClientActivities) {
   12713                 adj = clientHiddenAdj;
   12714                 app.adjType = "bg-client-act";
   12715             } else {
   12716                 // Whoops, this process is completely empty as far as we know
   12717                 // at this point.
   12718                 adj = emptyAdj;
   12719                 app.empty = true;
   12720                 app.adjType = "bg-empty";
   12721             }
   12722         }
   12723 
   12724         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   12725             if (app.foregroundServices) {
   12726                 // The user is aware of this app, so make it visible.
   12727                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   12728                 app.hidden = false;
   12729                 app.adjType = "fg-service";
   12730                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   12731             } else if (app.forcingToForeground != null) {
   12732                 // The user is aware of this app, so make it visible.
   12733                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   12734                 app.hidden = false;
   12735                 app.adjType = "force-fg";
   12736                 app.adjSource = app.forcingToForeground;
   12737                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   12738             }
   12739         }
   12740 
   12741         if (app.foregroundServices) {
   12742             interesting = true;
   12743         }
   12744 
   12745         if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
   12746             // We don't want to kill the current heavy-weight process.
   12747             adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
   12748             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   12749             app.hidden = false;
   12750             app.adjType = "heavy";
   12751         }
   12752 
   12753         if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
   12754             // This process is hosting what we currently consider to be the
   12755             // home app, so we don't want to let it go into the background.
   12756             adj = ProcessList.HOME_APP_ADJ;
   12757             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   12758             app.hidden = false;
   12759             app.adjType = "home";
   12760         }
   12761 
   12762         if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
   12763                 && app.activities.size() > 0) {
   12764             // This was the previous process that showed UI to the user.
   12765             // We want to try to keep it around more aggressively, to give
   12766             // a good experience around switching between two apps.
   12767             adj = ProcessList.PREVIOUS_APP_ADJ;
   12768             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   12769             app.hidden = false;
   12770             app.adjType = "previous";
   12771         }
   12772 
   12773         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
   12774                 + " reason=" + app.adjType);
   12775 
   12776         // By default, we use the computed adjustment.  It may be changed if
   12777         // there are applications dependent on our services or providers, but
   12778         // this gives us a baseline and makes sure we don't get into an
   12779         // infinite recursion.
   12780         app.adjSeq = mAdjSeq;
   12781         app.curRawAdj = app.nonStoppingAdj = adj;
   12782 
   12783         if (mBackupTarget != null && app == mBackupTarget.app) {
   12784             // If possible we want to avoid killing apps while they're being backed up
   12785             if (adj > ProcessList.BACKUP_APP_ADJ) {
   12786                 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
   12787                 adj = ProcessList.BACKUP_APP_ADJ;
   12788                 app.adjType = "backup";
   12789                 app.hidden = false;
   12790             }
   12791         }
   12792 
   12793         if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   12794                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   12795             final long now = SystemClock.uptimeMillis();
   12796             // This process is more important if the top activity is
   12797             // bound to the service.
   12798             Iterator<ServiceRecord> jt = app.services.iterator();
   12799             while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
   12800                 ServiceRecord s = jt.next();
   12801                 if (s.startRequested) {
   12802                     if (app.hasShownUi && app != mHomeProcess) {
   12803                         // If this process has shown some UI, let it immediately
   12804                         // go to the LRU list because it may be pretty heavy with
   12805                         // UI stuff.  We'll tag it with a label just to help
   12806                         // debug and understand what is going on.
   12807                         if (adj > ProcessList.SERVICE_ADJ) {
   12808                             app.adjType = "started-bg-ui-services";
   12809                         }
   12810                     } else {
   12811                         if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
   12812                             // This service has seen some activity within
   12813                             // recent memory, so we will keep its process ahead
   12814                             // of the background processes.
   12815                             if (adj > ProcessList.SERVICE_ADJ) {
   12816                                 adj = ProcessList.SERVICE_ADJ;
   12817                                 app.adjType = "started-services";
   12818                                 app.hidden = false;
   12819                             }
   12820                         }
   12821                         // If we have let the service slide into the background
   12822                         // state, still have some text describing what it is doing
   12823                         // even though the service no longer has an impact.
   12824                         if (adj > ProcessList.SERVICE_ADJ) {
   12825                             app.adjType = "started-bg-services";
   12826                         }
   12827                     }
   12828                     // Don't kill this process because it is doing work; it
   12829                     // has said it is doing work.
   12830                     app.keeping = true;
   12831                 }
   12832                 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   12833                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   12834                     Iterator<ArrayList<ConnectionRecord>> kt
   12835                             = s.connections.values().iterator();
   12836                     while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
   12837                         ArrayList<ConnectionRecord> clist = kt.next();
   12838                         for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
   12839                             // XXX should compute this based on the max of
   12840                             // all connected clients.
   12841                             ConnectionRecord cr = clist.get(i);
   12842                             if (cr.binding.client == app) {
   12843                                 // Binding to ourself is not interesting.
   12844                                 continue;
   12845                             }
   12846                             if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
   12847                                 ProcessRecord client = cr.binding.client;
   12848                                 int clientAdj = adj;
   12849                                 int myHiddenAdj = hiddenAdj;
   12850                                 if (myHiddenAdj > client.hiddenAdj) {
   12851                                     if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
   12852                                         myHiddenAdj = client.hiddenAdj;
   12853                                     } else {
   12854                                         myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
   12855                                     }
   12856                                 }
   12857                                 int myClientHiddenAdj = clientHiddenAdj;
   12858                                 if (myClientHiddenAdj > client.clientHiddenAdj) {
   12859                                     if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
   12860                                         myClientHiddenAdj = client.clientHiddenAdj;
   12861                                     } else {
   12862                                         myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
   12863                                     }
   12864                                 }
   12865                                 int myEmptyAdj = emptyAdj;
   12866                                 if (myEmptyAdj > client.emptyAdj) {
   12867                                     if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
   12868                                         myEmptyAdj = client.emptyAdj;
   12869                                     } else {
   12870                                         myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
   12871                                     }
   12872                                 }
   12873                                 clientAdj = computeOomAdjLocked(client, myHiddenAdj,
   12874                                         myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
   12875                                 String adjType = null;
   12876                                 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
   12877                                     // Not doing bind OOM management, so treat
   12878                                     // this guy more like a started service.
   12879                                     if (app.hasShownUi && app != mHomeProcess) {
   12880                                         // If this process has shown some UI, let it immediately
   12881                                         // go to the LRU list because it may be pretty heavy with
   12882                                         // UI stuff.  We'll tag it with a label just to help
   12883                                         // debug and understand what is going on.
   12884                                         if (adj > clientAdj) {
   12885                                             adjType = "bound-bg-ui-services";
   12886                                         }
   12887                                         app.hidden = false;
   12888                                         clientAdj = adj;
   12889                                     } else {
   12890                                         if (now >= (s.lastActivity
   12891                                                 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
   12892                                             // This service has not seen activity within
   12893                                             // recent memory, so allow it to drop to the
   12894                                             // LRU list if there is no other reason to keep
   12895                                             // it around.  We'll also tag it with a label just
   12896                                             // to help debug and undertand what is going on.
   12897                                             if (adj > clientAdj) {
   12898                                                 adjType = "bound-bg-services";
   12899                                             }
   12900                                             clientAdj = adj;
   12901                                         }
   12902                                     }
   12903                                 } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
   12904                                     if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) {
   12905                                         // If this connection is keeping the service
   12906                                         // created, then we want to try to better follow
   12907                                         // its memory management semantics for activities.
   12908                                         // That is, if it is sitting in the background
   12909                                         // LRU list as a hidden process (with activities),
   12910                                         // we don't want the service it is connected to
   12911                                         // to go into the empty LRU and quickly get killed,
   12912                                         // because I'll we'll do is just end up restarting
   12913                                         // the service.
   12914                                         app.hasClientActivities |= client.hasActivities;
   12915                                     }
   12916                                 }
   12917                                 if (adj > clientAdj) {
   12918                                     // If this process has recently shown UI, and
   12919                                     // the process that is binding to it is less
   12920                                     // important than being visible, then we don't
   12921                                     // care about the binding as much as we care
   12922                                     // about letting this process get into the LRU
   12923                                     // list to be killed and restarted if needed for
   12924                                     // memory.
   12925                                     if (app.hasShownUi && app != mHomeProcess
   12926                                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   12927                                         adjType = "bound-bg-ui-services";
   12928                                     } else {
   12929                                         if ((cr.flags&(Context.BIND_ABOVE_CLIENT
   12930                                                 |Context.BIND_IMPORTANT)) != 0) {
   12931                                             adj = clientAdj;
   12932                                         } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
   12933                                                 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
   12934                                                 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   12935                                             adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   12936                                         } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
   12937                                             adj = clientAdj;
   12938                                         } else {
   12939                                             app.pendingUiClean = true;
   12940                                             if (adj > ProcessList.VISIBLE_APP_ADJ) {
   12941                                                 adj = ProcessList.VISIBLE_APP_ADJ;
   12942                                             }
   12943                                         }
   12944                                         if (!client.hidden) {
   12945                                             app.hidden = false;
   12946                                         }
   12947                                         if (client.keeping) {
   12948                                             app.keeping = true;
   12949                                         }
   12950                                         adjType = "service";
   12951                                     }
   12952                                 }
   12953                                 if (adjType != null) {
   12954                                     app.adjType = adjType;
   12955                                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   12956                                             .REASON_SERVICE_IN_USE;
   12957                                     app.adjSource = cr.binding.client;
   12958                                     app.adjSourceOom = clientAdj;
   12959                                     app.adjTarget = s.name;
   12960                                 }
   12961                                 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   12962                                     if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   12963                                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   12964                                     }
   12965                                 }
   12966                             }
   12967                             final ActivityRecord a = cr.activity;
   12968                             if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
   12969                                 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
   12970                                         (a.visible || a.state == ActivityState.RESUMED
   12971                                          || a.state == ActivityState.PAUSING)) {
   12972                                     adj = ProcessList.FOREGROUND_APP_ADJ;
   12973                                     if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   12974                                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   12975                                     }
   12976                                     app.hidden = false;
   12977                                     app.adjType = "service";
   12978                                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   12979                                             .REASON_SERVICE_IN_USE;
   12980                                     app.adjSource = a;
   12981                                     app.adjSourceOom = adj;
   12982                                     app.adjTarget = s.name;
   12983                                 }
   12984                             }
   12985                         }
   12986                     }
   12987                 }
   12988             }
   12989 
   12990             // Finally, if this process has active services running in it, we
   12991             // would like to avoid killing it unless it would prevent the current
   12992             // application from running.  By default we put the process in
   12993             // with the rest of the background processes; as we scan through
   12994             // its services we may bump it up from there.
   12995             if (adj > hiddenAdj) {
   12996                 adj = hiddenAdj;
   12997                 app.hidden = false;
   12998                 app.adjType = "bg-services";
   12999             }
   13000         }
   13001 
   13002         if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   13003                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   13004             Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
   13005             while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
   13006                     || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   13007                 ContentProviderRecord cpr = jt.next();
   13008                 for (int i = cpr.connections.size()-1;
   13009                         i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   13010                                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
   13011                         i--) {
   13012                     ContentProviderConnection conn = cpr.connections.get(i);
   13013                     ProcessRecord client = conn.client;
   13014                     if (client == app) {
   13015                         // Being our own client is not interesting.
   13016                         continue;
   13017                     }
   13018                     int myHiddenAdj = hiddenAdj;
   13019                     if (myHiddenAdj > client.hiddenAdj) {
   13020                         if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
   13021                             myHiddenAdj = client.hiddenAdj;
   13022                         } else {
   13023                             myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
   13024                         }
   13025                     }
   13026                     int myClientHiddenAdj = clientHiddenAdj;
   13027                     if (myClientHiddenAdj > client.clientHiddenAdj) {
   13028                         if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) {
   13029                             myClientHiddenAdj = client.clientHiddenAdj;
   13030                         } else {
   13031                             myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
   13032                         }
   13033                     }
   13034                     int myEmptyAdj = emptyAdj;
   13035                     if (myEmptyAdj > client.emptyAdj) {
   13036                         if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
   13037                             myEmptyAdj = client.emptyAdj;
   13038                         } else {
   13039                             myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
   13040                         }
   13041                     }
   13042                     int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
   13043                             myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
   13044                     if (adj > clientAdj) {
   13045                         if (app.hasShownUi && app != mHomeProcess
   13046                                 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   13047                             app.adjType = "bg-ui-provider";
   13048                         } else {
   13049                             adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
   13050                                     ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
   13051                             app.adjType = "provider";
   13052                         }
   13053                         if (!client.hidden) {
   13054                             app.hidden = false;
   13055                         }
   13056                         if (client.keeping) {
   13057                             app.keeping = true;
   13058                         }
   13059                         app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   13060                                 .REASON_PROVIDER_IN_USE;
   13061                         app.adjSource = client;
   13062                         app.adjSourceOom = clientAdj;
   13063                         app.adjTarget = cpr.name;
   13064                     }
   13065                     if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   13066                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   13067                     }
   13068                 }
   13069                 // If the provider has external (non-framework) process
   13070                 // dependencies, ensure that its adjustment is at least
   13071                 // FOREGROUND_APP_ADJ.
   13072                 if (cpr.hasExternalProcessHandles()) {
   13073                     if (adj > ProcessList.FOREGROUND_APP_ADJ) {
   13074                         adj = ProcessList.FOREGROUND_APP_ADJ;
   13075                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   13076                         app.hidden = false;
   13077                         app.keeping = true;
   13078                         app.adjType = "provider";
   13079                         app.adjTarget = cpr.name;
   13080                     }
   13081                 }
   13082             }
   13083         }
   13084 
   13085         if (adj == ProcessList.SERVICE_ADJ) {
   13086             if (doingAll) {
   13087                 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
   13088                 mNewNumServiceProcs++;
   13089             }
   13090             if (app.serviceb) {
   13091                 adj = ProcessList.SERVICE_B_ADJ;
   13092             }
   13093         } else {
   13094             app.serviceb = false;
   13095         }
   13096 
   13097         app.nonStoppingAdj = adj;
   13098 
   13099         if (hasStoppingActivities) {
   13100             // Only upgrade adjustment.
   13101             if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   13102                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   13103                 app.adjType = "stopping";
   13104             }
   13105         }
   13106 
   13107         app.curRawAdj = adj;
   13108 
   13109         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
   13110         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
   13111         if (adj > app.maxAdj) {
   13112             adj = app.maxAdj;
   13113             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   13114                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   13115             }
   13116         }
   13117         if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
   13118             app.keeping = true;
   13119         }
   13120 
   13121         if (app.hasAboveClient) {
   13122             // If this process has bound to any services with BIND_ABOVE_CLIENT,
   13123             // then we need to drop its adjustment to be lower than the service's
   13124             // in order to honor the request.  We want to drop it by one adjustment
   13125             // level...  but there is special meaning applied to various levels so
   13126             // we will skip some of them.
   13127             if (adj < ProcessList.FOREGROUND_APP_ADJ) {
   13128                 // System process will not get dropped, ever
   13129             } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
   13130                 adj = ProcessList.VISIBLE_APP_ADJ;
   13131             } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
   13132                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   13133             } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
   13134                 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
   13135             } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
   13136                 adj++;
   13137             }
   13138         }
   13139 
   13140         int importance = app.memImportance;
   13141         if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
   13142             app.curAdj = adj;
   13143             app.curSchedGroup = schedGroup;
   13144             if (!interesting) {
   13145                 // For this reporting, if there is not something explicitly
   13146                 // interesting in this process then we will push it to the
   13147                 // background importance.
   13148                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   13149             } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   13150                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   13151             } else if (adj >= ProcessList.SERVICE_B_ADJ) {
   13152                 importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   13153             } else if (adj >= ProcessList.HOME_APP_ADJ) {
   13154                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   13155             } else if (adj >= ProcessList.SERVICE_ADJ) {
   13156                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   13157             } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   13158                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
   13159             } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   13160                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
   13161             } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
   13162                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
   13163             } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
   13164                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
   13165             } else {
   13166                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
   13167             }
   13168         }
   13169 
   13170         int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
   13171         if (foregroundActivities != app.foregroundActivities) {
   13172             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
   13173         }
   13174         if (changes != 0) {
   13175             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
   13176             app.memImportance = importance;
   13177             app.foregroundActivities = foregroundActivities;
   13178             int i = mPendingProcessChanges.size()-1;
   13179             ProcessChangeItem item = null;
   13180             while (i >= 0) {
   13181                 item = mPendingProcessChanges.get(i);
   13182                 if (item.pid == app.pid) {
   13183                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
   13184                     break;
   13185                 }
   13186                 i--;
   13187             }
   13188             if (i < 0) {
   13189                 // No existing item in pending changes; need a new one.
   13190                 final int NA = mAvailProcessChanges.size();
   13191                 if (NA > 0) {
   13192                     item = mAvailProcessChanges.remove(NA-1);
   13193                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
   13194                 } else {
   13195                     item = new ProcessChangeItem();
   13196                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
   13197                 }
   13198                 item.changes = 0;
   13199                 item.pid = app.pid;
   13200                 item.uid = app.info.uid;
   13201                 if (mPendingProcessChanges.size() == 0) {
   13202                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
   13203                             "*** Enqueueing dispatch processes changed!");
   13204                     mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
   13205                 }
   13206                 mPendingProcessChanges.add(item);
   13207             }
   13208             item.changes |= changes;
   13209             item.importance = importance;
   13210             item.foregroundActivities = foregroundActivities;
   13211             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
   13212                     + Integer.toHexString(System.identityHashCode(item))
   13213                     + " " + app.toShortString() + ": changes=" + item.changes
   13214                     + " importance=" + item.importance
   13215                     + " foreground=" + item.foregroundActivities
   13216                     + " type=" + app.adjType + " source=" + app.adjSource
   13217                     + " target=" + app.adjTarget);
   13218         }
   13219 
   13220         return app.curRawAdj;
   13221     }
   13222 
   13223     /**
   13224      * Ask a given process to GC right now.
   13225      */
   13226     final void performAppGcLocked(ProcessRecord app) {
   13227         try {
   13228             app.lastRequestedGc = SystemClock.uptimeMillis();
   13229             if (app.thread != null) {
   13230                 if (app.reportLowMemory) {
   13231                     app.reportLowMemory = false;
   13232                     app.thread.scheduleLowMemory();
   13233                 } else {
   13234                     app.thread.processInBackground();
   13235                 }
   13236             }
   13237         } catch (Exception e) {
   13238             // whatever.
   13239         }
   13240     }
   13241 
   13242     /**
   13243      * Returns true if things are idle enough to perform GCs.
   13244      */
   13245     private final boolean canGcNowLocked() {
   13246         boolean processingBroadcasts = false;
   13247         for (BroadcastQueue q : mBroadcastQueues) {
   13248             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
   13249                 processingBroadcasts = true;
   13250             }
   13251         }
   13252         return !processingBroadcasts
   13253                 && (mSleeping || (mMainStack.mResumedActivity != null &&
   13254                         mMainStack.mResumedActivity.idle));
   13255     }
   13256 
   13257     /**
   13258      * Perform GCs on all processes that are waiting for it, but only
   13259      * if things are idle.
   13260      */
   13261     final void performAppGcsLocked() {
   13262         final int N = mProcessesToGc.size();
   13263         if (N <= 0) {
   13264             return;
   13265         }
   13266         if (canGcNowLocked()) {
   13267             while (mProcessesToGc.size() > 0) {
   13268                 ProcessRecord proc = mProcessesToGc.remove(0);
   13269                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
   13270                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
   13271                             <= SystemClock.uptimeMillis()) {
   13272                         // To avoid spamming the system, we will GC processes one
   13273                         // at a time, waiting a few seconds between each.
   13274                         performAppGcLocked(proc);
   13275                         scheduleAppGcsLocked();
   13276                         return;
   13277                     } else {
   13278                         // It hasn't been long enough since we last GCed this
   13279                         // process...  put it in the list to wait for its time.
   13280                         addProcessToGcListLocked(proc);
   13281                         break;
   13282                     }
   13283                 }
   13284             }
   13285 
   13286             scheduleAppGcsLocked();
   13287         }
   13288     }
   13289 
   13290     /**
   13291      * If all looks good, perform GCs on all processes waiting for them.
   13292      */
   13293     final void performAppGcsIfAppropriateLocked() {
   13294         if (canGcNowLocked()) {
   13295             performAppGcsLocked();
   13296             return;
   13297         }
   13298         // Still not idle, wait some more.
   13299         scheduleAppGcsLocked();
   13300     }
   13301 
   13302     /**
   13303      * Schedule the execution of all pending app GCs.
   13304      */
   13305     final void scheduleAppGcsLocked() {
   13306         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
   13307 
   13308         if (mProcessesToGc.size() > 0) {
   13309             // Schedule a GC for the time to the next process.
   13310             ProcessRecord proc = mProcessesToGc.get(0);
   13311             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
   13312 
   13313             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
   13314             long now = SystemClock.uptimeMillis();
   13315             if (when < (now+GC_TIMEOUT)) {
   13316                 when = now + GC_TIMEOUT;
   13317             }
   13318             mHandler.sendMessageAtTime(msg, when);
   13319         }
   13320     }
   13321 
   13322     /**
   13323      * Add a process to the array of processes waiting to be GCed.  Keeps the
   13324      * list in sorted order by the last GC time.  The process can't already be
   13325      * on the list.
   13326      */
   13327     final void addProcessToGcListLocked(ProcessRecord proc) {
   13328         boolean added = false;
   13329         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
   13330             if (mProcessesToGc.get(i).lastRequestedGc <
   13331                     proc.lastRequestedGc) {
   13332                 added = true;
   13333                 mProcessesToGc.add(i+1, proc);
   13334                 break;
   13335             }
   13336         }
   13337         if (!added) {
   13338             mProcessesToGc.add(0, proc);
   13339         }
   13340     }
   13341 
   13342     /**
   13343      * Set up to ask a process to GC itself.  This will either do it
   13344      * immediately, or put it on the list of processes to gc the next
   13345      * time things are idle.
   13346      */
   13347     final void scheduleAppGcLocked(ProcessRecord app) {
   13348         long now = SystemClock.uptimeMillis();
   13349         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
   13350             return;
   13351         }
   13352         if (!mProcessesToGc.contains(app)) {
   13353             addProcessToGcListLocked(app);
   13354             scheduleAppGcsLocked();
   13355         }
   13356     }
   13357 
   13358     final void checkExcessivePowerUsageLocked(boolean doKills) {
   13359         updateCpuStatsNow();
   13360 
   13361         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   13362         boolean doWakeKills = doKills;
   13363         boolean doCpuKills = doKills;
   13364         if (mLastPowerCheckRealtime == 0) {
   13365             doWakeKills = false;
   13366         }
   13367         if (mLastPowerCheckUptime == 0) {
   13368             doCpuKills = false;
   13369         }
   13370         if (stats.isScreenOn()) {
   13371             doWakeKills = false;
   13372         }
   13373         final long curRealtime = SystemClock.elapsedRealtime();
   13374         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
   13375         final long curUptime = SystemClock.uptimeMillis();
   13376         final long uptimeSince = curUptime - mLastPowerCheckUptime;
   13377         mLastPowerCheckRealtime = curRealtime;
   13378         mLastPowerCheckUptime = curUptime;
   13379         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
   13380             doWakeKills = false;
   13381         }
   13382         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
   13383             doCpuKills = false;
   13384         }
   13385         int i = mLruProcesses.size();
   13386         while (i > 0) {
   13387             i--;
   13388             ProcessRecord app = mLruProcesses.get(i);
   13389             if (!app.keeping) {
   13390                 long wtime;
   13391                 synchronized (stats) {
   13392                     wtime = stats.getProcessWakeTime(app.info.uid,
   13393                             app.pid, curRealtime);
   13394                 }
   13395                 long wtimeUsed = wtime - app.lastWakeTime;
   13396                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
   13397                 if (DEBUG_POWER) {
   13398                     StringBuilder sb = new StringBuilder(128);
   13399                     sb.append("Wake for ");
   13400                     app.toShortString(sb);
   13401                     sb.append(": over ");
   13402                     TimeUtils.formatDuration(realtimeSince, sb);
   13403                     sb.append(" used ");
   13404                     TimeUtils.formatDuration(wtimeUsed, sb);
   13405                     sb.append(" (");
   13406                     sb.append((wtimeUsed*100)/realtimeSince);
   13407                     sb.append("%)");
   13408                     Slog.i(TAG, sb.toString());
   13409                     sb.setLength(0);
   13410                     sb.append("CPU for ");
   13411                     app.toShortString(sb);
   13412                     sb.append(": over ");
   13413                     TimeUtils.formatDuration(uptimeSince, sb);
   13414                     sb.append(" used ");
   13415                     TimeUtils.formatDuration(cputimeUsed, sb);
   13416                     sb.append(" (");
   13417                     sb.append((cputimeUsed*100)/uptimeSince);
   13418                     sb.append("%)");
   13419                     Slog.i(TAG, sb.toString());
   13420                 }
   13421                 // If a process has held a wake lock for more
   13422                 // than 50% of the time during this period,
   13423                 // that sounds bad.  Kill!
   13424                 if (doWakeKills && realtimeSince > 0
   13425                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
   13426                     synchronized (stats) {
   13427                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
   13428                                 realtimeSince, wtimeUsed);
   13429                     }
   13430                     Slog.w(TAG, "Excessive wake lock in " + app.processName
   13431                             + " (pid " + app.pid + "): held " + wtimeUsed
   13432                             + " during " + realtimeSince);
   13433                     EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
   13434                             app.processName, app.setAdj, "excessive wake lock");
   13435                     Process.killProcessQuiet(app.pid);
   13436                 } else if (doCpuKills && uptimeSince > 0
   13437                         && ((cputimeUsed*100)/uptimeSince) >= 50) {
   13438                     synchronized (stats) {
   13439                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
   13440                                 uptimeSince, cputimeUsed);
   13441                     }
   13442                     Slog.w(TAG, "Excessive CPU in " + app.processName
   13443                             + " (pid " + app.pid + "): used " + cputimeUsed
   13444                             + " during " + uptimeSince);
   13445                     EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
   13446                             app.processName, app.setAdj, "excessive cpu");
   13447                     Process.killProcessQuiet(app.pid);
   13448                 } else {
   13449                     app.lastWakeTime = wtime;
   13450                     app.lastCpuTime = app.curCpuTime;
   13451                 }
   13452             }
   13453         }
   13454     }
   13455 
   13456     private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
   13457             int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
   13458         app.hiddenAdj = hiddenAdj;
   13459         app.clientHiddenAdj = clientHiddenAdj;
   13460         app.emptyAdj = emptyAdj;
   13461 
   13462         if (app.thread == null) {
   13463             return false;
   13464         }
   13465 
   13466         final boolean wasKeeping = app.keeping;
   13467 
   13468         boolean success = true;
   13469 
   13470         computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll);
   13471 
   13472         if (app.curRawAdj != app.setRawAdj) {
   13473             if (wasKeeping && !app.keeping) {
   13474                 // This app is no longer something we want to keep.  Note
   13475                 // its current wake lock time to later know to kill it if
   13476                 // it is not behaving well.
   13477                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   13478                 synchronized (stats) {
   13479                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
   13480                             app.pid, SystemClock.elapsedRealtime());
   13481                 }
   13482                 app.lastCpuTime = app.curCpuTime;
   13483             }
   13484 
   13485             app.setRawAdj = app.curRawAdj;
   13486         }
   13487 
   13488         if (app.curAdj != app.setAdj) {
   13489             if (Process.setOomAdj(app.pid, app.curAdj)) {
   13490                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
   13491                     TAG, "Set " + app.pid + " " + app.processName +
   13492                     " adj " + app.curAdj + ": " + app.adjType);
   13493                 app.setAdj = app.curAdj;
   13494             } else {
   13495                 success = false;
   13496                 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
   13497             }
   13498         }
   13499         if (app.setSchedGroup != app.curSchedGroup) {
   13500             app.setSchedGroup = app.curSchedGroup;
   13501             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   13502                     "Setting process group of " + app.processName
   13503                     + " to " + app.curSchedGroup);
   13504             if (app.waitingToKill != null &&
   13505                     app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
   13506                 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
   13507                 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
   13508                         app.processName, app.setAdj, app.waitingToKill);
   13509                 app.killedBackground = true;
   13510                 Process.killProcessQuiet(app.pid);
   13511                 success = false;
   13512             } else {
   13513                 if (true) {
   13514                     long oldId = Binder.clearCallingIdentity();
   13515                     try {
   13516                         Process.setProcessGroup(app.pid, app.curSchedGroup);
   13517                     } catch (Exception e) {
   13518                         Slog.w(TAG, "Failed setting process group of " + app.pid
   13519                                 + " to " + app.curSchedGroup);
   13520                         e.printStackTrace();
   13521                     } finally {
   13522                         Binder.restoreCallingIdentity(oldId);
   13523                     }
   13524                 } else {
   13525                     if (app.thread != null) {
   13526                         try {
   13527                             app.thread.setSchedulingGroup(app.curSchedGroup);
   13528                         } catch (RemoteException e) {
   13529                         }
   13530                     }
   13531                 }
   13532             }
   13533         }
   13534         return success;
   13535     }
   13536 
   13537     private final ActivityRecord resumedAppLocked() {
   13538         ActivityRecord resumedActivity = mMainStack.mResumedActivity;
   13539         if (resumedActivity == null || resumedActivity.app == null) {
   13540             resumedActivity = mMainStack.mPausingActivity;
   13541             if (resumedActivity == null || resumedActivity.app == null) {
   13542                 resumedActivity = mMainStack.topRunningActivityLocked(null);
   13543             }
   13544         }
   13545         return resumedActivity;
   13546     }
   13547 
   13548     final boolean updateOomAdjLocked(ProcessRecord app) {
   13549         final ActivityRecord TOP_ACT = resumedAppLocked();
   13550         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   13551         int curAdj = app.curAdj;
   13552         final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
   13553             && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
   13554 
   13555         mAdjSeq++;
   13556 
   13557         boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj,
   13558                 app.emptyAdj, TOP_APP, false);
   13559         final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
   13560             && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
   13561         if (nowHidden != wasHidden) {
   13562             // Changed to/from hidden state, so apps after it in the LRU
   13563             // list may also be changed.
   13564             updateOomAdjLocked();
   13565         }
   13566         return success;
   13567     }
   13568 
   13569     final void updateOomAdjLocked() {
   13570         final ActivityRecord TOP_ACT = resumedAppLocked();
   13571         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   13572         final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME;
   13573 
   13574         if (false) {
   13575             RuntimeException e = new RuntimeException();
   13576             e.fillInStackTrace();
   13577             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
   13578         }
   13579 
   13580         mAdjSeq++;
   13581         mNewNumServiceProcs = 0;
   13582 
   13583         final int emptyProcessLimit;
   13584         final int hiddenProcessLimit;
   13585         if (mProcessLimit <= 0) {
   13586             emptyProcessLimit = hiddenProcessLimit = 0;
   13587         } else if (mProcessLimit == 1) {
   13588             emptyProcessLimit = 1;
   13589             hiddenProcessLimit = 0;
   13590         } else {
   13591             emptyProcessLimit = (mProcessLimit*2)/3;
   13592             hiddenProcessLimit = mProcessLimit - emptyProcessLimit;
   13593         }
   13594 
   13595         // Let's determine how many processes we have running vs.
   13596         // how many slots we have for background processes; we may want
   13597         // to put multiple processes in a slot of there are enough of
   13598         // them.
   13599         int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
   13600                 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
   13601         int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs;
   13602         if (numEmptyProcs > hiddenProcessLimit) {
   13603             // If there are more empty processes than our limit on hidden
   13604             // processes, then use the hidden process limit for the factor.
   13605             // This ensures that the really old empty processes get pushed
   13606             // down to the bottom, so if we are running low on memory we will
   13607             // have a better chance at keeping around more hidden processes
   13608             // instead of a gazillion empty processes.
   13609             numEmptyProcs = hiddenProcessLimit;
   13610         }
   13611         int emptyFactor = numEmptyProcs/numSlots;
   13612         if (emptyFactor < 1) emptyFactor = 1;
   13613         int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
   13614         if (hiddenFactor < 1) hiddenFactor = 1;
   13615         int stepHidden = 0;
   13616         int stepEmpty = 0;
   13617         int numHidden = 0;
   13618         int numEmpty = 0;
   13619         int numTrimming = 0;
   13620 
   13621         mNumNonHiddenProcs = 0;
   13622         mNumHiddenProcs = 0;
   13623 
   13624         // First update the OOM adjustment for each of the
   13625         // application processes based on their current state.
   13626         int i = mLruProcesses.size();
   13627         int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
   13628         int nextHiddenAdj = curHiddenAdj+1;
   13629         int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
   13630         int nextEmptyAdj = curEmptyAdj+2;
   13631         int curClientHiddenAdj = curEmptyAdj;
   13632         while (i > 0) {
   13633             i--;
   13634             ProcessRecord app = mLruProcesses.get(i);
   13635             //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
   13636             updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true);
   13637             if (!app.killedBackground) {
   13638                 if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
   13639                     // This process was assigned as a hidden process...  step the
   13640                     // hidden level.
   13641                     mNumHiddenProcs++;
   13642                     if (curHiddenAdj != nextHiddenAdj) {
   13643                         stepHidden++;
   13644                         if (stepHidden >= hiddenFactor) {
   13645                             stepHidden = 0;
   13646                             curHiddenAdj = nextHiddenAdj;
   13647                             nextHiddenAdj += 2;
   13648                             if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
   13649                                 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
   13650                             }
   13651                             if (curClientHiddenAdj <= curHiddenAdj) {
   13652                                 curClientHiddenAdj = curHiddenAdj + 1;
   13653                                 if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
   13654                                     curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
   13655                                 }
   13656                             }
   13657                         }
   13658                     }
   13659                     numHidden++;
   13660                     if (numHidden > hiddenProcessLimit) {
   13661                         Slog.i(TAG, "No longer want " + app.processName
   13662                                 + " (pid " + app.pid + "): hidden #" + numHidden);
   13663                         EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
   13664                                 app.processName, app.setAdj, "too many background");
   13665                         app.killedBackground = true;
   13666                         Process.killProcessQuiet(app.pid);
   13667                     }
   13668                 } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) {
   13669                     // This process has a client that has activities.  We will have
   13670                     // given it the current hidden adj; here we will just leave it
   13671                     // without stepping the hidden adj.
   13672                     curClientHiddenAdj++;
   13673                     if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
   13674                         curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
   13675                     }
   13676                 } else {
   13677                     if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
   13678                         // This process was assigned as an empty process...  step the
   13679                         // empty level.
   13680                         if (curEmptyAdj != nextEmptyAdj) {
   13681                             stepEmpty++;
   13682                             if (stepEmpty >= emptyFactor) {
   13683                                 stepEmpty = 0;
   13684                                 curEmptyAdj = nextEmptyAdj;
   13685                                 nextEmptyAdj += 2;
   13686                                 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
   13687                                     nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
   13688                                 }
   13689                             }
   13690                         }
   13691                     } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
   13692                         mNumNonHiddenProcs++;
   13693                     }
   13694                     if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
   13695                             && !app.hasClientActivities) {
   13696                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
   13697                                 && app.lastActivityTime < oldTime) {
   13698                             Slog.i(TAG, "No longer want " + app.processName
   13699                                     + " (pid " + app.pid + "): empty for "
   13700                                     + ((oldTime+ProcessList.MAX_EMPTY_TIME-app.lastActivityTime)
   13701                                             / 1000) + "s");
   13702                             EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
   13703                                     app.processName, app.setAdj, "old background process");
   13704                             app.killedBackground = true;
   13705                             Process.killProcessQuiet(app.pid);
   13706                         } else {
   13707                             numEmpty++;
   13708                             if (numEmpty > emptyProcessLimit) {
   13709                                 Slog.i(TAG, "No longer want " + app.processName
   13710                                         + " (pid " + app.pid + "): empty #" + numEmpty);
   13711                                 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
   13712                                         app.processName, app.setAdj, "too many background");
   13713                                 app.killedBackground = true;
   13714                                 Process.killProcessQuiet(app.pid);
   13715                             }
   13716                         }
   13717                     }
   13718                 }
   13719                 if (app.isolated && app.services.size() <= 0) {
   13720                     // If this is an isolated process, and there are no
   13721                     // services running in it, then the process is no longer
   13722                     // needed.  We agressively kill these because we can by
   13723                     // definition not re-use the same process again, and it is
   13724                     // good to avoid having whatever code was running in them
   13725                     // left sitting around after no longer needed.
   13726                     Slog.i(TAG, "Isolated process " + app.processName
   13727                             + " (pid " + app.pid + ") no longer needed");
   13728                     EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
   13729                             app.processName, app.setAdj, "isolated not needed");
   13730                     app.killedBackground = true;
   13731                     Process.killProcessQuiet(app.pid);
   13732                 }
   13733                 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
   13734                         && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
   13735                         && !app.killedBackground) {
   13736                     numTrimming++;
   13737                 }
   13738             }
   13739         }
   13740 
   13741         mNumServiceProcs = mNewNumServiceProcs;
   13742 
   13743         // Now determine the memory trimming level of background processes.
   13744         // Unfortunately we need to start at the back of the list to do this
   13745         // properly.  We only do this if the number of background apps we
   13746         // are managing to keep around is less than half the maximum we desire;
   13747         // if we are keeping a good number around, we'll let them use whatever
   13748         // memory they want.
   13749         if (numHidden <= ProcessList.TRIM_HIDDEN_APPS
   13750                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
   13751             final int numHiddenAndEmpty = numHidden + numEmpty;
   13752             final int N = mLruProcesses.size();
   13753             int factor = numTrimming/3;
   13754             int minFactor = 2;
   13755             if (mHomeProcess != null) minFactor++;
   13756             if (mPreviousProcess != null) minFactor++;
   13757             if (factor < minFactor) factor = minFactor;
   13758             int step = 0;
   13759             int fgTrimLevel;
   13760             if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
   13761                 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
   13762             } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
   13763                 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
   13764             } else {
   13765                 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
   13766             }
   13767             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
   13768             for (i=0; i<N; i++) {
   13769                 ProcessRecord app = mLruProcesses.get(i);
   13770                 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
   13771                         && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
   13772                         && !app.killedBackground) {
   13773                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
   13774                         try {
   13775                             app.thread.scheduleTrimMemory(curLevel);
   13776                         } catch (RemoteException e) {
   13777                         }
   13778                         if (false) {
   13779                             // For now we won't do this; our memory trimming seems
   13780                             // to be good enough at this point that destroying
   13781                             // activities causes more harm than good.
   13782                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
   13783                                     && app != mHomeProcess && app != mPreviousProcess) {
   13784                                 // Need to do this on its own message because the stack may not
   13785                                 // be in a consistent state at this point.
   13786                                 // For these apps we will also finish their activities
   13787                                 // to help them free memory.
   13788                                 mMainStack.scheduleDestroyActivities(app, false, "trim");
   13789                             }
   13790                         }
   13791                     }
   13792                     app.trimMemoryLevel = curLevel;
   13793                     step++;
   13794                     if (step >= factor) {
   13795                         step = 0;
   13796                         switch (curLevel) {
   13797                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
   13798                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
   13799                                 break;
   13800                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
   13801                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   13802                                 break;
   13803                         }
   13804                     }
   13805                 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   13806                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
   13807                             && app.thread != null) {
   13808                         try {
   13809                             app.thread.scheduleTrimMemory(
   13810                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   13811                         } catch (RemoteException e) {
   13812                         }
   13813                     }
   13814                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   13815                 } else {
   13816                     if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
   13817                             && app.pendingUiClean) {
   13818                         // If this application is now in the background and it
   13819                         // had done UI, then give it the special trim level to
   13820                         // have it free UI resources.
   13821                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
   13822                         if (app.trimMemoryLevel < level && app.thread != null) {
   13823                             try {
   13824                                 app.thread.scheduleTrimMemory(level);
   13825                             } catch (RemoteException e) {
   13826                             }
   13827                         }
   13828                         app.pendingUiClean = false;
   13829                     }
   13830                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
   13831                         try {
   13832                             app.thread.scheduleTrimMemory(fgTrimLevel);
   13833                         } catch (RemoteException e) {
   13834                         }
   13835                     }
   13836                     app.trimMemoryLevel = fgTrimLevel;
   13837                 }
   13838             }
   13839         } else {
   13840             final int N = mLruProcesses.size();
   13841             for (i=0; i<N; i++) {
   13842                 ProcessRecord app = mLruProcesses.get(i);
   13843                 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
   13844                         && app.pendingUiClean) {
   13845                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
   13846                             && app.thread != null) {
   13847                         try {
   13848                             app.thread.scheduleTrimMemory(
   13849                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   13850                         } catch (RemoteException e) {
   13851                         }
   13852                     }
   13853                     app.pendingUiClean = false;
   13854                 }
   13855                 app.trimMemoryLevel = 0;
   13856             }
   13857         }
   13858 
   13859         if (mAlwaysFinishActivities) {
   13860             // Need to do this on its own message because the stack may not
   13861             // be in a consistent state at this point.
   13862             mMainStack.scheduleDestroyActivities(null, false, "always-finish");
   13863         }
   13864     }
   13865 
   13866     final void trimApplications() {
   13867         synchronized (this) {
   13868             int i;
   13869 
   13870             // First remove any unused application processes whose package
   13871             // has been removed.
   13872             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
   13873                 final ProcessRecord app = mRemovedProcesses.get(i);
   13874                 if (app.activities.size() == 0
   13875                         && app.curReceiver == null && app.services.size() == 0) {
   13876                     Slog.i(
   13877                         TAG, "Exiting empty application process "
   13878                         + app.processName + " ("
   13879                         + (app.thread != null ? app.thread.asBinder() : null)
   13880                         + ")\n");
   13881                     if (app.pid > 0 && app.pid != MY_PID) {
   13882                         EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
   13883                                 app.processName, app.setAdj, "empty");
   13884                         Process.killProcessQuiet(app.pid);
   13885                     } else {
   13886                         try {
   13887                             app.thread.scheduleExit();
   13888                         } catch (Exception e) {
   13889                             // Ignore exceptions.
   13890                         }
   13891                     }
   13892                     cleanUpApplicationRecordLocked(app, false, true, -1);
   13893                     mRemovedProcesses.remove(i);
   13894 
   13895                     if (app.persistent) {
   13896                         if (app.persistent) {
   13897                             addAppLocked(app.info, false);
   13898                         }
   13899                     }
   13900                 }
   13901             }
   13902 
   13903             // Now update the oom adj for all processes.
   13904             updateOomAdjLocked();
   13905         }
   13906     }
   13907 
   13908     /** This method sends the specified signal to each of the persistent apps */
   13909     public void signalPersistentProcesses(int sig) throws RemoteException {
   13910         if (sig != Process.SIGNAL_USR1) {
   13911             throw new SecurityException("Only SIGNAL_USR1 is allowed");
   13912         }
   13913 
   13914         synchronized (this) {
   13915             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
   13916                     != PackageManager.PERMISSION_GRANTED) {
   13917                 throw new SecurityException("Requires permission "
   13918                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
   13919             }
   13920 
   13921             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   13922                 ProcessRecord r = mLruProcesses.get(i);
   13923                 if (r.thread != null && r.persistent) {
   13924                     Process.sendSignal(r.pid, sig);
   13925                 }
   13926             }
   13927         }
   13928     }
   13929 
   13930     private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
   13931         if (proc == null || proc == mProfileProc) {
   13932             proc = mProfileProc;
   13933             path = mProfileFile;
   13934             profileType = mProfileType;
   13935             clearProfilerLocked();
   13936         }
   13937         if (proc == null) {
   13938             return;
   13939         }
   13940         try {
   13941             proc.thread.profilerControl(false, path, null, profileType);
   13942         } catch (RemoteException e) {
   13943             throw new IllegalStateException("Process disappeared");
   13944         }
   13945     }
   13946 
   13947     private void clearProfilerLocked() {
   13948         if (mProfileFd != null) {
   13949             try {
   13950                 mProfileFd.close();
   13951             } catch (IOException e) {
   13952             }
   13953         }
   13954         mProfileApp = null;
   13955         mProfileProc = null;
   13956         mProfileFile = null;
   13957         mProfileType = 0;
   13958         mAutoStopProfiler = false;
   13959     }
   13960 
   13961     public boolean profileControl(String process, int userId, boolean start,
   13962             String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
   13963 
   13964         try {
   13965             synchronized (this) {
   13966                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   13967                 // its own permission.
   13968                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   13969                         != PackageManager.PERMISSION_GRANTED) {
   13970                     throw new SecurityException("Requires permission "
   13971                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   13972                 }
   13973 
   13974                 if (start && fd == null) {
   13975                     throw new IllegalArgumentException("null fd");
   13976                 }
   13977 
   13978                 ProcessRecord proc = null;
   13979                 if (process != null) {
   13980                     proc = findProcessLocked(process, userId, "profileControl");
   13981                 }
   13982 
   13983                 if (start && (proc == null || proc.thread == null)) {
   13984                     throw new IllegalArgumentException("Unknown process: " + process);
   13985                 }
   13986 
   13987                 if (start) {
   13988                     stopProfilerLocked(null, null, 0);
   13989                     setProfileApp(proc.info, proc.processName, path, fd, false);
   13990                     mProfileProc = proc;
   13991                     mProfileType = profileType;
   13992                     try {
   13993                         fd = fd.dup();
   13994                     } catch (IOException e) {
   13995                         fd = null;
   13996                     }
   13997                     proc.thread.profilerControl(start, path, fd, profileType);
   13998                     fd = null;
   13999                     mProfileFd = null;
   14000                 } else {
   14001                     stopProfilerLocked(proc, path, profileType);
   14002                     if (fd != null) {
   14003                         try {
   14004                             fd.close();
   14005                         } catch (IOException e) {
   14006                         }
   14007                     }
   14008                 }
   14009 
   14010                 return true;
   14011             }
   14012         } catch (RemoteException e) {
   14013             throw new IllegalStateException("Process disappeared");
   14014         } finally {
   14015             if (fd != null) {
   14016                 try {
   14017                     fd.close();
   14018                 } catch (IOException e) {
   14019                 }
   14020             }
   14021         }
   14022     }
   14023 
   14024     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
   14025         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   14026                 userId, true, true, callName, null);
   14027         ProcessRecord proc = null;
   14028         try {
   14029             int pid = Integer.parseInt(process);
   14030             synchronized (mPidsSelfLocked) {
   14031                 proc = mPidsSelfLocked.get(pid);
   14032             }
   14033         } catch (NumberFormatException e) {
   14034         }
   14035 
   14036         if (proc == null) {
   14037             HashMap<String, SparseArray<ProcessRecord>> all
   14038                     = mProcessNames.getMap();
   14039             SparseArray<ProcessRecord> procs = all.get(process);
   14040             if (procs != null && procs.size() > 0) {
   14041                 proc = procs.valueAt(0);
   14042                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
   14043                     for (int i=1; i<procs.size(); i++) {
   14044                         ProcessRecord thisProc = procs.valueAt(i);
   14045                         if (thisProc.userId == userId) {
   14046                             proc = thisProc;
   14047                             break;
   14048                         }
   14049                     }
   14050                 }
   14051             }
   14052         }
   14053 
   14054         return proc;
   14055     }
   14056 
   14057     public boolean dumpHeap(String process, int userId, boolean managed,
   14058             String path, ParcelFileDescriptor fd) throws RemoteException {
   14059 
   14060         try {
   14061             synchronized (this) {
   14062                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   14063                 // its own permission (same as profileControl).
   14064                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   14065                         != PackageManager.PERMISSION_GRANTED) {
   14066                     throw new SecurityException("Requires permission "
   14067                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   14068                 }
   14069 
   14070                 if (fd == null) {
   14071                     throw new IllegalArgumentException("null fd");
   14072                 }
   14073 
   14074                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
   14075                 if (proc == null || proc.thread == null) {
   14076                     throw new IllegalArgumentException("Unknown process: " + process);
   14077                 }
   14078 
   14079                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   14080                 if (!isDebuggable) {
   14081                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   14082                         throw new SecurityException("Process not debuggable: " + proc);
   14083                     }
   14084                 }
   14085 
   14086                 proc.thread.dumpHeap(managed, path, fd);
   14087                 fd = null;
   14088                 return true;
   14089             }
   14090         } catch (RemoteException e) {
   14091             throw new IllegalStateException("Process disappeared");
   14092         } finally {
   14093             if (fd != null) {
   14094                 try {
   14095                     fd.close();
   14096                 } catch (IOException e) {
   14097                 }
   14098             }
   14099         }
   14100     }
   14101 
   14102     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
   14103     public void monitor() {
   14104         synchronized (this) { }
   14105     }
   14106 
   14107     void onCoreSettingsChange(Bundle settings) {
   14108         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   14109             ProcessRecord processRecord = mLruProcesses.get(i);
   14110             try {
   14111                 if (processRecord.thread != null) {
   14112                     processRecord.thread.setCoreSettings(settings);
   14113                 }
   14114             } catch (RemoteException re) {
   14115                 /* ignore */
   14116             }
   14117         }
   14118     }
   14119 
   14120     // Multi-user methods
   14121 
   14122     @Override
   14123     public boolean switchUser(int userId) {
   14124         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
   14125                 != PackageManager.PERMISSION_GRANTED) {
   14126             String msg = "Permission Denial: switchUser() from pid="
   14127                     + Binder.getCallingPid()
   14128                     + ", uid=" + Binder.getCallingUid()
   14129                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
   14130             Slog.w(TAG, msg);
   14131             throw new SecurityException(msg);
   14132         }
   14133 
   14134         final long ident = Binder.clearCallingIdentity();
   14135         try {
   14136             synchronized (this) {
   14137                 final int oldUserId = mCurrentUserId;
   14138                 if (oldUserId == userId) {
   14139                     return true;
   14140                 }
   14141 
   14142                 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
   14143                 if (userInfo == null) {
   14144                     Slog.w(TAG, "No user info for user #" + userId);
   14145                     return false;
   14146                 }
   14147 
   14148                 mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
   14149                         R.anim.screen_user_enter);
   14150 
   14151                 boolean needStart = false;
   14152 
   14153                 // If the user we are switching to is not currently started, then
   14154                 // we need to start it now.
   14155                 if (mStartedUsers.get(userId) == null) {
   14156                     mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
   14157                     updateStartedUserArrayLocked();
   14158                     needStart = true;
   14159                 }
   14160 
   14161                 mCurrentUserId = userId;
   14162                 mCurrentUserArray = new int[] { userId };
   14163                 final Integer userIdInt = Integer.valueOf(userId);
   14164                 mUserLru.remove(userIdInt);
   14165                 mUserLru.add(userIdInt);
   14166 
   14167                 mWindowManager.setCurrentUser(userId);
   14168 
   14169                 // Once the internal notion of the active user has switched, we lock the device
   14170                 // with the option to show the user switcher on the keyguard.
   14171                 mWindowManager.lockNow(LockPatternUtils.USER_SWITCH_LOCK_OPTIONS);
   14172 
   14173                 final UserStartedState uss = mStartedUsers.get(userId);
   14174 
   14175                 // Make sure user is in the started state.  If it is currently
   14176                 // stopping, we need to knock that off.
   14177                 if (uss.mState == UserStartedState.STATE_STOPPING) {
   14178                     // If we are stopping, we haven't sent ACTION_SHUTDOWN,
   14179                     // so we can just fairly silently bring the user back from
   14180                     // the almost-dead.
   14181                     uss.mState = UserStartedState.STATE_RUNNING;
   14182                     updateStartedUserArrayLocked();
   14183                     needStart = true;
   14184                 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
   14185                     // This means ACTION_SHUTDOWN has been sent, so we will
   14186                     // need to treat this as a new boot of the user.
   14187                     uss.mState = UserStartedState.STATE_BOOTING;
   14188                     updateStartedUserArrayLocked();
   14189                     needStart = true;
   14190                 }
   14191 
   14192                 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
   14193                 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
   14194                 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
   14195                         oldUserId, userId, uss));
   14196                 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
   14197                         oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
   14198                 if (needStart) {
   14199                     Intent intent = new Intent(Intent.ACTION_USER_STARTED);
   14200                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   14201                             | Intent.FLAG_RECEIVER_FOREGROUND);
   14202                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   14203                     broadcastIntentLocked(null, null, intent,
   14204                             null, null, 0, null, null, null,
   14205                             false, false, MY_PID, Process.SYSTEM_UID, userId);
   14206                 }
   14207 
   14208                 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
   14209                     if (userId != 0) {
   14210                         Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
   14211                         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   14212                         broadcastIntentLocked(null, null, intent, null,
   14213                                 new IIntentReceiver.Stub() {
   14214                                     public void performReceive(Intent intent, int resultCode,
   14215                                             String data, Bundle extras, boolean ordered,
   14216                                             boolean sticky, int sendingUser) {
   14217                                         userInitialized(uss);
   14218                                     }
   14219                                 }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
   14220                                 userId);
   14221                         uss.initializing = true;
   14222                     } else {
   14223                         getUserManagerLocked().makeInitialized(userInfo.id);
   14224                     }
   14225                 }
   14226 
   14227                 boolean haveActivities = mMainStack.switchUserLocked(userId, uss);
   14228                 if (!haveActivities) {
   14229                     startHomeActivityLocked(userId);
   14230                 }
   14231 
   14232                 getUserManagerLocked().userForeground(userId);
   14233                 sendUserSwitchBroadcastsLocked(oldUserId, userId);
   14234                 if (needStart) {
   14235                     Intent intent = new Intent(Intent.ACTION_USER_STARTING);
   14236                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   14237                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   14238                     broadcastIntentLocked(null, null, intent,
   14239                             null, new IIntentReceiver.Stub() {
   14240                                 @Override
   14241                                 public void performReceive(Intent intent, int resultCode, String data,
   14242                                         Bundle extras, boolean ordered, boolean sticky, int sendingUser)
   14243                                         throws RemoteException {
   14244                                 }
   14245                             }, 0, null, null,
   14246                             android.Manifest.permission.INTERACT_ACROSS_USERS,
   14247                             false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   14248                 }
   14249             }
   14250         } finally {
   14251             Binder.restoreCallingIdentity(ident);
   14252         }
   14253 
   14254         return true;
   14255     }
   14256 
   14257     void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
   14258         long ident = Binder.clearCallingIdentity();
   14259         try {
   14260             Intent intent;
   14261             if (oldUserId >= 0) {
   14262                 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
   14263                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   14264                         | Intent.FLAG_RECEIVER_FOREGROUND);
   14265                 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
   14266                 broadcastIntentLocked(null, null, intent,
   14267                         null, null, 0, null, null, null,
   14268                         false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
   14269             }
   14270             if (newUserId >= 0) {
   14271                 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
   14272                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   14273                         | Intent.FLAG_RECEIVER_FOREGROUND);
   14274                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
   14275                 broadcastIntentLocked(null, null, intent,
   14276                         null, null, 0, null, null, null,
   14277                         false, false, MY_PID, Process.SYSTEM_UID, newUserId);
   14278                 intent = new Intent(Intent.ACTION_USER_SWITCHED);
   14279                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   14280                         | Intent.FLAG_RECEIVER_FOREGROUND);
   14281                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
   14282                 broadcastIntentLocked(null, null, intent,
   14283                         null, null, 0, null, null,
   14284                         android.Manifest.permission.MANAGE_USERS,
   14285                         false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   14286             }
   14287         } finally {
   14288             Binder.restoreCallingIdentity(ident);
   14289         }
   14290     }
   14291 
   14292     void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
   14293             final int newUserId) {
   14294         final int N = mUserSwitchObservers.beginBroadcast();
   14295         if (N > 0) {
   14296             final IRemoteCallback callback = new IRemoteCallback.Stub() {
   14297                 int mCount = 0;
   14298                 @Override
   14299                 public void sendResult(Bundle data) throws RemoteException {
   14300                     synchronized (ActivityManagerService.this) {
   14301                         if (mCurUserSwitchCallback == this) {
   14302                             mCount++;
   14303                             if (mCount == N) {
   14304                                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
   14305                             }
   14306                         }
   14307                     }
   14308                 }
   14309             };
   14310             synchronized (this) {
   14311                 uss.switching = true;
   14312                 mCurUserSwitchCallback = callback;
   14313             }
   14314             for (int i=0; i<N; i++) {
   14315                 try {
   14316                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
   14317                             newUserId, callback);
   14318                 } catch (RemoteException e) {
   14319                 }
   14320             }
   14321         } else {
   14322             synchronized (this) {
   14323                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
   14324             }
   14325         }
   14326         mUserSwitchObservers.finishBroadcast();
   14327     }
   14328 
   14329     void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
   14330         synchronized (this) {
   14331             Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
   14332             sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
   14333         }
   14334     }
   14335 
   14336     void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
   14337         mCurUserSwitchCallback = null;
   14338         mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
   14339         mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
   14340                 oldUserId, newUserId, uss));
   14341     }
   14342 
   14343     void userInitialized(UserStartedState uss) {
   14344         synchronized (ActivityManagerService.this) {
   14345             getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
   14346             uss.initializing = false;
   14347             completeSwitchAndInitalizeLocked(uss);
   14348         }
   14349     }
   14350 
   14351     void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
   14352         final int N = mUserSwitchObservers.beginBroadcast();
   14353         for (int i=0; i<N; i++) {
   14354             try {
   14355                 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
   14356             } catch (RemoteException e) {
   14357             }
   14358         }
   14359         mUserSwitchObservers.finishBroadcast();
   14360         synchronized (this) {
   14361             uss.switching = false;
   14362             completeSwitchAndInitalizeLocked(uss);
   14363         }
   14364     }
   14365 
   14366     void completeSwitchAndInitalizeLocked(UserStartedState uss) {
   14367         if (!uss.switching && !uss.initializing) {
   14368             mWindowManager.stopFreezingScreen();
   14369         }
   14370     }
   14371 
   14372     void finishUserSwitch(UserStartedState uss) {
   14373         synchronized (this) {
   14374             if (uss.mState == UserStartedState.STATE_BOOTING
   14375                     && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
   14376                 uss.mState = UserStartedState.STATE_RUNNING;
   14377                 final int userId = uss.mHandle.getIdentifier();
   14378                 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
   14379                 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   14380                 broadcastIntentLocked(null, null, intent,
   14381                         null, null, 0, null, null,
   14382                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
   14383                         false, false, MY_PID, Process.SYSTEM_UID, userId);
   14384             }
   14385             int num = mUserLru.size();
   14386             int i = 0;
   14387             while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
   14388                 Integer oldUserId = mUserLru.get(i);
   14389                 UserStartedState oldUss = mStartedUsers.get(oldUserId);
   14390                 if (oldUss == null) {
   14391                     // Shouldn't happen, but be sane if it does.
   14392                     mUserLru.remove(i);
   14393                     num--;
   14394                     continue;
   14395                 }
   14396                 if (oldUss.mState == UserStartedState.STATE_STOPPING
   14397                         || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
   14398                     // This user is already stopping, doesn't count.
   14399                     num--;
   14400                     i++;
   14401                     continue;
   14402                 }
   14403                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
   14404                     // Owner and current can't be stopped, but count as running.
   14405                     i++;
   14406                     continue;
   14407                 }
   14408                 // This is a user to be stopped.
   14409                 stopUserLocked(oldUserId, null);
   14410                 num--;
   14411                 i++;
   14412             }
   14413         }
   14414     }
   14415 
   14416     @Override
   14417     public int stopUser(final int userId, final IStopUserCallback callback) {
   14418         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
   14419                 != PackageManager.PERMISSION_GRANTED) {
   14420             String msg = "Permission Denial: switchUser() from pid="
   14421                     + Binder.getCallingPid()
   14422                     + ", uid=" + Binder.getCallingUid()
   14423                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
   14424             Slog.w(TAG, msg);
   14425             throw new SecurityException(msg);
   14426         }
   14427         if (userId <= 0) {
   14428             throw new IllegalArgumentException("Can't stop primary user " + userId);
   14429         }
   14430         synchronized (this) {
   14431             return stopUserLocked(userId, callback);
   14432         }
   14433     }
   14434 
   14435     private int stopUserLocked(final int userId, final IStopUserCallback callback) {
   14436         if (mCurrentUserId == userId) {
   14437             return ActivityManager.USER_OP_IS_CURRENT;
   14438         }
   14439 
   14440         final UserStartedState uss = mStartedUsers.get(userId);
   14441         if (uss == null) {
   14442             // User is not started, nothing to do...  but we do need to
   14443             // callback if requested.
   14444             if (callback != null) {
   14445                 mHandler.post(new Runnable() {
   14446                     @Override
   14447                     public void run() {
   14448                         try {
   14449                             callback.userStopped(userId);
   14450                         } catch (RemoteException e) {
   14451                         }
   14452                     }
   14453                 });
   14454             }
   14455             return ActivityManager.USER_OP_SUCCESS;
   14456         }
   14457 
   14458         if (callback != null) {
   14459             uss.mStopCallbacks.add(callback);
   14460         }
   14461 
   14462         if (uss.mState != UserStartedState.STATE_STOPPING
   14463                 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
   14464             uss.mState = UserStartedState.STATE_STOPPING;
   14465             updateStartedUserArrayLocked();
   14466 
   14467             long ident = Binder.clearCallingIdentity();
   14468             try {
   14469                 // We are going to broadcast ACTION_USER_STOPPING and then
   14470                 // once that is down send a final ACTION_SHUTDOWN and then
   14471                 // stop the user.
   14472                 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
   14473                 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   14474                 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   14475                 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
   14476                 // This is the result receiver for the final shutdown broadcast.
   14477                 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
   14478                     @Override
   14479                     public void performReceive(Intent intent, int resultCode, String data,
   14480                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
   14481                         finishUserStop(uss);
   14482                     }
   14483                 };
   14484                 // This is the result receiver for the initial stopping broadcast.
   14485                 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
   14486                     @Override
   14487                     public void performReceive(Intent intent, int resultCode, String data,
   14488                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
   14489                         // On to the next.
   14490                         synchronized (ActivityManagerService.this) {
   14491                             if (uss.mState != UserStartedState.STATE_STOPPING) {
   14492                                 // Whoops, we are being started back up.  Abort, abort!
   14493                                 return;
   14494                             }
   14495                             uss.mState = UserStartedState.STATE_SHUTDOWN;
   14496                         }
   14497                         broadcastIntentLocked(null, null, shutdownIntent,
   14498                                 null, shutdownReceiver, 0, null, null, null,
   14499                                 true, false, MY_PID, Process.SYSTEM_UID, userId);
   14500                     }
   14501                 };
   14502                 // Kick things off.
   14503                 broadcastIntentLocked(null, null, stoppingIntent,
   14504                         null, stoppingReceiver, 0, null, null,
   14505                         android.Manifest.permission.INTERACT_ACROSS_USERS,
   14506                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   14507             } finally {
   14508                 Binder.restoreCallingIdentity(ident);
   14509             }
   14510         }
   14511 
   14512         return ActivityManager.USER_OP_SUCCESS;
   14513     }
   14514 
   14515     void finishUserStop(UserStartedState uss) {
   14516         final int userId = uss.mHandle.getIdentifier();
   14517         boolean stopped;
   14518         ArrayList<IStopUserCallback> callbacks;
   14519         synchronized (this) {
   14520             callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
   14521             if (mStartedUsers.get(userId) != uss) {
   14522                 stopped = false;
   14523             } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
   14524                 stopped = false;
   14525             } else {
   14526                 stopped = true;
   14527                 // User can no longer run.
   14528                 mStartedUsers.remove(userId);
   14529                 mUserLru.remove(Integer.valueOf(userId));
   14530                 updateStartedUserArrayLocked();
   14531 
   14532                 // Clean up all state and processes associated with the user.
   14533                 // Kill all the processes for the user.
   14534                 forceStopUserLocked(userId);
   14535             }
   14536         }
   14537 
   14538         for (int i=0; i<callbacks.size(); i++) {
   14539             try {
   14540                 if (stopped) callbacks.get(i).userStopped(userId);
   14541                 else callbacks.get(i).userStopAborted(userId);
   14542             } catch (RemoteException e) {
   14543             }
   14544         }
   14545     }
   14546 
   14547     @Override
   14548     public UserInfo getCurrentUser() {
   14549         if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
   14550                 != PackageManager.PERMISSION_GRANTED) && (
   14551                 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
   14552                 != PackageManager.PERMISSION_GRANTED)) {
   14553             String msg = "Permission Denial: getCurrentUser() from pid="
   14554                     + Binder.getCallingPid()
   14555                     + ", uid=" + Binder.getCallingUid()
   14556                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
   14557             Slog.w(TAG, msg);
   14558             throw new SecurityException(msg);
   14559         }
   14560         synchronized (this) {
   14561             return getUserManagerLocked().getUserInfo(mCurrentUserId);
   14562         }
   14563     }
   14564 
   14565     int getCurrentUserIdLocked() {
   14566         return mCurrentUserId;
   14567     }
   14568 
   14569     @Override
   14570     public boolean isUserRunning(int userId, boolean orStopped) {
   14571         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
   14572                 != PackageManager.PERMISSION_GRANTED) {
   14573             String msg = "Permission Denial: isUserRunning() from pid="
   14574                     + Binder.getCallingPid()
   14575                     + ", uid=" + Binder.getCallingUid()
   14576                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
   14577             Slog.w(TAG, msg);
   14578             throw new SecurityException(msg);
   14579         }
   14580         synchronized (this) {
   14581             return isUserRunningLocked(userId, orStopped);
   14582         }
   14583     }
   14584 
   14585     boolean isUserRunningLocked(int userId, boolean orStopped) {
   14586         UserStartedState state = mStartedUsers.get(userId);
   14587         if (state == null) {
   14588             return false;
   14589         }
   14590         if (orStopped) {
   14591             return true;
   14592         }
   14593         return state.mState != UserStartedState.STATE_STOPPING
   14594                 && state.mState != UserStartedState.STATE_SHUTDOWN;
   14595     }
   14596 
   14597     @Override
   14598     public int[] getRunningUserIds() {
   14599         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
   14600                 != PackageManager.PERMISSION_GRANTED) {
   14601             String msg = "Permission Denial: isUserRunning() from pid="
   14602                     + Binder.getCallingPid()
   14603                     + ", uid=" + Binder.getCallingUid()
   14604                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
   14605             Slog.w(TAG, msg);
   14606             throw new SecurityException(msg);
   14607         }
   14608         synchronized (this) {
   14609             return mStartedUserArray;
   14610         }
   14611     }
   14612 
   14613     private void updateStartedUserArrayLocked() {
   14614         int num = 0;
   14615         for (int i=0; i<mStartedUsers.size();  i++) {
   14616             UserStartedState uss = mStartedUsers.valueAt(i);
   14617             // This list does not include stopping users.
   14618             if (uss.mState != UserStartedState.STATE_STOPPING
   14619                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
   14620                 num++;
   14621             }
   14622         }
   14623         mStartedUserArray = new int[num];
   14624         num = 0;
   14625         for (int i=0; i<mStartedUsers.size();  i++) {
   14626             UserStartedState uss = mStartedUsers.valueAt(i);
   14627             if (uss.mState != UserStartedState.STATE_STOPPING
   14628                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
   14629                 mStartedUserArray[num] = mStartedUsers.keyAt(i);
   14630                 num++;
   14631             }
   14632         }
   14633     }
   14634 
   14635     @Override
   14636     public void registerUserSwitchObserver(IUserSwitchObserver observer) {
   14637         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
   14638                 != PackageManager.PERMISSION_GRANTED) {
   14639             String msg = "Permission Denial: registerUserSwitchObserver() from pid="
   14640                     + Binder.getCallingPid()
   14641                     + ", uid=" + Binder.getCallingUid()
   14642                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
   14643             Slog.w(TAG, msg);
   14644             throw new SecurityException(msg);
   14645         }
   14646 
   14647         mUserSwitchObservers.register(observer);
   14648     }
   14649 
   14650     @Override
   14651     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
   14652         mUserSwitchObservers.unregister(observer);
   14653     }
   14654 
   14655     private boolean userExists(int userId) {
   14656         if (userId == 0) {
   14657             return true;
   14658         }
   14659         UserManagerService ums = getUserManagerLocked();
   14660         return ums != null ? (ums.getUserInfo(userId) != null) : false;
   14661     }
   14662 
   14663     int[] getUsersLocked() {
   14664         UserManagerService ums = getUserManagerLocked();
   14665         return ums != null ? ums.getUserIds() : new int[] { 0 };
   14666     }
   14667 
   14668     UserManagerService getUserManagerLocked() {
   14669         if (mUserManager == null) {
   14670             IBinder b = ServiceManager.getService(Context.USER_SERVICE);
   14671             mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
   14672         }
   14673         return mUserManager;
   14674     }
   14675 
   14676     private void checkValidCaller(int uid, int userId) {
   14677         if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
   14678 
   14679         throw new SecurityException("Caller uid=" + uid
   14680                 + " is not privileged to communicate with user=" + userId);
   14681     }
   14682 
   14683     private int applyUserId(int uid, int userId) {
   14684         return UserHandle.getUid(userId, uid);
   14685     }
   14686 
   14687     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
   14688         if (info == null) return null;
   14689         ApplicationInfo newInfo = new ApplicationInfo(info);
   14690         newInfo.uid = applyUserId(info.uid, userId);
   14691         newInfo.dataDir = USER_DATA_DIR + userId + "/"
   14692                 + info.packageName;
   14693         return newInfo;
   14694     }
   14695 
   14696     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
   14697         if (aInfo == null
   14698                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
   14699             return aInfo;
   14700         }
   14701 
   14702         ActivityInfo info = new ActivityInfo(aInfo);
   14703         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
   14704         return info;
   14705     }
   14706 }
   14707