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 android.app.AppOpsManager;
     22 import android.appwidget.AppWidgetManager;
     23 import com.android.internal.R;
     24 import com.android.internal.os.BatteryStatsImpl;
     25 import com.android.internal.os.ProcessStats;
     26 import com.android.server.AppOpsService;
     27 import com.android.server.AttributeCache;
     28 import com.android.server.IntentResolver;
     29 import com.android.server.ProcessMap;
     30 import com.android.server.SystemServer;
     31 import com.android.server.Watchdog;
     32 import com.android.server.am.ActivityStack.ActivityState;
     33 import com.android.server.firewall.IntentFirewall;
     34 import com.android.server.pm.UserManagerService;
     35 import com.android.server.wm.AppTransition;
     36 import com.android.server.wm.WindowManagerService;
     37 
     38 import dalvik.system.Zygote;
     39 
     40 import android.app.Activity;
     41 import android.app.ActivityManager;
     42 import android.app.ActivityManagerNative;
     43 import android.app.ActivityOptions;
     44 import android.app.ActivityThread;
     45 import android.app.AlertDialog;
     46 import android.app.AppGlobals;
     47 import android.app.ApplicationErrorReport;
     48 import android.app.Dialog;
     49 import android.app.IActivityController;
     50 import android.app.IApplicationThread;
     51 import android.app.IInstrumentationWatcher;
     52 import android.app.INotificationManager;
     53 import android.app.IProcessObserver;
     54 import android.app.IServiceConnection;
     55 import android.app.IStopUserCallback;
     56 import android.app.IThumbnailReceiver;
     57 import android.app.IUiAutomationConnection;
     58 import android.app.IUserSwitchObserver;
     59 import android.app.Instrumentation;
     60 import android.app.Notification;
     61 import android.app.NotificationManager;
     62 import android.app.PendingIntent;
     63 import android.app.backup.IBackupManager;
     64 import android.content.ActivityNotFoundException;
     65 import android.content.BroadcastReceiver;
     66 import android.content.ClipData;
     67 import android.content.ComponentCallbacks2;
     68 import android.content.ComponentName;
     69 import android.content.ContentProvider;
     70 import android.content.ContentResolver;
     71 import android.content.Context;
     72 import android.content.DialogInterface;
     73 import android.content.IContentProvider;
     74 import android.content.IIntentReceiver;
     75 import android.content.IIntentSender;
     76 import android.content.Intent;
     77 import android.content.IntentFilter;
     78 import android.content.IntentSender;
     79 import android.content.pm.ActivityInfo;
     80 import android.content.pm.ApplicationInfo;
     81 import android.content.pm.ConfigurationInfo;
     82 import android.content.pm.IPackageDataObserver;
     83 import android.content.pm.IPackageManager;
     84 import android.content.pm.InstrumentationInfo;
     85 import android.content.pm.PackageInfo;
     86 import android.content.pm.PackageManager;
     87 import android.content.pm.UserInfo;
     88 import android.content.pm.PackageManager.NameNotFoundException;
     89 import android.content.pm.PathPermission;
     90 import android.content.pm.ProviderInfo;
     91 import android.content.pm.ResolveInfo;
     92 import android.content.pm.ServiceInfo;
     93 import android.content.res.CompatibilityInfo;
     94 import android.content.res.Configuration;
     95 import android.graphics.Bitmap;
     96 import android.net.Proxy;
     97 import android.net.ProxyProperties;
     98 import android.net.Uri;
     99 import android.os.Binder;
    100 import android.os.Build;
    101 import android.os.Bundle;
    102 import android.os.Debug;
    103 import android.os.DropBoxManager;
    104 import android.os.Environment;
    105 import android.os.FileObserver;
    106 import android.os.FileUtils;
    107 import android.os.Handler;
    108 import android.os.IBinder;
    109 import android.os.IPermissionController;
    110 import android.os.IRemoteCallback;
    111 import android.os.IUserManager;
    112 import android.os.Looper;
    113 import android.os.Message;
    114 import android.os.Parcel;
    115 import android.os.ParcelFileDescriptor;
    116 import android.os.Process;
    117 import android.os.RemoteCallbackList;
    118 import android.os.RemoteException;
    119 import android.os.SELinux;
    120 import android.os.ServiceManager;
    121 import android.os.StrictMode;
    122 import android.os.SystemClock;
    123 import android.os.SystemProperties;
    124 import android.os.UpdateLock;
    125 import android.os.UserHandle;
    126 import android.provider.Settings;
    127 import android.text.format.Time;
    128 import android.util.EventLog;
    129 import android.util.Log;
    130 import android.util.Pair;
    131 import android.util.PrintWriterPrinter;
    132 import android.util.Slog;
    133 import android.util.SparseArray;
    134 import android.util.TimeUtils;
    135 import android.view.Gravity;
    136 import android.view.LayoutInflater;
    137 import android.view.View;
    138 import android.view.WindowManager;
    139 
    140 import java.io.BufferedInputStream;
    141 import java.io.BufferedOutputStream;
    142 import java.io.BufferedReader;
    143 import java.io.DataInputStream;
    144 import java.io.DataOutputStream;
    145 import java.io.File;
    146 import java.io.FileDescriptor;
    147 import java.io.FileInputStream;
    148 import java.io.FileNotFoundException;
    149 import java.io.FileOutputStream;
    150 import java.io.IOException;
    151 import java.io.InputStreamReader;
    152 import java.io.PrintWriter;
    153 import java.io.StringWriter;
    154 import java.lang.ref.WeakReference;
    155 import java.util.ArrayList;
    156 import java.util.Arrays;
    157 import java.util.Collections;
    158 import java.util.Comparator;
    159 import java.util.HashMap;
    160 import java.util.HashSet;
    161 import java.util.Iterator;
    162 import java.util.List;
    163 import java.util.Locale;
    164 import java.util.Map;
    165 import java.util.Set;
    166 import java.util.concurrent.atomic.AtomicBoolean;
    167 import java.util.concurrent.atomic.AtomicLong;
    168 
    169 public final class ActivityManagerService  extends ActivityManagerNative
    170         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    171     private static final String USER_DATA_DIR = "/data/user/";
    172     static final String TAG = "ActivityManager";
    173     static final String TAG_MU = "ActivityManagerServiceMU";
    174     static final boolean DEBUG = false;
    175     static final boolean localLOGV = DEBUG;
    176     static final boolean DEBUG_SWITCH = localLOGV || false;
    177     static final boolean DEBUG_TASKS = localLOGV || false;
    178     static final boolean DEBUG_THUMBNAILS = localLOGV || false;
    179     static final boolean DEBUG_PAUSE = localLOGV || false;
    180     static final boolean DEBUG_OOM_ADJ = localLOGV || false;
    181     static final boolean DEBUG_TRANSITION = localLOGV || false;
    182     static final boolean DEBUG_BROADCAST = localLOGV || false;
    183     static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
    184     static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
    185     static final boolean DEBUG_SERVICE = localLOGV || false;
    186     static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
    187     static final boolean DEBUG_VISBILITY = localLOGV || false;
    188     static final boolean DEBUG_PROCESSES = localLOGV || false;
    189     static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
    190     static final boolean DEBUG_CLEANUP = localLOGV || false;
    191     static final boolean DEBUG_PROVIDER = localLOGV || false;
    192     static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
    193     static final boolean DEBUG_USER_LEAVING = localLOGV || false;
    194     static final boolean DEBUG_RESULTS = localLOGV || false;
    195     static final boolean DEBUG_BACKUP = localLOGV || false;
    196     static final boolean DEBUG_CONFIGURATION = localLOGV || false;
    197     static final boolean DEBUG_POWER = localLOGV || false;
    198     static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
    199     static final boolean DEBUG_MU = localLOGV || false;
    200     static final boolean DEBUG_IMMERSIVE = localLOGV || false;
    201     static final boolean VALIDATE_TOKENS = false;
    202     static final boolean SHOW_ACTIVITY_START_TIME = true;
    203 
    204     // Control over CPU and battery monitoring.
    205     static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
    206     static final boolean MONITOR_CPU_USAGE = true;
    207     static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
    208     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
    209     static final boolean MONITOR_THREAD_CPU_USAGE = false;
    210 
    211     // The flags that are set for all calls we make to the package manager.
    212     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
    213 
    214     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
    215 
    216     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
    217 
    218     // Maximum number of recent tasks that we can remember.
    219     static final int MAX_RECENT_TASKS = 20;
    220 
    221     // Amount of time after a call to stopAppSwitches() during which we will
    222     // prevent further untrusted switches from happening.
    223     static final long APP_SWITCH_DELAY_TIME = 5*1000;
    224 
    225     // How long we wait for a launched process to attach to the activity manager
    226     // before we decide it's never going to come up for real.
    227     static final int PROC_START_TIMEOUT = 10*1000;
    228 
    229     // How long we wait for a launched process to attach to the activity manager
    230     // before we decide it's never going to come up for real, when the process was
    231     // started with a wrapper for instrumentation (such as Valgrind) because it
    232     // could take much longer than usual.
    233     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
    234 
    235     // How long to wait after going idle before forcing apps to GC.
    236     static final int GC_TIMEOUT = 5*1000;
    237 
    238     // The minimum amount of time between successive GC requests for a process.
    239     static final int GC_MIN_INTERVAL = 60*1000;
    240 
    241     // The rate at which we check for apps using excessive power -- 15 mins.
    242     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
    243 
    244     // The minimum sample duration we will allow before deciding we have
    245     // enough data on wake locks to start killing things.
    246     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    247 
    248     // The minimum sample duration we will allow before deciding we have
    249     // enough data on CPU usage to start killing things.
    250     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    251 
    252     // How long we allow a receiver to run before giving up on it.
    253     static final int BROADCAST_FG_TIMEOUT = 10*1000;
    254     static final int BROADCAST_BG_TIMEOUT = 60*1000;
    255 
    256     // How long we wait until we timeout on key dispatching.
    257     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
    258 
    259     // How long we wait until we timeout on key dispatching during instrumentation.
    260     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
    261 
    262     // Amount of time we wait for observers to handle a user switch before
    263     // giving up on them and unfreezing the screen.
    264     static final int USER_SWITCH_TIMEOUT = 2*1000;
    265 
    266     // Maximum number of users we allow to be running at a time.
    267     static final int MAX_RUNNING_USERS = 3;
    268 
    269     // How long to wait in getTopActivityExtras for the activity to respond with the result.
    270     static final int PENDING_ACTIVITY_RESULT_TIMEOUT = 2*2000;
    271 
    272     static final int MY_PID = Process.myPid();
    273 
    274     static final String[] EMPTY_STRING_ARRAY = new String[0];
    275 
    276     public ActivityStack mMainStack;
    277 
    278     public IntentFirewall mIntentFirewall;
    279 
    280     private final boolean mHeadless;
    281 
    282     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
    283     // default actuion automatically.  Important for devices without direct input
    284     // devices.
    285     private boolean mShowDialogs = true;
    286 
    287     /**
    288      * Description of a request to start a new activity, which has been held
    289      * due to app switches being disabled.
    290      */
    291     static class PendingActivityLaunch {
    292         ActivityRecord r;
    293         ActivityRecord sourceRecord;
    294         int startFlags;
    295     }
    296 
    297     final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
    298             = new ArrayList<PendingActivityLaunch>();
    299 
    300 
    301     BroadcastQueue mFgBroadcastQueue;
    302     BroadcastQueue mBgBroadcastQueue;
    303     // Convenient for easy iteration over the queues. Foreground is first
    304     // so that dispatch of foreground broadcasts gets precedence.
    305     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
    306 
    307     BroadcastQueue broadcastQueueForIntent(Intent intent) {
    308         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
    309         if (DEBUG_BACKGROUND_BROADCAST) {
    310             Slog.i(TAG, "Broadcast intent " + intent + " on "
    311                     + (isFg ? "foreground" : "background")
    312                     + " queue");
    313         }
    314         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
    315     }
    316 
    317     BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
    318         for (BroadcastQueue queue : mBroadcastQueues) {
    319             BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
    320             if (r != null) {
    321                 return r;
    322             }
    323         }
    324         return null;
    325     }
    326 
    327     /**
    328      * Activity we have told the window manager to have key focus.
    329      */
    330     ActivityRecord mFocusedActivity = null;
    331 
    332     /**
    333      * List of intents that were used to start the most recent tasks.
    334      */
    335     final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
    336 
    337     public class PendingActivityExtras extends Binder implements Runnable {
    338         public final ActivityRecord activity;
    339         public boolean haveResult = false;
    340         public Bundle result = null;
    341         public PendingActivityExtras(ActivityRecord _activity) {
    342             activity = _activity;
    343         }
    344         @Override
    345         public void run() {
    346             Slog.w(TAG, "getTopActivityExtras failed: timeout retrieving from " + activity);
    347             synchronized (this) {
    348                 haveResult = true;
    349                 notifyAll();
    350             }
    351         }
    352     }
    353 
    354     final ArrayList<PendingActivityExtras> mPendingActivityExtras
    355             = new ArrayList<PendingActivityExtras>();
    356 
    357     /**
    358      * Process management.
    359      */
    360     final ProcessList mProcessList = new ProcessList();
    361 
    362     /**
    363      * All of the applications we currently have running organized by name.
    364      * The keys are strings of the application package name (as
    365      * returned by the package manager), and the keys are ApplicationRecord
    366      * objects.
    367      */
    368     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
    369 
    370     /**
    371      * The currently running isolated processes.
    372      */
    373     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
    374 
    375     /**
    376      * Counter for assigning isolated process uids, to avoid frequently reusing the
    377      * same ones.
    378      */
    379     int mNextIsolatedProcessUid = 0;
    380 
    381     /**
    382      * The currently running heavy-weight process, if any.
    383      */
    384     ProcessRecord mHeavyWeightProcess = null;
    385 
    386     /**
    387      * The last time that various processes have crashed.
    388      */
    389     final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
    390 
    391     /**
    392      * Set of applications that we consider to be bad, and will reject
    393      * incoming broadcasts from (which the user has no control over).
    394      * Processes are added to this set when they have crashed twice within
    395      * a minimum amount of time; they are removed from it when they are
    396      * later restarted (hopefully due to some user action).  The value is the
    397      * time it was added to the list.
    398      */
    399     final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
    400 
    401     /**
    402      * All of the processes we currently have running organized by pid.
    403      * The keys are the pid running the application.
    404      *
    405      * <p>NOTE: This object is protected by its own lock, NOT the global
    406      * activity manager lock!
    407      */
    408     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
    409 
    410     /**
    411      * All of the processes that have been forced to be foreground.  The key
    412      * is the pid of the caller who requested it (we hold a death
    413      * link on it).
    414      */
    415     abstract class ForegroundToken implements IBinder.DeathRecipient {
    416         int pid;
    417         IBinder token;
    418     }
    419     final SparseArray<ForegroundToken> mForegroundProcesses
    420             = new SparseArray<ForegroundToken>();
    421 
    422     /**
    423      * List of records for processes that someone had tried to start before the
    424      * system was ready.  We don't start them at that point, but ensure they
    425      * are started by the time booting is complete.
    426      */
    427     final ArrayList<ProcessRecord> mProcessesOnHold
    428             = new ArrayList<ProcessRecord>();
    429 
    430     /**
    431      * List of persistent applications that are in the process
    432      * of being started.
    433      */
    434     final ArrayList<ProcessRecord> mPersistentStartingProcesses
    435             = new ArrayList<ProcessRecord>();
    436 
    437     /**
    438      * Processes that are being forcibly torn down.
    439      */
    440     final ArrayList<ProcessRecord> mRemovedProcesses
    441             = new ArrayList<ProcessRecord>();
    442 
    443     /**
    444      * List of running applications, sorted by recent usage.
    445      * The first entry in the list is the least recently used.
    446      * It contains ApplicationRecord objects.  This list does NOT include
    447      * any persistent application records (since we never want to exit them).
    448      */
    449     final ArrayList<ProcessRecord> mLruProcesses
    450             = new ArrayList<ProcessRecord>();
    451 
    452     /**
    453      * List of processes that should gc as soon as things are idle.
    454      */
    455     final ArrayList<ProcessRecord> mProcessesToGc
    456             = new ArrayList<ProcessRecord>();
    457 
    458     /**
    459      * This is the process holding what we currently consider to be
    460      * the "home" activity.
    461      */
    462     ProcessRecord mHomeProcess;
    463 
    464     /**
    465      * This is the process holding the activity the user last visited that
    466      * is in a different process from the one they are currently in.
    467      */
    468     ProcessRecord mPreviousProcess;
    469 
    470     /**
    471      * The time at which the previous process was last visible.
    472      */
    473     long mPreviousProcessVisibleTime;
    474 
    475     /**
    476      * Which uses have been started, so are allowed to run code.
    477      */
    478     final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
    479 
    480     /**
    481      * LRU list of history of current users.  Most recently current is at the end.
    482      */
    483     final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
    484 
    485     /**
    486      * Constant array of the users that are currently started.
    487      */
    488     int[] mStartedUserArray = new int[] { 0 };
    489 
    490     /**
    491      * Registered observers of the user switching mechanics.
    492      */
    493     final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
    494             = new RemoteCallbackList<IUserSwitchObserver>();
    495 
    496     /**
    497      * Currently active user switch.
    498      */
    499     Object mCurUserSwitchCallback;
    500 
    501     /**
    502      * Packages that the user has asked to have run in screen size
    503      * compatibility mode instead of filling the screen.
    504      */
    505     final CompatModePackages mCompatModePackages;
    506 
    507     /**
    508      * Set of PendingResultRecord objects that are currently active.
    509      */
    510     final HashSet mPendingResultRecords = new HashSet();
    511 
    512     /**
    513      * Set of IntentSenderRecord objects that are currently active.
    514      */
    515     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
    516             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
    517 
    518     /**
    519      * Fingerprints (hashCode()) of stack traces that we've
    520      * already logged DropBox entries for.  Guarded by itself.  If
    521      * something (rogue user app) forces this over
    522      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
    523      */
    524     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
    525     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
    526 
    527     /**
    528      * Strict Mode background batched logging state.
    529      *
    530      * The string buffer is guarded by itself, and its lock is also
    531      * used to determine if another batched write is already
    532      * in-flight.
    533      */
    534     private final StringBuilder mStrictModeBuffer = new StringBuilder();
    535 
    536     /**
    537      * Keeps track of all IIntentReceivers that have been registered for
    538      * broadcasts.  Hash keys are the receiver IBinder, hash value is
    539      * a ReceiverList.
    540      */
    541     final HashMap mRegisteredReceivers = new HashMap();
    542 
    543     /**
    544      * Resolver for broadcast intents to registered receivers.
    545      * Holds BroadcastFilter (subclass of IntentFilter).
    546      */
    547     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
    548             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
    549         @Override
    550         protected boolean allowFilterResult(
    551                 BroadcastFilter filter, List<BroadcastFilter> dest) {
    552             IBinder target = filter.receiverList.receiver.asBinder();
    553             for (int i=dest.size()-1; i>=0; i--) {
    554                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
    555                     return false;
    556                 }
    557             }
    558             return true;
    559         }
    560 
    561         @Override
    562         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
    563             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
    564                     || userId == filter.owningUserId) {
    565                 return super.newResult(filter, match, userId);
    566             }
    567             return null;
    568         }
    569 
    570         @Override
    571         protected BroadcastFilter[] newArray(int size) {
    572             return new BroadcastFilter[size];
    573         }
    574 
    575         @Override
    576         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
    577             return packageName.equals(filter.packageName);
    578         }
    579     };
    580 
    581     /**
    582      * State of all active sticky broadcasts per user.  Keys are the action of the
    583      * sticky Intent, values are an ArrayList of all broadcasted intents with
    584      * that action (which should usually be one).  The SparseArray is keyed
    585      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
    586      * for stickies that are sent to all users.
    587      */
    588     final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts =
    589             new SparseArray<HashMap<String, ArrayList<Intent>>>();
    590 
    591     final ActiveServices mServices;
    592 
    593     /**
    594      * Backup/restore process management
    595      */
    596     String mBackupAppName = null;
    597     BackupRecord mBackupTarget = null;
    598 
    599     /**
    600      * List of PendingThumbnailsRecord objects of clients who are still
    601      * waiting to receive all of the thumbnails for a task.
    602      */
    603     final ArrayList mPendingThumbnails = new ArrayList();
    604 
    605     /**
    606      * List of HistoryRecord objects that have been finished and must
    607      * still report back to a pending thumbnail receiver.
    608      */
    609     final ArrayList mCancelledThumbnails = new ArrayList();
    610 
    611     final ProviderMap mProviderMap;
    612 
    613     /**
    614      * List of content providers who have clients waiting for them.  The
    615      * application is currently being launched and the provider will be
    616      * removed from this list once it is published.
    617      */
    618     final ArrayList<ContentProviderRecord> mLaunchingProviders
    619             = new ArrayList<ContentProviderRecord>();
    620 
    621     /**
    622      * Global set of specific Uri permissions that have been granted.
    623      */
    624     final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
    625             = new SparseArray<HashMap<Uri, UriPermission>>();
    626 
    627     CoreSettingsObserver mCoreSettingsObserver;
    628 
    629     /**
    630      * Thread-local storage used to carry caller permissions over through
    631      * indirect content-provider access.
    632      */
    633     private class Identity {
    634         public int pid;
    635         public int uid;
    636 
    637         Identity(int _pid, int _uid) {
    638             pid = _pid;
    639             uid = _uid;
    640         }
    641     }
    642 
    643     private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
    644 
    645     /**
    646      * All information we have collected about the runtime performance of
    647      * any user id that can impact battery performance.
    648      */
    649     final BatteryStatsService mBatteryStatsService;
    650 
    651     /**
    652      * Information about component usage
    653      */
    654     final UsageStatsService mUsageStatsService;
    655 
    656     /**
    657      * Information about and control over application operations
    658      */
    659     final AppOpsService mAppOpsService;
    660 
    661     /**
    662      * Current configuration information.  HistoryRecord objects are given
    663      * a reference to this object to indicate which configuration they are
    664      * currently running in, so this object must be kept immutable.
    665      */
    666     Configuration mConfiguration = new Configuration();
    667 
    668     /**
    669      * Current sequencing integer of the configuration, for skipping old
    670      * configurations.
    671      */
    672     int mConfigurationSeq = 0;
    673 
    674     /**
    675      * Hardware-reported OpenGLES version.
    676      */
    677     final int GL_ES_VERSION;
    678 
    679     /**
    680      * List of initialization arguments to pass to all processes when binding applications to them.
    681      * For example, references to the commonly used services.
    682      */
    683     HashMap<String, IBinder> mAppBindArgs;
    684 
    685     /**
    686      * Temporary to avoid allocations.  Protected by main lock.
    687      */
    688     final StringBuilder mStringBuilder = new StringBuilder(256);
    689 
    690     /**
    691      * Used to control how we initialize the service.
    692      */
    693     boolean mStartRunning = false;
    694     ComponentName mTopComponent;
    695     String mTopAction;
    696     String mTopData;
    697     boolean mProcessesReady = false;
    698     boolean mSystemReady = false;
    699     boolean mBooting = false;
    700     boolean mWaitingUpdate = false;
    701     boolean mDidUpdate = false;
    702     boolean mOnBattery = false;
    703     boolean mLaunchWarningShown = false;
    704 
    705     Context mContext;
    706 
    707     int mFactoryTest;
    708 
    709     boolean mCheckedForSetup;
    710 
    711     /**
    712      * The time at which we will allow normal application switches again,
    713      * after a call to {@link #stopAppSwitches()}.
    714      */
    715     long mAppSwitchesAllowedTime;
    716 
    717     /**
    718      * This is set to true after the first switch after mAppSwitchesAllowedTime
    719      * is set; any switches after that will clear the time.
    720      */
    721     boolean mDidAppSwitch;
    722 
    723     /**
    724      * Last time (in realtime) at which we checked for power usage.
    725      */
    726     long mLastPowerCheckRealtime;
    727 
    728     /**
    729      * Last time (in uptime) at which we checked for power usage.
    730      */
    731     long mLastPowerCheckUptime;
    732 
    733     /**
    734      * Set while we are wanting to sleep, to prevent any
    735      * activities from being started/resumed.
    736      */
    737     boolean mSleeping = false;
    738 
    739     /**
    740      * State of external calls telling us if the device is asleep.
    741      */
    742     boolean mWentToSleep = false;
    743 
    744     /**
    745      * State of external call telling us if the lock screen is shown.
    746      */
    747     boolean mLockScreenShown = false;
    748 
    749     /**
    750      * Set if we are shutting down the system, similar to sleeping.
    751      */
    752     boolean mShuttingDown = false;
    753 
    754     /**
    755      * Task identifier that activities are currently being started
    756      * in.  Incremented each time a new task is created.
    757      * todo: Replace this with a TokenSpace class that generates non-repeating
    758      * integers that won't wrap.
    759      */
    760     int mCurTask = 1;
    761 
    762     /**
    763      * Current sequence id for oom_adj computation traversal.
    764      */
    765     int mAdjSeq = 0;
    766 
    767     /**
    768      * Current sequence id for process LRU updating.
    769      */
    770     int mLruSeq = 0;
    771 
    772     /**
    773      * Keep track of the non-hidden/empty process we last found, to help
    774      * determine how to distribute hidden/empty processes next time.
    775      */
    776     int mNumNonHiddenProcs = 0;
    777 
    778     /**
    779      * Keep track of the number of hidden procs, to balance oom adj
    780      * distribution between those and empty procs.
    781      */
    782     int mNumHiddenProcs = 0;
    783 
    784     /**
    785      * Keep track of the number of service processes we last found, to
    786      * determine on the next iteration which should be B services.
    787      */
    788     int mNumServiceProcs = 0;
    789     int mNewNumServiceProcs = 0;
    790 
    791     /**
    792      * System monitoring: number of processes that died since the last
    793      * N procs were started.
    794      */
    795     int[] mProcDeaths = new int[20];
    796 
    797     /**
    798      * This is set if we had to do a delayed dexopt of an app before launching
    799      * it, to increasing the ANR timeouts in that case.
    800      */
    801     boolean mDidDexOpt;
    802 
    803     String mDebugApp = null;
    804     boolean mWaitForDebugger = false;
    805     boolean mDebugTransient = false;
    806     String mOrigDebugApp = null;
    807     boolean mOrigWaitForDebugger = false;
    808     boolean mAlwaysFinishActivities = false;
    809     IActivityController mController = null;
    810     String mProfileApp = null;
    811     ProcessRecord mProfileProc = null;
    812     String mProfileFile;
    813     ParcelFileDescriptor mProfileFd;
    814     int mProfileType = 0;
    815     boolean mAutoStopProfiler = false;
    816     String mOpenGlTraceApp = null;
    817 
    818     static class ProcessChangeItem {
    819         static final int CHANGE_ACTIVITIES = 1<<0;
    820         static final int CHANGE_IMPORTANCE= 1<<1;
    821         int changes;
    822         int uid;
    823         int pid;
    824         int importance;
    825         boolean foregroundActivities;
    826     }
    827 
    828     final RemoteCallbackList<IProcessObserver> mProcessObservers
    829             = new RemoteCallbackList<IProcessObserver>();
    830     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
    831 
    832     final ArrayList<ProcessChangeItem> mPendingProcessChanges
    833             = new ArrayList<ProcessChangeItem>();
    834     final ArrayList<ProcessChangeItem> mAvailProcessChanges
    835             = new ArrayList<ProcessChangeItem>();
    836 
    837     /**
    838      * Runtime statistics collection thread.  This object's lock is used to
    839      * protect all related state.
    840      */
    841     final Thread mProcessStatsThread;
    842 
    843     /**
    844      * Used to collect process stats when showing not responding dialog.
    845      * Protected by mProcessStatsThread.
    846      */
    847     final ProcessStats mProcessStats = new ProcessStats(
    848             MONITOR_THREAD_CPU_USAGE);
    849     final AtomicLong mLastCpuTime = new AtomicLong(0);
    850     final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
    851 
    852     long mLastWriteTime = 0;
    853 
    854     /**
    855      * Used to retain an update lock when the foreground activity is in
    856      * immersive mode.
    857      */
    858     final UpdateLock mUpdateLock = new UpdateLock("immersive");
    859 
    860     /**
    861      * Set to true after the system has finished booting.
    862      */
    863     boolean mBooted = false;
    864 
    865     int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
    866     int mProcessLimitOverride = -1;
    867 
    868     WindowManagerService mWindowManager;
    869 
    870     static ActivityManagerService mSelf;
    871     static ActivityThread mSystemThread;
    872 
    873     private int mCurrentUserId = 0;
    874     private int[] mCurrentUserArray = new int[] { 0 };
    875     private UserManagerService mUserManager;
    876 
    877     private final class AppDeathRecipient implements IBinder.DeathRecipient {
    878         final ProcessRecord mApp;
    879         final int mPid;
    880         final IApplicationThread mAppThread;
    881 
    882         AppDeathRecipient(ProcessRecord app, int pid,
    883                 IApplicationThread thread) {
    884             if (localLOGV) Slog.v(
    885                 TAG, "New death recipient " + this
    886                 + " for thread " + thread.asBinder());
    887             mApp = app;
    888             mPid = pid;
    889             mAppThread = thread;
    890         }
    891 
    892         public void binderDied() {
    893             if (localLOGV) Slog.v(
    894                 TAG, "Death received in " + this
    895                 + " for thread " + mAppThread.asBinder());
    896             synchronized(ActivityManagerService.this) {
    897                 appDiedLocked(mApp, mPid, mAppThread);
    898             }
    899         }
    900     }
    901 
    902     static final int SHOW_ERROR_MSG = 1;
    903     static final int SHOW_NOT_RESPONDING_MSG = 2;
    904     static final int SHOW_FACTORY_ERROR_MSG = 3;
    905     static final int UPDATE_CONFIGURATION_MSG = 4;
    906     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
    907     static final int WAIT_FOR_DEBUGGER_MSG = 6;
    908     static final int SERVICE_TIMEOUT_MSG = 12;
    909     static final int UPDATE_TIME_ZONE = 13;
    910     static final int SHOW_UID_ERROR_MSG = 14;
    911     static final int IM_FEELING_LUCKY_MSG = 15;
    912     static final int PROC_START_TIMEOUT_MSG = 20;
    913     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
    914     static final int KILL_APPLICATION_MSG = 22;
    915     static final int FINALIZE_PENDING_INTENT_MSG = 23;
    916     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
    917     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
    918     static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
    919     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
    920     static final int CLEAR_DNS_CACHE = 28;
    921     static final int UPDATE_HTTP_PROXY = 29;
    922     static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
    923     static final int DISPATCH_PROCESSES_CHANGED = 31;
    924     static final int DISPATCH_PROCESS_DIED = 32;
    925     static final int REPORT_MEM_USAGE = 33;
    926     static final int REPORT_USER_SWITCH_MSG = 34;
    927     static final int CONTINUE_USER_SWITCH_MSG = 35;
    928     static final int USER_SWITCH_TIMEOUT_MSG = 36;
    929     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
    930 
    931     static final int FIRST_ACTIVITY_STACK_MSG = 100;
    932     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
    933     static final int FIRST_COMPAT_MODE_MSG = 300;
    934 
    935     AlertDialog mUidAlert;
    936     CompatModeDialog mCompatModeDialog;
    937     long mLastMemUsageReportTime = 0;
    938 
    939     /**
    940      * Flag whether the current user is a "monkey", i.e. whether
    941      * the UI is driven by a UI automation tool.
    942      */
    943     private boolean mUserIsMonkey;
    944 
    945     final Handler mHandler = new Handler() {
    946         //public Handler() {
    947         //    if (localLOGV) Slog.v(TAG, "Handler started!");
    948         //}
    949 
    950         public void handleMessage(Message msg) {
    951             switch (msg.what) {
    952             case SHOW_ERROR_MSG: {
    953                 HashMap data = (HashMap) msg.obj;
    954                 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
    955                         Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
    956                 synchronized (ActivityManagerService.this) {
    957                     ProcessRecord proc = (ProcessRecord)data.get("app");
    958                     AppErrorResult res = (AppErrorResult) data.get("result");
    959                     if (proc != null && proc.crashDialog != null) {
    960                         Slog.e(TAG, "App already has crash dialog: " + proc);
    961                         if (res != null) {
    962                             res.set(0);
    963                         }
    964                         return;
    965                     }
    966                     if (!showBackground && UserHandle.getAppId(proc.uid)
    967                             >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
    968                             && proc.pid != MY_PID) {
    969                         Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
    970                         if (res != null) {
    971                             res.set(0);
    972                         }
    973                         return;
    974                     }
    975                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
    976                         Dialog d = new AppErrorDialog(mContext,
    977                                 ActivityManagerService.this, res, proc);
    978                         d.show();
    979                         proc.crashDialog = d;
    980                     } else {
    981                         // The device is asleep, so just pretend that the user
    982                         // saw a crash dialog and hit "force quit".
    983                         if (res != null) {
    984                             res.set(0);
    985                         }
    986                     }
    987                 }
    988 
    989                 ensureBootCompleted();
    990             } break;
    991             case SHOW_NOT_RESPONDING_MSG: {
    992                 synchronized (ActivityManagerService.this) {
    993                     HashMap data = (HashMap) msg.obj;
    994                     ProcessRecord proc = (ProcessRecord)data.get("app");
    995                     if (proc != null && proc.anrDialog != null) {
    996                         Slog.e(TAG, "App already has anr dialog: " + proc);
    997                         return;
    998                     }
    999 
   1000                     Intent intent = new Intent("android.intent.action.ANR");
   1001                     if (!mProcessesReady) {
   1002                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   1003                                 | Intent.FLAG_RECEIVER_FOREGROUND);
   1004                     }
   1005                     broadcastIntentLocked(null, null, intent,
   1006                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   1007                             false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
   1008 
   1009                     if (mShowDialogs) {
   1010                         Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
   1011                                 mContext, proc, (ActivityRecord)data.get("activity"),
   1012                                 msg.arg1 != 0);
   1013                         d.show();
   1014                         proc.anrDialog = d;
   1015                     } else {
   1016                         // Just kill the app if there is no dialog to be shown.
   1017                         killAppAtUsersRequest(proc, null);
   1018                     }
   1019                 }
   1020 
   1021                 ensureBootCompleted();
   1022             } break;
   1023             case SHOW_STRICT_MODE_VIOLATION_MSG: {
   1024                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
   1025                 synchronized (ActivityManagerService.this) {
   1026                     ProcessRecord proc = (ProcessRecord) data.get("app");
   1027                     if (proc == null) {
   1028                         Slog.e(TAG, "App not found when showing strict mode dialog.");
   1029                         break;
   1030                     }
   1031                     if (proc.crashDialog != null) {
   1032                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
   1033                         return;
   1034                     }
   1035                     AppErrorResult res = (AppErrorResult) data.get("result");
   1036                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
   1037                         Dialog d = new StrictModeViolationDialog(mContext,
   1038                                 ActivityManagerService.this, res, proc);
   1039                         d.show();
   1040                         proc.crashDialog = d;
   1041                     } else {
   1042                         // The device is asleep, so just pretend that the user
   1043                         // saw a crash dialog and hit "force quit".
   1044                         res.set(0);
   1045                     }
   1046                 }
   1047                 ensureBootCompleted();
   1048             } break;
   1049             case SHOW_FACTORY_ERROR_MSG: {
   1050                 Dialog d = new FactoryErrorDialog(
   1051                     mContext, msg.getData().getCharSequence("msg"));
   1052                 d.show();
   1053                 ensureBootCompleted();
   1054             } break;
   1055             case UPDATE_CONFIGURATION_MSG: {
   1056                 final ContentResolver resolver = mContext.getContentResolver();
   1057                 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
   1058             } break;
   1059             case GC_BACKGROUND_PROCESSES_MSG: {
   1060                 synchronized (ActivityManagerService.this) {
   1061                     performAppGcsIfAppropriateLocked();
   1062                 }
   1063             } break;
   1064             case WAIT_FOR_DEBUGGER_MSG: {
   1065                 synchronized (ActivityManagerService.this) {
   1066                     ProcessRecord app = (ProcessRecord)msg.obj;
   1067                     if (msg.arg1 != 0) {
   1068                         if (!app.waitedForDebugger) {
   1069                             Dialog d = new AppWaitingForDebuggerDialog(
   1070                                     ActivityManagerService.this,
   1071                                     mContext, app);
   1072                             app.waitDialog = d;
   1073                             app.waitedForDebugger = true;
   1074                             d.show();
   1075                         }
   1076                     } else {
   1077                         if (app.waitDialog != null) {
   1078                             app.waitDialog.dismiss();
   1079                             app.waitDialog = null;
   1080                         }
   1081                     }
   1082                 }
   1083             } break;
   1084             case SERVICE_TIMEOUT_MSG: {
   1085                 if (mDidDexOpt) {
   1086                     mDidDexOpt = false;
   1087                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   1088                     nmsg.obj = msg.obj;
   1089                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
   1090                     return;
   1091                 }
   1092                 mServices.serviceTimeout((ProcessRecord)msg.obj);
   1093             } break;
   1094             case UPDATE_TIME_ZONE: {
   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.updateTimeZone();
   1101                             } catch (RemoteException ex) {
   1102                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
   1103                             }
   1104                         }
   1105                     }
   1106                 }
   1107             } break;
   1108             case CLEAR_DNS_CACHE: {
   1109                 synchronized (ActivityManagerService.this) {
   1110                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1111                         ProcessRecord r = mLruProcesses.get(i);
   1112                         if (r.thread != null) {
   1113                             try {
   1114                                 r.thread.clearDnsCache();
   1115                             } catch (RemoteException ex) {
   1116                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
   1117                             }
   1118                         }
   1119                     }
   1120                 }
   1121             } break;
   1122             case UPDATE_HTTP_PROXY: {
   1123                 ProxyProperties proxy = (ProxyProperties)msg.obj;
   1124                 String host = "";
   1125                 String port = "";
   1126                 String exclList = "";
   1127                 if (proxy != null) {
   1128                     host = proxy.getHost();
   1129                     port = Integer.toString(proxy.getPort());
   1130                     exclList = proxy.getExclusionList();
   1131                 }
   1132                 synchronized (ActivityManagerService.this) {
   1133                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1134                         ProcessRecord r = mLruProcesses.get(i);
   1135                         if (r.thread != null) {
   1136                             try {
   1137                                 r.thread.setHttpProxy(host, port, exclList);
   1138                             } catch (RemoteException ex) {
   1139                                 Slog.w(TAG, "Failed to update http proxy for: " +
   1140                                         r.info.processName);
   1141                             }
   1142                         }
   1143                     }
   1144                 }
   1145             } break;
   1146             case SHOW_UID_ERROR_MSG: {
   1147                 String title = "System UIDs Inconsistent";
   1148                 String text = "UIDs on the system are inconsistent, you need to wipe your"
   1149                         + " data partition or your device will be unstable.";
   1150                 Log.e(TAG, title + ": " + text);
   1151                 if (mShowDialogs) {
   1152                     // XXX This is a temporary dialog, no need to localize.
   1153                     AlertDialog d = new BaseErrorDialog(mContext);
   1154                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
   1155                     d.setCancelable(false);
   1156                     d.setTitle(title);
   1157                     d.setMessage(text);
   1158                     d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
   1159                             mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
   1160                     mUidAlert = d;
   1161                     d.show();
   1162                 }
   1163             } break;
   1164             case IM_FEELING_LUCKY_MSG: {
   1165                 if (mUidAlert != null) {
   1166                     mUidAlert.dismiss();
   1167                     mUidAlert = null;
   1168                 }
   1169             } break;
   1170             case PROC_START_TIMEOUT_MSG: {
   1171                 if (mDidDexOpt) {
   1172                     mDidDexOpt = false;
   1173                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   1174                     nmsg.obj = msg.obj;
   1175                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
   1176                     return;
   1177                 }
   1178                 ProcessRecord app = (ProcessRecord)msg.obj;
   1179                 synchronized (ActivityManagerService.this) {
   1180                     processStartTimedOutLocked(app);
   1181                 }
   1182             } break;
   1183             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
   1184                 synchronized (ActivityManagerService.this) {
   1185                     doPendingActivityLaunchesLocked(true);
   1186                 }
   1187             } break;
   1188             case KILL_APPLICATION_MSG: {
   1189                 synchronized (ActivityManagerService.this) {
   1190                     int appid = msg.arg1;
   1191                     boolean restart = (msg.arg2 == 1);
   1192                     String pkg = (String) msg.obj;
   1193                     forceStopPackageLocked(pkg, appid, restart, false, true, false,
   1194                             UserHandle.USER_ALL);
   1195                 }
   1196             } break;
   1197             case FINALIZE_PENDING_INTENT_MSG: {
   1198                 ((PendingIntentRecord)msg.obj).completeFinalize();
   1199             } break;
   1200             case POST_HEAVY_NOTIFICATION_MSG: {
   1201                 INotificationManager inm = NotificationManager.getService();
   1202                 if (inm == null) {
   1203                     return;
   1204                 }
   1205 
   1206                 ActivityRecord root = (ActivityRecord)msg.obj;
   1207                 ProcessRecord process = root.app;
   1208                 if (process == null) {
   1209                     return;
   1210                 }
   1211 
   1212                 try {
   1213                     Context context = mContext.createPackageContext(process.info.packageName, 0);
   1214                     String text = mContext.getString(R.string.heavy_weight_notification,
   1215                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
   1216                     Notification notification = new Notification();
   1217                     notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
   1218                     notification.when = 0;
   1219                     notification.flags = Notification.FLAG_ONGOING_EVENT;
   1220                     notification.tickerText = text;
   1221                     notification.defaults = 0; // please be quiet
   1222                     notification.sound = null;
   1223                     notification.vibrate = null;
   1224                     notification.setLatestEventInfo(context, text,
   1225                             mContext.getText(R.string.heavy_weight_notification_detail),
   1226                             PendingIntent.getActivityAsUser(mContext, 0, root.intent,
   1227                                     PendingIntent.FLAG_CANCEL_CURRENT, null,
   1228                                     new UserHandle(root.userId)));
   1229 
   1230                     try {
   1231                         int[] outId = new int[1];
   1232                         inm.enqueueNotificationWithTag("android", "android", null,
   1233                                 R.string.heavy_weight_notification,
   1234                                 notification, outId, root.userId);
   1235                     } catch (RuntimeException e) {
   1236                         Slog.w(ActivityManagerService.TAG,
   1237                                 "Error showing notification for heavy-weight app", e);
   1238                     } catch (RemoteException e) {
   1239                     }
   1240                 } catch (NameNotFoundException e) {
   1241                     Slog.w(TAG, "Unable to create context for heavy notification", e);
   1242                 }
   1243             } break;
   1244             case CANCEL_HEAVY_NOTIFICATION_MSG: {
   1245                 INotificationManager inm = NotificationManager.getService();
   1246                 if (inm == null) {
   1247                     return;
   1248                 }
   1249                 try {
   1250                     inm.cancelNotificationWithTag("android", null,
   1251                             R.string.heavy_weight_notification,  msg.arg1);
   1252                 } catch (RuntimeException e) {
   1253                     Slog.w(ActivityManagerService.TAG,
   1254                             "Error canceling notification for service", e);
   1255                 } catch (RemoteException e) {
   1256                 }
   1257             } break;
   1258             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
   1259                 synchronized (ActivityManagerService.this) {
   1260                     checkExcessivePowerUsageLocked(true);
   1261                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1262                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1263                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   1264                 }
   1265             } break;
   1266             case SHOW_COMPAT_MODE_DIALOG_MSG: {
   1267                 synchronized (ActivityManagerService.this) {
   1268                     ActivityRecord ar = (ActivityRecord)msg.obj;
   1269                     if (mCompatModeDialog != null) {
   1270                         if (mCompatModeDialog.mAppInfo.packageName.equals(
   1271                                 ar.info.applicationInfo.packageName)) {
   1272                             return;
   1273                         }
   1274                         mCompatModeDialog.dismiss();
   1275                         mCompatModeDialog = null;
   1276                     }
   1277                     if (ar != null && false) {
   1278                         if (mCompatModePackages.getPackageAskCompatModeLocked(
   1279                                 ar.packageName)) {
   1280                             int mode = mCompatModePackages.computeCompatModeLocked(
   1281                                     ar.info.applicationInfo);
   1282                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
   1283                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
   1284                                 mCompatModeDialog = new CompatModeDialog(
   1285                                         ActivityManagerService.this, mContext,
   1286                                         ar.info.applicationInfo);
   1287                                 mCompatModeDialog.show();
   1288                             }
   1289                         }
   1290                     }
   1291                 }
   1292                 break;
   1293             }
   1294             case DISPATCH_PROCESSES_CHANGED: {
   1295                 dispatchProcessesChanged();
   1296                 break;
   1297             }
   1298             case DISPATCH_PROCESS_DIED: {
   1299                 final int pid = msg.arg1;
   1300                 final int uid = msg.arg2;
   1301                 dispatchProcessDied(pid, uid);
   1302                 break;
   1303             }
   1304             case REPORT_MEM_USAGE: {
   1305                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   1306                 if (!isDebuggable) {
   1307                     return;
   1308                 }
   1309                 synchronized (ActivityManagerService.this) {
   1310                     long now = SystemClock.uptimeMillis();
   1311                     if (now < (mLastMemUsageReportTime+5*60*1000)) {
   1312                         // Don't report more than every 5 minutes to somewhat
   1313                         // avoid spamming.
   1314                         return;
   1315                     }
   1316                     mLastMemUsageReportTime = now;
   1317                 }
   1318                 Thread thread = new Thread() {
   1319                     @Override public void run() {
   1320                         StringBuilder dropBuilder = new StringBuilder(1024);
   1321                         StringBuilder logBuilder = new StringBuilder(1024);
   1322                         StringWriter oomSw = new StringWriter();
   1323                         PrintWriter oomPw = new PrintWriter(oomSw);
   1324                         StringWriter catSw = new StringWriter();
   1325                         PrintWriter catPw = new PrintWriter(catSw);
   1326                         String[] emptyArgs = new String[] { };
   1327                         StringBuilder tag = new StringBuilder(128);
   1328                         StringBuilder stack = new StringBuilder(128);
   1329                         tag.append("Low on memory -- ");
   1330                         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
   1331                                 tag, stack);
   1332                         dropBuilder.append(stack);
   1333                         dropBuilder.append('\n');
   1334                         dropBuilder.append('\n');
   1335                         String oomString = oomSw.toString();
   1336                         dropBuilder.append(oomString);
   1337                         dropBuilder.append('\n');
   1338                         logBuilder.append(oomString);
   1339                         try {
   1340                             java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
   1341                                     "procrank", });
   1342                             final InputStreamReader converter = new InputStreamReader(
   1343                                     proc.getInputStream());
   1344                             BufferedReader in = new BufferedReader(converter);
   1345                             String line;
   1346                             while (true) {
   1347                                 line = in.readLine();
   1348                                 if (line == null) {
   1349                                     break;
   1350                                 }
   1351                                 if (line.length() > 0) {
   1352                                     logBuilder.append(line);
   1353                                     logBuilder.append('\n');
   1354                                 }
   1355                                 dropBuilder.append(line);
   1356                                 dropBuilder.append('\n');
   1357                             }
   1358                             converter.close();
   1359                         } catch (IOException e) {
   1360                         }
   1361                         synchronized (ActivityManagerService.this) {
   1362                             catPw.println();
   1363                             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
   1364                             catPw.println();
   1365                             mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
   1366                                     false, false, null);
   1367                             catPw.println();
   1368                             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
   1369                         }
   1370                         dropBuilder.append(catSw.toString());
   1371                         addErrorToDropBox("lowmem", null, "system_server", null,
   1372                                 null, tag.toString(), dropBuilder.toString(), null, null);
   1373                         Slog.i(TAG, logBuilder.toString());
   1374                         synchronized (ActivityManagerService.this) {
   1375                             long now = SystemClock.uptimeMillis();
   1376                             if (mLastMemUsageReportTime < now) {
   1377                                 mLastMemUsageReportTime = now;
   1378                             }
   1379                         }
   1380                     }
   1381                 };
   1382                 thread.start();
   1383                 break;
   1384             }
   1385             case REPORT_USER_SWITCH_MSG: {
   1386                 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
   1387                 break;
   1388             }
   1389             case CONTINUE_USER_SWITCH_MSG: {
   1390                 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
   1391                 break;
   1392             }
   1393             case USER_SWITCH_TIMEOUT_MSG: {
   1394                 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
   1395                 break;
   1396             }
   1397             case IMMERSIVE_MODE_LOCK_MSG: {
   1398                 final boolean nextState = (msg.arg1 != 0);
   1399                 if (mUpdateLock.isHeld() != nextState) {
   1400                     if (DEBUG_IMMERSIVE) {
   1401                         final ActivityRecord r = (ActivityRecord) msg.obj;
   1402                         Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
   1403                     }
   1404                     if (nextState) {
   1405                         mUpdateLock.acquire();
   1406                     } else {
   1407                         mUpdateLock.release();
   1408                     }
   1409                 }
   1410                 break;
   1411             }
   1412             }
   1413         }
   1414     };
   1415 
   1416     public static void setSystemProcess() {
   1417         try {
   1418             ActivityManagerService m = mSelf;
   1419 
   1420             ServiceManager.addService("activity", m, true);
   1421             ServiceManager.addService("meminfo", new MemBinder(m));
   1422             ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
   1423             ServiceManager.addService("dbinfo", new DbBinder(m));
   1424             if (MONITOR_CPU_USAGE) {
   1425                 ServiceManager.addService("cpuinfo", new CpuBinder(m));
   1426             }
   1427             ServiceManager.addService("permission", new PermissionController(m));
   1428 
   1429             ApplicationInfo info =
   1430                 mSelf.mContext.getPackageManager().getApplicationInfo(
   1431                             "android", STOCK_PM_FLAGS);
   1432             mSystemThread.installSystemApplicationInfo(info);
   1433 
   1434             synchronized (mSelf) {
   1435                 ProcessRecord app = mSelf.newProcessRecordLocked(
   1436                         mSystemThread.getApplicationThread(), info,
   1437                         info.processName, false);
   1438                 app.persistent = true;
   1439                 app.pid = MY_PID;
   1440                 app.maxAdj = ProcessList.SYSTEM_ADJ;
   1441                 mSelf.mProcessNames.put(app.processName, app.uid, app);
   1442                 synchronized (mSelf.mPidsSelfLocked) {
   1443                     mSelf.mPidsSelfLocked.put(app.pid, app);
   1444                 }
   1445                 mSelf.updateLruProcessLocked(app, true);
   1446             }
   1447         } catch (PackageManager.NameNotFoundException e) {
   1448             throw new RuntimeException(
   1449                     "Unable to find android system package", e);
   1450         }
   1451     }
   1452 
   1453     public void setWindowManager(WindowManagerService wm) {
   1454         mWindowManager = wm;
   1455     }
   1456 
   1457     public void startObservingNativeCrashes() {
   1458         final NativeCrashListener ncl = new NativeCrashListener();
   1459         ncl.start();
   1460     }
   1461 
   1462     public static final Context main(int factoryTest) {
   1463         AThread thr = new AThread();
   1464         thr.start();
   1465 
   1466         synchronized (thr) {
   1467             while (thr.mService == null) {
   1468                 try {
   1469                     thr.wait();
   1470                 } catch (InterruptedException e) {
   1471                 }
   1472             }
   1473         }
   1474 
   1475         ActivityManagerService m = thr.mService;
   1476         mSelf = m;
   1477         ActivityThread at = ActivityThread.systemMain();
   1478         mSystemThread = at;
   1479         Context context = at.getSystemContext();
   1480         context.setTheme(android.R.style.Theme_Holo);
   1481         m.mContext = context;
   1482         m.mFactoryTest = factoryTest;
   1483         m.mMainStack = new ActivityStack(m, context, true, thr.mLooper);
   1484         m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface());
   1485 
   1486         m.mBatteryStatsService.publish(context);
   1487         m.mUsageStatsService.publish(context);
   1488         m.mAppOpsService.publish(context);
   1489 
   1490         synchronized (thr) {
   1491             thr.mReady = true;
   1492             thr.notifyAll();
   1493         }
   1494 
   1495         m.startRunning(null, null, null, null);
   1496 
   1497         return context;
   1498     }
   1499 
   1500     public static ActivityManagerService self() {
   1501         return mSelf;
   1502     }
   1503 
   1504     static class AThread extends Thread {
   1505         ActivityManagerService mService;
   1506         Looper mLooper;
   1507         boolean mReady = false;
   1508 
   1509         public AThread() {
   1510             super("ActivityManager");
   1511         }
   1512 
   1513         public void run() {
   1514             Looper.prepare();
   1515 
   1516             android.os.Process.setThreadPriority(
   1517                     android.os.Process.THREAD_PRIORITY_FOREGROUND);
   1518             android.os.Process.setCanSelfBackground(false);
   1519 
   1520             ActivityManagerService m = new ActivityManagerService();
   1521 
   1522             synchronized (this) {
   1523                 mService = m;
   1524                 mLooper = Looper.myLooper();
   1525                 notifyAll();
   1526             }
   1527 
   1528             synchronized (this) {
   1529                 while (!mReady) {
   1530                     try {
   1531                         wait();
   1532                     } catch (InterruptedException e) {
   1533                     }
   1534                 }
   1535             }
   1536 
   1537             // For debug builds, log event loop stalls to dropbox for analysis.
   1538             if (StrictMode.conditionallyEnableDebugLogging()) {
   1539                 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
   1540             }
   1541 
   1542             Looper.loop();
   1543         }
   1544     }
   1545 
   1546     static class MemBinder extends Binder {
   1547         ActivityManagerService mActivityManagerService;
   1548         MemBinder(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 meminfo from from pid="
   1557                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1558                         + " without permission " + android.Manifest.permission.DUMP);
   1559                 return;
   1560             }
   1561 
   1562             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
   1563                     false, null, null, null);
   1564         }
   1565     }
   1566 
   1567     static class GraphicsBinder extends Binder {
   1568         ActivityManagerService mActivityManagerService;
   1569         GraphicsBinder(ActivityManagerService activityManagerService) {
   1570             mActivityManagerService = activityManagerService;
   1571         }
   1572 
   1573         @Override
   1574         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1575             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1576                     != PackageManager.PERMISSION_GRANTED) {
   1577                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
   1578                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1579                         + " without permission " + android.Manifest.permission.DUMP);
   1580                 return;
   1581             }
   1582 
   1583             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
   1584         }
   1585     }
   1586 
   1587     static class DbBinder extends Binder {
   1588         ActivityManagerService mActivityManagerService;
   1589         DbBinder(ActivityManagerService activityManagerService) {
   1590             mActivityManagerService = activityManagerService;
   1591         }
   1592 
   1593         @Override
   1594         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1595             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1596                     != PackageManager.PERMISSION_GRANTED) {
   1597                 pw.println("Permission Denial: can't dump dbinfo from from pid="
   1598                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1599                         + " without permission " + android.Manifest.permission.DUMP);
   1600                 return;
   1601             }
   1602 
   1603             mActivityManagerService.dumpDbInfo(fd, pw, args);
   1604         }
   1605     }
   1606 
   1607     static class CpuBinder extends Binder {
   1608         ActivityManagerService mActivityManagerService;
   1609         CpuBinder(ActivityManagerService activityManagerService) {
   1610             mActivityManagerService = activityManagerService;
   1611         }
   1612 
   1613         @Override
   1614         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1615             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1616                     != PackageManager.PERMISSION_GRANTED) {
   1617                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
   1618                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1619                         + " without permission " + android.Manifest.permission.DUMP);
   1620                 return;
   1621             }
   1622 
   1623             synchronized (mActivityManagerService.mProcessStatsThread) {
   1624                 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
   1625                 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
   1626                         SystemClock.uptimeMillis()));
   1627             }
   1628         }
   1629     }
   1630 
   1631     private ActivityManagerService() {
   1632         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
   1633 
   1634         mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
   1635         mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
   1636         mBroadcastQueues[0] = mFgBroadcastQueue;
   1637         mBroadcastQueues[1] = mBgBroadcastQueue;
   1638 
   1639         mServices = new ActiveServices(this);
   1640         mProviderMap = new ProviderMap(this);
   1641 
   1642         File dataDir = Environment.getDataDirectory();
   1643         File systemDir = new File(dataDir, "system");
   1644         systemDir.mkdirs();
   1645         mBatteryStatsService = new BatteryStatsService(new File(
   1646                 systemDir, "batterystats.bin").toString());
   1647         mBatteryStatsService.getActiveStatistics().readLocked();
   1648         mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
   1649         mOnBattery = DEBUG_POWER ? true
   1650                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
   1651         mBatteryStatsService.getActiveStatistics().setCallback(this);
   1652 
   1653         mUsageStatsService = new UsageStatsService(new File(
   1654                 systemDir, "usagestats").toString());
   1655         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"));
   1656         mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
   1657 
   1658         // User 0 is the first and only user that runs at boot.
   1659         mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
   1660         mUserLru.add(Integer.valueOf(0));
   1661         updateStartedUserArrayLocked();
   1662 
   1663         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
   1664             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
   1665 
   1666         mConfiguration.setToDefaults();
   1667         mConfiguration.setLocale(Locale.getDefault());
   1668 
   1669         mConfigurationSeq = mConfiguration.seq = 1;
   1670         mProcessStats.init();
   1671 
   1672         mCompatModePackages = new CompatModePackages(this, systemDir);
   1673 
   1674         // Add ourself to the Watchdog monitors.
   1675         Watchdog.getInstance().addMonitor(this);
   1676 
   1677         mProcessStatsThread = new Thread("ProcessStats") {
   1678             public void run() {
   1679                 while (true) {
   1680                     try {
   1681                         try {
   1682                             synchronized(this) {
   1683                                 final long now = SystemClock.uptimeMillis();
   1684                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
   1685                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
   1686                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
   1687                                 //        + ", write delay=" + nextWriteDelay);
   1688                                 if (nextWriteDelay < nextCpuDelay) {
   1689                                     nextCpuDelay = nextWriteDelay;
   1690                                 }
   1691                                 if (nextCpuDelay > 0) {
   1692                                     mProcessStatsMutexFree.set(true);
   1693                                     this.wait(nextCpuDelay);
   1694                                 }
   1695                             }
   1696                         } catch (InterruptedException e) {
   1697                         }
   1698                         updateCpuStatsNow();
   1699                     } catch (Exception e) {
   1700                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
   1701                     }
   1702                 }
   1703             }
   1704         };
   1705         mProcessStatsThread.start();
   1706     }
   1707 
   1708     @Override
   1709     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   1710             throws RemoteException {
   1711         if (code == SYSPROPS_TRANSACTION) {
   1712             // We need to tell all apps about the system property change.
   1713             ArrayList<IBinder> procs = new ArrayList<IBinder>();
   1714             synchronized(this) {
   1715                 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   1716                     final int NA = apps.size();
   1717                     for (int ia=0; ia<NA; ia++) {
   1718                         ProcessRecord app = apps.valueAt(ia);
   1719                         if (app.thread != null) {
   1720                             procs.add(app.thread.asBinder());
   1721                         }
   1722                     }
   1723                 }
   1724             }
   1725 
   1726             int N = procs.size();
   1727             for (int i=0; i<N; i++) {
   1728                 Parcel data2 = Parcel.obtain();
   1729                 try {
   1730                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
   1731                 } catch (RemoteException e) {
   1732                 }
   1733                 data2.recycle();
   1734             }
   1735         }
   1736         try {
   1737             return super.onTransact(code, data, reply, flags);
   1738         } catch (RuntimeException e) {
   1739             // The activity manager only throws security exceptions, so let's
   1740             // log all others.
   1741             if (!(e instanceof SecurityException)) {
   1742                 Slog.e(TAG, "Activity Manager Crash", e);
   1743             }
   1744             throw e;
   1745         }
   1746     }
   1747 
   1748     void updateCpuStats() {
   1749         final long now = SystemClock.uptimeMillis();
   1750         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
   1751             return;
   1752         }
   1753         if (mProcessStatsMutexFree.compareAndSet(true, false)) {
   1754             synchronized (mProcessStatsThread) {
   1755                 mProcessStatsThread.notify();
   1756             }
   1757         }
   1758     }
   1759 
   1760     void updateCpuStatsNow() {
   1761         synchronized (mProcessStatsThread) {
   1762             mProcessStatsMutexFree.set(false);
   1763             final long now = SystemClock.uptimeMillis();
   1764             boolean haveNewCpuStats = false;
   1765 
   1766             if (MONITOR_CPU_USAGE &&
   1767                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
   1768                 mLastCpuTime.set(now);
   1769                 haveNewCpuStats = true;
   1770                 mProcessStats.update();
   1771                 //Slog.i(TAG, mProcessStats.printCurrentState());
   1772                 //Slog.i(TAG, "Total CPU usage: "
   1773                 //        + mProcessStats.getTotalCpuPercent() + "%");
   1774 
   1775                 // Slog the cpu usage if the property is set.
   1776                 if ("true".equals(SystemProperties.get("events.cpu"))) {
   1777                     int user = mProcessStats.getLastUserTime();
   1778                     int system = mProcessStats.getLastSystemTime();
   1779                     int iowait = mProcessStats.getLastIoWaitTime();
   1780                     int irq = mProcessStats.getLastIrqTime();
   1781                     int softIrq = mProcessStats.getLastSoftIrqTime();
   1782                     int idle = mProcessStats.getLastIdleTime();
   1783 
   1784                     int total = user + system + iowait + irq + softIrq + idle;
   1785                     if (total == 0) total = 1;
   1786 
   1787                     EventLog.writeEvent(EventLogTags.CPU,
   1788                             ((user+system+iowait+irq+softIrq) * 100) / total,
   1789                             (user * 100) / total,
   1790                             (system * 100) / total,
   1791                             (iowait * 100) / total,
   1792                             (irq * 100) / total,
   1793                             (softIrq * 100) / total);
   1794                 }
   1795             }
   1796 
   1797             long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
   1798             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
   1799             synchronized(bstats) {
   1800                 synchronized(mPidsSelfLocked) {
   1801                     if (haveNewCpuStats) {
   1802                         if (mOnBattery) {
   1803                             int perc = bstats.startAddingCpuLocked();
   1804                             int totalUTime = 0;
   1805                             int totalSTime = 0;
   1806                             final int N = mProcessStats.countStats();
   1807                             for (int i=0; i<N; i++) {
   1808                                 ProcessStats.Stats st = mProcessStats.getStats(i);
   1809                                 if (!st.working) {
   1810                                     continue;
   1811                                 }
   1812                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
   1813                                 int otherUTime = (st.rel_utime*perc)/100;
   1814                                 int otherSTime = (st.rel_stime*perc)/100;
   1815                                 totalUTime += otherUTime;
   1816                                 totalSTime += otherSTime;
   1817                                 if (pr != null) {
   1818                                     BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
   1819                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
   1820                                             st.rel_stime-otherSTime);
   1821                                     ps.addSpeedStepTimes(cpuSpeedTimes);
   1822                                     pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
   1823                                 } else {
   1824                                     BatteryStatsImpl.Uid.Proc ps =
   1825                                             bstats.getProcessStatsLocked(st.name, st.pid);
   1826                                     if (ps != null) {
   1827                                         ps.addCpuTimeLocked(st.rel_utime-otherUTime,
   1828                                                 st.rel_stime-otherSTime);
   1829                                         ps.addSpeedStepTimes(cpuSpeedTimes);
   1830                                     }
   1831                                 }
   1832                             }
   1833                             bstats.finishAddingCpuLocked(perc, totalUTime,
   1834                                     totalSTime, cpuSpeedTimes);
   1835                         }
   1836                     }
   1837                 }
   1838 
   1839                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
   1840                     mLastWriteTime = now;
   1841                     mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
   1842                 }
   1843             }
   1844         }
   1845     }
   1846 
   1847     @Override
   1848     public void batteryNeedsCpuUpdate() {
   1849         updateCpuStatsNow();
   1850     }
   1851 
   1852     @Override
   1853     public void batteryPowerChanged(boolean onBattery) {
   1854         // When plugging in, update the CPU stats first before changing
   1855         // the plug state.
   1856         updateCpuStatsNow();
   1857         synchronized (this) {
   1858             synchronized(mPidsSelfLocked) {
   1859                 mOnBattery = DEBUG_POWER ? true : onBattery;
   1860             }
   1861         }
   1862     }
   1863 
   1864     /**
   1865      * Initialize the application bind args. These are passed to each
   1866      * process when the bindApplication() IPC is sent to the process. They're
   1867      * lazily setup to make sure the services are running when they're asked for.
   1868      */
   1869     private HashMap<String, IBinder> getCommonServicesLocked() {
   1870         if (mAppBindArgs == null) {
   1871             mAppBindArgs = new HashMap<String, IBinder>();
   1872 
   1873             // Setup the application init args
   1874             mAppBindArgs.put("package", ServiceManager.getService("package"));
   1875             mAppBindArgs.put("window", ServiceManager.getService("window"));
   1876             mAppBindArgs.put(Context.ALARM_SERVICE,
   1877                     ServiceManager.getService(Context.ALARM_SERVICE));
   1878         }
   1879         return mAppBindArgs;
   1880     }
   1881 
   1882     final void setFocusedActivityLocked(ActivityRecord r) {
   1883         if (mFocusedActivity != r) {
   1884             mFocusedActivity = r;
   1885             if (r != null) {
   1886                 mWindowManager.setFocusedApp(r.appToken, true);
   1887             }
   1888             applyUpdateLockStateLocked(r);
   1889         }
   1890     }
   1891 
   1892     final void applyUpdateLockStateLocked(ActivityRecord r) {
   1893         // Modifications to the UpdateLock state are done on our handler, outside
   1894         // the activity manager's locks.  The new state is determined based on the
   1895         // state *now* of the relevant activity record.  The object is passed to
   1896         // the handler solely for logging detail, not to be consulted/modified.
   1897         final boolean nextState = r != null && r.immersive;
   1898         mHandler.sendMessage(
   1899                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
   1900     }
   1901 
   1902     private final void updateLruProcessInternalLocked(ProcessRecord app, int bestPos) {
   1903         // put it on the LRU to keep track of when it should be exited.
   1904         int lrui = mLruProcesses.indexOf(app);
   1905         if (lrui >= 0) mLruProcesses.remove(lrui);
   1906 
   1907         int i = mLruProcesses.size()-1;
   1908         int skipTop = 0;
   1909 
   1910         app.lruSeq = mLruSeq;
   1911 
   1912         // compute the new weight for this process.
   1913         app.lastActivityTime = SystemClock.uptimeMillis();
   1914         if (app.activities.size() > 0) {
   1915             // If this process has activities, we more strongly want to keep
   1916             // it around.
   1917             app.lruWeight = app.lastActivityTime;
   1918         } else if (app.pubProviders.size() > 0) {
   1919             // If this process contains content providers, we want to keep
   1920             // it a little more strongly.
   1921             app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
   1922             // Also don't let it kick out the first few "real" hidden processes.
   1923             skipTop = ProcessList.MIN_HIDDEN_APPS;
   1924         } else {
   1925             // If this process doesn't have activities, we less strongly
   1926             // want to keep it around, and generally want to avoid getting
   1927             // in front of any very recently used activities.
   1928             app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
   1929             // Also don't let it kick out the first few "real" hidden processes.
   1930             skipTop = ProcessList.MIN_HIDDEN_APPS;
   1931         }
   1932 
   1933         while (i >= 0) {
   1934             ProcessRecord p = mLruProcesses.get(i);
   1935             // If this app shouldn't be in front of the first N background
   1936             // apps, then skip over that many that are currently hidden.
   1937             if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   1938                 skipTop--;
   1939             }
   1940             if (p.lruWeight <= app.lruWeight || i < bestPos) {
   1941                 mLruProcesses.add(i+1, app);
   1942                 break;
   1943             }
   1944             i--;
   1945         }
   1946         if (i < 0) {
   1947             mLruProcesses.add(0, app);
   1948         }
   1949 
   1950         // If the app is currently using a content provider or service,
   1951         // bump those processes as well.
   1952         if (app.connections.size() > 0) {
   1953             for (ConnectionRecord cr : app.connections) {
   1954                 if (cr.binding != null && cr.binding.service != null
   1955                         && cr.binding.service.app != null
   1956                         && cr.binding.service.app.lruSeq != mLruSeq) {
   1957                     updateLruProcessInternalLocked(cr.binding.service.app, i+1);
   1958                 }
   1959             }
   1960         }
   1961         for (int j=app.conProviders.size()-1; j>=0; j--) {
   1962             ContentProviderRecord cpr = app.conProviders.get(j).provider;
   1963             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
   1964                 updateLruProcessInternalLocked(cpr.proc, i+1);
   1965             }
   1966         }
   1967     }
   1968 
   1969     final void updateLruProcessLocked(ProcessRecord app,
   1970             boolean oomAdj) {
   1971         mLruSeq++;
   1972         updateLruProcessInternalLocked(app, 0);
   1973 
   1974         //Slog.i(TAG, "Putting proc to front: " + app.processName);
   1975         if (oomAdj) {
   1976             updateOomAdjLocked();
   1977         }
   1978     }
   1979 
   1980     final ProcessRecord getProcessRecordLocked(
   1981             String processName, int uid) {
   1982         if (uid == Process.SYSTEM_UID) {
   1983             // The system gets to run in any process.  If there are multiple
   1984             // processes with the same uid, just pick the first (this
   1985             // should never happen).
   1986             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
   1987                     processName);
   1988             if (procs == null) return null;
   1989             final int N = procs.size();
   1990             for (int i = 0; i < N; i++) {
   1991                 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
   1992             }
   1993         }
   1994         ProcessRecord proc = mProcessNames.get(processName, uid);
   1995         return proc;
   1996     }
   1997 
   1998     void ensurePackageDexOpt(String packageName) {
   1999         IPackageManager pm = AppGlobals.getPackageManager();
   2000         try {
   2001             if (pm.performDexOpt(packageName)) {
   2002                 mDidDexOpt = true;
   2003             }
   2004         } catch (RemoteException e) {
   2005         }
   2006     }
   2007 
   2008     boolean isNextTransitionForward() {
   2009         int transit = mWindowManager.getPendingAppTransition();
   2010         return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
   2011                 || transit == AppTransition.TRANSIT_TASK_OPEN
   2012                 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
   2013     }
   2014 
   2015     final ProcessRecord startProcessLocked(String processName,
   2016             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
   2017             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
   2018             boolean isolated) {
   2019         ProcessRecord app;
   2020         if (!isolated) {
   2021             app = getProcessRecordLocked(processName, info.uid);
   2022         } else {
   2023             // If this is an isolated process, it can't re-use an existing process.
   2024             app = null;
   2025         }
   2026         // We don't have to do anything more if:
   2027         // (1) There is an existing application record; and
   2028         // (2) The caller doesn't think it is dead, OR there is no thread
   2029         //     object attached to it so we know it couldn't have crashed; and
   2030         // (3) There is a pid assigned to it, so it is either starting or
   2031         //     already running.
   2032         if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
   2033                 + " app=" + app + " knownToBeDead=" + knownToBeDead
   2034                 + " thread=" + (app != null ? app.thread : null)
   2035                 + " pid=" + (app != null ? app.pid : -1));
   2036         if (app != null && app.pid > 0) {
   2037             if (!knownToBeDead || app.thread == null) {
   2038                 // We already have the app running, or are waiting for it to
   2039                 // come up (we have a pid but not yet its thread), so keep it.
   2040                 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
   2041                 // If this is a new package in the process, add the package to the list
   2042                 app.addPackage(info.packageName);
   2043                 return app;
   2044             } else {
   2045                 // An application record is attached to a previous process,
   2046                 // clean it up now.
   2047                 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
   2048                 handleAppDiedLocked(app, true, true);
   2049             }
   2050         }
   2051 
   2052         String hostingNameStr = hostingName != null
   2053                 ? hostingName.flattenToShortString() : null;
   2054 
   2055         if (!isolated) {
   2056             if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
   2057                 // If we are in the background, then check to see if this process
   2058                 // is bad.  If so, we will just silently fail.
   2059                 if (mBadProcesses.get(info.processName, info.uid) != null) {
   2060                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
   2061                             + "/" + info.processName);
   2062                     return null;
   2063                 }
   2064             } else {
   2065                 // When the user is explicitly starting a process, then clear its
   2066                 // crash count so that we won't make it bad until they see at
   2067                 // least one crash dialog again, and make the process good again
   2068                 // if it had been bad.
   2069                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
   2070                         + "/" + info.processName);
   2071                 mProcessCrashTimes.remove(info.processName, info.uid);
   2072                 if (mBadProcesses.get(info.processName, info.uid) != null) {
   2073                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
   2074                             UserHandle.getUserId(info.uid), info.uid,
   2075                             info.processName);
   2076                     mBadProcesses.remove(info.processName, info.uid);
   2077                     if (app != null) {
   2078                         app.bad = false;
   2079                     }
   2080                 }
   2081             }
   2082         }
   2083 
   2084         if (app == null) {
   2085             app = newProcessRecordLocked(null, info, processName, isolated);
   2086             if (app == null) {
   2087                 Slog.w(TAG, "Failed making new process record for "
   2088                         + processName + "/" + info.uid + " isolated=" + isolated);
   2089                 return null;
   2090             }
   2091             mProcessNames.put(processName, app.uid, app);
   2092             if (isolated) {
   2093                 mIsolatedProcesses.put(app.uid, app);
   2094             }
   2095         } else {
   2096             // If this is a new package in the process, add the package to the list
   2097             app.addPackage(info.packageName);
   2098         }
   2099 
   2100         // If the system is not ready yet, then hold off on starting this
   2101         // process until it is.
   2102         if (!mProcessesReady
   2103                 && !isAllowedWhileBooting(info)
   2104                 && !allowWhileBooting) {
   2105             if (!mProcessesOnHold.contains(app)) {
   2106                 mProcessesOnHold.add(app);
   2107             }
   2108             if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
   2109             return app;
   2110         }
   2111 
   2112         startProcessLocked(app, hostingType, hostingNameStr);
   2113         return (app.pid != 0) ? app : null;
   2114     }
   2115 
   2116     boolean isAllowedWhileBooting(ApplicationInfo ai) {
   2117         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
   2118     }
   2119 
   2120     private final void startProcessLocked(ProcessRecord app,
   2121             String hostingType, String hostingNameStr) {
   2122         if (app.pid > 0 && app.pid != MY_PID) {
   2123             synchronized (mPidsSelfLocked) {
   2124                 mPidsSelfLocked.remove(app.pid);
   2125                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   2126             }
   2127             app.setPid(0);
   2128         }
   2129 
   2130         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   2131                 "startProcessLocked removing on hold: " + app);
   2132         mProcessesOnHold.remove(app);
   2133 
   2134         updateCpuStats();
   2135 
   2136         System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
   2137         mProcDeaths[0] = 0;
   2138 
   2139         try {
   2140             int uid = app.uid;
   2141 
   2142             int[] gids = null;
   2143             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
   2144             if (!app.isolated) {
   2145                 int[] permGids = null;
   2146                 try {
   2147                     final PackageManager pm = mContext.getPackageManager();
   2148                     permGids = pm.getPackageGids(app.info.packageName);
   2149 
   2150                     if (Environment.isExternalStorageEmulated()) {
   2151                         if (pm.checkPermission(
   2152                                 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
   2153                                 app.info.packageName) == PERMISSION_GRANTED) {
   2154                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
   2155                         } else {
   2156                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
   2157                         }
   2158                     }
   2159                 } catch (PackageManager.NameNotFoundException e) {
   2160                     Slog.w(TAG, "Unable to retrieve gids", e);
   2161                 }
   2162 
   2163                 /*
   2164                  * Add shared application GID so applications can share some
   2165                  * resources like shared libraries
   2166                  */
   2167                 if (permGids == null) {
   2168                     gids = new int[1];
   2169                 } else {
   2170                     gids = new int[permGids.length + 1];
   2171                     System.arraycopy(permGids, 0, gids, 1, permGids.length);
   2172                 }
   2173                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
   2174             }
   2175             if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
   2176                 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
   2177                         && mTopComponent != null
   2178                         && app.processName.equals(mTopComponent.getPackageName())) {
   2179                     uid = 0;
   2180                 }
   2181                 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
   2182                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
   2183                     uid = 0;
   2184                 }
   2185             }
   2186             int debugFlags = 0;
   2187             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   2188                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
   2189                 // Also turn on CheckJNI for debuggable apps. It's quite
   2190                 // awkward to turn on otherwise.
   2191                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   2192             }
   2193             // Run the app in safe mode if its manifest requests so or the
   2194             // system is booted in safe mode.
   2195             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
   2196                 Zygote.systemInSafeMode == true) {
   2197                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
   2198             }
   2199             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
   2200                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   2201             }
   2202             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
   2203                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
   2204             }
   2205             if ("1".equals(SystemProperties.get("debug.assert"))) {
   2206                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
   2207             }
   2208 
   2209             // Start the process.  It will either succeed and return a result containing
   2210             // the PID of the new process, or else throw a RuntimeException.
   2211             Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
   2212                     app.processName, uid, uid, gids, debugFlags, mountExternal,
   2213                     app.info.targetSdkVersion, app.info.seinfo, null);
   2214 
   2215             BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
   2216             synchronized (bs) {
   2217                 if (bs.isOnBattery()) {
   2218                     app.batteryStats.incStartsLocked();
   2219                 }
   2220             }
   2221 
   2222             EventLog.writeEvent(EventLogTags.AM_PROC_START,
   2223                     UserHandle.getUserId(uid), startResult.pid, uid,
   2224                     app.processName, hostingType,
   2225                     hostingNameStr != null ? hostingNameStr : "");
   2226 
   2227             if (app.persistent) {
   2228                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
   2229             }
   2230 
   2231             StringBuilder buf = mStringBuilder;
   2232             buf.setLength(0);
   2233             buf.append("Start proc ");
   2234             buf.append(app.processName);
   2235             buf.append(" for ");
   2236             buf.append(hostingType);
   2237             if (hostingNameStr != null) {
   2238                 buf.append(" ");
   2239                 buf.append(hostingNameStr);
   2240             }
   2241             buf.append(": pid=");
   2242             buf.append(startResult.pid);
   2243             buf.append(" uid=");
   2244             buf.append(uid);
   2245             buf.append(" gids={");
   2246             if (gids != null) {
   2247                 for (int gi=0; gi<gids.length; gi++) {
   2248                     if (gi != 0) buf.append(", ");
   2249                     buf.append(gids[gi]);
   2250 
   2251                 }
   2252             }
   2253             buf.append("}");
   2254             Slog.i(TAG, buf.toString());
   2255             app.setPid(startResult.pid);
   2256             app.usingWrapper = startResult.usingWrapper;
   2257             app.removed = false;
   2258             synchronized (mPidsSelfLocked) {
   2259                 this.mPidsSelfLocked.put(startResult.pid, app);
   2260                 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   2261                 msg.obj = app;
   2262                 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
   2263                         ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
   2264             }
   2265         } catch (RuntimeException e) {
   2266             // XXX do better error recovery.
   2267             app.setPid(0);
   2268             Slog.e(TAG, "Failure starting process " + app.processName, e);
   2269         }
   2270     }
   2271 
   2272     void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
   2273         if (resumed) {
   2274             mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
   2275         } else {
   2276             mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
   2277         }
   2278     }
   2279 
   2280     boolean startHomeActivityLocked(int userId) {
   2281         if (mHeadless) {
   2282             // Added because none of the other calls to ensureBootCompleted seem to fire
   2283             // when running headless.
   2284             ensureBootCompleted();
   2285             return false;
   2286         }
   2287 
   2288         if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
   2289                 && mTopAction == null) {
   2290             // We are running in factory test mode, but unable to find
   2291             // the factory test app, so just sit around displaying the
   2292             // error message and don't try to start anything.
   2293             return false;
   2294         }
   2295         Intent intent = new Intent(
   2296             mTopAction,
   2297             mTopData != null ? Uri.parse(mTopData) : null);
   2298         intent.setComponent(mTopComponent);
   2299         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   2300             intent.addCategory(Intent.CATEGORY_HOME);
   2301         }
   2302         ActivityInfo aInfo =
   2303             resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
   2304         if (aInfo != null) {
   2305             intent.setComponent(new ComponentName(
   2306                     aInfo.applicationInfo.packageName, aInfo.name));
   2307             // Don't do this if the home app is currently being
   2308             // instrumented.
   2309             aInfo = new ActivityInfo(aInfo);
   2310             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
   2311             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
   2312                     aInfo.applicationInfo.uid);
   2313             if (app == null || app.instrumentationClass == null) {
   2314                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
   2315                 mMainStack.startActivityLocked(null, intent, null, aInfo,
   2316                         null, null, 0, 0, 0, null, 0, null, false, null);
   2317             }
   2318         }
   2319 
   2320         return true;
   2321     }
   2322 
   2323     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
   2324         ActivityInfo ai = null;
   2325         ComponentName comp = intent.getComponent();
   2326         try {
   2327             if (comp != null) {
   2328                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
   2329             } else {
   2330                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
   2331                         intent,
   2332                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
   2333                             flags, userId);
   2334 
   2335                 if (info != null) {
   2336                     ai = info.activityInfo;
   2337                 }
   2338             }
   2339         } catch (RemoteException e) {
   2340             // ignore
   2341         }
   2342 
   2343         return ai;
   2344     }
   2345 
   2346     /**
   2347      * Starts the "new version setup screen" if appropriate.
   2348      */
   2349     void startSetupActivityLocked() {
   2350         // Only do this once per boot.
   2351         if (mCheckedForSetup) {
   2352             return;
   2353         }
   2354 
   2355         // We will show this screen if the current one is a different
   2356         // version than the last one shown, and we are not running in
   2357         // low-level factory test mode.
   2358         final ContentResolver resolver = mContext.getContentResolver();
   2359         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
   2360                 Settings.Global.getInt(resolver,
   2361                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
   2362             mCheckedForSetup = true;
   2363 
   2364             // See if we should be showing the platform update setup UI.
   2365             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
   2366             List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
   2367                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
   2368 
   2369             // We don't allow third party apps to replace this.
   2370             ResolveInfo ri = null;
   2371             for (int i=0; ris != null && i<ris.size(); i++) {
   2372                 if ((ris.get(i).activityInfo.applicationInfo.flags
   2373                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
   2374                     ri = ris.get(i);
   2375                     break;
   2376                 }
   2377             }
   2378 
   2379             if (ri != null) {
   2380                 String vers = ri.activityInfo.metaData != null
   2381                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
   2382                         : null;
   2383                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
   2384                     vers = ri.activityInfo.applicationInfo.metaData.getString(
   2385                             Intent.METADATA_SETUP_VERSION);
   2386                 }
   2387                 String lastVers = Settings.Secure.getString(
   2388                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
   2389                 if (vers != null && !vers.equals(lastVers)) {
   2390                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   2391                     intent.setComponent(new ComponentName(
   2392                             ri.activityInfo.packageName, ri.activityInfo.name));
   2393                     mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
   2394                             null, null, 0, 0, 0, null, 0, null, false, null);
   2395                 }
   2396             }
   2397         }
   2398     }
   2399 
   2400     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
   2401         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
   2402     }
   2403 
   2404     void enforceNotIsolatedCaller(String caller) {
   2405         if (UserHandle.isIsolated(Binder.getCallingUid())) {
   2406             throw new SecurityException("Isolated process not allowed to call " + caller);
   2407         }
   2408     }
   2409 
   2410     public int getFrontActivityScreenCompatMode() {
   2411         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
   2412         synchronized (this) {
   2413             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
   2414         }
   2415     }
   2416 
   2417     public void setFrontActivityScreenCompatMode(int mode) {
   2418         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   2419                 "setFrontActivityScreenCompatMode");
   2420         synchronized (this) {
   2421             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
   2422         }
   2423     }
   2424 
   2425     public int getPackageScreenCompatMode(String packageName) {
   2426         enforceNotIsolatedCaller("getPackageScreenCompatMode");
   2427         synchronized (this) {
   2428             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
   2429         }
   2430     }
   2431 
   2432     public void setPackageScreenCompatMode(String packageName, int mode) {
   2433         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   2434                 "setPackageScreenCompatMode");
   2435         synchronized (this) {
   2436             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
   2437         }
   2438     }
   2439 
   2440     public boolean getPackageAskScreenCompat(String packageName) {
   2441         enforceNotIsolatedCaller("getPackageAskScreenCompat");
   2442         synchronized (this) {
   2443             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
   2444         }
   2445     }
   2446 
   2447     public void setPackageAskScreenCompat(String packageName, boolean ask) {
   2448         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   2449                 "setPackageAskScreenCompat");
   2450         synchronized (this) {
   2451             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
   2452         }
   2453     }
   2454 
   2455     void reportResumedActivityLocked(ActivityRecord r) {
   2456         //Slog.i(TAG, "**** REPORT RESUME: " + r);
   2457         updateUsageStats(r, true);
   2458     }
   2459 
   2460     private void dispatchProcessesChanged() {
   2461         int N;
   2462         synchronized (this) {
   2463             N = mPendingProcessChanges.size();
   2464             if (mActiveProcessChanges.length < N) {
   2465                 mActiveProcessChanges = new ProcessChangeItem[N];
   2466             }
   2467             mPendingProcessChanges.toArray(mActiveProcessChanges);
   2468             mAvailProcessChanges.addAll(mPendingProcessChanges);
   2469             mPendingProcessChanges.clear();
   2470             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
   2471         }
   2472         int i = mProcessObservers.beginBroadcast();
   2473         while (i > 0) {
   2474             i--;
   2475             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   2476             if (observer != null) {
   2477                 try {
   2478                     for (int j=0; j<N; j++) {
   2479                         ProcessChangeItem item = mActiveProcessChanges[j];
   2480                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
   2481                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
   2482                                     + item.pid + " uid=" + item.uid + ": "
   2483                                     + item.foregroundActivities);
   2484                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
   2485                                     item.foregroundActivities);
   2486                         }
   2487                         if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
   2488                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
   2489                                     + item.pid + " uid=" + item.uid + ": " + item.importance);
   2490                             observer.onImportanceChanged(item.pid, item.uid,
   2491                                     item.importance);
   2492                         }
   2493                     }
   2494                 } catch (RemoteException e) {
   2495                 }
   2496             }
   2497         }
   2498         mProcessObservers.finishBroadcast();
   2499     }
   2500 
   2501     private void dispatchProcessDied(int pid, int uid) {
   2502         int i = mProcessObservers.beginBroadcast();
   2503         while (i > 0) {
   2504             i--;
   2505             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   2506             if (observer != null) {
   2507                 try {
   2508                     observer.onProcessDied(pid, uid);
   2509                 } catch (RemoteException e) {
   2510                 }
   2511             }
   2512         }
   2513         mProcessObservers.finishBroadcast();
   2514     }
   2515 
   2516     final void doPendingActivityLaunchesLocked(boolean doResume) {
   2517         final int N = mPendingActivityLaunches.size();
   2518         if (N <= 0) {
   2519             return;
   2520         }
   2521         for (int i=0; i<N; i++) {
   2522             PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
   2523             mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
   2524                     pal.startFlags, doResume && i == (N-1), null);
   2525         }
   2526         mPendingActivityLaunches.clear();
   2527     }
   2528 
   2529     public final int startActivity(IApplicationThread caller, String callingPackage,
   2530             Intent intent, String resolvedType, IBinder resultTo,
   2531             String resultWho, int requestCode, int startFlags,
   2532             String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
   2533         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
   2534                 resultWho, requestCode,
   2535                 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
   2536     }
   2537 
   2538     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
   2539             Intent intent, String resolvedType, IBinder resultTo,
   2540             String resultWho, int requestCode, int startFlags,
   2541             String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
   2542         enforceNotIsolatedCaller("startActivity");
   2543         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   2544                 false, true, "startActivity", null);
   2545         return mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
   2546                 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
   2547                 null, null, options, userId);
   2548     }
   2549 
   2550     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
   2551             Intent intent, String resolvedType, IBinder resultTo,
   2552             String resultWho, int requestCode, int startFlags, String profileFile,
   2553             ParcelFileDescriptor profileFd, Bundle options, int userId) {
   2554         enforceNotIsolatedCaller("startActivityAndWait");
   2555         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   2556                 false, true, "startActivityAndWait", null);
   2557         WaitResult res = new WaitResult();
   2558         mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
   2559                 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
   2560                 res, null, options, UserHandle.getCallingUserId());
   2561         return res;
   2562     }
   2563 
   2564     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
   2565             Intent intent, String resolvedType, IBinder resultTo,
   2566             String resultWho, int requestCode, int startFlags, Configuration config,
   2567             Bundle options, int userId) {
   2568         enforceNotIsolatedCaller("startActivityWithConfig");
   2569         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   2570                 false, true, "startActivityWithConfig", null);
   2571         int ret = mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
   2572                 resultTo, resultWho, requestCode, startFlags,
   2573                 null, null, null, config, options, userId);
   2574         return ret;
   2575     }
   2576 
   2577     public int startActivityIntentSender(IApplicationThread caller,
   2578             IntentSender intent, Intent fillInIntent, String resolvedType,
   2579             IBinder resultTo, String resultWho, int requestCode,
   2580             int flagsMask, int flagsValues, Bundle options) {
   2581         enforceNotIsolatedCaller("startActivityIntentSender");
   2582         // Refuse possible leaked file descriptors
   2583         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
   2584             throw new IllegalArgumentException("File descriptors passed in Intent");
   2585         }
   2586 
   2587         IIntentSender sender = intent.getTarget();
   2588         if (!(sender instanceof PendingIntentRecord)) {
   2589             throw new IllegalArgumentException("Bad PendingIntent object");
   2590         }
   2591 
   2592         PendingIntentRecord pir = (PendingIntentRecord)sender;
   2593 
   2594         synchronized (this) {
   2595             // If this is coming from the currently resumed activity, it is
   2596             // effectively saying that app switches are allowed at this point.
   2597             if (mMainStack.mResumedActivity != null
   2598                     && mMainStack.mResumedActivity.info.applicationInfo.uid ==
   2599                             Binder.getCallingUid()) {
   2600                 mAppSwitchesAllowedTime = 0;
   2601             }
   2602         }
   2603         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
   2604                 resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
   2605         return ret;
   2606     }
   2607 
   2608     public boolean startNextMatchingActivity(IBinder callingActivity,
   2609             Intent intent, Bundle options) {
   2610         // Refuse possible leaked file descriptors
   2611         if (intent != null && intent.hasFileDescriptors() == true) {
   2612             throw new IllegalArgumentException("File descriptors passed in Intent");
   2613         }
   2614 
   2615         synchronized (this) {
   2616             ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
   2617             if (r == null) {
   2618                 ActivityOptions.abort(options);
   2619                 return false;
   2620             }
   2621             if (r.app == null || r.app.thread == null) {
   2622                 // The caller is not running...  d'oh!
   2623                 ActivityOptions.abort(options);
   2624                 return false;
   2625             }
   2626             intent = new Intent(intent);
   2627             // The caller is not allowed to change the data.
   2628             intent.setDataAndType(r.intent.getData(), r.intent.getType());
   2629             // And we are resetting to find the next component...
   2630             intent.setComponent(null);
   2631 
   2632             ActivityInfo aInfo = null;
   2633             try {
   2634                 List<ResolveInfo> resolves =
   2635                     AppGlobals.getPackageManager().queryIntentActivities(
   2636                             intent, r.resolvedType,
   2637                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
   2638                             UserHandle.getCallingUserId());
   2639 
   2640                 // Look for the original activity in the list...
   2641                 final int N = resolves != null ? resolves.size() : 0;
   2642                 for (int i=0; i<N; i++) {
   2643                     ResolveInfo rInfo = resolves.get(i);
   2644                     if (rInfo.activityInfo.packageName.equals(r.packageName)
   2645                             && rInfo.activityInfo.name.equals(r.info.name)) {
   2646                         // We found the current one...  the next matching is
   2647                         // after it.
   2648                         i++;
   2649                         if (i<N) {
   2650                             aInfo = resolves.get(i).activityInfo;
   2651                         }
   2652                         break;
   2653                     }
   2654                 }
   2655             } catch (RemoteException e) {
   2656             }
   2657 
   2658             if (aInfo == null) {
   2659                 // Nobody who is next!
   2660                 ActivityOptions.abort(options);
   2661                 return false;
   2662             }
   2663 
   2664             intent.setComponent(new ComponentName(
   2665                     aInfo.applicationInfo.packageName, aInfo.name));
   2666             intent.setFlags(intent.getFlags()&~(
   2667                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
   2668                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
   2669                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
   2670                     Intent.FLAG_ACTIVITY_NEW_TASK));
   2671 
   2672             // Okay now we need to start the new activity, replacing the
   2673             // currently running activity.  This is a little tricky because
   2674             // we want to start the new one as if the current one is finished,
   2675             // but not finish the current one first so that there is no flicker.
   2676             // And thus...
   2677             final boolean wasFinishing = r.finishing;
   2678             r.finishing = true;
   2679 
   2680             // Propagate reply information over to the new activity.
   2681             final ActivityRecord resultTo = r.resultTo;
   2682             final String resultWho = r.resultWho;
   2683             final int requestCode = r.requestCode;
   2684             r.resultTo = null;
   2685             if (resultTo != null) {
   2686                 resultTo.removeResultsLocked(r, resultWho, requestCode);
   2687             }
   2688 
   2689             final long origId = Binder.clearCallingIdentity();
   2690             int res = mMainStack.startActivityLocked(r.app.thread, intent,
   2691                     r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
   2692                     resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
   2693                     options, false, null);
   2694             Binder.restoreCallingIdentity(origId);
   2695 
   2696             r.finishing = wasFinishing;
   2697             if (res != ActivityManager.START_SUCCESS) {
   2698                 return false;
   2699             }
   2700             return true;
   2701         }
   2702     }
   2703 
   2704     final int startActivityInPackage(int uid, String callingPackage,
   2705             Intent intent, String resolvedType, IBinder resultTo,
   2706             String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
   2707 
   2708         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   2709                 false, true, "startActivityInPackage", null);
   2710 
   2711         int ret = mMainStack.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
   2712                 resultTo, resultWho, requestCode, startFlags,
   2713                 null, null, null, null, options, userId);
   2714         return ret;
   2715     }
   2716 
   2717     public final int startActivities(IApplicationThread caller, String callingPackage,
   2718             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
   2719             int userId) {
   2720         enforceNotIsolatedCaller("startActivities");
   2721         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   2722                 false, true, "startActivity", null);
   2723         int ret = mMainStack.startActivities(caller, -1, callingPackage, intents,
   2724                 resolvedTypes, resultTo, options, userId);
   2725         return ret;
   2726     }
   2727 
   2728     final int startActivitiesInPackage(int uid, String callingPackage,
   2729             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
   2730             Bundle options, int userId) {
   2731 
   2732         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   2733                 false, true, "startActivityInPackage", null);
   2734         int ret = mMainStack.startActivities(null, uid, callingPackage, intents, resolvedTypes,
   2735                 resultTo, options, userId);
   2736         return ret;
   2737     }
   2738 
   2739     final void addRecentTaskLocked(TaskRecord task) {
   2740         int N = mRecentTasks.size();
   2741         // Quick case: check if the top-most recent task is the same.
   2742         if (N > 0 && mRecentTasks.get(0) == task) {
   2743             return;
   2744         }
   2745         // Remove any existing entries that are the same kind of task.
   2746         for (int i=0; i<N; i++) {
   2747             TaskRecord tr = mRecentTasks.get(i);
   2748             if (task.userId == tr.userId
   2749                     && ((task.affinity != null && task.affinity.equals(tr.affinity))
   2750                     || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
   2751                 mRecentTasks.remove(i);
   2752                 i--;
   2753                 N--;
   2754                 if (task.intent == null) {
   2755                     // If the new recent task we are adding is not fully
   2756                     // specified, then replace it with the existing recent task.
   2757                     task = tr;
   2758                 }
   2759             }
   2760         }
   2761         if (N >= MAX_RECENT_TASKS) {
   2762             mRecentTasks.remove(N-1);
   2763         }
   2764         mRecentTasks.add(0, task);
   2765     }
   2766 
   2767     public void setRequestedOrientation(IBinder token,
   2768             int requestedOrientation) {
   2769         synchronized (this) {
   2770             ActivityRecord r = mMainStack.isInStackLocked(token);
   2771             if (r == null) {
   2772                 return;
   2773             }
   2774             final long origId = Binder.clearCallingIdentity();
   2775             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
   2776             Configuration config = mWindowManager.updateOrientationFromAppTokens(
   2777                     mConfiguration,
   2778                     r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
   2779             if (config != null) {
   2780                 r.frozenBeforeDestroy = true;
   2781                 if (!updateConfigurationLocked(config, r, false, false)) {
   2782                     mMainStack.resumeTopActivityLocked(null);
   2783                 }
   2784             }
   2785             Binder.restoreCallingIdentity(origId);
   2786         }
   2787     }
   2788 
   2789     public int getRequestedOrientation(IBinder token) {
   2790         synchronized (this) {
   2791             ActivityRecord r = mMainStack.isInStackLocked(token);
   2792             if (r == null) {
   2793                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
   2794             }
   2795             return mWindowManager.getAppOrientation(r.appToken);
   2796         }
   2797     }
   2798 
   2799     /**
   2800      * This is the internal entry point for handling Activity.finish().
   2801      *
   2802      * @param token The Binder token referencing the Activity we want to finish.
   2803      * @param resultCode Result code, if any, from this Activity.
   2804      * @param resultData Result data (Intent), if any, from this Activity.
   2805      *
   2806      * @return Returns true if the activity successfully finished, or false if it is still running.
   2807      */
   2808     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
   2809         // Refuse possible leaked file descriptors
   2810         if (resultData != null && resultData.hasFileDescriptors() == true) {
   2811             throw new IllegalArgumentException("File descriptors passed in Intent");
   2812         }
   2813 
   2814         synchronized(this) {
   2815             if (mController != null) {
   2816                 // Find the first activity that is not finishing.
   2817                 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
   2818                 if (next != null) {
   2819                     // ask watcher if this is allowed
   2820                     boolean resumeOK = true;
   2821                     try {
   2822                         resumeOK = mController.activityResuming(next.packageName);
   2823                     } catch (RemoteException e) {
   2824                         mController = null;
   2825                         Watchdog.getInstance().setActivityController(null);
   2826                     }
   2827 
   2828                     if (!resumeOK) {
   2829                         return false;
   2830                     }
   2831                 }
   2832             }
   2833             final long origId = Binder.clearCallingIdentity();
   2834             boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
   2835                     resultData, "app-request", true);
   2836             Binder.restoreCallingIdentity(origId);
   2837             return res;
   2838         }
   2839     }
   2840 
   2841     public final void finishHeavyWeightApp() {
   2842         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   2843                 != PackageManager.PERMISSION_GRANTED) {
   2844             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
   2845                     + Binder.getCallingPid()
   2846                     + ", uid=" + Binder.getCallingUid()
   2847                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   2848             Slog.w(TAG, msg);
   2849             throw new SecurityException(msg);
   2850         }
   2851 
   2852         synchronized(this) {
   2853             if (mHeavyWeightProcess == null) {
   2854                 return;
   2855             }
   2856 
   2857             ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
   2858                     mHeavyWeightProcess.activities);
   2859             for (int i=0; i<activities.size(); i++) {
   2860                 ActivityRecord r = activities.get(i);
   2861                 if (!r.finishing) {
   2862                     int index = mMainStack.indexOfTokenLocked(r.appToken);
   2863                     if (index >= 0) {
   2864                         mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
   2865                                 null, "finish-heavy", true);
   2866                     }
   2867                 }
   2868             }
   2869 
   2870             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   2871                     mHeavyWeightProcess.userId, 0));
   2872             mHeavyWeightProcess = null;
   2873         }
   2874     }
   2875 
   2876     public void crashApplication(int uid, int initialPid, String packageName,
   2877             String message) {
   2878         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   2879                 != PackageManager.PERMISSION_GRANTED) {
   2880             String msg = "Permission Denial: crashApplication() from pid="
   2881                     + Binder.getCallingPid()
   2882                     + ", uid=" + Binder.getCallingUid()
   2883                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   2884             Slog.w(TAG, msg);
   2885             throw new SecurityException(msg);
   2886         }
   2887 
   2888         synchronized(this) {
   2889             ProcessRecord proc = null;
   2890 
   2891             // Figure out which process to kill.  We don't trust that initialPid
   2892             // still has any relation to current pids, so must scan through the
   2893             // list.
   2894             synchronized (mPidsSelfLocked) {
   2895                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   2896                     ProcessRecord p = mPidsSelfLocked.valueAt(i);
   2897                     if (p.uid != uid) {
   2898                         continue;
   2899                     }
   2900                     if (p.pid == initialPid) {
   2901                         proc = p;
   2902                         break;
   2903                     }
   2904                     for (String str : p.pkgList) {
   2905                         if (str.equals(packageName)) {
   2906                             proc = p;
   2907                         }
   2908                     }
   2909                 }
   2910             }
   2911 
   2912             if (proc == null) {
   2913                 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
   2914                         + " initialPid=" + initialPid
   2915                         + " packageName=" + packageName);
   2916                 return;
   2917             }
   2918 
   2919             if (proc.thread != null) {
   2920                 if (proc.pid == Process.myPid()) {
   2921                     Log.w(TAG, "crashApplication: trying to crash self!");
   2922                     return;
   2923                 }
   2924                 long ident = Binder.clearCallingIdentity();
   2925                 try {
   2926                     proc.thread.scheduleCrash(message);
   2927                 } catch (RemoteException e) {
   2928                 }
   2929                 Binder.restoreCallingIdentity(ident);
   2930             }
   2931         }
   2932     }
   2933 
   2934     public final void finishSubActivity(IBinder token, String resultWho,
   2935             int requestCode) {
   2936         synchronized(this) {
   2937             final long origId = Binder.clearCallingIdentity();
   2938             mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
   2939             Binder.restoreCallingIdentity(origId);
   2940         }
   2941     }
   2942 
   2943     public boolean finishActivityAffinity(IBinder token) {
   2944         synchronized(this) {
   2945             final long origId = Binder.clearCallingIdentity();
   2946             boolean res = mMainStack.finishActivityAffinityLocked(token);
   2947             Binder.restoreCallingIdentity(origId);
   2948             return res;
   2949         }
   2950     }
   2951 
   2952     public boolean willActivityBeVisible(IBinder token) {
   2953         synchronized(this) {
   2954             int i;
   2955             for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
   2956                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   2957                 if (r.appToken == token) {
   2958                     return true;
   2959                 }
   2960                 if (r.fullscreen && !r.finishing) {
   2961                     return false;
   2962                 }
   2963             }
   2964             return true;
   2965         }
   2966     }
   2967 
   2968     public void overridePendingTransition(IBinder token, String packageName,
   2969             int enterAnim, int exitAnim) {
   2970         synchronized(this) {
   2971             ActivityRecord self = mMainStack.isInStackLocked(token);
   2972             if (self == null) {
   2973                 return;
   2974             }
   2975 
   2976             final long origId = Binder.clearCallingIdentity();
   2977 
   2978             if (self.state == ActivityState.RESUMED
   2979                     || self.state == ActivityState.PAUSING) {
   2980                 mWindowManager.overridePendingAppTransition(packageName,
   2981                         enterAnim, exitAnim, null);
   2982             }
   2983 
   2984             Binder.restoreCallingIdentity(origId);
   2985         }
   2986     }
   2987 
   2988     /**
   2989      * Main function for removing an existing process from the activity manager
   2990      * as a result of that process going away.  Clears out all connections
   2991      * to the process.
   2992      */
   2993     private final void handleAppDiedLocked(ProcessRecord app,
   2994             boolean restarting, boolean allowRestart) {
   2995         cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
   2996         if (!restarting) {
   2997             mLruProcesses.remove(app);
   2998         }
   2999 
   3000         if (mProfileProc == app) {
   3001             clearProfilerLocked();
   3002         }
   3003 
   3004         // Just in case...
   3005         if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
   3006             if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG,
   3007                     "App died while pausing: " + mMainStack.mPausingActivity);
   3008             mMainStack.mPausingActivity = null;
   3009         }
   3010         if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
   3011             mMainStack.mLastPausedActivity = null;
   3012         }
   3013 
   3014         // Remove this application's activities from active lists.
   3015         boolean hasVisibleActivities = mMainStack.removeHistoryRecordsForAppLocked(app);
   3016 
   3017         app.activities.clear();
   3018 
   3019         if (app.instrumentationClass != null) {
   3020             Slog.w(TAG, "Crash of app " + app.processName
   3021                   + " running instrumentation " + app.instrumentationClass);
   3022             Bundle info = new Bundle();
   3023             info.putString("shortMsg", "Process crashed.");
   3024             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
   3025         }
   3026 
   3027         if (!restarting) {
   3028             if (!mMainStack.resumeTopActivityLocked(null)) {
   3029                 // If there was nothing to resume, and we are not already
   3030                 // restarting this process, but there is a visible activity that
   3031                 // is hosted by the process...  then make sure all visible
   3032                 // activities are running, taking care of restarting this
   3033                 // process.
   3034                 if (hasVisibleActivities) {
   3035                     mMainStack.ensureActivitiesVisibleLocked(null, 0);
   3036                 }
   3037             }
   3038         }
   3039     }
   3040 
   3041     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
   3042         IBinder threadBinder = thread.asBinder();
   3043         // Find the application record.
   3044         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   3045             ProcessRecord rec = mLruProcesses.get(i);
   3046             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
   3047                 return i;
   3048             }
   3049         }
   3050         return -1;
   3051     }
   3052 
   3053     final ProcessRecord getRecordForAppLocked(
   3054             IApplicationThread thread) {
   3055         if (thread == null) {
   3056             return null;
   3057         }
   3058 
   3059         int appIndex = getLRURecordIndexForAppLocked(thread);
   3060         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
   3061     }
   3062 
   3063     final void appDiedLocked(ProcessRecord app, int pid,
   3064             IApplicationThread thread) {
   3065 
   3066         mProcDeaths[0]++;
   3067 
   3068         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   3069         synchronized (stats) {
   3070             stats.noteProcessDiedLocked(app.info.uid, pid);
   3071         }
   3072 
   3073         // Clean up already done if the process has been re-started.
   3074         if (app.pid == pid && app.thread != null &&
   3075                 app.thread.asBinder() == thread.asBinder()) {
   3076             if (!app.killedBackground) {
   3077                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   3078                         + ") has died.");
   3079             }
   3080             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
   3081             if (DEBUG_CLEANUP) Slog.v(
   3082                 TAG, "Dying app: " + app + ", pid: " + pid
   3083                 + ", thread: " + thread.asBinder());
   3084             boolean doLowMem = app.instrumentationClass == null;
   3085             handleAppDiedLocked(app, false, true);
   3086 
   3087             if (doLowMem) {
   3088                 // If there are no longer any background processes running,
   3089                 // and the app that died was not running instrumentation,
   3090                 // then tell everyone we are now low on memory.
   3091                 boolean haveBg = false;
   3092                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   3093                     ProcessRecord rec = mLruProcesses.get(i);
   3094                     if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   3095                         haveBg = true;
   3096                         break;
   3097                     }
   3098                 }
   3099 
   3100                 if (!haveBg) {
   3101                     EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
   3102                     long now = SystemClock.uptimeMillis();
   3103                     for (int i=mLruProcesses.size()-1; i>=0; i--) {
   3104                         ProcessRecord rec = mLruProcesses.get(i);
   3105                         if (rec != app && rec.thread != null &&
   3106                                 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
   3107                             // The low memory report is overriding any current
   3108                             // state for a GC request.  Make sure to do
   3109                             // heavy/important/visible/foreground processes first.
   3110                             if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   3111                                 rec.lastRequestedGc = 0;
   3112                             } else {
   3113                                 rec.lastRequestedGc = rec.lastLowMemory;
   3114                             }
   3115                             rec.reportLowMemory = true;
   3116                             rec.lastLowMemory = now;
   3117                             mProcessesToGc.remove(rec);
   3118                             addProcessToGcListLocked(rec);
   3119                         }
   3120                     }
   3121                     mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
   3122                     scheduleAppGcsLocked();
   3123                 }
   3124             }
   3125         } else if (app.pid != pid) {
   3126             // A new process has already been started.
   3127             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   3128                     + ") has died and restarted (pid " + app.pid + ").");
   3129             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
   3130         } else if (DEBUG_PROCESSES) {
   3131             Slog.d(TAG, "Received spurious death notification for thread "
   3132                     + thread.asBinder());
   3133         }
   3134     }
   3135 
   3136     /**
   3137      * If a stack trace dump file is configured, dump process stack traces.
   3138      * @param clearTraces causes the dump file to be erased prior to the new
   3139      *    traces being written, if true; when false, the new traces will be
   3140      *    appended to any existing file content.
   3141      * @param firstPids of dalvik VM processes to dump stack traces for first
   3142      * @param lastPids of dalvik VM processes to dump stack traces for last
   3143      * @param nativeProcs optional list of native process names to dump stack crawls
   3144      * @return file containing stack traces, or null if no dump file is configured
   3145      */
   3146     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
   3147             ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
   3148         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   3149         if (tracesPath == null || tracesPath.length() == 0) {
   3150             return null;
   3151         }
   3152 
   3153         File tracesFile = new File(tracesPath);
   3154         try {
   3155             File tracesDir = tracesFile.getParentFile();
   3156             if (!tracesDir.exists()) {
   3157                 tracesFile.mkdirs();
   3158                 if (!SELinux.restorecon(tracesDir)) {
   3159                     return null;
   3160                 }
   3161             }
   3162             FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
   3163 
   3164             if (clearTraces && tracesFile.exists()) tracesFile.delete();
   3165             tracesFile.createNewFile();
   3166             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   3167         } catch (IOException e) {
   3168             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
   3169             return null;
   3170         }
   3171 
   3172         dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
   3173         return tracesFile;
   3174     }
   3175 
   3176     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
   3177             ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
   3178         // Use a FileObserver to detect when traces finish writing.
   3179         // The order of traces is considered important to maintain for legibility.
   3180         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
   3181             public synchronized void onEvent(int event, String path) { notify(); }
   3182         };
   3183 
   3184         try {
   3185             observer.startWatching();
   3186 
   3187             // First collect all of the stacks of the most important pids.
   3188             if (firstPids != null) {
   3189                 try {
   3190                     int num = firstPids.size();
   3191                     for (int i = 0; i < num; i++) {
   3192                         synchronized (observer) {
   3193                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
   3194                             observer.wait(200);  // Wait for write-close, give up after 200msec
   3195                         }
   3196                     }
   3197                 } catch (InterruptedException e) {
   3198                     Log.wtf(TAG, e);
   3199                 }
   3200             }
   3201 
   3202             // Next measure CPU usage.
   3203             if (processStats != null) {
   3204                 processStats.init();
   3205                 System.gc();
   3206                 processStats.update();
   3207                 try {
   3208                     synchronized (processStats) {
   3209                         processStats.wait(500); // measure over 1/2 second.
   3210                     }
   3211                 } catch (InterruptedException e) {
   3212                 }
   3213                 processStats.update();
   3214 
   3215                 // We'll take the stack crawls of just the top apps using CPU.
   3216                 final int N = processStats.countWorkingStats();
   3217                 int numProcs = 0;
   3218                 for (int i=0; i<N && numProcs<5; i++) {
   3219                     ProcessStats.Stats stats = processStats.getWorkingStats(i);
   3220                     if (lastPids.indexOfKey(stats.pid) >= 0) {
   3221                         numProcs++;
   3222                         try {
   3223                             synchronized (observer) {
   3224                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
   3225                                 observer.wait(200);  // Wait for write-close, give up after 200msec
   3226                             }
   3227                         } catch (InterruptedException e) {
   3228                             Log.wtf(TAG, e);
   3229                         }
   3230 
   3231                     }
   3232                 }
   3233             }
   3234 
   3235         } finally {
   3236             observer.stopWatching();
   3237         }
   3238 
   3239         if (nativeProcs != null) {
   3240             int[] pids = Process.getPidsForCommands(nativeProcs);
   3241             if (pids != null) {
   3242                 for (int pid : pids) {
   3243                     Debug.dumpNativeBacktraceToFile(pid, tracesPath);
   3244                 }
   3245             }
   3246         }
   3247     }
   3248 
   3249     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
   3250         if (true || IS_USER_BUILD) {
   3251             return;
   3252         }
   3253         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   3254         if (tracesPath == null || tracesPath.length() == 0) {
   3255             return;
   3256         }
   3257 
   3258         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
   3259         StrictMode.allowThreadDiskWrites();
   3260         try {
   3261             final File tracesFile = new File(tracesPath);
   3262             final File tracesDir = tracesFile.getParentFile();
   3263             final File tracesTmp = new File(tracesDir, "__tmp__");
   3264             try {
   3265                 if (!tracesDir.exists()) {
   3266                     tracesFile.mkdirs();
   3267                     if (!SELinux.restorecon(tracesDir.getPath())) {
   3268                         return;
   3269                     }
   3270                 }
   3271                 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
   3272 
   3273                 if (tracesFile.exists()) {
   3274                     tracesTmp.delete();
   3275                     tracesFile.renameTo(tracesTmp);
   3276                 }
   3277                 StringBuilder sb = new StringBuilder();
   3278                 Time tobj = new Time();
   3279                 tobj.set(System.currentTimeMillis());
   3280                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
   3281                 sb.append(": ");
   3282                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
   3283                 sb.append(" since ");
   3284                 sb.append(msg);
   3285                 FileOutputStream fos = new FileOutputStream(tracesFile);
   3286                 fos.write(sb.toString().getBytes());
   3287                 if (app == null) {
   3288                     fos.write("\n*** No application process!".getBytes());
   3289                 }
   3290                 fos.close();
   3291                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   3292             } catch (IOException e) {
   3293                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
   3294                 return;
   3295             }
   3296 
   3297             if (app != null) {
   3298                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
   3299                 firstPids.add(app.pid);
   3300                 dumpStackTraces(tracesPath, firstPids, null, null, null);
   3301             }
   3302 
   3303             File lastTracesFile = null;
   3304             File curTracesFile = null;
   3305             for (int i=9; i>=0; i--) {
   3306                 String name = String.format("slow%02d.txt", i);
   3307                 curTracesFile = new File(tracesDir, name);
   3308                 if (curTracesFile.exists()) {
   3309                     if (lastTracesFile != null) {
   3310                         curTracesFile.renameTo(lastTracesFile);
   3311                     } else {
   3312                         curTracesFile.delete();
   3313                     }
   3314                 }
   3315                 lastTracesFile = curTracesFile;
   3316             }
   3317             tracesFile.renameTo(curTracesFile);
   3318             if (tracesTmp.exists()) {
   3319                 tracesTmp.renameTo(tracesFile);
   3320             }
   3321         } finally {
   3322             StrictMode.setThreadPolicy(oldPolicy);
   3323         }
   3324     }
   3325 
   3326     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
   3327             ActivityRecord parent, boolean aboveSystem, final String annotation) {
   3328         ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
   3329         SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
   3330 
   3331         if (mController != null) {
   3332             try {
   3333                 // 0 == continue, -1 = kill process immediately
   3334                 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
   3335                 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
   3336             } catch (RemoteException e) {
   3337                 mController = null;
   3338                 Watchdog.getInstance().setActivityController(null);
   3339             }
   3340         }
   3341 
   3342         long anrTime = SystemClock.uptimeMillis();
   3343         if (MONITOR_CPU_USAGE) {
   3344             updateCpuStatsNow();
   3345         }
   3346 
   3347         synchronized (this) {
   3348             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
   3349             if (mShuttingDown) {
   3350                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
   3351                 return;
   3352             } else if (app.notResponding) {
   3353                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
   3354                 return;
   3355             } else if (app.crashing) {
   3356                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
   3357                 return;
   3358             }
   3359 
   3360             // In case we come through here for the same app before completing
   3361             // this one, mark as anring now so we will bail out.
   3362             app.notResponding = true;
   3363 
   3364             // Log the ANR to the event log.
   3365             EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
   3366                     app.processName, app.info.flags, annotation);
   3367 
   3368             // Dump thread traces as quickly as we can, starting with "interesting" processes.
   3369             firstPids.add(app.pid);
   3370 
   3371             int parentPid = app.pid;
   3372             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
   3373             if (parentPid != app.pid) firstPids.add(parentPid);
   3374 
   3375             if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
   3376 
   3377             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   3378                 ProcessRecord r = mLruProcesses.get(i);
   3379                 if (r != null && r.thread != null) {
   3380                     int pid = r.pid;
   3381                     if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
   3382                         if (r.persistent) {
   3383                             firstPids.add(pid);
   3384                         } else {
   3385                             lastPids.put(pid, Boolean.TRUE);
   3386                         }
   3387                     }
   3388                 }
   3389             }
   3390         }
   3391 
   3392         // Log the ANR to the main log.
   3393         StringBuilder info = new StringBuilder();
   3394         info.setLength(0);
   3395         info.append("ANR in ").append(app.processName);
   3396         if (activity != null && activity.shortComponentName != null) {
   3397             info.append(" (").append(activity.shortComponentName).append(")");
   3398         }
   3399         info.append("\n");
   3400         if (annotation != null) {
   3401             info.append("Reason: ").append(annotation).append("\n");
   3402         }
   3403         if (parent != null && parent != activity) {
   3404             info.append("Parent: ").append(parent.shortComponentName).append("\n");
   3405         }
   3406 
   3407         final ProcessStats processStats = new ProcessStats(true);
   3408 
   3409         File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
   3410 
   3411         String cpuInfo = null;
   3412         if (MONITOR_CPU_USAGE) {
   3413             updateCpuStatsNow();
   3414             synchronized (mProcessStatsThread) {
   3415                 cpuInfo = mProcessStats.printCurrentState(anrTime);
   3416             }
   3417             info.append(processStats.printCurrentLoad());
   3418             info.append(cpuInfo);
   3419         }
   3420 
   3421         info.append(processStats.printCurrentState(anrTime));
   3422 
   3423         Slog.e(TAG, info.toString());
   3424         if (tracesFile == null) {
   3425             // There is no trace file, so dump (only) the alleged culprit's threads to the log
   3426             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
   3427         }
   3428 
   3429         addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
   3430                 cpuInfo, tracesFile, null);
   3431 
   3432         if (mController != null) {
   3433             try {
   3434                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
   3435                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
   3436                 if (res != 0) {
   3437                     if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
   3438                     return;
   3439                 }
   3440             } catch (RemoteException e) {
   3441                 mController = null;
   3442                 Watchdog.getInstance().setActivityController(null);
   3443             }
   3444         }
   3445 
   3446         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
   3447         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
   3448                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
   3449 
   3450         synchronized (this) {
   3451             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
   3452                 Slog.w(TAG, "Killing " + app + ": background ANR");
   3453                 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
   3454                         app.processName, app.setAdj, "background ANR");
   3455                 Process.killProcessQuiet(app.pid);
   3456                 return;
   3457             }
   3458 
   3459             // Set the app's notResponding state, and look up the errorReportReceiver
   3460             makeAppNotRespondingLocked(app,
   3461                     activity != null ? activity.shortComponentName : null,
   3462                     annotation != null ? "ANR " + annotation : "ANR",
   3463                     info.toString());
   3464 
   3465             // Bring up the infamous App Not Responding dialog
   3466             Message msg = Message.obtain();
   3467             HashMap map = new HashMap();
   3468             msg.what = SHOW_NOT_RESPONDING_MSG;
   3469             msg.obj = map;
   3470             msg.arg1 = aboveSystem ? 1 : 0;
   3471             map.put("app", app);
   3472             if (activity != null) {
   3473                 map.put("activity", activity);
   3474             }
   3475 
   3476             mHandler.sendMessage(msg);
   3477         }
   3478     }
   3479 
   3480     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
   3481         if (!mLaunchWarningShown) {
   3482             mLaunchWarningShown = true;
   3483             mHandler.post(new Runnable() {
   3484                 @Override
   3485                 public void run() {
   3486                     synchronized (ActivityManagerService.this) {
   3487                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
   3488                         d.show();
   3489                         mHandler.postDelayed(new Runnable() {
   3490                             @Override
   3491                             public void run() {
   3492                                 synchronized (ActivityManagerService.this) {
   3493                                     d.dismiss();
   3494                                     mLaunchWarningShown = false;
   3495                                 }
   3496                             }
   3497                         }, 4000);
   3498                     }
   3499                 }
   3500             });
   3501         }
   3502     }
   3503 
   3504     public boolean clearApplicationUserData(final String packageName,
   3505             final IPackageDataObserver observer, int userId) {
   3506         enforceNotIsolatedCaller("clearApplicationUserData");
   3507         int uid = Binder.getCallingUid();
   3508         int pid = Binder.getCallingPid();
   3509         userId = handleIncomingUser(pid, uid,
   3510                 userId, false, true, "clearApplicationUserData", null);
   3511         long callingId = Binder.clearCallingIdentity();
   3512         try {
   3513             IPackageManager pm = AppGlobals.getPackageManager();
   3514             int pkgUid = -1;
   3515             synchronized(this) {
   3516                 try {
   3517                     pkgUid = pm.getPackageUid(packageName, userId);
   3518                 } catch (RemoteException e) {
   3519                 }
   3520                 if (pkgUid == -1) {
   3521                     Slog.w(TAG, "Invalid packageName: " + packageName);
   3522                     if (observer != null) {
   3523                         try {
   3524                             observer.onRemoveCompleted(packageName, false);
   3525                         } catch (RemoteException e) {
   3526                             Slog.i(TAG, "Observer no longer exists.");
   3527                         }
   3528                     }
   3529                     return false;
   3530                 }
   3531                 if (uid == pkgUid || checkComponentPermission(
   3532                         android.Manifest.permission.CLEAR_APP_USER_DATA,
   3533                         pid, uid, -1, true)
   3534                         == PackageManager.PERMISSION_GRANTED) {
   3535                     forceStopPackageLocked(packageName, pkgUid);
   3536                 } else {
   3537                     throw new SecurityException(pid+" does not have permission:"+
   3538                             android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
   3539                                     "for process:"+packageName);
   3540                 }
   3541             }
   3542 
   3543             try {
   3544                 //clear application user data
   3545                 pm.clearApplicationUserData(packageName, observer, userId);
   3546                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
   3547                         Uri.fromParts("package", packageName, null));
   3548                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
   3549                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
   3550                         null, null, 0, null, null, null, false, false, userId);
   3551             } catch (RemoteException e) {
   3552             }
   3553         } finally {
   3554             Binder.restoreCallingIdentity(callingId);
   3555         }
   3556         return true;
   3557     }
   3558 
   3559     public void killBackgroundProcesses(final String packageName, int userId) {
   3560         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   3561                 != PackageManager.PERMISSION_GRANTED &&
   3562                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
   3563                         != PackageManager.PERMISSION_GRANTED) {
   3564             String msg = "Permission Denial: killBackgroundProcesses() from pid="
   3565                     + Binder.getCallingPid()
   3566                     + ", uid=" + Binder.getCallingUid()
   3567                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   3568             Slog.w(TAG, msg);
   3569             throw new SecurityException(msg);
   3570         }
   3571 
   3572         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   3573                 userId, true, true, "killBackgroundProcesses", null);
   3574         long callingId = Binder.clearCallingIdentity();
   3575         try {
   3576             IPackageManager pm = AppGlobals.getPackageManager();
   3577             synchronized(this) {
   3578                 int appId = -1;
   3579                 try {
   3580                     appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
   3581                 } catch (RemoteException e) {
   3582                 }
   3583                 if (appId == -1) {
   3584                     Slog.w(TAG, "Invalid packageName: " + packageName);
   3585                     return;
   3586                 }
   3587                 killPackageProcessesLocked(packageName, appId, userId,
   3588                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
   3589             }
   3590         } finally {
   3591             Binder.restoreCallingIdentity(callingId);
   3592         }
   3593     }
   3594 
   3595     public void killAllBackgroundProcesses() {
   3596         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   3597                 != PackageManager.PERMISSION_GRANTED) {
   3598             String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
   3599                     + Binder.getCallingPid()
   3600                     + ", uid=" + Binder.getCallingUid()
   3601                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   3602             Slog.w(TAG, msg);
   3603             throw new SecurityException(msg);
   3604         }
   3605 
   3606         long callingId = Binder.clearCallingIdentity();
   3607         try {
   3608             synchronized(this) {
   3609                 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   3610                 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   3611                     final int NA = apps.size();
   3612                     for (int ia=0; ia<NA; ia++) {
   3613                         ProcessRecord app = apps.valueAt(ia);
   3614                         if (app.persistent) {
   3615                             // we don't kill persistent processes
   3616                             continue;
   3617                         }
   3618                         if (app.removed) {
   3619                             procs.add(app);
   3620                         } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   3621                             app.removed = true;
   3622                             procs.add(app);
   3623                         }
   3624                     }
   3625                 }
   3626 
   3627                 int N = procs.size();
   3628                 for (int i=0; i<N; i++) {
   3629                     removeProcessLocked(procs.get(i), false, true, "kill all background");
   3630                 }
   3631             }
   3632         } finally {
   3633             Binder.restoreCallingIdentity(callingId);
   3634         }
   3635     }
   3636 
   3637     public void forceStopPackage(final String packageName, int userId) {
   3638         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   3639                 != PackageManager.PERMISSION_GRANTED) {
   3640             String msg = "Permission Denial: forceStopPackage() from pid="
   3641                     + Binder.getCallingPid()
   3642                     + ", uid=" + Binder.getCallingUid()
   3643                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   3644             Slog.w(TAG, msg);
   3645             throw new SecurityException(msg);
   3646         }
   3647         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   3648                 userId, true, true, "forceStopPackage", null);
   3649         long callingId = Binder.clearCallingIdentity();
   3650         try {
   3651             IPackageManager pm = AppGlobals.getPackageManager();
   3652             synchronized(this) {
   3653                 int[] users = userId == UserHandle.USER_ALL
   3654                         ? getUsersLocked() : new int[] { userId };
   3655                 for (int user : users) {
   3656                     int pkgUid = -1;
   3657                     try {
   3658                         pkgUid = pm.getPackageUid(packageName, user);
   3659                     } catch (RemoteException e) {
   3660                     }
   3661                     if (pkgUid == -1) {
   3662                         Slog.w(TAG, "Invalid packageName: " + packageName);
   3663                         continue;
   3664                     }
   3665                     try {
   3666                         pm.setPackageStoppedState(packageName, true, user);
   3667                     } catch (RemoteException e) {
   3668                     } catch (IllegalArgumentException e) {
   3669                         Slog.w(TAG, "Failed trying to unstop package "
   3670                                 + packageName + ": " + e);
   3671                     }
   3672                     if (isUserRunningLocked(user, false)) {
   3673                         forceStopPackageLocked(packageName, pkgUid);
   3674                     }
   3675                 }
   3676             }
   3677         } finally {
   3678             Binder.restoreCallingIdentity(callingId);
   3679         }
   3680     }
   3681 
   3682     /*
   3683      * The pkg name and app id have to be specified.
   3684      */
   3685     public void killApplicationWithAppId(String pkg, int appid) {
   3686         if (pkg == null) {
   3687             return;
   3688         }
   3689         // Make sure the uid is valid.
   3690         if (appid < 0) {
   3691             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
   3692             return;
   3693         }
   3694         int callerUid = Binder.getCallingUid();
   3695         // Only the system server can kill an application
   3696         if (callerUid == Process.SYSTEM_UID) {
   3697             // Post an aysnc message to kill the application
   3698             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
   3699             msg.arg1 = appid;
   3700             msg.arg2 = 0;
   3701             msg.obj = pkg;
   3702             mHandler.sendMessage(msg);
   3703         } else {
   3704             throw new SecurityException(callerUid + " cannot kill pkg: " +
   3705                     pkg);
   3706         }
   3707     }
   3708 
   3709     public void closeSystemDialogs(String reason) {
   3710         enforceNotIsolatedCaller("closeSystemDialogs");
   3711 
   3712         final int pid = Binder.getCallingPid();
   3713         final int uid = Binder.getCallingUid();
   3714         final long origId = Binder.clearCallingIdentity();
   3715         try {
   3716             synchronized (this) {
   3717                 // Only allow this from foreground processes, so that background
   3718                 // applications can't abuse it to prevent system UI from being shown.
   3719                 if (uid >= Process.FIRST_APPLICATION_UID) {
   3720                     ProcessRecord proc;
   3721                     synchronized (mPidsSelfLocked) {
   3722                         proc = mPidsSelfLocked.get(pid);
   3723                     }
   3724                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   3725                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
   3726                                 + " from background process " + proc);
   3727                         return;
   3728                     }
   3729                 }
   3730                 closeSystemDialogsLocked(reason);
   3731             }
   3732         } finally {
   3733             Binder.restoreCallingIdentity(origId);
   3734         }
   3735     }
   3736 
   3737     void closeSystemDialogsLocked(String reason) {
   3738         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
   3739         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   3740                 | Intent.FLAG_RECEIVER_FOREGROUND);
   3741         if (reason != null) {
   3742             intent.putExtra("reason", reason);
   3743         }
   3744         mWindowManager.closeSystemDialogs(reason);
   3745 
   3746         for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
   3747             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   3748             if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
   3749                 r.stack.finishActivityLocked(r, i,
   3750                         Activity.RESULT_CANCELED, null, "close-sys", true);
   3751             }
   3752         }
   3753 
   3754         broadcastIntentLocked(null, null, intent, null,
   3755                 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
   3756                 Process.SYSTEM_UID, UserHandle.USER_ALL);
   3757     }
   3758 
   3759     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
   3760             throws RemoteException {
   3761         enforceNotIsolatedCaller("getProcessMemoryInfo");
   3762         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
   3763         for (int i=pids.length-1; i>=0; i--) {
   3764             infos[i] = new Debug.MemoryInfo();
   3765             Debug.getMemoryInfo(pids[i], infos[i]);
   3766         }
   3767         return infos;
   3768     }
   3769 
   3770     public long[] getProcessPss(int[] pids) throws RemoteException {
   3771         enforceNotIsolatedCaller("getProcessPss");
   3772         long[] pss = new long[pids.length];
   3773         for (int i=pids.length-1; i>=0; i--) {
   3774             pss[i] = Debug.getPss(pids[i]);
   3775         }
   3776         return pss;
   3777     }
   3778 
   3779     public void killApplicationProcess(String processName, int uid) {
   3780         if (processName == null) {
   3781             return;
   3782         }
   3783 
   3784         int callerUid = Binder.getCallingUid();
   3785         // Only the system server can kill an application
   3786         if (callerUid == Process.SYSTEM_UID) {
   3787             synchronized (this) {
   3788                 ProcessRecord app = getProcessRecordLocked(processName, uid);
   3789                 if (app != null && app.thread != null) {
   3790                     try {
   3791                         app.thread.scheduleSuicide();
   3792                     } catch (RemoteException e) {
   3793                         // If the other end already died, then our work here is done.
   3794                     }
   3795                 } else {
   3796                     Slog.w(TAG, "Process/uid not found attempting kill of "
   3797                             + processName + " / " + uid);
   3798                 }
   3799             }
   3800         } else {
   3801             throw new SecurityException(callerUid + " cannot kill app process: " +
   3802                     processName);
   3803         }
   3804     }
   3805 
   3806     private void forceStopPackageLocked(final String packageName, int uid) {
   3807         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
   3808                 false, true, false, UserHandle.getUserId(uid));
   3809         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
   3810                 Uri.fromParts("package", packageName, null));
   3811         if (!mProcessesReady) {
   3812             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   3813                     | Intent.FLAG_RECEIVER_FOREGROUND);
   3814         }
   3815         intent.putExtra(Intent.EXTRA_UID, uid);
   3816         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
   3817         broadcastIntentLocked(null, null, intent,
   3818                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   3819                 false, false,
   3820                 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
   3821     }
   3822 
   3823     private void forceStopUserLocked(int userId) {
   3824         forceStopPackageLocked(null, -1, false, false, true, false, userId);
   3825         Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
   3826         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   3827                 | Intent.FLAG_RECEIVER_FOREGROUND);
   3828         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   3829         broadcastIntentLocked(null, null, intent,
   3830                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   3831                 false, false,
   3832                 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   3833     }
   3834 
   3835     private final boolean killPackageProcessesLocked(String packageName, int appId,
   3836             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
   3837             boolean doit, boolean evenPersistent, String reason) {
   3838         ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   3839 
   3840         // Remove all processes this package may have touched: all with the
   3841         // same UID (except for the system or root user), and all whose name
   3842         // matches the package name.
   3843         final String procNamePrefix = packageName != null ? (packageName + ":") : null;
   3844         for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   3845             final int NA = apps.size();
   3846             for (int ia=0; ia<NA; ia++) {
   3847                 ProcessRecord app = apps.valueAt(ia);
   3848                 if (app.persistent && !evenPersistent) {
   3849                     // we don't kill persistent processes
   3850                     continue;
   3851                 }
   3852                 if (app.removed) {
   3853                     if (doit) {
   3854                         procs.add(app);
   3855                     }
   3856                     continue;
   3857                 }
   3858 
   3859                 // Skip process if it doesn't meet our oom adj requirement.
   3860                 if (app.setAdj < minOomAdj) {
   3861                     continue;
   3862                 }
   3863 
   3864                 // If no package is specified, we call all processes under the
   3865                 // give user id.
   3866                 if (packageName == null) {
   3867                     if (app.userId != userId) {
   3868                         continue;
   3869                     }
   3870                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
   3871                         continue;
   3872                     }
   3873                 // Package has been specified, we want to hit all processes
   3874                 // that match it.  We need to qualify this by the processes
   3875                 // that are running under the specified app and user ID.
   3876                 } else {
   3877                     if (UserHandle.getAppId(app.uid) != appId) {
   3878                         continue;
   3879                     }
   3880                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
   3881                         continue;
   3882                     }
   3883                     if (!app.pkgList.contains(packageName)) {
   3884                         continue;
   3885                     }
   3886                 }
   3887 
   3888                 // Process has passed all conditions, kill it!
   3889                 if (!doit) {
   3890                     return true;
   3891                 }
   3892                 app.removed = true;
   3893                 procs.add(app);
   3894             }
   3895         }
   3896 
   3897         int N = procs.size();
   3898         for (int i=0; i<N; i++) {
   3899             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
   3900         }
   3901         return N > 0;
   3902     }
   3903 
   3904     private final boolean forceStopPackageLocked(String name, int appId,
   3905             boolean callerWillRestart, boolean purgeCache, boolean doit,
   3906             boolean evenPersistent, int userId) {
   3907         int i;
   3908         int N;
   3909 
   3910         if (userId == UserHandle.USER_ALL && name == null) {
   3911             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
   3912         }
   3913 
   3914         if (appId < 0 && name != null) {
   3915             try {
   3916                 appId = UserHandle.getAppId(
   3917                         AppGlobals.getPackageManager().getPackageUid(name, 0));
   3918             } catch (RemoteException e) {
   3919             }
   3920         }
   3921 
   3922         if (doit) {
   3923             if (name != null) {
   3924                 Slog.i(TAG, "Force stopping package " + name + " appid=" + appId
   3925                         + " user=" + userId);
   3926             } else {
   3927                 Slog.i(TAG, "Force stopping user " + userId);
   3928             }
   3929 
   3930             Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
   3931             while (badApps.hasNext()) {
   3932                 SparseArray<Long> ba = badApps.next();
   3933                 for (i=ba.size()-1; i>=0; i--) {
   3934                     boolean remove = false;
   3935                     final int entUid = ba.keyAt(i);
   3936                     if (name != null) {
   3937                         if (userId == UserHandle.USER_ALL) {
   3938                             if (UserHandle.getAppId(entUid) == appId) {
   3939                                 remove = true;
   3940                             }
   3941                         } else {
   3942                             if (entUid == UserHandle.getUid(userId, appId)) {
   3943                                 remove = true;
   3944                             }
   3945                         }
   3946                     } else if (UserHandle.getUserId(entUid) == userId) {
   3947                         remove = true;
   3948                     }
   3949                     if (remove) {
   3950                         ba.removeAt(i);
   3951                     }
   3952                 }
   3953                 if (ba.size() == 0) {
   3954                     badApps.remove();
   3955                 }
   3956             }
   3957         }
   3958 
   3959         boolean didSomething = killPackageProcessesLocked(name, appId, userId,
   3960                 -100, callerWillRestart, true, doit, evenPersistent,
   3961                 name == null ? ("force stop user " + userId) : ("force stop " + name));
   3962 
   3963         TaskRecord lastTask = null;
   3964         for (i=0; i<mMainStack.mHistory.size(); i++) {
   3965             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   3966             final boolean samePackage = r.packageName.equals(name)
   3967                     || (name == null && r.userId == userId);
   3968             if ((userId == UserHandle.USER_ALL || r.userId == userId)
   3969                     && (samePackage || r.task == lastTask)
   3970                     && (r.app == null || evenPersistent || !r.app.persistent)) {
   3971                 if (!doit) {
   3972                     if (r.finishing) {
   3973                         // If this activity is just finishing, then it is not
   3974                         // interesting as far as something to stop.
   3975                         continue;
   3976                     }
   3977                     return true;
   3978                 }
   3979                 didSomething = true;
   3980                 Slog.i(TAG, "  Force finishing activity " + r);
   3981                 if (samePackage) {
   3982                     if (r.app != null) {
   3983                         r.app.removed = true;
   3984                     }
   3985                     r.app = null;
   3986                 }
   3987                 lastTask = r.task;
   3988                 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
   3989                         null, "force-stop", true)) {
   3990                     i--;
   3991                 }
   3992             }
   3993         }
   3994 
   3995         if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
   3996             if (!doit) {
   3997                 return true;
   3998             }
   3999             didSomething = true;
   4000         }
   4001 
   4002         if (name == null) {
   4003             // Remove all sticky broadcasts from this user.
   4004             mStickyBroadcasts.remove(userId);
   4005         }
   4006 
   4007         ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
   4008         if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
   4009                 userId, providers)) {
   4010             if (!doit) {
   4011                 return true;
   4012             }
   4013             didSomething = true;
   4014         }
   4015         N = providers.size();
   4016         for (i=0; i<N; i++) {
   4017             removeDyingProviderLocked(null, providers.get(i), true);
   4018         }
   4019 
   4020         if (name == null) {
   4021             // Remove pending intents.  For now we only do this when force
   4022             // stopping users, because we have some problems when doing this
   4023             // for packages -- app widgets are not currently cleaned up for
   4024             // such packages, so they can be left with bad pending intents.
   4025             if (mIntentSenderRecords.size() > 0) {
   4026                 Iterator<WeakReference<PendingIntentRecord>> it
   4027                         = mIntentSenderRecords.values().iterator();
   4028                 while (it.hasNext()) {
   4029                     WeakReference<PendingIntentRecord> wpir = it.next();
   4030                     if (wpir == null) {
   4031                         it.remove();
   4032                         continue;
   4033                     }
   4034                     PendingIntentRecord pir = wpir.get();
   4035                     if (pir == null) {
   4036                         it.remove();
   4037                         continue;
   4038                     }
   4039                     if (name == null) {
   4040                         // Stopping user, remove all objects for the user.
   4041                         if (pir.key.userId != userId) {
   4042                             // Not the same user, skip it.
   4043                             continue;
   4044                         }
   4045                     } else {
   4046                         if (UserHandle.getAppId(pir.uid) != appId) {
   4047                             // Different app id, skip it.
   4048                             continue;
   4049                         }
   4050                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
   4051                             // Different user, skip it.
   4052                             continue;
   4053                         }
   4054                         if (!pir.key.packageName.equals(name)) {
   4055                             // Different package, skip it.
   4056                             continue;
   4057                         }
   4058                     }
   4059                     if (!doit) {
   4060                         return true;
   4061                     }
   4062                     didSomething = true;
   4063                     it.remove();
   4064                     pir.canceled = true;
   4065                     if (pir.key.activity != null) {
   4066                         pir.key.activity.pendingResults.remove(pir.ref);
   4067                     }
   4068                 }
   4069             }
   4070         }
   4071 
   4072         if (doit) {
   4073             if (purgeCache && name != null) {
   4074                 AttributeCache ac = AttributeCache.instance();
   4075                 if (ac != null) {
   4076                     ac.removePackage(name);
   4077                 }
   4078             }
   4079             if (mBooted) {
   4080                 mMainStack.resumeTopActivityLocked(null);
   4081                 mMainStack.scheduleIdleLocked();
   4082             }
   4083         }
   4084 
   4085         return didSomething;
   4086     }
   4087 
   4088     private final boolean removeProcessLocked(ProcessRecord app,
   4089             boolean callerWillRestart, boolean allowRestart, String reason) {
   4090         final String name = app.processName;
   4091         final int uid = app.uid;
   4092         if (DEBUG_PROCESSES) Slog.d(
   4093             TAG, "Force removing proc " + app.toShortString() + " (" + name
   4094             + "/" + uid + ")");
   4095 
   4096         mProcessNames.remove(name, uid);
   4097         mIsolatedProcesses.remove(app.uid);
   4098         if (mHeavyWeightProcess == app) {
   4099             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   4100                     mHeavyWeightProcess.userId, 0));
   4101             mHeavyWeightProcess = null;
   4102         }
   4103         boolean needRestart = false;
   4104         if (app.pid > 0 && app.pid != MY_PID) {
   4105             int pid = app.pid;
   4106             synchronized (mPidsSelfLocked) {
   4107                 mPidsSelfLocked.remove(pid);
   4108                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   4109             }
   4110             Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
   4111             handleAppDiedLocked(app, true, allowRestart);
   4112             mLruProcesses.remove(app);
   4113             Process.killProcessQuiet(pid);
   4114 
   4115             if (app.persistent && !app.isolated) {
   4116                 if (!callerWillRestart) {
   4117                     addAppLocked(app.info, false);
   4118                 } else {
   4119                     needRestart = true;
   4120                 }
   4121             }
   4122         } else {
   4123             mRemovedProcesses.add(app);
   4124         }
   4125 
   4126         return needRestart;
   4127     }
   4128 
   4129     private final void processStartTimedOutLocked(ProcessRecord app) {
   4130         final int pid = app.pid;
   4131         boolean gone = false;
   4132         synchronized (mPidsSelfLocked) {
   4133             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
   4134             if (knownApp != null && knownApp.thread == null) {
   4135                 mPidsSelfLocked.remove(pid);
   4136                 gone = true;
   4137             }
   4138         }
   4139 
   4140         if (gone) {
   4141             Slog.w(TAG, "Process " + app + " failed to attach");
   4142             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
   4143                     pid, app.uid, app.processName);
   4144             mProcessNames.remove(app.processName, app.uid);
   4145             mIsolatedProcesses.remove(app.uid);
   4146             if (mHeavyWeightProcess == app) {
   4147                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   4148                         mHeavyWeightProcess.userId, 0));
   4149                 mHeavyWeightProcess = null;
   4150             }
   4151             // Take care of any launching providers waiting for this process.
   4152             checkAppInLaunchingProvidersLocked(app, true);
   4153             // Take care of any services that are waiting for the process.
   4154             mServices.processStartTimedOutLocked(app);
   4155             EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, pid,
   4156                     app.processName, app.setAdj, "start timeout");
   4157             Process.killProcessQuiet(pid);
   4158             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
   4159                 Slog.w(TAG, "Unattached app died before backup, skipping");
   4160                 try {
   4161                     IBackupManager bm = IBackupManager.Stub.asInterface(
   4162                             ServiceManager.getService(Context.BACKUP_SERVICE));
   4163                     bm.agentDisconnected(app.info.packageName);
   4164                 } catch (RemoteException e) {
   4165                     // Can't happen; the backup manager is local
   4166                 }
   4167             }
   4168             if (isPendingBroadcastProcessLocked(pid)) {
   4169                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   4170                 skipPendingBroadcastLocked(pid);
   4171             }
   4172         } else {
   4173             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
   4174         }
   4175     }
   4176 
   4177     private final boolean attachApplicationLocked(IApplicationThread thread,
   4178             int pid) {
   4179 
   4180         // Find the application record that is being attached...  either via
   4181         // the pid if we are running in multiple processes, or just pull the
   4182         // next app record if we are emulating process with anonymous threads.
   4183         ProcessRecord app;
   4184         if (pid != MY_PID && pid >= 0) {
   4185             synchronized (mPidsSelfLocked) {
   4186                 app = mPidsSelfLocked.get(pid);
   4187             }
   4188         } else {
   4189             app = null;
   4190         }
   4191 
   4192         if (app == null) {
   4193             Slog.w(TAG, "No pending application record for pid " + pid
   4194                     + " (IApplicationThread " + thread + "); dropping process");
   4195             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
   4196             if (pid > 0 && pid != MY_PID) {
   4197                 Process.killProcessQuiet(pid);
   4198             } else {
   4199                 try {
   4200                     thread.scheduleExit();
   4201                 } catch (Exception e) {
   4202                     // Ignore exceptions.
   4203                 }
   4204             }
   4205             return false;
   4206         }
   4207 
   4208         // If this application record is still attached to a previous
   4209         // process, clean it up now.
   4210         if (app.thread != null) {
   4211             handleAppDiedLocked(app, true, true);
   4212         }
   4213 
   4214         // Tell the process all about itself.
   4215 
   4216         if (localLOGV) Slog.v(
   4217                 TAG, "Binding process pid " + pid + " to record " + app);
   4218 
   4219         String processName = app.processName;
   4220         try {
   4221             AppDeathRecipient adr = new AppDeathRecipient(
   4222                     app, pid, thread);
   4223             thread.asBinder().linkToDeath(adr, 0);
   4224             app.deathRecipient = adr;
   4225         } catch (RemoteException e) {
   4226             app.resetPackageList();
   4227             startProcessLocked(app, "link fail", processName);
   4228             return false;
   4229         }
   4230 
   4231         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
   4232 
   4233         app.thread = thread;
   4234         app.curAdj = app.setAdj = -100;
   4235         app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
   4236         app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   4237         app.forcingToForeground = null;
   4238         app.foregroundServices = false;
   4239         app.hasShownUi = false;
   4240         app.debugging = false;
   4241 
   4242         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   4243 
   4244         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
   4245         List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
   4246 
   4247         if (!normalMode) {
   4248             Slog.i(TAG, "Launching preboot mode app: " + app);
   4249         }
   4250 
   4251         if (localLOGV) Slog.v(
   4252             TAG, "New app record " + app
   4253             + " thread=" + thread.asBinder() + " pid=" + pid);
   4254         try {
   4255             int testMode = IApplicationThread.DEBUG_OFF;
   4256             if (mDebugApp != null && mDebugApp.equals(processName)) {
   4257                 testMode = mWaitForDebugger
   4258                     ? IApplicationThread.DEBUG_WAIT
   4259                     : IApplicationThread.DEBUG_ON;
   4260                 app.debugging = true;
   4261                 if (mDebugTransient) {
   4262                     mDebugApp = mOrigDebugApp;
   4263                     mWaitForDebugger = mOrigWaitForDebugger;
   4264                 }
   4265             }
   4266             String profileFile = app.instrumentationProfileFile;
   4267             ParcelFileDescriptor profileFd = null;
   4268             boolean profileAutoStop = false;
   4269             if (mProfileApp != null && mProfileApp.equals(processName)) {
   4270                 mProfileProc = app;
   4271                 profileFile = mProfileFile;
   4272                 profileFd = mProfileFd;
   4273                 profileAutoStop = mAutoStopProfiler;
   4274             }
   4275             boolean enableOpenGlTrace = false;
   4276             if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
   4277                 enableOpenGlTrace = true;
   4278                 mOpenGlTraceApp = null;
   4279             }
   4280 
   4281             // If the app is being launched for restore or full backup, set it up specially
   4282             boolean isRestrictedBackupMode = false;
   4283             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
   4284                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
   4285                         || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
   4286                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
   4287             }
   4288 
   4289             ensurePackageDexOpt(app.instrumentationInfo != null
   4290                     ? app.instrumentationInfo.packageName
   4291                     : app.info.packageName);
   4292             if (app.instrumentationClass != null) {
   4293                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
   4294             }
   4295             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
   4296                     + processName + " with config " + mConfiguration);
   4297             ApplicationInfo appInfo = app.instrumentationInfo != null
   4298                     ? app.instrumentationInfo : app.info;
   4299             app.compat = compatibilityInfoForPackageLocked(appInfo);
   4300             if (profileFd != null) {
   4301                 profileFd = profileFd.dup();
   4302             }
   4303             thread.bindApplication(processName, appInfo, providers,
   4304                     app.instrumentationClass, profileFile, profileFd, profileAutoStop,
   4305                     app.instrumentationArguments, app.instrumentationWatcher,
   4306                     app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
   4307                     isRestrictedBackupMode || !normalMode, app.persistent,
   4308                     new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
   4309                     mCoreSettingsObserver.getCoreSettingsLocked());
   4310             updateLruProcessLocked(app, false);
   4311             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
   4312         } catch (Exception e) {
   4313             // todo: Yikes!  What should we do?  For now we will try to
   4314             // start another process, but that could easily get us in
   4315             // an infinite loop of restarting processes...
   4316             Slog.w(TAG, "Exception thrown during bind!", e);
   4317 
   4318             app.resetPackageList();
   4319             app.unlinkDeathRecipient();
   4320             startProcessLocked(app, "bind fail", processName);
   4321             return false;
   4322         }
   4323 
   4324         // Remove this record from the list of starting applications.
   4325         mPersistentStartingProcesses.remove(app);
   4326         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   4327                 "Attach application locked removing on hold: " + app);
   4328         mProcessesOnHold.remove(app);
   4329 
   4330         boolean badApp = false;
   4331         boolean didSomething = false;
   4332 
   4333         // See if the top visible activity is waiting to run in this process...
   4334         ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
   4335         if (hr != null && normalMode) {
   4336             if (hr.app == null && app.uid == hr.info.applicationInfo.uid
   4337                     && processName.equals(hr.processName)) {
   4338                 try {
   4339                     if (mHeadless) {
   4340                         Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
   4341                     } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
   4342                         didSomething = true;
   4343                     }
   4344                 } catch (Exception e) {
   4345                     Slog.w(TAG, "Exception in new application when starting activity "
   4346                           + hr.intent.getComponent().flattenToShortString(), e);
   4347                     badApp = true;
   4348                 }
   4349             } else {
   4350                 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
   4351             }
   4352         }
   4353 
   4354         // Find any services that should be running in this process...
   4355         if (!badApp) {
   4356             try {
   4357                 didSomething |= mServices.attachApplicationLocked(app, processName);
   4358             } catch (Exception e) {
   4359                 badApp = true;
   4360             }
   4361         }
   4362 
   4363         // Check if a next-broadcast receiver is in this process...
   4364         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
   4365             try {
   4366                 didSomething = sendPendingBroadcastsLocked(app);
   4367             } catch (Exception e) {
   4368                 // If the app died trying to launch the receiver we declare it 'bad'
   4369                 badApp = true;
   4370             }
   4371         }
   4372 
   4373         // Check whether the next backup agent is in this process...
   4374         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
   4375             if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
   4376             ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
   4377             try {
   4378                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
   4379                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
   4380                         mBackupTarget.backupMode);
   4381             } catch (Exception e) {
   4382                 Slog.w(TAG, "Exception scheduling backup agent creation: ");
   4383                 e.printStackTrace();
   4384             }
   4385         }
   4386 
   4387         if (badApp) {
   4388             // todo: Also need to kill application to deal with all
   4389             // kinds of exceptions.
   4390             handleAppDiedLocked(app, false, true);
   4391             return false;
   4392         }
   4393 
   4394         if (!didSomething) {
   4395             updateOomAdjLocked();
   4396         }
   4397 
   4398         return true;
   4399     }
   4400 
   4401     public final void attachApplication(IApplicationThread thread) {
   4402         synchronized (this) {
   4403             int callingPid = Binder.getCallingPid();
   4404             final long origId = Binder.clearCallingIdentity();
   4405             attachApplicationLocked(thread, callingPid);
   4406             Binder.restoreCallingIdentity(origId);
   4407         }
   4408     }
   4409 
   4410     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
   4411         final long origId = Binder.clearCallingIdentity();
   4412         ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
   4413         if (stopProfiling) {
   4414             synchronized (this) {
   4415                 if (mProfileProc == r.app) {
   4416                     if (mProfileFd != null) {
   4417                         try {
   4418                             mProfileFd.close();
   4419                         } catch (IOException e) {
   4420                         }
   4421                         clearProfilerLocked();
   4422                     }
   4423                 }
   4424             }
   4425         }
   4426         Binder.restoreCallingIdentity(origId);
   4427     }
   4428 
   4429     void enableScreenAfterBoot() {
   4430         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
   4431                 SystemClock.uptimeMillis());
   4432         mWindowManager.enableScreenAfterBoot();
   4433 
   4434         synchronized (this) {
   4435             updateEventDispatchingLocked();
   4436         }
   4437     }
   4438 
   4439     public void showBootMessage(final CharSequence msg, final boolean always) {
   4440         enforceNotIsolatedCaller("showBootMessage");
   4441         mWindowManager.showBootMessage(msg, always);
   4442     }
   4443 
   4444     public void dismissKeyguardOnNextActivity() {
   4445         enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
   4446         final long token = Binder.clearCallingIdentity();
   4447         try {
   4448             synchronized (this) {
   4449                 if (mLockScreenShown) {
   4450                     mLockScreenShown = false;
   4451                     comeOutOfSleepIfNeededLocked();
   4452                 }
   4453                 mMainStack.dismissKeyguardOnNextActivityLocked();
   4454             }
   4455         } finally {
   4456             Binder.restoreCallingIdentity(token);
   4457         }
   4458     }
   4459 
   4460     final void finishBooting() {
   4461         IntentFilter pkgFilter = new IntentFilter();
   4462         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
   4463         pkgFilter.addDataScheme("package");
   4464         mContext.registerReceiver(new BroadcastReceiver() {
   4465             @Override
   4466             public void onReceive(Context context, Intent intent) {
   4467                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
   4468                 if (pkgs != null) {
   4469                     for (String pkg : pkgs) {
   4470                         synchronized (ActivityManagerService.this) {
   4471                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
   4472                                 setResultCode(Activity.RESULT_OK);
   4473                                 return;
   4474                             }
   4475                         }
   4476                     }
   4477                 }
   4478             }
   4479         }, pkgFilter);
   4480 
   4481         synchronized (this) {
   4482             // Ensure that any processes we had put on hold are now started
   4483             // up.
   4484             final int NP = mProcessesOnHold.size();
   4485             if (NP > 0) {
   4486                 ArrayList<ProcessRecord> procs =
   4487                     new ArrayList<ProcessRecord>(mProcessesOnHold);
   4488                 for (int ip=0; ip<NP; ip++) {
   4489                     if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
   4490                             + procs.get(ip));
   4491                     startProcessLocked(procs.get(ip), "on-hold", null);
   4492                 }
   4493             }
   4494 
   4495             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   4496                 // Start looking for apps that are abusing wake locks.
   4497                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   4498                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   4499                 // Tell anyone interested that we are done booting!
   4500                 SystemProperties.set("sys.boot_completed", "1");
   4501                 SystemProperties.set("dev.bootcomplete", "1");
   4502                 for (int i=0; i<mStartedUsers.size(); i++) {
   4503                     UserStartedState uss = mStartedUsers.valueAt(i);
   4504                     if (uss.mState == UserStartedState.STATE_BOOTING) {
   4505                         uss.mState = UserStartedState.STATE_RUNNING;
   4506                         final int userId = mStartedUsers.keyAt(i);
   4507                         Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
   4508                         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   4509                         broadcastIntentLocked(null, null, intent,
   4510                                 null, null, 0, null, null,
   4511                                 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
   4512                                 AppOpsManager.OP_NONE, false, false, MY_PID, Process.SYSTEM_UID,
   4513                                 userId);
   4514                     }
   4515                 }
   4516             }
   4517         }
   4518     }
   4519 
   4520     final void ensureBootCompleted() {
   4521         boolean booting;
   4522         boolean enableScreen;
   4523         synchronized (this) {
   4524             booting = mBooting;
   4525             mBooting = false;
   4526             enableScreen = !mBooted;
   4527             mBooted = true;
   4528         }
   4529 
   4530         if (booting) {
   4531             finishBooting();
   4532         }
   4533 
   4534         if (enableScreen) {
   4535             enableScreenAfterBoot();
   4536         }
   4537     }
   4538 
   4539     public final void activityResumed(IBinder token) {
   4540         final long origId = Binder.clearCallingIdentity();
   4541         mMainStack.activityResumed(token);
   4542         Binder.restoreCallingIdentity(origId);
   4543     }
   4544 
   4545     public final void activityPaused(IBinder token) {
   4546         final long origId = Binder.clearCallingIdentity();
   4547         mMainStack.activityPaused(token, false);
   4548         Binder.restoreCallingIdentity(origId);
   4549     }
   4550 
   4551     public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
   4552             CharSequence description) {
   4553         if (localLOGV) Slog.v(
   4554             TAG, "Activity stopped: token=" + token);
   4555 
   4556         // Refuse possible leaked file descriptors
   4557         if (icicle != null && icicle.hasFileDescriptors()) {
   4558             throw new IllegalArgumentException("File descriptors passed in Bundle");
   4559         }
   4560 
   4561         ActivityRecord r = null;
   4562 
   4563         final long origId = Binder.clearCallingIdentity();
   4564 
   4565         synchronized (this) {
   4566             r = mMainStack.isInStackLocked(token);
   4567             if (r != null) {
   4568                 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
   4569             }
   4570         }
   4571 
   4572         if (r != null) {
   4573             sendPendingThumbnail(r, null, null, null, false);
   4574         }
   4575 
   4576         trimApplications();
   4577 
   4578         Binder.restoreCallingIdentity(origId);
   4579     }
   4580 
   4581     public final void activityDestroyed(IBinder token) {
   4582         if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
   4583         mMainStack.activityDestroyed(token);
   4584     }
   4585 
   4586     public String getCallingPackage(IBinder token) {
   4587         synchronized (this) {
   4588             ActivityRecord r = getCallingRecordLocked(token);
   4589             return r != null ? r.info.packageName : null;
   4590         }
   4591     }
   4592 
   4593     public ComponentName getCallingActivity(IBinder token) {
   4594         synchronized (this) {
   4595             ActivityRecord r = getCallingRecordLocked(token);
   4596             return r != null ? r.intent.getComponent() : null;
   4597         }
   4598     }
   4599 
   4600     private ActivityRecord getCallingRecordLocked(IBinder token) {
   4601         ActivityRecord r = mMainStack.isInStackLocked(token);
   4602         if (r == null) {
   4603             return null;
   4604         }
   4605         return r.resultTo;
   4606     }
   4607 
   4608     public ComponentName getActivityClassForToken(IBinder token) {
   4609         synchronized(this) {
   4610             ActivityRecord r = mMainStack.isInStackLocked(token);
   4611             if (r == null) {
   4612                 return null;
   4613             }
   4614             return r.intent.getComponent();
   4615         }
   4616     }
   4617 
   4618     public String getPackageForToken(IBinder token) {
   4619         synchronized(this) {
   4620             ActivityRecord r = mMainStack.isInStackLocked(token);
   4621             if (r == null) {
   4622                 return null;
   4623             }
   4624             return r.packageName;
   4625         }
   4626     }
   4627 
   4628     public IIntentSender getIntentSender(int type,
   4629             String packageName, IBinder token, String resultWho,
   4630             int requestCode, Intent[] intents, String[] resolvedTypes,
   4631             int flags, Bundle options, int userId) {
   4632         enforceNotIsolatedCaller("getIntentSender");
   4633         // Refuse possible leaked file descriptors
   4634         if (intents != null) {
   4635             if (intents.length < 1) {
   4636                 throw new IllegalArgumentException("Intents array length must be >= 1");
   4637             }
   4638             for (int i=0; i<intents.length; i++) {
   4639                 Intent intent = intents[i];
   4640                 if (intent != null) {
   4641                     if (intent.hasFileDescriptors()) {
   4642                         throw new IllegalArgumentException("File descriptors passed in Intent");
   4643                     }
   4644                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
   4645                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   4646                         throw new IllegalArgumentException(
   4647                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   4648                     }
   4649                     intents[i] = new Intent(intent);
   4650                 }
   4651             }
   4652             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
   4653                 throw new IllegalArgumentException(
   4654                         "Intent array length does not match resolvedTypes length");
   4655             }
   4656         }
   4657         if (options != null) {
   4658             if (options.hasFileDescriptors()) {
   4659                 throw new IllegalArgumentException("File descriptors passed in options");
   4660             }
   4661         }
   4662 
   4663         synchronized(this) {
   4664             int callingUid = Binder.getCallingUid();
   4665             int origUserId = userId;
   4666             userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
   4667                     type == ActivityManager.INTENT_SENDER_BROADCAST, false,
   4668                     "getIntentSender", null);
   4669             if (origUserId == UserHandle.USER_CURRENT) {
   4670                 // We don't want to evaluate this until the pending intent is
   4671                 // actually executed.  However, we do want to always do the
   4672                 // security checking for it above.
   4673                 userId = UserHandle.USER_CURRENT;
   4674             }
   4675             try {
   4676                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   4677                     int uid = AppGlobals.getPackageManager()
   4678                             .getPackageUid(packageName, UserHandle.getUserId(callingUid));
   4679                     if (!UserHandle.isSameApp(callingUid, uid)) {
   4680                         String msg = "Permission Denial: getIntentSender() from pid="
   4681                             + Binder.getCallingPid()
   4682                             + ", uid=" + Binder.getCallingUid()
   4683                             + ", (need uid=" + uid + ")"
   4684                             + " is not allowed to send as package " + packageName;
   4685                         Slog.w(TAG, msg);
   4686                         throw new SecurityException(msg);
   4687                     }
   4688                 }
   4689 
   4690                 return getIntentSenderLocked(type, packageName, callingUid, userId,
   4691                         token, resultWho, requestCode, intents, resolvedTypes, flags, options);
   4692 
   4693             } catch (RemoteException e) {
   4694                 throw new SecurityException(e);
   4695             }
   4696         }
   4697     }
   4698 
   4699     IIntentSender getIntentSenderLocked(int type, String packageName,
   4700             int callingUid, int userId, IBinder token, String resultWho,
   4701             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
   4702             Bundle options) {
   4703         if (DEBUG_MU)
   4704             Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
   4705         ActivityRecord activity = null;
   4706         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   4707             activity = mMainStack.isInStackLocked(token);
   4708             if (activity == null) {
   4709                 return null;
   4710             }
   4711             if (activity.finishing) {
   4712                 return null;
   4713             }
   4714         }
   4715 
   4716         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
   4717         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
   4718         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
   4719         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
   4720                 |PendingIntent.FLAG_UPDATE_CURRENT);
   4721 
   4722         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
   4723                 type, packageName, activity, resultWho,
   4724                 requestCode, intents, resolvedTypes, flags, options, userId);
   4725         WeakReference<PendingIntentRecord> ref;
   4726         ref = mIntentSenderRecords.get(key);
   4727         PendingIntentRecord rec = ref != null ? ref.get() : null;
   4728         if (rec != null) {
   4729             if (!cancelCurrent) {
   4730                 if (updateCurrent) {
   4731                     if (rec.key.requestIntent != null) {
   4732                         rec.key.requestIntent.replaceExtras(intents != null ?
   4733                                 intents[intents.length - 1] : null);
   4734                     }
   4735                     if (intents != null) {
   4736                         intents[intents.length-1] = rec.key.requestIntent;
   4737                         rec.key.allIntents = intents;
   4738                         rec.key.allResolvedTypes = resolvedTypes;
   4739                     } else {
   4740                         rec.key.allIntents = null;
   4741                         rec.key.allResolvedTypes = null;
   4742                     }
   4743                 }
   4744                 return rec;
   4745             }
   4746             rec.canceled = true;
   4747             mIntentSenderRecords.remove(key);
   4748         }
   4749         if (noCreate) {
   4750             return rec;
   4751         }
   4752         rec = new PendingIntentRecord(this, key, callingUid);
   4753         mIntentSenderRecords.put(key, rec.ref);
   4754         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   4755             if (activity.pendingResults == null) {
   4756                 activity.pendingResults
   4757                         = new HashSet<WeakReference<PendingIntentRecord>>();
   4758             }
   4759             activity.pendingResults.add(rec.ref);
   4760         }
   4761         return rec;
   4762     }
   4763 
   4764     public void cancelIntentSender(IIntentSender sender) {
   4765         if (!(sender instanceof PendingIntentRecord)) {
   4766             return;
   4767         }
   4768         synchronized(this) {
   4769             PendingIntentRecord rec = (PendingIntentRecord)sender;
   4770             try {
   4771                 int uid = AppGlobals.getPackageManager()
   4772                         .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
   4773                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
   4774                     String msg = "Permission Denial: cancelIntentSender() from pid="
   4775                         + Binder.getCallingPid()
   4776                         + ", uid=" + Binder.getCallingUid()
   4777                         + " is not allowed to cancel packges "
   4778                         + rec.key.packageName;
   4779                     Slog.w(TAG, msg);
   4780                     throw new SecurityException(msg);
   4781                 }
   4782             } catch (RemoteException e) {
   4783                 throw new SecurityException(e);
   4784             }
   4785             cancelIntentSenderLocked(rec, true);
   4786         }
   4787     }
   4788 
   4789     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
   4790         rec.canceled = true;
   4791         mIntentSenderRecords.remove(rec.key);
   4792         if (cleanActivity && rec.key.activity != null) {
   4793             rec.key.activity.pendingResults.remove(rec.ref);
   4794         }
   4795     }
   4796 
   4797     public String getPackageForIntentSender(IIntentSender pendingResult) {
   4798         if (!(pendingResult instanceof PendingIntentRecord)) {
   4799             return null;
   4800         }
   4801         try {
   4802             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   4803             return res.key.packageName;
   4804         } catch (ClassCastException e) {
   4805         }
   4806         return null;
   4807     }
   4808 
   4809     public int getUidForIntentSender(IIntentSender sender) {
   4810         if (sender instanceof PendingIntentRecord) {
   4811             try {
   4812                 PendingIntentRecord res = (PendingIntentRecord)sender;
   4813                 return res.uid;
   4814             } catch (ClassCastException e) {
   4815             }
   4816         }
   4817         return -1;
   4818     }
   4819 
   4820     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
   4821         if (!(pendingResult instanceof PendingIntentRecord)) {
   4822             return false;
   4823         }
   4824         try {
   4825             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   4826             if (res.key.allIntents == null) {
   4827                 return false;
   4828             }
   4829             for (int i=0; i<res.key.allIntents.length; i++) {
   4830                 Intent intent = res.key.allIntents[i];
   4831                 if (intent.getPackage() != null && intent.getComponent() != null) {
   4832                     return false;
   4833                 }
   4834             }
   4835             return true;
   4836         } catch (ClassCastException e) {
   4837         }
   4838         return false;
   4839     }
   4840 
   4841     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
   4842         if (!(pendingResult instanceof PendingIntentRecord)) {
   4843             return false;
   4844         }
   4845         try {
   4846             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   4847             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
   4848                 return true;
   4849             }
   4850             return false;
   4851         } catch (ClassCastException e) {
   4852         }
   4853         return false;
   4854     }
   4855 
   4856     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
   4857         if (!(pendingResult instanceof PendingIntentRecord)) {
   4858             return null;
   4859         }
   4860         try {
   4861             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   4862             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
   4863         } catch (ClassCastException e) {
   4864         }
   4865         return null;
   4866     }
   4867 
   4868     public void setProcessLimit(int max) {
   4869         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   4870                 "setProcessLimit()");
   4871         synchronized (this) {
   4872             mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
   4873             mProcessLimitOverride = max;
   4874         }
   4875         trimApplications();
   4876     }
   4877 
   4878     public int getProcessLimit() {
   4879         synchronized (this) {
   4880             return mProcessLimitOverride;
   4881         }
   4882     }
   4883 
   4884     void foregroundTokenDied(ForegroundToken token) {
   4885         synchronized (ActivityManagerService.this) {
   4886             synchronized (mPidsSelfLocked) {
   4887                 ForegroundToken cur
   4888                     = mForegroundProcesses.get(token.pid);
   4889                 if (cur != token) {
   4890                     return;
   4891                 }
   4892                 mForegroundProcesses.remove(token.pid);
   4893                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
   4894                 if (pr == null) {
   4895                     return;
   4896                 }
   4897                 pr.forcingToForeground = null;
   4898                 pr.foregroundServices = false;
   4899             }
   4900             updateOomAdjLocked();
   4901         }
   4902     }
   4903 
   4904     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
   4905         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   4906                 "setProcessForeground()");
   4907         synchronized(this) {
   4908             boolean changed = false;
   4909 
   4910             synchronized (mPidsSelfLocked) {
   4911                 ProcessRecord pr = mPidsSelfLocked.get(pid);
   4912                 if (pr == null && isForeground) {
   4913                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
   4914                     return;
   4915                 }
   4916                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
   4917                 if (oldToken != null) {
   4918                     oldToken.token.unlinkToDeath(oldToken, 0);
   4919                     mForegroundProcesses.remove(pid);
   4920                     if (pr != null) {
   4921                         pr.forcingToForeground = null;
   4922                     }
   4923                     changed = true;
   4924                 }
   4925                 if (isForeground && token != null) {
   4926                     ForegroundToken newToken = new ForegroundToken() {
   4927                         public void binderDied() {
   4928                             foregroundTokenDied(this);
   4929                         }
   4930                     };
   4931                     newToken.pid = pid;
   4932                     newToken.token = token;
   4933                     try {
   4934                         token.linkToDeath(newToken, 0);
   4935                         mForegroundProcesses.put(pid, newToken);
   4936                         pr.forcingToForeground = token;
   4937                         changed = true;
   4938                     } catch (RemoteException e) {
   4939                         // If the process died while doing this, we will later
   4940                         // do the cleanup with the process death link.
   4941                     }
   4942                 }
   4943             }
   4944 
   4945             if (changed) {
   4946                 updateOomAdjLocked();
   4947             }
   4948         }
   4949     }
   4950 
   4951     // =========================================================
   4952     // PERMISSIONS
   4953     // =========================================================
   4954 
   4955     static class PermissionController extends IPermissionController.Stub {
   4956         ActivityManagerService mActivityManagerService;
   4957         PermissionController(ActivityManagerService activityManagerService) {
   4958             mActivityManagerService = activityManagerService;
   4959         }
   4960 
   4961         public boolean checkPermission(String permission, int pid, int uid) {
   4962             return mActivityManagerService.checkPermission(permission, pid,
   4963                     uid) == PackageManager.PERMISSION_GRANTED;
   4964         }
   4965     }
   4966 
   4967     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
   4968         public int checkComponentPermission(String permission, int pid, int uid,
   4969                 int owningUid, boolean exported) {
   4970             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
   4971                     owningUid, exported);
   4972         }
   4973 
   4974         public Object getAMSLock() {
   4975             return ActivityManagerService.this;
   4976         }
   4977     }
   4978 
   4979     /**
   4980      * This can be called with or without the global lock held.
   4981      */
   4982     int checkComponentPermission(String permission, int pid, int uid,
   4983             int owningUid, boolean exported) {
   4984         // We might be performing an operation on behalf of an indirect binder
   4985         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
   4986         // client identity accordingly before proceeding.
   4987         Identity tlsIdentity = sCallerIdentity.get();
   4988         if (tlsIdentity != null) {
   4989             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
   4990                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
   4991             uid = tlsIdentity.uid;
   4992             pid = tlsIdentity.pid;
   4993         }
   4994 
   4995         if (pid == MY_PID) {
   4996             return PackageManager.PERMISSION_GRANTED;
   4997         }
   4998 
   4999         return ActivityManager.checkComponentPermission(permission, uid,
   5000                 owningUid, exported);
   5001     }
   5002 
   5003     /**
   5004      * As the only public entry point for permissions checking, this method
   5005      * can enforce the semantic that requesting a check on a null global
   5006      * permission is automatically denied.  (Internally a null permission
   5007      * string is used when calling {@link #checkComponentPermission} in cases
   5008      * when only uid-based security is needed.)
   5009      *
   5010      * This can be called with or without the global lock held.
   5011      */
   5012     public int checkPermission(String permission, int pid, int uid) {
   5013         if (permission == null) {
   5014             return PackageManager.PERMISSION_DENIED;
   5015         }
   5016         return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
   5017     }
   5018 
   5019     /**
   5020      * Binder IPC calls go through the public entry point.
   5021      * This can be called with or without the global lock held.
   5022      */
   5023     int checkCallingPermission(String permission) {
   5024         return checkPermission(permission,
   5025                 Binder.getCallingPid(),
   5026                 UserHandle.getAppId(Binder.getCallingUid()));
   5027     }
   5028 
   5029     /**
   5030      * This can be called with or without the global lock held.
   5031      */
   5032     void enforceCallingPermission(String permission, String func) {
   5033         if (checkCallingPermission(permission)
   5034                 == PackageManager.PERMISSION_GRANTED) {
   5035             return;
   5036         }
   5037 
   5038         String msg = "Permission Denial: " + func + " from pid="
   5039                 + Binder.getCallingPid()
   5040                 + ", uid=" + Binder.getCallingUid()
   5041                 + " requires " + permission;
   5042         Slog.w(TAG, msg);
   5043         throw new SecurityException(msg);
   5044     }
   5045 
   5046     /**
   5047      * Determine if UID is holding permissions required to access {@link Uri} in
   5048      * the given {@link ProviderInfo}. Final permission checking is always done
   5049      * in {@link ContentProvider}.
   5050      */
   5051     private final boolean checkHoldingPermissionsLocked(
   5052             IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
   5053         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5054                 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
   5055 
   5056         if (pi.applicationInfo.uid == uid) {
   5057             return true;
   5058         } else if (!pi.exported) {
   5059             return false;
   5060         }
   5061 
   5062         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
   5063         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
   5064         try {
   5065             // check if target holds top-level <provider> permissions
   5066             if (!readMet && pi.readPermission != null
   5067                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
   5068                 readMet = true;
   5069             }
   5070             if (!writeMet && pi.writePermission != null
   5071                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
   5072                 writeMet = true;
   5073             }
   5074 
   5075             // track if unprotected read/write is allowed; any denied
   5076             // <path-permission> below removes this ability
   5077             boolean allowDefaultRead = pi.readPermission == null;
   5078             boolean allowDefaultWrite = pi.writePermission == null;
   5079 
   5080             // check if target holds any <path-permission> that match uri
   5081             final PathPermission[] pps = pi.pathPermissions;
   5082             if (pps != null) {
   5083                 final String path = uri.getPath();
   5084                 int i = pps.length;
   5085                 while (i > 0 && (!readMet || !writeMet)) {
   5086                     i--;
   5087                     PathPermission pp = pps[i];
   5088                     if (pp.match(path)) {
   5089                         if (!readMet) {
   5090                             final String pprperm = pp.getReadPermission();
   5091                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
   5092                                     + pprperm + " for " + pp.getPath()
   5093                                     + ": match=" + pp.match(path)
   5094                                     + " check=" + pm.checkUidPermission(pprperm, uid));
   5095                             if (pprperm != null) {
   5096                                 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
   5097                                     readMet = true;
   5098                                 } else {
   5099                                     allowDefaultRead = false;
   5100                                 }
   5101                             }
   5102                         }
   5103                         if (!writeMet) {
   5104                             final String ppwperm = pp.getWritePermission();
   5105                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
   5106                                     + ppwperm + " for " + pp.getPath()
   5107                                     + ": match=" + pp.match(path)
   5108                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
   5109                             if (ppwperm != null) {
   5110                                 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
   5111                                     writeMet = true;
   5112                                 } else {
   5113                                     allowDefaultWrite = false;
   5114                                 }
   5115                             }
   5116                         }
   5117                     }
   5118                 }
   5119             }
   5120 
   5121             // grant unprotected <provider> read/write, if not blocked by
   5122             // <path-permission> above
   5123             if (allowDefaultRead) readMet = true;
   5124             if (allowDefaultWrite) writeMet = true;
   5125 
   5126         } catch (RemoteException e) {
   5127             return false;
   5128         }
   5129 
   5130         return readMet && writeMet;
   5131     }
   5132 
   5133     private final boolean checkUriPermissionLocked(Uri uri, int uid,
   5134             int modeFlags) {
   5135         // Root gets to do everything.
   5136         if (uid == 0) {
   5137             return true;
   5138         }
   5139         HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   5140         if (perms == null) return false;
   5141         UriPermission perm = perms.get(uri);
   5142         if (perm == null) return false;
   5143         return (modeFlags&perm.modeFlags) == modeFlags;
   5144     }
   5145 
   5146     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
   5147         enforceNotIsolatedCaller("checkUriPermission");
   5148 
   5149         // Another redirected-binder-call permissions check as in
   5150         // {@link checkComponentPermission}.
   5151         Identity tlsIdentity = sCallerIdentity.get();
   5152         if (tlsIdentity != null) {
   5153             uid = tlsIdentity.uid;
   5154             pid = tlsIdentity.pid;
   5155         }
   5156 
   5157         // Our own process gets to do everything.
   5158         if (pid == MY_PID) {
   5159             return PackageManager.PERMISSION_GRANTED;
   5160         }
   5161         synchronized(this) {
   5162             return checkUriPermissionLocked(uri, uid, modeFlags)
   5163                     ? PackageManager.PERMISSION_GRANTED
   5164                     : PackageManager.PERMISSION_DENIED;
   5165         }
   5166     }
   5167 
   5168     /**
   5169      * Check if the targetPkg can be granted permission to access uri by
   5170      * the callingUid using the given modeFlags.  Throws a security exception
   5171      * if callingUid is not allowed to do this.  Returns the uid of the target
   5172      * if the URI permission grant should be performed; returns -1 if it is not
   5173      * needed (for example targetPkg already has permission to access the URI).
   5174      * If you already know the uid of the target, you can supply it in
   5175      * lastTargetUid else set that to -1.
   5176      */
   5177     int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
   5178             Uri uri, int modeFlags, int lastTargetUid) {
   5179         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   5180                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   5181         if (modeFlags == 0) {
   5182             return -1;
   5183         }
   5184 
   5185         if (targetPkg != null) {
   5186             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5187                     "Checking grant " + targetPkg + " permission to " + uri);
   5188         }
   5189 
   5190         final IPackageManager pm = AppGlobals.getPackageManager();
   5191 
   5192         // If this is not a content: uri, we can't do anything with it.
   5193         if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
   5194             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5195                     "Can't grant URI permission for non-content URI: " + uri);
   5196             return -1;
   5197         }
   5198 
   5199         String name = uri.getAuthority();
   5200         ProviderInfo pi = null;
   5201         ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
   5202                 UserHandle.getUserId(callingUid));
   5203         if (cpr != null) {
   5204             pi = cpr.info;
   5205         } else {
   5206             try {
   5207                 pi = pm.resolveContentProvider(name,
   5208                         PackageManager.GET_URI_PERMISSION_PATTERNS,
   5209                         UserHandle.getUserId(callingUid));
   5210             } catch (RemoteException ex) {
   5211             }
   5212         }
   5213         if (pi == null) {
   5214             Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
   5215             return -1;
   5216         }
   5217 
   5218         int targetUid = lastTargetUid;
   5219         if (targetUid < 0 && targetPkg != null) {
   5220             try {
   5221                 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
   5222                 if (targetUid < 0) {
   5223                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5224                             "Can't grant URI permission no uid for: " + targetPkg);
   5225                     return -1;
   5226                 }
   5227             } catch (RemoteException ex) {
   5228                 return -1;
   5229             }
   5230         }
   5231 
   5232         if (targetUid >= 0) {
   5233             // First...  does the target actually need this permission?
   5234             if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
   5235                 // No need to grant the target this permission.
   5236                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5237                         "Target " + targetPkg + " already has full permission to " + uri);
   5238                 return -1;
   5239             }
   5240         } else {
   5241             // First...  there is no target package, so can anyone access it?
   5242             boolean allowed = pi.exported;
   5243             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   5244                 if (pi.readPermission != null) {
   5245                     allowed = false;
   5246                 }
   5247             }
   5248             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   5249                 if (pi.writePermission != null) {
   5250                     allowed = false;
   5251                 }
   5252             }
   5253             if (allowed) {
   5254                 return -1;
   5255             }
   5256         }
   5257 
   5258         // Second...  is the provider allowing granting of URI permissions?
   5259         if (!pi.grantUriPermissions) {
   5260             throw new SecurityException("Provider " + pi.packageName
   5261                     + "/" + pi.name
   5262                     + " does not allow granting of Uri permissions (uri "
   5263                     + uri + ")");
   5264         }
   5265         if (pi.uriPermissionPatterns != null) {
   5266             final int N = pi.uriPermissionPatterns.length;
   5267             boolean allowed = false;
   5268             for (int i=0; i<N; i++) {
   5269                 if (pi.uriPermissionPatterns[i] != null
   5270                         && pi.uriPermissionPatterns[i].match(uri.getPath())) {
   5271                     allowed = true;
   5272                     break;
   5273                 }
   5274             }
   5275             if (!allowed) {
   5276                 throw new SecurityException("Provider " + pi.packageName
   5277                         + "/" + pi.name
   5278                         + " does not allow granting of permission to path of Uri "
   5279                         + uri);
   5280             }
   5281         }
   5282 
   5283         // Third...  does the caller itself have permission to access
   5284         // this uri?
   5285         if (callingUid != Process.myUid()) {
   5286             if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
   5287                 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
   5288                     throw new SecurityException("Uid " + callingUid
   5289                             + " does not have permission to uri " + uri);
   5290                 }
   5291             }
   5292         }
   5293 
   5294         return targetUid;
   5295     }
   5296 
   5297     public int checkGrantUriPermission(int callingUid, String targetPkg,
   5298             Uri uri, int modeFlags) {
   5299         enforceNotIsolatedCaller("checkGrantUriPermission");
   5300         synchronized(this) {
   5301             return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
   5302         }
   5303     }
   5304 
   5305     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
   5306             Uri uri, int modeFlags, UriPermissionOwner owner) {
   5307         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   5308                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   5309         if (modeFlags == 0) {
   5310             return;
   5311         }
   5312 
   5313         // So here we are: the caller has the assumed permission
   5314         // to the uri, and the target doesn't.  Let's now give this to
   5315         // the target.
   5316 
   5317         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5318                 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
   5319 
   5320         HashMap<Uri, UriPermission> targetUris
   5321                 = mGrantedUriPermissions.get(targetUid);
   5322         if (targetUris == null) {
   5323             targetUris = new HashMap<Uri, UriPermission>();
   5324             mGrantedUriPermissions.put(targetUid, targetUris);
   5325         }
   5326 
   5327         UriPermission perm = targetUris.get(uri);
   5328         if (perm == null) {
   5329             perm = new UriPermission(targetUid, uri);
   5330             targetUris.put(uri, perm);
   5331         }
   5332 
   5333         perm.modeFlags |= modeFlags;
   5334         if (owner == null) {
   5335             perm.globalModeFlags |= modeFlags;
   5336         } else {
   5337             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   5338                  perm.readOwners.add(owner);
   5339                  owner.addReadPermission(perm);
   5340             }
   5341             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   5342                  perm.writeOwners.add(owner);
   5343                  owner.addWritePermission(perm);
   5344             }
   5345         }
   5346     }
   5347 
   5348     void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
   5349             int modeFlags, UriPermissionOwner owner) {
   5350         if (targetPkg == null) {
   5351             throw new NullPointerException("targetPkg");
   5352         }
   5353 
   5354         int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
   5355         if (targetUid < 0) {
   5356             return;
   5357         }
   5358 
   5359         grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
   5360     }
   5361 
   5362     static class NeededUriGrants extends ArrayList<Uri> {
   5363         final String targetPkg;
   5364         final int targetUid;
   5365         final int flags;
   5366 
   5367         NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
   5368             targetPkg = _targetPkg;
   5369             targetUid = _targetUid;
   5370             flags = _flags;
   5371         }
   5372     }
   5373 
   5374     /**
   5375      * Like checkGrantUriPermissionLocked, but takes an Intent.
   5376      */
   5377     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
   5378             String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
   5379         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5380                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
   5381                 + " clip=" + (intent != null ? intent.getClipData() : null)
   5382                 + " from " + intent + "; flags=0x"
   5383                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
   5384 
   5385         if (targetPkg == null) {
   5386             throw new NullPointerException("targetPkg");
   5387         }
   5388 
   5389         if (intent == null) {
   5390             return null;
   5391         }
   5392         Uri data = intent.getData();
   5393         ClipData clip = intent.getClipData();
   5394         if (data == null && clip == null) {
   5395             return null;
   5396         }
   5397         if (data != null) {
   5398             int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
   5399                 mode, needed != null ? needed.targetUid : -1);
   5400             if (target > 0) {
   5401                 if (needed == null) {
   5402                     needed = new NeededUriGrants(targetPkg, target, mode);
   5403                 }
   5404                 needed.add(data);
   5405             }
   5406         }
   5407         if (clip != null) {
   5408             for (int i=0; i<clip.getItemCount(); i++) {
   5409                 Uri uri = clip.getItemAt(i).getUri();
   5410                 if (uri != null) {
   5411                     int target = -1;
   5412                     target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
   5413                             mode, needed != null ? needed.targetUid : -1);
   5414                     if (target > 0) {
   5415                         if (needed == null) {
   5416                             needed = new NeededUriGrants(targetPkg, target, mode);
   5417                         }
   5418                         needed.add(uri);
   5419                     }
   5420                 } else {
   5421                     Intent clipIntent = clip.getItemAt(i).getIntent();
   5422                     if (clipIntent != null) {
   5423                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
   5424                                 callingUid, targetPkg, clipIntent, mode, needed);
   5425                         if (newNeeded != null) {
   5426                             needed = newNeeded;
   5427                         }
   5428                     }
   5429                 }
   5430             }
   5431         }
   5432 
   5433         return needed;
   5434     }
   5435 
   5436     /**
   5437      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
   5438      */
   5439     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
   5440             UriPermissionOwner owner) {
   5441         if (needed != null) {
   5442             for (int i=0; i<needed.size(); i++) {
   5443                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
   5444                         needed.get(i), needed.flags, owner);
   5445             }
   5446         }
   5447     }
   5448 
   5449     void grantUriPermissionFromIntentLocked(int callingUid,
   5450             String targetPkg, Intent intent, UriPermissionOwner owner) {
   5451         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
   5452                 intent, intent != null ? intent.getFlags() : 0, null);
   5453         if (needed == null) {
   5454             return;
   5455         }
   5456 
   5457         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
   5458     }
   5459 
   5460     public void grantUriPermission(IApplicationThread caller, String targetPkg,
   5461             Uri uri, int modeFlags) {
   5462         enforceNotIsolatedCaller("grantUriPermission");
   5463         synchronized(this) {
   5464             final ProcessRecord r = getRecordForAppLocked(caller);
   5465             if (r == null) {
   5466                 throw new SecurityException("Unable to find app for caller "
   5467                         + caller
   5468                         + " when granting permission to uri " + uri);
   5469             }
   5470             if (targetPkg == null) {
   5471                 throw new IllegalArgumentException("null target");
   5472             }
   5473             if (uri == null) {
   5474                 throw new IllegalArgumentException("null uri");
   5475             }
   5476 
   5477             grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
   5478                     null);
   5479         }
   5480     }
   5481 
   5482     void removeUriPermissionIfNeededLocked(UriPermission perm) {
   5483         if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
   5484                 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
   5485             HashMap<Uri, UriPermission> perms
   5486                     = mGrantedUriPermissions.get(perm.uid);
   5487             if (perms != null) {
   5488                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5489                         "Removing " + perm.uid + " permission to " + perm.uri);
   5490                 perms.remove(perm.uri);
   5491                 if (perms.size() == 0) {
   5492                     mGrantedUriPermissions.remove(perm.uid);
   5493                 }
   5494             }
   5495         }
   5496     }
   5497 
   5498     private void revokeUriPermissionLocked(int callingUid, Uri uri,
   5499             int modeFlags) {
   5500         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   5501                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   5502         if (modeFlags == 0) {
   5503             return;
   5504         }
   5505 
   5506         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5507                 "Revoking all granted permissions to " + uri);
   5508 
   5509         final IPackageManager pm = AppGlobals.getPackageManager();
   5510 
   5511         final String authority = uri.getAuthority();
   5512         ProviderInfo pi = null;
   5513         int userId = UserHandle.getUserId(callingUid);
   5514         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
   5515         if (cpr != null) {
   5516             pi = cpr.info;
   5517         } else {
   5518             try {
   5519                 pi = pm.resolveContentProvider(authority,
   5520                         PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
   5521             } catch (RemoteException ex) {
   5522             }
   5523         }
   5524         if (pi == null) {
   5525             Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
   5526             return;
   5527         }
   5528 
   5529         // Does the caller have this permission on the URI?
   5530         if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
   5531             // Right now, if you are not the original owner of the permission,
   5532             // you are not allowed to revoke it.
   5533             //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
   5534                 throw new SecurityException("Uid " + callingUid
   5535                         + " does not have permission to uri " + uri);
   5536             //}
   5537         }
   5538 
   5539         // Go through all of the permissions and remove any that match.
   5540         final List<String> SEGMENTS = uri.getPathSegments();
   5541         if (SEGMENTS != null) {
   5542             final int NS = SEGMENTS.size();
   5543             int N = mGrantedUriPermissions.size();
   5544             for (int i=0; i<N; i++) {
   5545                 HashMap<Uri, UriPermission> perms
   5546                         = mGrantedUriPermissions.valueAt(i);
   5547                 Iterator<UriPermission> it = perms.values().iterator();
   5548             toploop:
   5549                 while (it.hasNext()) {
   5550                     UriPermission perm = it.next();
   5551                     Uri targetUri = perm.uri;
   5552                     if (!authority.equals(targetUri.getAuthority())) {
   5553                         continue;
   5554                     }
   5555                     List<String> targetSegments = targetUri.getPathSegments();
   5556                     if (targetSegments == null) {
   5557                         continue;
   5558                     }
   5559                     if (targetSegments.size() < NS) {
   5560                         continue;
   5561                     }
   5562                     for (int j=0; j<NS; j++) {
   5563                         if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
   5564                             continue toploop;
   5565                         }
   5566                     }
   5567                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5568                             "Revoking " + perm.uid + " permission to " + perm.uri);
   5569                     perm.clearModes(modeFlags);
   5570                     if (perm.modeFlags == 0) {
   5571                         it.remove();
   5572                     }
   5573                 }
   5574                 if (perms.size() == 0) {
   5575                     mGrantedUriPermissions.remove(
   5576                             mGrantedUriPermissions.keyAt(i));
   5577                     N--;
   5578                     i--;
   5579                 }
   5580             }
   5581         }
   5582     }
   5583 
   5584     public void revokeUriPermission(IApplicationThread caller, Uri uri,
   5585             int modeFlags) {
   5586         enforceNotIsolatedCaller("revokeUriPermission");
   5587         synchronized(this) {
   5588             final ProcessRecord r = getRecordForAppLocked(caller);
   5589             if (r == null) {
   5590                 throw new SecurityException("Unable to find app for caller "
   5591                         + caller
   5592                         + " when revoking permission to uri " + uri);
   5593             }
   5594             if (uri == null) {
   5595                 Slog.w(TAG, "revokeUriPermission: null uri");
   5596                 return;
   5597             }
   5598 
   5599             modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   5600                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   5601             if (modeFlags == 0) {
   5602                 return;
   5603             }
   5604 
   5605             final IPackageManager pm = AppGlobals.getPackageManager();
   5606 
   5607             final String authority = uri.getAuthority();
   5608             ProviderInfo pi = null;
   5609             ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
   5610             if (cpr != null) {
   5611                 pi = cpr.info;
   5612             } else {
   5613                 try {
   5614                     pi = pm.resolveContentProvider(authority,
   5615                             PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
   5616                 } catch (RemoteException ex) {
   5617                 }
   5618             }
   5619             if (pi == null) {
   5620                 Slog.w(TAG, "No content provider found for permission revoke: "
   5621                         + uri.toSafeString());
   5622                 return;
   5623             }
   5624 
   5625             revokeUriPermissionLocked(r.uid, uri, modeFlags);
   5626         }
   5627     }
   5628 
   5629     @Override
   5630     public IBinder newUriPermissionOwner(String name) {
   5631         enforceNotIsolatedCaller("newUriPermissionOwner");
   5632         synchronized(this) {
   5633             UriPermissionOwner owner = new UriPermissionOwner(this, name);
   5634             return owner.getExternalTokenLocked();
   5635         }
   5636     }
   5637 
   5638     @Override
   5639     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
   5640             Uri uri, int modeFlags) {
   5641         synchronized(this) {
   5642             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   5643             if (owner == null) {
   5644                 throw new IllegalArgumentException("Unknown owner: " + token);
   5645             }
   5646             if (fromUid != Binder.getCallingUid()) {
   5647                 if (Binder.getCallingUid() != Process.myUid()) {
   5648                     // Only system code can grant URI permissions on behalf
   5649                     // of other users.
   5650                     throw new SecurityException("nice try");
   5651                 }
   5652             }
   5653             if (targetPkg == null) {
   5654                 throw new IllegalArgumentException("null target");
   5655             }
   5656             if (uri == null) {
   5657                 throw new IllegalArgumentException("null uri");
   5658             }
   5659 
   5660             grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
   5661         }
   5662     }
   5663 
   5664     @Override
   5665     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
   5666         synchronized(this) {
   5667             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   5668             if (owner == null) {
   5669                 throw new IllegalArgumentException("Unknown owner: " + token);
   5670             }
   5671 
   5672             if (uri == null) {
   5673                 owner.removeUriPermissionsLocked(mode);
   5674             } else {
   5675                 owner.removeUriPermissionLocked(uri, mode);
   5676             }
   5677         }
   5678     }
   5679 
   5680     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
   5681         synchronized (this) {
   5682             ProcessRecord app =
   5683                 who != null ? getRecordForAppLocked(who) : null;
   5684             if (app == null) return;
   5685 
   5686             Message msg = Message.obtain();
   5687             msg.what = WAIT_FOR_DEBUGGER_MSG;
   5688             msg.obj = app;
   5689             msg.arg1 = waiting ? 1 : 0;
   5690             mHandler.sendMessage(msg);
   5691         }
   5692     }
   5693 
   5694     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
   5695         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
   5696         final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
   5697         outInfo.availMem = Process.getFreeMemory();
   5698         outInfo.totalMem = Process.getTotalMemory();
   5699         outInfo.threshold = homeAppMem;
   5700         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
   5701         outInfo.hiddenAppThreshold = hiddenAppMem;
   5702         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
   5703                 ProcessList.SERVICE_ADJ);
   5704         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
   5705                 ProcessList.VISIBLE_APP_ADJ);
   5706         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
   5707                 ProcessList.FOREGROUND_APP_ADJ);
   5708     }
   5709 
   5710     // =========================================================
   5711     // TASK MANAGEMENT
   5712     // =========================================================
   5713 
   5714     public List getTasks(int maxNum, int flags,
   5715                          IThumbnailReceiver receiver) {
   5716         ArrayList list = new ArrayList();
   5717 
   5718         PendingThumbnailsRecord pending = null;
   5719         IApplicationThread topThumbnail = null;
   5720         ActivityRecord topRecord = null;
   5721 
   5722         synchronized(this) {
   5723             if (localLOGV) Slog.v(
   5724                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
   5725                 + ", receiver=" + receiver);
   5726 
   5727             if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
   5728                     != PackageManager.PERMISSION_GRANTED) {
   5729                 if (receiver != null) {
   5730                     // If the caller wants to wait for pending thumbnails,
   5731                     // it ain't gonna get them.
   5732                     try {
   5733                         receiver.finished();
   5734                     } catch (RemoteException ex) {
   5735                     }
   5736                 }
   5737                 String msg = "Permission Denial: getTasks() from pid="
   5738                         + Binder.getCallingPid()
   5739                         + ", uid=" + Binder.getCallingUid()
   5740                         + " requires " + android.Manifest.permission.GET_TASKS;
   5741                 Slog.w(TAG, msg);
   5742                 throw new SecurityException(msg);
   5743             }
   5744 
   5745             int pos = mMainStack.mHistory.size()-1;
   5746             ActivityRecord next =
   5747                 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
   5748             ActivityRecord top = null;
   5749             TaskRecord curTask = null;
   5750             int numActivities = 0;
   5751             int numRunning = 0;
   5752             while (pos >= 0 && maxNum > 0) {
   5753                 final ActivityRecord r = next;
   5754                 pos--;
   5755                 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
   5756 
   5757                 // Initialize state for next task if needed.
   5758                 if (top == null ||
   5759                         (top.state == ActivityState.INITIALIZING
   5760                             && top.task == r.task)) {
   5761                     top = r;
   5762                     curTask = r.task;
   5763                     numActivities = numRunning = 0;
   5764                 }
   5765 
   5766                 // Add 'r' into the current task.
   5767                 numActivities++;
   5768                 if (r.app != null && r.app.thread != null) {
   5769                     numRunning++;
   5770                 }
   5771 
   5772                 if (localLOGV) Slog.v(
   5773                     TAG, r.intent.getComponent().flattenToShortString()
   5774                     + ": task=" + r.task);
   5775 
   5776                 // If the next one is a different task, generate a new
   5777                 // TaskInfo entry for what we have.
   5778                 if (next == null || next.task != curTask) {
   5779                     ActivityManager.RunningTaskInfo ci
   5780                             = new ActivityManager.RunningTaskInfo();
   5781                     ci.id = curTask.taskId;
   5782                     ci.baseActivity = r.intent.getComponent();
   5783                     ci.topActivity = top.intent.getComponent();
   5784                     if (top.thumbHolder != null) {
   5785                         ci.description = top.thumbHolder.lastDescription;
   5786                     }
   5787                     ci.numActivities = numActivities;
   5788                     ci.numRunning = numRunning;
   5789                     //System.out.println(
   5790                     //    "#" + maxNum + ": " + " descr=" + ci.description);
   5791                     if (ci.thumbnail == null && receiver != null) {
   5792                         if (localLOGV) Slog.v(
   5793                             TAG, "State=" + top.state + "Idle=" + top.idle
   5794                             + " app=" + top.app
   5795                             + " thr=" + (top.app != null ? top.app.thread : null));
   5796                         if (top.state == ActivityState.RESUMED
   5797                                 || top.state == ActivityState.PAUSING) {
   5798                             if (top.idle && top.app != null
   5799                                 && top.app.thread != null) {
   5800                                 topRecord = top;
   5801                                 topThumbnail = top.app.thread;
   5802                             } else {
   5803                                 top.thumbnailNeeded = true;
   5804                             }
   5805                         }
   5806                         if (pending == null) {
   5807                             pending = new PendingThumbnailsRecord(receiver);
   5808                         }
   5809                         pending.pendingRecords.add(top);
   5810                     }
   5811                     list.add(ci);
   5812                     maxNum--;
   5813                     top = null;
   5814                 }
   5815             }
   5816 
   5817             if (pending != null) {
   5818                 mPendingThumbnails.add(pending);
   5819             }
   5820         }
   5821 
   5822         if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
   5823 
   5824         if (topThumbnail != null) {
   5825             if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
   5826             try {
   5827                 topThumbnail.requestThumbnail(topRecord.appToken);
   5828             } catch (Exception e) {
   5829                 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
   5830                 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
   5831             }
   5832         }
   5833 
   5834         if (pending == null && receiver != null) {
   5835             // In this case all thumbnails were available and the client
   5836             // is being asked to be told when the remaining ones come in...
   5837             // which is unusually, since the top-most currently running
   5838             // activity should never have a canned thumbnail!  Oh well.
   5839             try {
   5840                 receiver.finished();
   5841             } catch (RemoteException ex) {
   5842             }
   5843         }
   5844 
   5845         return list;
   5846     }
   5847 
   5848     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
   5849             int flags, int userId) {
   5850         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   5851                 false, true, "getRecentTasks", null);
   5852 
   5853         synchronized (this) {
   5854             enforceCallingPermission(android.Manifest.permission.GET_TASKS,
   5855                     "getRecentTasks()");
   5856             final boolean detailed = checkCallingPermission(
   5857                     android.Manifest.permission.GET_DETAILED_TASKS)
   5858                     == PackageManager.PERMISSION_GRANTED;
   5859 
   5860             IPackageManager pm = AppGlobals.getPackageManager();
   5861 
   5862             final int N = mRecentTasks.size();
   5863             ArrayList<ActivityManager.RecentTaskInfo> res
   5864                     = new ArrayList<ActivityManager.RecentTaskInfo>(
   5865                             maxNum < N ? maxNum : N);
   5866             for (int i=0; i<N && maxNum > 0; i++) {
   5867                 TaskRecord tr = mRecentTasks.get(i);
   5868                 // Only add calling user's recent tasks
   5869                 if (tr.userId != userId) continue;
   5870                 // Return the entry if desired by the caller.  We always return
   5871                 // the first entry, because callers always expect this to be the
   5872                 // foreground app.  We may filter others if the caller has
   5873                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
   5874                 // we should exclude the entry.
   5875 
   5876                 if (i == 0
   5877                         || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
   5878                         || (tr.intent == null)
   5879                         || ((tr.intent.getFlags()
   5880                                 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
   5881                     ActivityManager.RecentTaskInfo rti
   5882                             = new ActivityManager.RecentTaskInfo();
   5883                     rti.id = tr.numActivities > 0 ? tr.taskId : -1;
   5884                     rti.persistentId = tr.taskId;
   5885                     rti.baseIntent = new Intent(
   5886                             tr.intent != null ? tr.intent : tr.affinityIntent);
   5887                     if (!detailed) {
   5888                         rti.baseIntent.replaceExtras((Bundle)null);
   5889                     }
   5890                     rti.origActivity = tr.origActivity;
   5891                     rti.description = tr.lastDescription;
   5892 
   5893                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
   5894                         // Check whether this activity is currently available.
   5895                         try {
   5896                             if (rti.origActivity != null) {
   5897                                 if (pm.getActivityInfo(rti.origActivity, 0, userId)
   5898                                         == null) {
   5899                                     continue;
   5900                                 }
   5901                             } else if (rti.baseIntent != null) {
   5902                                 if (pm.queryIntentActivities(rti.baseIntent,
   5903                                         null, 0, userId) == null) {
   5904                                     continue;
   5905                                 }
   5906                             }
   5907                         } catch (RemoteException e) {
   5908                             // Will never happen.
   5909                         }
   5910                     }
   5911 
   5912                     res.add(rti);
   5913                     maxNum--;
   5914                 }
   5915             }
   5916             return res;
   5917         }
   5918     }
   5919 
   5920     private TaskRecord taskForIdLocked(int id) {
   5921         final int N = mRecentTasks.size();
   5922         for (int i=0; i<N; i++) {
   5923             TaskRecord tr = mRecentTasks.get(i);
   5924             if (tr.taskId == id) {
   5925                 return tr;
   5926             }
   5927         }
   5928         return null;
   5929     }
   5930 
   5931     public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
   5932         synchronized (this) {
   5933             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
   5934                     "getTaskThumbnails()");
   5935             TaskRecord tr = taskForIdLocked(id);
   5936             if (tr != null) {
   5937                 return mMainStack.getTaskThumbnailsLocked(tr);
   5938             }
   5939         }
   5940         return null;
   5941     }
   5942 
   5943     public Bitmap getTaskTopThumbnail(int id) {
   5944         synchronized (this) {
   5945             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
   5946                     "getTaskTopThumbnail()");
   5947             TaskRecord tr = taskForIdLocked(id);
   5948             if (tr != null) {
   5949                 return mMainStack.getTaskTopThumbnailLocked(tr);
   5950             }
   5951         }
   5952         return null;
   5953     }
   5954 
   5955     public boolean removeSubTask(int taskId, int subTaskIndex) {
   5956         synchronized (this) {
   5957             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
   5958                     "removeSubTask()");
   5959             long ident = Binder.clearCallingIdentity();
   5960             try {
   5961                 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
   5962                         true) != null;
   5963             } finally {
   5964                 Binder.restoreCallingIdentity(ident);
   5965             }
   5966         }
   5967     }
   5968 
   5969     private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
   5970         final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
   5971         Intent baseIntent = new Intent(
   5972                 tr.intent != null ? tr.intent : tr.affinityIntent);
   5973         ComponentName component = baseIntent.getComponent();
   5974         if (component == null) {
   5975             Slog.w(TAG, "Now component for base intent of task: " + tr);
   5976             return;
   5977         }
   5978 
   5979         // Find any running services associated with this app.
   5980         mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
   5981 
   5982         if (killProcesses) {
   5983             // Find any running processes associated with this app.
   5984             final String pkg = component.getPackageName();
   5985             ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   5986             HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
   5987             for (SparseArray<ProcessRecord> uids : pmap.values()) {
   5988                 for (int i=0; i<uids.size(); i++) {
   5989                     ProcessRecord proc = uids.valueAt(i);
   5990                     if (proc.userId != tr.userId) {
   5991                         continue;
   5992                     }
   5993                     if (!proc.pkgList.contains(pkg)) {
   5994                         continue;
   5995                     }
   5996                     procs.add(proc);
   5997                 }
   5998             }
   5999 
   6000             // Kill the running processes.
   6001             for (int i=0; i<procs.size(); i++) {
   6002                 ProcessRecord pr = procs.get(i);
   6003                 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
   6004                     Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
   6005                     EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
   6006                             pr.processName, pr.setAdj, "remove task");
   6007                     pr.killedBackground = true;
   6008                     Process.killProcessQuiet(pr.pid);
   6009                 } else {
   6010                     pr.waitingToKill = "remove task";
   6011                 }
   6012             }
   6013         }
   6014     }
   6015 
   6016     public boolean removeTask(int taskId, int flags) {
   6017         synchronized (this) {
   6018             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
   6019                     "removeTask()");
   6020             long ident = Binder.clearCallingIdentity();
   6021             try {
   6022                 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
   6023                         false);
   6024                 if (r != null) {
   6025                     mRecentTasks.remove(r.task);
   6026                     cleanUpRemovedTaskLocked(r.task, flags);
   6027                     return true;
   6028                 } else {
   6029                     TaskRecord tr = null;
   6030                     int i=0;
   6031                     while (i < mRecentTasks.size()) {
   6032                         TaskRecord t = mRecentTasks.get(i);
   6033                         if (t.taskId == taskId) {
   6034                             tr = t;
   6035                             break;
   6036                         }
   6037                         i++;
   6038                     }
   6039                     if (tr != null) {
   6040                         if (tr.numActivities <= 0) {
   6041                             // Caller is just removing a recent task that is
   6042                             // not actively running.  That is easy!
   6043                             mRecentTasks.remove(i);
   6044                             cleanUpRemovedTaskLocked(tr, flags);
   6045                             return true;
   6046                         } else {
   6047                             Slog.w(TAG, "removeTask: task " + taskId
   6048                                     + " does not have activities to remove, "
   6049                                     + " but numActivities=" + tr.numActivities
   6050                                     + ": " + tr);
   6051                         }
   6052                     }
   6053                 }
   6054             } finally {
   6055                 Binder.restoreCallingIdentity(ident);
   6056             }
   6057         }
   6058         return false;
   6059     }
   6060 
   6061     private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
   6062         int j;
   6063         TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
   6064         TaskRecord jt = startTask;
   6065 
   6066         // First look backwards
   6067         for (j=startIndex-1; j>=0; j--) {
   6068             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
   6069             if (r.task != jt) {
   6070                 jt = r.task;
   6071                 if (affinity.equals(jt.affinity)) {
   6072                     return j;
   6073                 }
   6074             }
   6075         }
   6076 
   6077         // Now look forwards
   6078         final int N = mMainStack.mHistory.size();
   6079         jt = startTask;
   6080         for (j=startIndex+1; j<N; j++) {
   6081             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
   6082             if (r.task != jt) {
   6083                 if (affinity.equals(jt.affinity)) {
   6084                     return j;
   6085                 }
   6086                 jt = r.task;
   6087             }
   6088         }
   6089 
   6090         // Might it be at the top?
   6091         if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
   6092             return N-1;
   6093         }
   6094 
   6095         return -1;
   6096     }
   6097 
   6098     /**
   6099      * TODO: Add mController hook
   6100      */
   6101     public void moveTaskToFront(int task, int flags, Bundle options) {
   6102         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   6103                 "moveTaskToFront()");
   6104 
   6105         synchronized(this) {
   6106             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   6107                     Binder.getCallingUid(), "Task to front")) {
   6108                 ActivityOptions.abort(options);
   6109                 return;
   6110             }
   6111             final long origId = Binder.clearCallingIdentity();
   6112             try {
   6113                 TaskRecord tr = taskForIdLocked(task);
   6114                 if (tr != null) {
   6115                     if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
   6116                         mMainStack.mUserLeaving = true;
   6117                     }
   6118                     if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
   6119                         // Caller wants the home activity moved with it.  To accomplish this,
   6120                         // we'll just move the home task to the top first.
   6121                         mMainStack.moveHomeToFrontLocked();
   6122                     }
   6123                     mMainStack.moveTaskToFrontLocked(tr, null, options);
   6124                     return;
   6125                 }
   6126                 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
   6127                     ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
   6128                     if (hr.task.taskId == task) {
   6129                         if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
   6130                             mMainStack.mUserLeaving = true;
   6131                         }
   6132                         if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
   6133                             // Caller wants the home activity moved with it.  To accomplish this,
   6134                             // we'll just move the home task to the top first.
   6135                             mMainStack.moveHomeToFrontLocked();
   6136                         }
   6137                         mMainStack.moveTaskToFrontLocked(hr.task, null, options);
   6138                         return;
   6139                     }
   6140                 }
   6141             } finally {
   6142                 Binder.restoreCallingIdentity(origId);
   6143             }
   6144             ActivityOptions.abort(options);
   6145         }
   6146     }
   6147 
   6148     public void moveTaskToBack(int task) {
   6149         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   6150                 "moveTaskToBack()");
   6151 
   6152         synchronized(this) {
   6153             if (mMainStack.mResumedActivity != null
   6154                     && mMainStack.mResumedActivity.task.taskId == task) {
   6155                 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   6156                         Binder.getCallingUid(), "Task to back")) {
   6157                     return;
   6158                 }
   6159             }
   6160             final long origId = Binder.clearCallingIdentity();
   6161             mMainStack.moveTaskToBackLocked(task, null);
   6162             Binder.restoreCallingIdentity(origId);
   6163         }
   6164     }
   6165 
   6166     /**
   6167      * Moves an activity, and all of the other activities within the same task, to the bottom
   6168      * of the history stack.  The activity's order within the task is unchanged.
   6169      *
   6170      * @param token A reference to the activity we wish to move
   6171      * @param nonRoot If false then this only works if the activity is the root
   6172      *                of a task; if true it will work for any activity in a task.
   6173      * @return Returns true if the move completed, false if not.
   6174      */
   6175     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
   6176         enforceNotIsolatedCaller("moveActivityTaskToBack");
   6177         synchronized(this) {
   6178             final long origId = Binder.clearCallingIdentity();
   6179             int taskId = getTaskForActivityLocked(token, !nonRoot);
   6180             if (taskId >= 0) {
   6181                 return mMainStack.moveTaskToBackLocked(taskId, null);
   6182             }
   6183             Binder.restoreCallingIdentity(origId);
   6184         }
   6185         return false;
   6186     }
   6187 
   6188     public void moveTaskBackwards(int task) {
   6189         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   6190                 "moveTaskBackwards()");
   6191 
   6192         synchronized(this) {
   6193             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   6194                     Binder.getCallingUid(), "Task backwards")) {
   6195                 return;
   6196             }
   6197             final long origId = Binder.clearCallingIdentity();
   6198             moveTaskBackwardsLocked(task);
   6199             Binder.restoreCallingIdentity(origId);
   6200         }
   6201     }
   6202 
   6203     private final void moveTaskBackwardsLocked(int task) {
   6204         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
   6205     }
   6206 
   6207     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
   6208         synchronized(this) {
   6209             return getTaskForActivityLocked(token, onlyRoot);
   6210         }
   6211     }
   6212 
   6213     int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
   6214         final int N = mMainStack.mHistory.size();
   6215         TaskRecord lastTask = null;
   6216         for (int i=0; i<N; i++) {
   6217             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   6218             if (r.appToken == token) {
   6219                 if (!onlyRoot || lastTask != r.task) {
   6220                     return r.task.taskId;
   6221                 }
   6222                 return -1;
   6223             }
   6224             lastTask = r.task;
   6225         }
   6226 
   6227         return -1;
   6228     }
   6229 
   6230     // =========================================================
   6231     // THUMBNAILS
   6232     // =========================================================
   6233 
   6234     public void reportThumbnail(IBinder token,
   6235             Bitmap thumbnail, CharSequence description) {
   6236         //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
   6237         final long origId = Binder.clearCallingIdentity();
   6238         sendPendingThumbnail(null, token, thumbnail, description, true);
   6239         Binder.restoreCallingIdentity(origId);
   6240     }
   6241 
   6242     final void sendPendingThumbnail(ActivityRecord r, IBinder token,
   6243             Bitmap thumbnail, CharSequence description, boolean always) {
   6244         TaskRecord task = null;
   6245         ArrayList receivers = null;
   6246 
   6247         //System.out.println("Send pending thumbnail: " + r);
   6248 
   6249         synchronized(this) {
   6250             if (r == null) {
   6251                 r = mMainStack.isInStackLocked(token);
   6252                 if (r == null) {
   6253                     return;
   6254                 }
   6255             }
   6256             if (thumbnail == null && r.thumbHolder != null) {
   6257                 thumbnail = r.thumbHolder.lastThumbnail;
   6258                 description = r.thumbHolder.lastDescription;
   6259             }
   6260             if (thumbnail == null && !always) {
   6261                 // If there is no thumbnail, and this entry is not actually
   6262                 // going away, then abort for now and pick up the next
   6263                 // thumbnail we get.
   6264                 return;
   6265             }
   6266             task = r.task;
   6267 
   6268             int N = mPendingThumbnails.size();
   6269             int i=0;
   6270             while (i<N) {
   6271                 PendingThumbnailsRecord pr =
   6272                     (PendingThumbnailsRecord)mPendingThumbnails.get(i);
   6273                 //System.out.println("Looking in " + pr.pendingRecords);
   6274                 if (pr.pendingRecords.remove(r)) {
   6275                     if (receivers == null) {
   6276                         receivers = new ArrayList();
   6277                     }
   6278                     receivers.add(pr);
   6279                     if (pr.pendingRecords.size() == 0) {
   6280                         pr.finished = true;
   6281                         mPendingThumbnails.remove(i);
   6282                         N--;
   6283                         continue;
   6284                     }
   6285                 }
   6286                 i++;
   6287             }
   6288         }
   6289 
   6290         if (receivers != null) {
   6291             final int N = receivers.size();
   6292             for (int i=0; i<N; i++) {
   6293                 try {
   6294                     PendingThumbnailsRecord pr =
   6295                         (PendingThumbnailsRecord)receivers.get(i);
   6296                     pr.receiver.newThumbnail(
   6297                         task != null ? task.taskId : -1, thumbnail, description);
   6298                     if (pr.finished) {
   6299                         pr.receiver.finished();
   6300                     }
   6301                 } catch (Exception e) {
   6302                     Slog.w(TAG, "Exception thrown when sending thumbnail", e);
   6303                 }
   6304             }
   6305         }
   6306     }
   6307 
   6308     // =========================================================
   6309     // CONTENT PROVIDERS
   6310     // =========================================================
   6311 
   6312     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
   6313         List<ProviderInfo> providers = null;
   6314         try {
   6315             providers = AppGlobals.getPackageManager().
   6316                 queryContentProviders(app.processName, app.uid,
   6317                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
   6318         } catch (RemoteException ex) {
   6319         }
   6320         if (DEBUG_MU)
   6321             Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
   6322         int userId = app.userId;
   6323         if (providers != null) {
   6324             int N = providers.size();
   6325             for (int i=0; i<N; i++) {
   6326                 ProviderInfo cpi =
   6327                     (ProviderInfo)providers.get(i);
   6328                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
   6329                         cpi.name, cpi.flags);
   6330                 if (singleton && UserHandle.getUserId(app.uid) != 0) {
   6331                     // This is a singleton provider, but a user besides the
   6332                     // default user is asking to initialize a process it runs
   6333                     // in...  well, no, it doesn't actually run in this process,
   6334                     // it runs in the process of the default user.  Get rid of it.
   6335                     providers.remove(i);
   6336                     N--;
   6337                     continue;
   6338                 }
   6339 
   6340                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   6341                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
   6342                 if (cpr == null) {
   6343                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
   6344                     mProviderMap.putProviderByClass(comp, cpr);
   6345                 }
   6346                 if (DEBUG_MU)
   6347                     Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
   6348                 app.pubProviders.put(cpi.name, cpr);
   6349                 app.addPackage(cpi.applicationInfo.packageName);
   6350                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
   6351             }
   6352         }
   6353         return providers;
   6354     }
   6355 
   6356     /**
   6357      * Check if {@link ProcessRecord} has a possible chance at accessing the
   6358      * given {@link ProviderInfo}. Final permission checking is always done
   6359      * in {@link ContentProvider}.
   6360      */
   6361     private final String checkContentProviderPermissionLocked(
   6362             ProviderInfo cpi, ProcessRecord r) {
   6363         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
   6364         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
   6365         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
   6366                 cpi.applicationInfo.uid, cpi.exported)
   6367                 == PackageManager.PERMISSION_GRANTED) {
   6368             return null;
   6369         }
   6370         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
   6371                 cpi.applicationInfo.uid, cpi.exported)
   6372                 == PackageManager.PERMISSION_GRANTED) {
   6373             return null;
   6374         }
   6375 
   6376         PathPermission[] pps = cpi.pathPermissions;
   6377         if (pps != null) {
   6378             int i = pps.length;
   6379             while (i > 0) {
   6380                 i--;
   6381                 PathPermission pp = pps[i];
   6382                 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
   6383                         cpi.applicationInfo.uid, cpi.exported)
   6384                         == PackageManager.PERMISSION_GRANTED) {
   6385                     return null;
   6386                 }
   6387                 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
   6388                         cpi.applicationInfo.uid, cpi.exported)
   6389                         == PackageManager.PERMISSION_GRANTED) {
   6390                     return null;
   6391                 }
   6392             }
   6393         }
   6394 
   6395         HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   6396         if (perms != null) {
   6397             for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
   6398                 if (uri.getKey().getAuthority().equals(cpi.authority)) {
   6399                     return null;
   6400                 }
   6401             }
   6402         }
   6403 
   6404         String msg;
   6405         if (!cpi.exported) {
   6406             msg = "Permission Denial: opening provider " + cpi.name
   6407                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   6408                     + ", uid=" + callingUid + ") that is not exported from uid "
   6409                     + cpi.applicationInfo.uid;
   6410         } else {
   6411             msg = "Permission Denial: opening provider " + cpi.name
   6412                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   6413                     + ", uid=" + callingUid + ") requires "
   6414                     + cpi.readPermission + " or " + cpi.writePermission;
   6415         }
   6416         Slog.w(TAG, msg);
   6417         return msg;
   6418     }
   6419 
   6420     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
   6421             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   6422         if (r != null) {
   6423             for (int i=0; i<r.conProviders.size(); i++) {
   6424                 ContentProviderConnection conn = r.conProviders.get(i);
   6425                 if (conn.provider == cpr) {
   6426                     if (DEBUG_PROVIDER) Slog.v(TAG,
   6427                             "Adding provider requested by "
   6428                             + r.processName + " from process "
   6429                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   6430                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   6431                     if (stable) {
   6432                         conn.stableCount++;
   6433                         conn.numStableIncs++;
   6434                     } else {
   6435                         conn.unstableCount++;
   6436                         conn.numUnstableIncs++;
   6437                     }
   6438                     return conn;
   6439                 }
   6440             }
   6441             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
   6442             if (stable) {
   6443                 conn.stableCount = 1;
   6444                 conn.numStableIncs = 1;
   6445             } else {
   6446                 conn.unstableCount = 1;
   6447                 conn.numUnstableIncs = 1;
   6448             }
   6449             cpr.connections.add(conn);
   6450             r.conProviders.add(conn);
   6451             return conn;
   6452         }
   6453         cpr.addExternalProcessHandleLocked(externalProcessToken);
   6454         return null;
   6455     }
   6456 
   6457     boolean decProviderCountLocked(ContentProviderConnection conn,
   6458             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   6459         if (conn != null) {
   6460             cpr = conn.provider;
   6461             if (DEBUG_PROVIDER) Slog.v(TAG,
   6462                     "Removing provider requested by "
   6463                     + conn.client.processName + " from process "
   6464                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   6465                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   6466             if (stable) {
   6467                 conn.stableCount--;
   6468             } else {
   6469                 conn.unstableCount--;
   6470             }
   6471             if (conn.stableCount == 0 && conn.unstableCount == 0) {
   6472                 cpr.connections.remove(conn);
   6473                 conn.client.conProviders.remove(conn);
   6474                 return true;
   6475             }
   6476             return false;
   6477         }
   6478         cpr.removeExternalProcessHandleLocked(externalProcessToken);
   6479         return false;
   6480     }
   6481 
   6482     private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
   6483             String name, IBinder token, boolean stable, int userId) {
   6484         ContentProviderRecord cpr;
   6485         ContentProviderConnection conn = null;
   6486         ProviderInfo cpi = null;
   6487 
   6488         synchronized(this) {
   6489             ProcessRecord r = null;
   6490             if (caller != null) {
   6491                 r = getRecordForAppLocked(caller);
   6492                 if (r == null) {
   6493                     throw new SecurityException(
   6494                             "Unable to find app for caller " + caller
   6495                           + " (pid=" + Binder.getCallingPid()
   6496                           + ") when getting content provider " + name);
   6497                 }
   6498             }
   6499 
   6500             // First check if this content provider has been published...
   6501             cpr = mProviderMap.getProviderByName(name, userId);
   6502             boolean providerRunning = cpr != null;
   6503             if (providerRunning) {
   6504                 cpi = cpr.info;
   6505                 String msg;
   6506                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
   6507                     throw new SecurityException(msg);
   6508                 }
   6509 
   6510                 if (r != null && cpr.canRunHere(r)) {
   6511                     // This provider has been published or is in the process
   6512                     // of being published...  but it is also allowed to run
   6513                     // in the caller's process, so don't make a connection
   6514                     // and just let the caller instantiate its own instance.
   6515                     ContentProviderHolder holder = cpr.newHolder(null);
   6516                     // don't give caller the provider object, it needs
   6517                     // to make its own.
   6518                     holder.provider = null;
   6519                     return holder;
   6520                 }
   6521 
   6522                 final long origId = Binder.clearCallingIdentity();
   6523 
   6524                 // In this case the provider instance already exists, so we can
   6525                 // return it right away.
   6526                 conn = incProviderCountLocked(r, cpr, token, stable);
   6527                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
   6528                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   6529                         // If this is a perceptible app accessing the provider,
   6530                         // make sure to count it as being accessed and thus
   6531                         // back up on the LRU list.  This is good because
   6532                         // content providers are often expensive to start.
   6533                         updateLruProcessLocked(cpr.proc, false);
   6534                     }
   6535                 }
   6536 
   6537                 if (cpr.proc != null) {
   6538                     if (false) {
   6539                         if (cpr.name.flattenToShortString().equals(
   6540                                 "com.android.providers.calendar/.CalendarProvider2")) {
   6541                             Slog.v(TAG, "****************** KILLING "
   6542                                 + cpr.name.flattenToShortString());
   6543                             Process.killProcess(cpr.proc.pid);
   6544                         }
   6545                     }
   6546                     boolean success = updateOomAdjLocked(cpr.proc);
   6547                     if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
   6548                     // NOTE: there is still a race here where a signal could be
   6549                     // pending on the process even though we managed to update its
   6550                     // adj level.  Not sure what to do about this, but at least
   6551                     // the race is now smaller.
   6552                     if (!success) {
   6553                         // Uh oh...  it looks like the provider's process
   6554                         // has been killed on us.  We need to wait for a new
   6555                         // process to be started, and make sure its death
   6556                         // doesn't kill our process.
   6557                         Slog.i(TAG,
   6558                                 "Existing provider " + cpr.name.flattenToShortString()
   6559                                 + " is crashing; detaching " + r);
   6560                         boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
   6561                         appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
   6562                         if (!lastRef) {
   6563                             // This wasn't the last ref our process had on
   6564                             // the provider...  we have now been killed, bail.
   6565                             return null;
   6566                         }
   6567                         providerRunning = false;
   6568                         conn = null;
   6569                     }
   6570                 }
   6571 
   6572                 Binder.restoreCallingIdentity(origId);
   6573             }
   6574 
   6575             boolean singleton;
   6576             if (!providerRunning) {
   6577                 try {
   6578                     cpi = AppGlobals.getPackageManager().
   6579                         resolveContentProvider(name,
   6580                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
   6581                 } catch (RemoteException ex) {
   6582                 }
   6583                 if (cpi == null) {
   6584                     return null;
   6585                 }
   6586                 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
   6587                         cpi.name, cpi.flags);
   6588                 if (singleton) {
   6589                     userId = 0;
   6590                 }
   6591                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
   6592 
   6593                 String msg;
   6594                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
   6595                     throw new SecurityException(msg);
   6596                 }
   6597 
   6598                 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
   6599                         && !cpi.processName.equals("system")) {
   6600                     // If this content provider does not run in the system
   6601                     // process, and the system is not yet ready to run other
   6602                     // processes, then fail fast instead of hanging.
   6603                     throw new IllegalArgumentException(
   6604                             "Attempt to launch content provider before system ready");
   6605                 }
   6606 
   6607                 // Make sure that the user who owns this provider is started.  If not,
   6608                 // we don't want to allow it to run.
   6609                 if (mStartedUsers.get(userId) == null) {
   6610                     Slog.w(TAG, "Unable to launch app "
   6611                             + cpi.applicationInfo.packageName + "/"
   6612                             + cpi.applicationInfo.uid + " for provider "
   6613                             + name + ": user " + userId + " is stopped");
   6614                     return null;
   6615                 }
   6616 
   6617                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   6618                 cpr = mProviderMap.getProviderByClass(comp, userId);
   6619                 final boolean firstClass = cpr == null;
   6620                 if (firstClass) {
   6621                     try {
   6622                         ApplicationInfo ai =
   6623                             AppGlobals.getPackageManager().
   6624                                 getApplicationInfo(
   6625                                         cpi.applicationInfo.packageName,
   6626                                         STOCK_PM_FLAGS, userId);
   6627                         if (ai == null) {
   6628                             Slog.w(TAG, "No package info for content provider "
   6629                                     + cpi.name);
   6630                             return null;
   6631                         }
   6632                         ai = getAppInfoForUser(ai, userId);
   6633                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
   6634                     } catch (RemoteException ex) {
   6635                         // pm is in same process, this will never happen.
   6636                     }
   6637                 }
   6638 
   6639                 if (r != null && cpr.canRunHere(r)) {
   6640                     // If this is a multiprocess provider, then just return its
   6641                     // info and allow the caller to instantiate it.  Only do
   6642                     // this if the provider is the same user as the caller's
   6643                     // process, or can run as root (so can be in any process).
   6644                     return cpr.newHolder(null);
   6645                 }
   6646 
   6647                 if (DEBUG_PROVIDER) {
   6648                     RuntimeException e = new RuntimeException("here");
   6649                     Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
   6650                           + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
   6651                 }
   6652 
   6653                 // This is single process, and our app is now connecting to it.
   6654                 // See if we are already in the process of launching this
   6655                 // provider.
   6656                 final int N = mLaunchingProviders.size();
   6657                 int i;
   6658                 for (i=0; i<N; i++) {
   6659                     if (mLaunchingProviders.get(i) == cpr) {
   6660                         break;
   6661                     }
   6662                 }
   6663 
   6664                 // If the provider is not already being launched, then get it
   6665                 // started.
   6666                 if (i >= N) {
   6667                     final long origId = Binder.clearCallingIdentity();
   6668 
   6669                     try {
   6670                         // Content provider is now in use, its package can't be stopped.
   6671                         try {
   6672                             AppGlobals.getPackageManager().setPackageStoppedState(
   6673                                     cpr.appInfo.packageName, false, userId);
   6674                         } catch (RemoteException e) {
   6675                         } catch (IllegalArgumentException e) {
   6676                             Slog.w(TAG, "Failed trying to unstop package "
   6677                                     + cpr.appInfo.packageName + ": " + e);
   6678                         }
   6679 
   6680                         ProcessRecord proc = startProcessLocked(cpi.processName,
   6681                                 cpr.appInfo, false, 0, "content provider",
   6682                                 new ComponentName(cpi.applicationInfo.packageName,
   6683                                         cpi.name), false, false);
   6684                         if (proc == null) {
   6685                             Slog.w(TAG, "Unable to launch app "
   6686                                     + cpi.applicationInfo.packageName + "/"
   6687                                     + cpi.applicationInfo.uid + " for provider "
   6688                                     + name + ": process is bad");
   6689                             return null;
   6690                         }
   6691                         cpr.launchingApp = proc;
   6692                         mLaunchingProviders.add(cpr);
   6693                     } finally {
   6694                         Binder.restoreCallingIdentity(origId);
   6695                     }
   6696                 }
   6697 
   6698                 // Make sure the provider is published (the same provider class
   6699                 // may be published under multiple names).
   6700                 if (firstClass) {
   6701                     mProviderMap.putProviderByClass(comp, cpr);
   6702                 }
   6703 
   6704                 mProviderMap.putProviderByName(name, cpr);
   6705                 conn = incProviderCountLocked(r, cpr, token, stable);
   6706                 if (conn != null) {
   6707                     conn.waiting = true;
   6708                 }
   6709             }
   6710         }
   6711 
   6712         // Wait for the provider to be published...
   6713         synchronized (cpr) {
   6714             while (cpr.provider == null) {
   6715                 if (cpr.launchingApp == null) {
   6716                     Slog.w(TAG, "Unable to launch app "
   6717                             + cpi.applicationInfo.packageName + "/"
   6718                             + cpi.applicationInfo.uid + " for provider "
   6719                             + name + ": launching app became null");
   6720                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
   6721                             UserHandle.getUserId(cpi.applicationInfo.uid),
   6722                             cpi.applicationInfo.packageName,
   6723                             cpi.applicationInfo.uid, name);
   6724                     return null;
   6725                 }
   6726                 try {
   6727                     if (DEBUG_MU) {
   6728                         Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
   6729                                 + cpr.launchingApp);
   6730                     }
   6731                     if (conn != null) {
   6732                         conn.waiting = true;
   6733                     }
   6734                     cpr.wait();
   6735                 } catch (InterruptedException ex) {
   6736                 } finally {
   6737                     if (conn != null) {
   6738                         conn.waiting = false;
   6739                     }
   6740                 }
   6741             }
   6742         }
   6743         return cpr != null ? cpr.newHolder(conn) : null;
   6744     }
   6745 
   6746     public final ContentProviderHolder getContentProvider(
   6747             IApplicationThread caller, String name, int userId, boolean stable) {
   6748         enforceNotIsolatedCaller("getContentProvider");
   6749         if (caller == null) {
   6750             String msg = "null IApplicationThread when getting content provider "
   6751                     + name;
   6752             Slog.w(TAG, msg);
   6753             throw new SecurityException(msg);
   6754         }
   6755 
   6756         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   6757                 false, true, "getContentProvider", null);
   6758         return getContentProviderImpl(caller, name, null, stable, userId);
   6759     }
   6760 
   6761     public ContentProviderHolder getContentProviderExternal(
   6762             String name, int userId, IBinder token) {
   6763         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   6764             "Do not have permission in call getContentProviderExternal()");
   6765         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   6766                 false, true, "getContentProvider", null);
   6767         return getContentProviderExternalUnchecked(name, token, userId);
   6768     }
   6769 
   6770     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
   6771             IBinder token, int userId) {
   6772         return getContentProviderImpl(null, name, token, true, userId);
   6773     }
   6774 
   6775     /**
   6776      * Drop a content provider from a ProcessRecord's bookkeeping
   6777      */
   6778     public void removeContentProvider(IBinder connection, boolean stable) {
   6779         enforceNotIsolatedCaller("removeContentProvider");
   6780         synchronized (this) {
   6781             ContentProviderConnection conn;
   6782             try {
   6783                 conn = (ContentProviderConnection)connection;
   6784             } catch (ClassCastException e) {
   6785                 String msg ="removeContentProvider: " + connection
   6786                         + " not a ContentProviderConnection";
   6787                 Slog.w(TAG, msg);
   6788                 throw new IllegalArgumentException(msg);
   6789             }
   6790             if (conn == null) {
   6791                 throw new NullPointerException("connection is null");
   6792             }
   6793             if (decProviderCountLocked(conn, null, null, stable)) {
   6794                 updateOomAdjLocked();
   6795             }
   6796         }
   6797     }
   6798 
   6799     public void removeContentProviderExternal(String name, IBinder token) {
   6800         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   6801             "Do not have permission in call removeContentProviderExternal()");
   6802         removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
   6803     }
   6804 
   6805     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
   6806         synchronized (this) {
   6807             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
   6808             if(cpr == null) {
   6809                 //remove from mProvidersByClass
   6810                 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
   6811                 return;
   6812             }
   6813 
   6814             //update content provider record entry info
   6815             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
   6816             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
   6817             if (localCpr.hasExternalProcessHandles()) {
   6818                 if (localCpr.removeExternalProcessHandleLocked(token)) {
   6819                     updateOomAdjLocked();
   6820                 } else {
   6821                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
   6822                             + " with no external reference for token: "
   6823                             + token + ".");
   6824                 }
   6825             } else {
   6826                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
   6827                         + " with no external references.");
   6828             }
   6829         }
   6830     }
   6831 
   6832     public final void publishContentProviders(IApplicationThread caller,
   6833             List<ContentProviderHolder> providers) {
   6834         if (providers == null) {
   6835             return;
   6836         }
   6837 
   6838         enforceNotIsolatedCaller("publishContentProviders");
   6839         synchronized (this) {
   6840             final ProcessRecord r = getRecordForAppLocked(caller);
   6841             if (DEBUG_MU)
   6842                 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
   6843             if (r == null) {
   6844                 throw new SecurityException(
   6845                         "Unable to find app for caller " + caller
   6846                       + " (pid=" + Binder.getCallingPid()
   6847                       + ") when publishing content providers");
   6848             }
   6849 
   6850             final long origId = Binder.clearCallingIdentity();
   6851 
   6852             final int N = providers.size();
   6853             for (int i=0; i<N; i++) {
   6854                 ContentProviderHolder src = providers.get(i);
   6855                 if (src == null || src.info == null || src.provider == null) {
   6856                     continue;
   6857                 }
   6858                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
   6859                 if (DEBUG_MU)
   6860                     Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
   6861                 if (dst != null) {
   6862                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
   6863                     mProviderMap.putProviderByClass(comp, dst);
   6864                     String names[] = dst.info.authority.split(";");
   6865                     for (int j = 0; j < names.length; j++) {
   6866                         mProviderMap.putProviderByName(names[j], dst);
   6867                     }
   6868 
   6869                     int NL = mLaunchingProviders.size();
   6870                     int j;
   6871                     for (j=0; j<NL; j++) {
   6872                         if (mLaunchingProviders.get(j) == dst) {
   6873                             mLaunchingProviders.remove(j);
   6874                             j--;
   6875                             NL--;
   6876                         }
   6877                     }
   6878                     synchronized (dst) {
   6879                         dst.provider = src.provider;
   6880                         dst.proc = r;
   6881                         dst.notifyAll();
   6882                     }
   6883                     updateOomAdjLocked(r);
   6884                 }
   6885             }
   6886 
   6887             Binder.restoreCallingIdentity(origId);
   6888         }
   6889     }
   6890 
   6891     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
   6892         ContentProviderConnection conn;
   6893         try {
   6894             conn = (ContentProviderConnection)connection;
   6895         } catch (ClassCastException e) {
   6896             String msg ="refContentProvider: " + connection
   6897                     + " not a ContentProviderConnection";
   6898             Slog.w(TAG, msg);
   6899             throw new IllegalArgumentException(msg);
   6900         }
   6901         if (conn == null) {
   6902             throw new NullPointerException("connection is null");
   6903         }
   6904 
   6905         synchronized (this) {
   6906             if (stable > 0) {
   6907                 conn.numStableIncs += stable;
   6908             }
   6909             stable = conn.stableCount + stable;
   6910             if (stable < 0) {
   6911                 throw new IllegalStateException("stableCount < 0: " + stable);
   6912             }
   6913 
   6914             if (unstable > 0) {
   6915                 conn.numUnstableIncs += unstable;
   6916             }
   6917             unstable = conn.unstableCount + unstable;
   6918             if (unstable < 0) {
   6919                 throw new IllegalStateException("unstableCount < 0: " + unstable);
   6920             }
   6921 
   6922             if ((stable+unstable) <= 0) {
   6923                 throw new IllegalStateException("ref counts can't go to zero here: stable="
   6924                         + stable + " unstable=" + unstable);
   6925             }
   6926             conn.stableCount = stable;
   6927             conn.unstableCount = unstable;
   6928             return !conn.dead;
   6929         }
   6930     }
   6931 
   6932     public void unstableProviderDied(IBinder connection) {
   6933         ContentProviderConnection conn;
   6934         try {
   6935             conn = (ContentProviderConnection)connection;
   6936         } catch (ClassCastException e) {
   6937             String msg ="refContentProvider: " + connection
   6938                     + " not a ContentProviderConnection";
   6939             Slog.w(TAG, msg);
   6940             throw new IllegalArgumentException(msg);
   6941         }
   6942         if (conn == null) {
   6943             throw new NullPointerException("connection is null");
   6944         }
   6945 
   6946         // Safely retrieve the content provider associated with the connection.
   6947         IContentProvider provider;
   6948         synchronized (this) {
   6949             provider = conn.provider.provider;
   6950         }
   6951 
   6952         if (provider == null) {
   6953             // Um, yeah, we're way ahead of you.
   6954             return;
   6955         }
   6956 
   6957         // Make sure the caller is being honest with us.
   6958         if (provider.asBinder().pingBinder()) {
   6959             // Er, no, still looks good to us.
   6960             synchronized (this) {
   6961                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
   6962                         + " says " + conn + " died, but we don't agree");
   6963                 return;
   6964             }
   6965         }
   6966 
   6967         // Well look at that!  It's dead!
   6968         synchronized (this) {
   6969             if (conn.provider.provider != provider) {
   6970                 // But something changed...  good enough.
   6971                 return;
   6972             }
   6973 
   6974             ProcessRecord proc = conn.provider.proc;
   6975             if (proc == null || proc.thread == null) {
   6976                 // Seems like the process is already cleaned up.
   6977                 return;
   6978             }
   6979 
   6980             // As far as we're concerned, this is just like receiving a
   6981             // death notification...  just a bit prematurely.
   6982             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
   6983                     + ") early provider death");
   6984             final long ident = Binder.clearCallingIdentity();
   6985             try {
   6986                 appDiedLocked(proc, proc.pid, proc.thread);
   6987             } finally {
   6988                 Binder.restoreCallingIdentity(ident);
   6989             }
   6990         }
   6991     }
   6992 
   6993     public static final void installSystemProviders() {
   6994         List<ProviderInfo> providers;
   6995         synchronized (mSelf) {
   6996             ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
   6997             providers = mSelf.generateApplicationProvidersLocked(app);
   6998             if (providers != null) {
   6999                 for (int i=providers.size()-1; i>=0; i--) {
   7000                     ProviderInfo pi = (ProviderInfo)providers.get(i);
   7001                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   7002                         Slog.w(TAG, "Not installing system proc provider " + pi.name
   7003                                 + ": not system .apk");
   7004                         providers.remove(i);
   7005                     }
   7006                 }
   7007             }
   7008         }
   7009         if (providers != null) {
   7010             mSystemThread.installSystemProviders(providers);
   7011         }
   7012 
   7013         mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
   7014 
   7015         mSelf.mUsageStatsService.monitorPackages();
   7016     }
   7017 
   7018     /**
   7019      * Allows app to retrieve the MIME type of a URI without having permission
   7020      * to access its content provider.
   7021      *
   7022      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
   7023      *
   7024      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
   7025      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
   7026      */
   7027     public String getProviderMimeType(Uri uri, int userId) {
   7028         enforceNotIsolatedCaller("getProviderMimeType");
   7029         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   7030                 userId, false, true, "getProviderMimeType", null);
   7031         final String name = uri.getAuthority();
   7032         final long ident = Binder.clearCallingIdentity();
   7033         ContentProviderHolder holder = null;
   7034 
   7035         try {
   7036             holder = getContentProviderExternalUnchecked(name, null, userId);
   7037             if (holder != null) {
   7038                 return holder.provider.getType(uri);
   7039             }
   7040         } catch (RemoteException e) {
   7041             Log.w(TAG, "Content provider dead retrieving " + uri, e);
   7042             return null;
   7043         } finally {
   7044             if (holder != null) {
   7045                 removeContentProviderExternalUnchecked(name, null, userId);
   7046             }
   7047             Binder.restoreCallingIdentity(ident);
   7048         }
   7049 
   7050         return null;
   7051     }
   7052 
   7053     // =========================================================
   7054     // GLOBAL MANAGEMENT
   7055     // =========================================================
   7056 
   7057     final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
   7058             ApplicationInfo info, String customProcess, boolean isolated) {
   7059         String proc = customProcess != null ? customProcess : info.processName;
   7060         BatteryStatsImpl.Uid.Proc ps = null;
   7061         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   7062         int uid = info.uid;
   7063         if (isolated) {
   7064             int userId = UserHandle.getUserId(uid);
   7065             int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
   7066             uid = 0;
   7067             while (true) {
   7068                 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
   7069                         || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
   7070                     mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
   7071                 }
   7072                 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
   7073                 mNextIsolatedProcessUid++;
   7074                 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
   7075                     // No process for this uid, use it.
   7076                     break;
   7077                 }
   7078                 stepsLeft--;
   7079                 if (stepsLeft <= 0) {
   7080                     return null;
   7081                 }
   7082             }
   7083         }
   7084         synchronized (stats) {
   7085             ps = stats.getProcessStatsLocked(info.uid, proc);
   7086         }
   7087         return new ProcessRecord(ps, thread, info, proc, uid);
   7088     }
   7089 
   7090     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
   7091         ProcessRecord app;
   7092         if (!isolated) {
   7093             app = getProcessRecordLocked(info.processName, info.uid);
   7094         } else {
   7095             app = null;
   7096         }
   7097 
   7098         if (app == null) {
   7099             app = newProcessRecordLocked(null, info, null, isolated);
   7100             mProcessNames.put(info.processName, app.uid, app);
   7101             if (isolated) {
   7102                 mIsolatedProcesses.put(app.uid, app);
   7103             }
   7104             updateLruProcessLocked(app, true);
   7105         }
   7106 
   7107         // This package really, really can not be stopped.
   7108         try {
   7109             AppGlobals.getPackageManager().setPackageStoppedState(
   7110                     info.packageName, false, UserHandle.getUserId(app.uid));
   7111         } catch (RemoteException e) {
   7112         } catch (IllegalArgumentException e) {
   7113             Slog.w(TAG, "Failed trying to unstop package "
   7114                     + info.packageName + ": " + e);
   7115         }
   7116 
   7117         if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
   7118                 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
   7119             app.persistent = true;
   7120             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
   7121         }
   7122         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
   7123             mPersistentStartingProcesses.add(app);
   7124             startProcessLocked(app, "added application", app.processName);
   7125         }
   7126 
   7127         return app;
   7128     }
   7129 
   7130     public void unhandledBack() {
   7131         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
   7132                 "unhandledBack()");
   7133 
   7134         synchronized(this) {
   7135             int count = mMainStack.mHistory.size();
   7136             if (DEBUG_SWITCH) Slog.d(
   7137                 TAG, "Performing unhandledBack(): stack size = " + count);
   7138             if (count > 1) {
   7139                 final long origId = Binder.clearCallingIdentity();
   7140                 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
   7141                         count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
   7142                 Binder.restoreCallingIdentity(origId);
   7143             }
   7144         }
   7145     }
   7146 
   7147     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
   7148         enforceNotIsolatedCaller("openContentUri");
   7149         final int userId = UserHandle.getCallingUserId();
   7150         String name = uri.getAuthority();
   7151         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
   7152         ParcelFileDescriptor pfd = null;
   7153         if (cph != null) {
   7154             // We record the binder invoker's uid in thread-local storage before
   7155             // going to the content provider to open the file.  Later, in the code
   7156             // that handles all permissions checks, we look for this uid and use
   7157             // that rather than the Activity Manager's own uid.  The effect is that
   7158             // we do the check against the caller's permissions even though it looks
   7159             // to the content provider like the Activity Manager itself is making
   7160             // the request.
   7161             sCallerIdentity.set(new Identity(
   7162                     Binder.getCallingPid(), Binder.getCallingUid()));
   7163             try {
   7164                 pfd = cph.provider.openFile(null, uri, "r");
   7165             } catch (FileNotFoundException e) {
   7166                 // do nothing; pfd will be returned null
   7167             } finally {
   7168                 // Ensure that whatever happens, we clean up the identity state
   7169                 sCallerIdentity.remove();
   7170             }
   7171 
   7172             // We've got the fd now, so we're done with the provider.
   7173             removeContentProviderExternalUnchecked(name, null, userId);
   7174         } else {
   7175             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
   7176         }
   7177         return pfd;
   7178     }
   7179 
   7180     // Actually is sleeping or shutting down or whatever else in the future
   7181     // is an inactive state.
   7182     public boolean isSleeping() {
   7183         return mSleeping || mShuttingDown;
   7184     }
   7185 
   7186     public void goingToSleep() {
   7187         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
   7188                 != PackageManager.PERMISSION_GRANTED) {
   7189             throw new SecurityException("Requires permission "
   7190                     + android.Manifest.permission.DEVICE_POWER);
   7191         }
   7192 
   7193         synchronized(this) {
   7194             mWentToSleep = true;
   7195             updateEventDispatchingLocked();
   7196 
   7197             if (!mSleeping) {
   7198                 mSleeping = true;
   7199                 mMainStack.stopIfSleepingLocked();
   7200 
   7201                 // Initialize the wake times of all processes.
   7202                 checkExcessivePowerUsageLocked(false);
   7203                 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   7204                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   7205                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   7206             }
   7207         }
   7208     }
   7209 
   7210     public boolean shutdown(int timeout) {
   7211         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
   7212                 != PackageManager.PERMISSION_GRANTED) {
   7213             throw new SecurityException("Requires permission "
   7214                     + android.Manifest.permission.SHUTDOWN);
   7215         }
   7216 
   7217         boolean timedout = false;
   7218 
   7219         synchronized(this) {
   7220             mShuttingDown = true;
   7221             updateEventDispatchingLocked();
   7222 
   7223             if (mMainStack.mResumedActivity != null) {
   7224                 mMainStack.stopIfSleepingLocked();
   7225                 final long endTime = System.currentTimeMillis() + timeout;
   7226                 while (mMainStack.mResumedActivity != null
   7227                         || mMainStack.mPausingActivity != null) {
   7228                     long delay = endTime - System.currentTimeMillis();
   7229                     if (delay <= 0) {
   7230                         Slog.w(TAG, "Activity manager shutdown timed out");
   7231                         timedout = true;
   7232                         break;
   7233                     }
   7234                     try {
   7235                         this.wait();
   7236                     } catch (InterruptedException e) {
   7237                     }
   7238                 }
   7239             }
   7240         }
   7241 
   7242         mAppOpsService.shutdown();
   7243         mUsageStatsService.shutdown();
   7244         mBatteryStatsService.shutdown();
   7245 
   7246         return timedout;
   7247     }
   7248 
   7249     public final void activitySlept(IBinder token) {
   7250         if (localLOGV) Slog.v(
   7251             TAG, "Activity slept: token=" + token);
   7252 
   7253         ActivityRecord r = null;
   7254 
   7255         final long origId = Binder.clearCallingIdentity();
   7256 
   7257         synchronized (this) {
   7258             r = mMainStack.isInStackLocked(token);
   7259             if (r != null) {
   7260                 mMainStack.activitySleptLocked(r);
   7261             }
   7262         }
   7263 
   7264         Binder.restoreCallingIdentity(origId);
   7265     }
   7266 
   7267     private void comeOutOfSleepIfNeededLocked() {
   7268         if (!mWentToSleep && !mLockScreenShown) {
   7269             if (mSleeping) {
   7270                 mSleeping = false;
   7271                 mMainStack.awakeFromSleepingLocked();
   7272                 mMainStack.resumeTopActivityLocked(null);
   7273             }
   7274         }
   7275     }
   7276 
   7277     public void wakingUp() {
   7278         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
   7279                 != PackageManager.PERMISSION_GRANTED) {
   7280             throw new SecurityException("Requires permission "
   7281                     + android.Manifest.permission.DEVICE_POWER);
   7282         }
   7283 
   7284         synchronized(this) {
   7285             mWentToSleep = false;
   7286             updateEventDispatchingLocked();
   7287             comeOutOfSleepIfNeededLocked();
   7288         }
   7289     }
   7290 
   7291     private void updateEventDispatchingLocked() {
   7292         mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
   7293     }
   7294 
   7295     public void setLockScreenShown(boolean shown) {
   7296         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
   7297                 != PackageManager.PERMISSION_GRANTED) {
   7298             throw new SecurityException("Requires permission "
   7299                     + android.Manifest.permission.DEVICE_POWER);
   7300         }
   7301 
   7302         synchronized(this) {
   7303             mLockScreenShown = shown;
   7304             comeOutOfSleepIfNeededLocked();
   7305         }
   7306     }
   7307 
   7308     public void stopAppSwitches() {
   7309         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   7310                 != PackageManager.PERMISSION_GRANTED) {
   7311             throw new SecurityException("Requires permission "
   7312                     + android.Manifest.permission.STOP_APP_SWITCHES);
   7313         }
   7314 
   7315         synchronized(this) {
   7316             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
   7317                     + APP_SWITCH_DELAY_TIME;
   7318             mDidAppSwitch = false;
   7319             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   7320             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   7321             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
   7322         }
   7323     }
   7324 
   7325     public void resumeAppSwitches() {
   7326         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   7327                 != PackageManager.PERMISSION_GRANTED) {
   7328             throw new SecurityException("Requires permission "
   7329                     + android.Manifest.permission.STOP_APP_SWITCHES);
   7330         }
   7331 
   7332         synchronized(this) {
   7333             // Note that we don't execute any pending app switches... we will
   7334             // let those wait until either the timeout, or the next start
   7335             // activity request.
   7336             mAppSwitchesAllowedTime = 0;
   7337         }
   7338     }
   7339 
   7340     boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
   7341             String name) {
   7342         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
   7343             return true;
   7344         }
   7345 
   7346         final int perm = checkComponentPermission(
   7347                 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
   7348                 callingUid, -1, true);
   7349         if (perm == PackageManager.PERMISSION_GRANTED) {
   7350             return true;
   7351         }
   7352 
   7353         Slog.w(TAG, name + " request from " + callingUid + " stopped");
   7354         return false;
   7355     }
   7356 
   7357     public void setDebugApp(String packageName, boolean waitForDebugger,
   7358             boolean persistent) {
   7359         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
   7360                 "setDebugApp()");
   7361 
   7362         // Note that this is not really thread safe if there are multiple
   7363         // callers into it at the same time, but that's not a situation we
   7364         // care about.
   7365         if (persistent) {
   7366             final ContentResolver resolver = mContext.getContentResolver();
   7367             Settings.Global.putString(
   7368                 resolver, Settings.Global.DEBUG_APP,
   7369                 packageName);
   7370             Settings.Global.putInt(
   7371                 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
   7372                 waitForDebugger ? 1 : 0);
   7373         }
   7374 
   7375         synchronized (this) {
   7376             if (!persistent) {
   7377                 mOrigDebugApp = mDebugApp;
   7378                 mOrigWaitForDebugger = mWaitForDebugger;
   7379             }
   7380             mDebugApp = packageName;
   7381             mWaitForDebugger = waitForDebugger;
   7382             mDebugTransient = !persistent;
   7383             if (packageName != null) {
   7384                 final long origId = Binder.clearCallingIdentity();
   7385                 forceStopPackageLocked(packageName, -1, false, false, true, true,
   7386                         UserHandle.USER_ALL);
   7387                 Binder.restoreCallingIdentity(origId);
   7388             }
   7389         }
   7390     }
   7391 
   7392     void setOpenGlTraceApp(ApplicationInfo app, String processName) {
   7393         synchronized (this) {
   7394             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   7395             if (!isDebuggable) {
   7396                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   7397                     throw new SecurityException("Process not debuggable: " + app.packageName);
   7398                 }
   7399             }
   7400 
   7401             mOpenGlTraceApp = processName;
   7402         }
   7403     }
   7404 
   7405     void setProfileApp(ApplicationInfo app, String processName, String profileFile,
   7406             ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
   7407         synchronized (this) {
   7408             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   7409             if (!isDebuggable) {
   7410                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   7411                     throw new SecurityException("Process not debuggable: " + app.packageName);
   7412                 }
   7413             }
   7414             mProfileApp = processName;
   7415             mProfileFile = profileFile;
   7416             if (mProfileFd != null) {
   7417                 try {
   7418                     mProfileFd.close();
   7419                 } catch (IOException e) {
   7420                 }
   7421                 mProfileFd = null;
   7422             }
   7423             mProfileFd = profileFd;
   7424             mProfileType = 0;
   7425             mAutoStopProfiler = autoStopProfiler;
   7426         }
   7427     }
   7428 
   7429     public void setAlwaysFinish(boolean enabled) {
   7430         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
   7431                 "setAlwaysFinish()");
   7432 
   7433         Settings.Global.putInt(
   7434                 mContext.getContentResolver(),
   7435                 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
   7436 
   7437         synchronized (this) {
   7438             mAlwaysFinishActivities = enabled;
   7439         }
   7440     }
   7441 
   7442     public void setActivityController(IActivityController controller) {
   7443         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   7444                 "setActivityController()");
   7445         synchronized (this) {
   7446             mController = controller;
   7447             Watchdog.getInstance().setActivityController(controller);
   7448         }
   7449     }
   7450 
   7451     public void setUserIsMonkey(boolean userIsMonkey) {
   7452         synchronized (this) {
   7453             synchronized (mPidsSelfLocked) {
   7454                 final int callingPid = Binder.getCallingPid();
   7455                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
   7456                 if (precessRecord == null) {
   7457                     throw new SecurityException("Unknown process: " + callingPid);
   7458                 }
   7459                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
   7460                     throw new SecurityException("Only an instrumentation process "
   7461                             + "with a UiAutomation can call setUserIsMonkey");
   7462                 }
   7463             }
   7464             mUserIsMonkey = userIsMonkey;
   7465         }
   7466     }
   7467 
   7468     public boolean isUserAMonkey() {
   7469         synchronized (this) {
   7470             // If there is a controller also implies the user is a monkey.
   7471             return (mUserIsMonkey || mController != null);
   7472         }
   7473     }
   7474 
   7475     public void requestBugReport() {
   7476         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
   7477         SystemProperties.set("ctl.start", "bugreport");
   7478     }
   7479 
   7480     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
   7481         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
   7482     }
   7483 
   7484     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
   7485         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
   7486             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
   7487         }
   7488         return KEY_DISPATCHING_TIMEOUT;
   7489     }
   7490 
   7491 
   7492     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem) {
   7493         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
   7494                 != PackageManager.PERMISSION_GRANTED) {
   7495             throw new SecurityException("Requires permission "
   7496                     + android.Manifest.permission.FILTER_EVENTS);
   7497         }
   7498         ProcessRecord proc;
   7499         long timeout;
   7500         synchronized (this) {
   7501             synchronized (mPidsSelfLocked) {
   7502                 proc = mPidsSelfLocked.get(pid);
   7503             }
   7504             timeout = getInputDispatchingTimeoutLocked(proc);
   7505         }
   7506 
   7507         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem)) {
   7508             return -1;
   7509         }
   7510 
   7511         return timeout;
   7512     }
   7513 
   7514     /**
   7515      * Handle input dispatching timeouts.
   7516      * Returns whether input dispatching should be aborted or not.
   7517      */
   7518     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
   7519             final ActivityRecord activity, final ActivityRecord parent,
   7520             final boolean aboveSystem) {
   7521         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
   7522                 != PackageManager.PERMISSION_GRANTED) {
   7523             throw new SecurityException("Requires permission "
   7524                     + android.Manifest.permission.FILTER_EVENTS);
   7525         }
   7526 
   7527         if (proc != null) {
   7528             synchronized (this) {
   7529                 if (proc.debugging) {
   7530                     return false;
   7531                 }
   7532 
   7533                 if (mDidDexOpt) {
   7534                     // Give more time since we were dexopting.
   7535                     mDidDexOpt = false;
   7536                     return false;
   7537                 }
   7538 
   7539                 if (proc.instrumentationClass != null) {
   7540                     Bundle info = new Bundle();
   7541                     info.putString("shortMsg", "keyDispatchingTimedOut");
   7542                     info.putString("longMsg", "Timed out while dispatching key event");
   7543                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
   7544                     return true;
   7545                 }
   7546             }
   7547             mHandler.post(new Runnable() {
   7548                 @Override
   7549                 public void run() {
   7550                     appNotResponding(proc, activity, parent, aboveSystem, "keyDispatchingTimedOut");
   7551                 }
   7552             });
   7553         }
   7554 
   7555         return true;
   7556     }
   7557 
   7558     public Bundle getTopActivityExtras(int requestType) {
   7559         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
   7560                 "getTopActivityExtras()");
   7561         PendingActivityExtras pae;
   7562         Bundle extras = new Bundle();
   7563         synchronized (this) {
   7564             ActivityRecord activity = mMainStack.mResumedActivity;
   7565             if (activity == null) {
   7566                 Slog.w(TAG, "getTopActivityExtras failed: no resumed activity");
   7567                 return null;
   7568             }
   7569             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
   7570             if (activity.app == null || activity.app.thread == null) {
   7571                 Slog.w(TAG, "getTopActivityExtras failed: no process for " + activity);
   7572                 return extras;
   7573             }
   7574             if (activity.app.pid == Binder.getCallingPid()) {
   7575                 Slog.w(TAG, "getTopActivityExtras failed: request process same as " + activity);
   7576                 return extras;
   7577             }
   7578             pae = new PendingActivityExtras(activity);
   7579             try {
   7580                 activity.app.thread.requestActivityExtras(activity.appToken, pae, requestType);
   7581                 mPendingActivityExtras.add(pae);
   7582                 mHandler.postDelayed(pae, PENDING_ACTIVITY_RESULT_TIMEOUT);
   7583             } catch (RemoteException e) {
   7584                 Slog.w(TAG, "getTopActivityExtras failed: crash calling " + activity);
   7585                 return extras;
   7586             }
   7587         }
   7588         synchronized (pae) {
   7589             while (!pae.haveResult) {
   7590                 try {
   7591                     pae.wait();
   7592                 } catch (InterruptedException e) {
   7593                 }
   7594             }
   7595             if (pae.result != null) {
   7596                 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
   7597             }
   7598         }
   7599         synchronized (this) {
   7600             mPendingActivityExtras.remove(pae);
   7601             mHandler.removeCallbacks(pae);
   7602         }
   7603         return extras;
   7604     }
   7605 
   7606     public void reportTopActivityExtras(IBinder token, Bundle extras) {
   7607         PendingActivityExtras pae = (PendingActivityExtras)token;
   7608         synchronized (pae) {
   7609             pae.result = extras;
   7610             pae.haveResult = true;
   7611             pae.notifyAll();
   7612         }
   7613     }
   7614 
   7615     public void registerProcessObserver(IProcessObserver observer) {
   7616         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   7617                 "registerProcessObserver()");
   7618         synchronized (this) {
   7619             mProcessObservers.register(observer);
   7620         }
   7621     }
   7622 
   7623     public void unregisterProcessObserver(IProcessObserver observer) {
   7624         synchronized (this) {
   7625             mProcessObservers.unregister(observer);
   7626         }
   7627     }
   7628 
   7629     public void setImmersive(IBinder token, boolean immersive) {
   7630         synchronized(this) {
   7631             final ActivityRecord r = mMainStack.isInStackLocked(token);
   7632             if (r == null) {
   7633                 throw new IllegalArgumentException();
   7634             }
   7635             r.immersive = immersive;
   7636 
   7637             // update associated state if we're frontmost
   7638             if (r == mFocusedActivity) {
   7639                 if (DEBUG_IMMERSIVE) {
   7640                     Slog.d(TAG, "Frontmost changed immersion: "+ r);
   7641                 }
   7642                 applyUpdateLockStateLocked(r);
   7643             }
   7644         }
   7645     }
   7646 
   7647     public boolean isImmersive(IBinder token) {
   7648         synchronized (this) {
   7649             ActivityRecord r = mMainStack.isInStackLocked(token);
   7650             if (r == null) {
   7651                 throw new IllegalArgumentException();
   7652             }
   7653             return r.immersive;
   7654         }
   7655     }
   7656 
   7657     public boolean isTopActivityImmersive() {
   7658         enforceNotIsolatedCaller("startActivity");
   7659         synchronized (this) {
   7660             ActivityRecord r = mMainStack.topRunningActivityLocked(null);
   7661             return (r != null) ? r.immersive : false;
   7662         }
   7663     }
   7664 
   7665     public final void enterSafeMode() {
   7666         synchronized(this) {
   7667             // It only makes sense to do this before the system is ready
   7668             // and started launching other packages.
   7669             if (!mSystemReady) {
   7670                 try {
   7671                     AppGlobals.getPackageManager().enterSafeMode();
   7672                 } catch (RemoteException e) {
   7673                 }
   7674             }
   7675         }
   7676     }
   7677 
   7678     public final void showSafeModeOverlay() {
   7679         View v = LayoutInflater.from(mContext).inflate(
   7680                 com.android.internal.R.layout.safe_mode, null);
   7681         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
   7682         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
   7683         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
   7684         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
   7685         lp.gravity = Gravity.BOTTOM | Gravity.START;
   7686         lp.format = v.getBackground().getOpacity();
   7687         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
   7688                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
   7689         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
   7690         ((WindowManager)mContext.getSystemService(
   7691                 Context.WINDOW_SERVICE)).addView(v, lp);
   7692     }
   7693 
   7694     public void noteWakeupAlarm(IIntentSender sender) {
   7695         if (!(sender instanceof PendingIntentRecord)) {
   7696             return;
   7697         }
   7698         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   7699         synchronized (stats) {
   7700             if (mBatteryStatsService.isOnBattery()) {
   7701                 mBatteryStatsService.enforceCallingPermission();
   7702                 PendingIntentRecord rec = (PendingIntentRecord)sender;
   7703                 int MY_UID = Binder.getCallingUid();
   7704                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
   7705                 BatteryStatsImpl.Uid.Pkg pkg =
   7706                     stats.getPackageStatsLocked(uid, rec.key.packageName);
   7707                 pkg.incWakeupsLocked();
   7708             }
   7709         }
   7710     }
   7711 
   7712     public boolean killPids(int[] pids, String pReason, boolean secure) {
   7713         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   7714             throw new SecurityException("killPids only available to the system");
   7715         }
   7716         String reason = (pReason == null) ? "Unknown" : pReason;
   7717         // XXX Note: don't acquire main activity lock here, because the window
   7718         // manager calls in with its locks held.
   7719 
   7720         boolean killed = false;
   7721         synchronized (mPidsSelfLocked) {
   7722             int[] types = new int[pids.length];
   7723             int worstType = 0;
   7724             for (int i=0; i<pids.length; i++) {
   7725                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   7726                 if (proc != null) {
   7727                     int type = proc.setAdj;
   7728                     types[i] = type;
   7729                     if (type > worstType) {
   7730                         worstType = type;
   7731                     }
   7732                 }
   7733             }
   7734 
   7735             // If the worst oom_adj is somewhere in the hidden proc LRU range,
   7736             // then constrain it so we will kill all hidden procs.
   7737             if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
   7738                     && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
   7739                 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
   7740             }
   7741 
   7742             // If this is not a secure call, don't let it kill processes that
   7743             // are important.
   7744             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
   7745                 worstType = ProcessList.SERVICE_ADJ;
   7746             }
   7747 
   7748             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
   7749             for (int i=0; i<pids.length; i++) {
   7750                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   7751                 if (proc == null) {
   7752                     continue;
   7753                 }
   7754                 int adj = proc.setAdj;
   7755                 if (adj >= worstType && !proc.killedBackground) {
   7756                     Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
   7757                     EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, proc.pid,
   7758                             proc.processName, adj, reason);
   7759                     killed = true;
   7760                     proc.killedBackground = true;
   7761                     Process.killProcessQuiet(pids[i]);
   7762                 }
   7763             }
   7764         }
   7765         return killed;
   7766     }
   7767 
   7768     @Override
   7769     public void killUid(int uid, String reason) {
   7770         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   7771             throw new SecurityException("killUid only available to the system");
   7772         }
   7773         synchronized (this) {
   7774             killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
   7775                     ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
   7776                     reason != null ? reason : "kill uid");
   7777         }
   7778     }
   7779 
   7780     @Override
   7781     public boolean killProcessesBelowForeground(String reason) {
   7782         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   7783             throw new SecurityException("killProcessesBelowForeground() only available to system");
   7784         }
   7785 
   7786         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
   7787     }
   7788 
   7789     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
   7790         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   7791             throw new SecurityException("killProcessesBelowAdj() only available to system");
   7792         }
   7793 
   7794         boolean killed = false;
   7795         synchronized (mPidsSelfLocked) {
   7796             final int size = mPidsSelfLocked.size();
   7797             for (int i = 0; i < size; i++) {
   7798                 final int pid = mPidsSelfLocked.keyAt(i);
   7799                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   7800                 if (proc == null) continue;
   7801 
   7802                 final int adj = proc.setAdj;
   7803                 if (adj > belowAdj && !proc.killedBackground) {
   7804                     Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
   7805                     EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId,
   7806                             proc.pid, proc.processName, adj, reason);
   7807                     killed = true;
   7808                     proc.killedBackground = true;
   7809                     Process.killProcessQuiet(pid);
   7810                 }
   7811             }
   7812         }
   7813         return killed;
   7814     }
   7815 
   7816     @Override
   7817     public void hang(final IBinder who, boolean allowRestart) {
   7818         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   7819                 != PackageManager.PERMISSION_GRANTED) {
   7820             throw new SecurityException("Requires permission "
   7821                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   7822         }
   7823 
   7824         final IBinder.DeathRecipient death = new DeathRecipient() {
   7825             @Override
   7826             public void binderDied() {
   7827                 synchronized (this) {
   7828                     notifyAll();
   7829                 }
   7830             }
   7831         };
   7832 
   7833         try {
   7834             who.linkToDeath(death, 0);
   7835         } catch (RemoteException e) {
   7836             Slog.w(TAG, "hang: given caller IBinder is already dead.");
   7837             return;
   7838         }
   7839 
   7840         synchronized (this) {
   7841             Watchdog.getInstance().setAllowRestart(allowRestart);
   7842             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
   7843             synchronized (death) {
   7844                 while (who.isBinderAlive()) {
   7845                     try {
   7846                         death.wait();
   7847                     } catch (InterruptedException e) {
   7848                     }
   7849                 }
   7850             }
   7851             Watchdog.getInstance().setAllowRestart(true);
   7852         }
   7853     }
   7854 
   7855     public final void startRunning(String pkg, String cls, String action,
   7856             String data) {
   7857         synchronized(this) {
   7858             if (mStartRunning) {
   7859                 return;
   7860             }
   7861             mStartRunning = true;
   7862             mTopComponent = pkg != null && cls != null
   7863                     ? new ComponentName(pkg, cls) : null;
   7864             mTopAction = action != null ? action : Intent.ACTION_MAIN;
   7865             mTopData = data;
   7866             if (!mSystemReady) {
   7867                 return;
   7868             }
   7869         }
   7870 
   7871         systemReady(null);
   7872     }
   7873 
   7874     private void retrieveSettings() {
   7875         final ContentResolver resolver = mContext.getContentResolver();
   7876         String debugApp = Settings.Global.getString(
   7877             resolver, Settings.Global.DEBUG_APP);
   7878         boolean waitForDebugger = Settings.Global.getInt(
   7879             resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
   7880         boolean alwaysFinishActivities = Settings.Global.getInt(
   7881             resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
   7882 
   7883         Configuration configuration = new Configuration();
   7884         Settings.System.getConfiguration(resolver, configuration);
   7885 
   7886         synchronized (this) {
   7887             mDebugApp = mOrigDebugApp = debugApp;
   7888             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
   7889             mAlwaysFinishActivities = alwaysFinishActivities;
   7890             // This happens before any activities are started, so we can
   7891             // change mConfiguration in-place.
   7892             updateConfigurationLocked(configuration, null, false, true);
   7893             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
   7894         }
   7895     }
   7896 
   7897     public boolean testIsSystemReady() {
   7898         // no need to synchronize(this) just to read & return the value
   7899         return mSystemReady;
   7900     }
   7901 
   7902     private static File getCalledPreBootReceiversFile() {
   7903         File dataDir = Environment.getDataDirectory();
   7904         File systemDir = new File(dataDir, "system");
   7905         File fname = new File(systemDir, "called_pre_boots.dat");
   7906         return fname;
   7907     }
   7908 
   7909     static final int LAST_DONE_VERSION = 10000;
   7910 
   7911     private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
   7912         ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
   7913         File file = getCalledPreBootReceiversFile();
   7914         FileInputStream fis = null;
   7915         try {
   7916             fis = new FileInputStream(file);
   7917             DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
   7918             int fvers = dis.readInt();
   7919             if (fvers == LAST_DONE_VERSION) {
   7920                 String vers = dis.readUTF();
   7921                 String codename = dis.readUTF();
   7922                 String build = dis.readUTF();
   7923                 if (android.os.Build.VERSION.RELEASE.equals(vers)
   7924                         && android.os.Build.VERSION.CODENAME.equals(codename)
   7925                         && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
   7926                     int num = dis.readInt();
   7927                     while (num > 0) {
   7928                         num--;
   7929                         String pkg = dis.readUTF();
   7930                         String cls = dis.readUTF();
   7931                         lastDoneReceivers.add(new ComponentName(pkg, cls));
   7932                     }
   7933                 }
   7934             }
   7935         } catch (FileNotFoundException e) {
   7936         } catch (IOException e) {
   7937             Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
   7938         } finally {
   7939             if (fis != null) {
   7940                 try {
   7941                     fis.close();
   7942                 } catch (IOException e) {
   7943                 }
   7944             }
   7945         }
   7946         return lastDoneReceivers;
   7947     }
   7948 
   7949     private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
   7950         File file = getCalledPreBootReceiversFile();
   7951         FileOutputStream fos = null;
   7952         DataOutputStream dos = null;
   7953         try {
   7954             Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
   7955             fos = new FileOutputStream(file);
   7956             dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
   7957             dos.writeInt(LAST_DONE_VERSION);
   7958             dos.writeUTF(android.os.Build.VERSION.RELEASE);
   7959             dos.writeUTF(android.os.Build.VERSION.CODENAME);
   7960             dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
   7961             dos.writeInt(list.size());
   7962             for (int i=0; i<list.size(); i++) {
   7963                 dos.writeUTF(list.get(i).getPackageName());
   7964                 dos.writeUTF(list.get(i).getClassName());
   7965             }
   7966         } catch (IOException e) {
   7967             Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
   7968             file.delete();
   7969         } finally {
   7970             FileUtils.sync(fos);
   7971             if (dos != null) {
   7972                 try {
   7973                     dos.close();
   7974                 } catch (IOException e) {
   7975                     // TODO Auto-generated catch block
   7976                     e.printStackTrace();
   7977                 }
   7978             }
   7979         }
   7980     }
   7981 
   7982     public void systemReady(final Runnable goingCallback) {
   7983         synchronized(this) {
   7984             if (mSystemReady) {
   7985                 if (goingCallback != null) goingCallback.run();
   7986                 return;
   7987             }
   7988 
   7989             // Check to see if there are any update receivers to run.
   7990             if (!mDidUpdate) {
   7991                 if (mWaitingUpdate) {
   7992                     return;
   7993                 }
   7994                 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
   7995                 List<ResolveInfo> ris = null;
   7996                 try {
   7997                     ris = AppGlobals.getPackageManager().queryIntentReceivers(
   7998                             intent, null, 0, 0);
   7999                 } catch (RemoteException e) {
   8000                 }
   8001                 if (ris != null) {
   8002                     for (int i=ris.size()-1; i>=0; i--) {
   8003                         if ((ris.get(i).activityInfo.applicationInfo.flags
   8004                                 &ApplicationInfo.FLAG_SYSTEM) == 0) {
   8005                             ris.remove(i);
   8006                         }
   8007                     }
   8008                     intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
   8009 
   8010                     ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
   8011 
   8012                     final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
   8013                     for (int i=0; i<ris.size(); i++) {
   8014                         ActivityInfo ai = ris.get(i).activityInfo;
   8015                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
   8016                         if (lastDoneReceivers.contains(comp)) {
   8017                             ris.remove(i);
   8018                             i--;
   8019                         }
   8020                     }
   8021 
   8022                     final int[] users = getUsersLocked();
   8023                     for (int i=0; i<ris.size(); i++) {
   8024                         ActivityInfo ai = ris.get(i).activityInfo;
   8025                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
   8026                         doneReceivers.add(comp);
   8027                         intent.setComponent(comp);
   8028                         for (int j=0; j<users.length; j++) {
   8029                             IIntentReceiver finisher = null;
   8030                             if (i == ris.size()-1 && j == users.length-1) {
   8031                                 finisher = new IIntentReceiver.Stub() {
   8032                                     public void performReceive(Intent intent, int resultCode,
   8033                                             String data, Bundle extras, boolean ordered,
   8034                                             boolean sticky, int sendingUser) {
   8035                                         // The raw IIntentReceiver interface is called
   8036                                         // with the AM lock held, so redispatch to
   8037                                         // execute our code without the lock.
   8038                                         mHandler.post(new Runnable() {
   8039                                             public void run() {
   8040                                                 synchronized (ActivityManagerService.this) {
   8041                                                     mDidUpdate = true;
   8042                                                 }
   8043                                                 writeLastDonePreBootReceivers(doneReceivers);
   8044                                                 showBootMessage(mContext.getText(
   8045                                                         R.string.android_upgrading_complete),
   8046                                                         false);
   8047                                                 systemReady(goingCallback);
   8048                                             }
   8049                                         });
   8050                                     }
   8051                                 };
   8052                             }
   8053                             Slog.i(TAG, "Sending system update to " + intent.getComponent()
   8054                                     + " for user " + users[j]);
   8055                             broadcastIntentLocked(null, null, intent, null, finisher,
   8056                                     0, null, null, null, AppOpsManager.OP_NONE,
   8057                                     true, false, MY_PID, Process.SYSTEM_UID,
   8058                                     users[j]);
   8059                             if (finisher != null) {
   8060                                 mWaitingUpdate = true;
   8061                             }
   8062                         }
   8063                     }
   8064                 }
   8065                 if (mWaitingUpdate) {
   8066                     return;
   8067                 }
   8068                 mDidUpdate = true;
   8069             }
   8070 
   8071             mAppOpsService.systemReady();
   8072             mSystemReady = true;
   8073             if (!mStartRunning) {
   8074                 return;
   8075             }
   8076         }
   8077 
   8078         ArrayList<ProcessRecord> procsToKill = null;
   8079         synchronized(mPidsSelfLocked) {
   8080             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
   8081                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   8082                 if (!isAllowedWhileBooting(proc.info)){
   8083                     if (procsToKill == null) {
   8084                         procsToKill = new ArrayList<ProcessRecord>();
   8085                     }
   8086                     procsToKill.add(proc);
   8087                 }
   8088             }
   8089         }
   8090 
   8091         synchronized(this) {
   8092             if (procsToKill != null) {
   8093                 for (int i=procsToKill.size()-1; i>=0; i--) {
   8094                     ProcessRecord proc = procsToKill.get(i);
   8095                     Slog.i(TAG, "Removing system update proc: " + proc);
   8096                     removeProcessLocked(proc, true, false, "system update done");
   8097                 }
   8098             }
   8099 
   8100             // Now that we have cleaned up any update processes, we
   8101             // are ready to start launching real processes and know that
   8102             // we won't trample on them any more.
   8103             mProcessesReady = true;
   8104         }
   8105 
   8106         Slog.i(TAG, "System now ready");
   8107         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
   8108             SystemClock.uptimeMillis());
   8109 
   8110         synchronized(this) {
   8111             // Make sure we have no pre-ready processes sitting around.
   8112 
   8113             if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
   8114                 ResolveInfo ri = mContext.getPackageManager()
   8115                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
   8116                                 STOCK_PM_FLAGS);
   8117                 CharSequence errorMsg = null;
   8118                 if (ri != null) {
   8119                     ActivityInfo ai = ri.activityInfo;
   8120                     ApplicationInfo app = ai.applicationInfo;
   8121                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   8122                         mTopAction = Intent.ACTION_FACTORY_TEST;
   8123                         mTopData = null;
   8124                         mTopComponent = new ComponentName(app.packageName,
   8125                                 ai.name);
   8126                     } else {
   8127                         errorMsg = mContext.getResources().getText(
   8128                                 com.android.internal.R.string.factorytest_not_system);
   8129                     }
   8130                 } else {
   8131                     errorMsg = mContext.getResources().getText(
   8132                             com.android.internal.R.string.factorytest_no_action);
   8133                 }
   8134                 if (errorMsg != null) {
   8135                     mTopAction = null;
   8136                     mTopData = null;
   8137                     mTopComponent = null;
   8138                     Message msg = Message.obtain();
   8139                     msg.what = SHOW_FACTORY_ERROR_MSG;
   8140                     msg.getData().putCharSequence("msg", errorMsg);
   8141                     mHandler.sendMessage(msg);
   8142                 }
   8143             }
   8144         }
   8145 
   8146         retrieveSettings();
   8147 
   8148         if (goingCallback != null) goingCallback.run();
   8149 
   8150         synchronized (this) {
   8151             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   8152                 try {
   8153                     List apps = AppGlobals.getPackageManager().
   8154                         getPersistentApplications(STOCK_PM_FLAGS);
   8155                     if (apps != null) {
   8156                         int N = apps.size();
   8157                         int i;
   8158                         for (i=0; i<N; i++) {
   8159                             ApplicationInfo info
   8160                                 = (ApplicationInfo)apps.get(i);
   8161                             if (info != null &&
   8162                                     !info.packageName.equals("android")) {
   8163                                 addAppLocked(info, false);
   8164                             }
   8165                         }
   8166                     }
   8167                 } catch (RemoteException ex) {
   8168                     // pm is in same process, this will never happen.
   8169                 }
   8170             }
   8171 
   8172             // Start up initial activity.
   8173             mBooting = true;
   8174 
   8175             try {
   8176                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
   8177                     Message msg = Message.obtain();
   8178                     msg.what = SHOW_UID_ERROR_MSG;
   8179                     mHandler.sendMessage(msg);
   8180                 }
   8181             } catch (RemoteException e) {
   8182             }
   8183 
   8184             long ident = Binder.clearCallingIdentity();
   8185             try {
   8186                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
   8187                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   8188                         | Intent.FLAG_RECEIVER_FOREGROUND);
   8189                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
   8190                 broadcastIntentLocked(null, null, intent,
   8191                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   8192                         false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
   8193                 intent = new Intent(Intent.ACTION_USER_STARTING);
   8194                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   8195                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
   8196                 broadcastIntentLocked(null, null, intent,
   8197                         null, new IIntentReceiver.Stub() {
   8198                             @Override
   8199                             public void performReceive(Intent intent, int resultCode, String data,
   8200                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
   8201                                     throws RemoteException {
   8202                             }
   8203                         }, 0, null, null,
   8204                         android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
   8205                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   8206             } finally {
   8207                 Binder.restoreCallingIdentity(ident);
   8208             }
   8209             mMainStack.resumeTopActivityLocked(null);
   8210             sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
   8211         }
   8212     }
   8213 
   8214     private boolean makeAppCrashingLocked(ProcessRecord app,
   8215             String shortMsg, String longMsg, String stackTrace) {
   8216         app.crashing = true;
   8217         app.crashingReport = generateProcessError(app,
   8218                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
   8219         startAppProblemLocked(app);
   8220         app.stopFreezingAllLocked();
   8221         return handleAppCrashLocked(app);
   8222     }
   8223 
   8224     private void makeAppNotRespondingLocked(ProcessRecord app,
   8225             String activity, String shortMsg, String longMsg) {
   8226         app.notResponding = true;
   8227         app.notRespondingReport = generateProcessError(app,
   8228                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
   8229                 activity, shortMsg, longMsg, null);
   8230         startAppProblemLocked(app);
   8231         app.stopFreezingAllLocked();
   8232     }
   8233 
   8234     /**
   8235      * Generate a process error record, suitable for attachment to a ProcessRecord.
   8236      *
   8237      * @param app The ProcessRecord in which the error occurred.
   8238      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
   8239      *                      ActivityManager.AppErrorStateInfo
   8240      * @param activity The activity associated with the crash, if known.
   8241      * @param shortMsg Short message describing the crash.
   8242      * @param longMsg Long message describing the crash.
   8243      * @param stackTrace Full crash stack trace, may be null.
   8244      *
   8245      * @return Returns a fully-formed AppErrorStateInfo record.
   8246      */
   8247     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
   8248             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
   8249         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
   8250 
   8251         report.condition = condition;
   8252         report.processName = app.processName;
   8253         report.pid = app.pid;
   8254         report.uid = app.info.uid;
   8255         report.tag = activity;
   8256         report.shortMsg = shortMsg;
   8257         report.longMsg = longMsg;
   8258         report.stackTrace = stackTrace;
   8259 
   8260         return report;
   8261     }
   8262 
   8263     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
   8264         synchronized (this) {
   8265             app.crashing = false;
   8266             app.crashingReport = null;
   8267             app.notResponding = false;
   8268             app.notRespondingReport = null;
   8269             if (app.anrDialog == fromDialog) {
   8270                 app.anrDialog = null;
   8271             }
   8272             if (app.waitDialog == fromDialog) {
   8273                 app.waitDialog = null;
   8274             }
   8275             if (app.pid > 0 && app.pid != MY_PID) {
   8276                 handleAppCrashLocked(app);
   8277                 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
   8278                 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
   8279                         app.processName, app.setAdj, "user's request after error");
   8280                 Process.killProcessQuiet(app.pid);
   8281             }
   8282         }
   8283     }
   8284 
   8285     private boolean handleAppCrashLocked(ProcessRecord app) {
   8286         if (mHeadless) {
   8287             Log.e(TAG, "handleAppCrashLocked: " + app.processName);
   8288             return false;
   8289         }
   8290         long now = SystemClock.uptimeMillis();
   8291 
   8292         Long crashTime;
   8293         if (!app.isolated) {
   8294             crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
   8295         } else {
   8296             crashTime = null;
   8297         }
   8298         if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
   8299             // This process loses!
   8300             Slog.w(TAG, "Process " + app.info.processName
   8301                     + " has crashed too many times: killing!");
   8302             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
   8303                     app.userId, app.info.processName, app.uid);
   8304             for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
   8305                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   8306                 if (r.app == app) {
   8307                     Slog.w(TAG, "  Force finishing activity "
   8308                         + r.intent.getComponent().flattenToShortString());
   8309                     r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
   8310                             null, "crashed", false);
   8311                 }
   8312             }
   8313             if (!app.persistent) {
   8314                 // We don't want to start this process again until the user
   8315                 // explicitly does so...  but for persistent process, we really
   8316                 // need to keep it running.  If a persistent process is actually
   8317                 // repeatedly crashing, then badness for everyone.
   8318                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
   8319                         app.info.processName);
   8320                 if (!app.isolated) {
   8321                     // XXX We don't have a way to mark isolated processes
   8322                     // as bad, since they don't have a peristent identity.
   8323                     mBadProcesses.put(app.info.processName, app.uid, now);
   8324                     mProcessCrashTimes.remove(app.info.processName, app.uid);
   8325                 }
   8326                 app.bad = true;
   8327                 app.removed = true;
   8328                 // Don't let services in this process be restarted and potentially
   8329                 // annoy the user repeatedly.  Unless it is persistent, since those
   8330                 // processes run critical code.
   8331                 removeProcessLocked(app, false, false, "crash");
   8332                 mMainStack.resumeTopActivityLocked(null);
   8333                 return false;
   8334             }
   8335             mMainStack.resumeTopActivityLocked(null);
   8336         } else {
   8337             ActivityRecord r = mMainStack.topRunningActivityLocked(null);
   8338             if (r != null && r.app == app) {
   8339                 // If the top running activity is from this crashing
   8340                 // process, then terminate it to avoid getting in a loop.
   8341                 Slog.w(TAG, "  Force finishing activity "
   8342                         + r.intent.getComponent().flattenToShortString());
   8343                 int index = mMainStack.indexOfActivityLocked(r);
   8344                 r.stack.finishActivityLocked(r, index,
   8345                         Activity.RESULT_CANCELED, null, "crashed", false);
   8346                 // Also terminate any activities below it that aren't yet
   8347                 // stopped, to avoid a situation where one will get
   8348                 // re-start our crashing activity once it gets resumed again.
   8349                 index--;
   8350                 if (index >= 0) {
   8351                     r = (ActivityRecord)mMainStack.mHistory.get(index);
   8352                     if (r.state == ActivityState.RESUMED
   8353                             || r.state == ActivityState.PAUSING
   8354                             || r.state == ActivityState.PAUSED) {
   8355                         if (!r.isHomeActivity || mHomeProcess != r.app) {
   8356                             Slog.w(TAG, "  Force finishing activity "
   8357                                     + r.intent.getComponent().flattenToShortString());
   8358                             r.stack.finishActivityLocked(r, index,
   8359                                     Activity.RESULT_CANCELED, null, "crashed", false);
   8360                         }
   8361                     }
   8362                 }
   8363             }
   8364         }
   8365 
   8366         // Bump up the crash count of any services currently running in the proc.
   8367         if (app.services.size() != 0) {
   8368             // Any services running in the application need to be placed
   8369             // back in the pending list.
   8370             Iterator<ServiceRecord> it = app.services.iterator();
   8371             while (it.hasNext()) {
   8372                 ServiceRecord sr = it.next();
   8373                 sr.crashCount++;
   8374             }
   8375         }
   8376 
   8377         // If the crashing process is what we consider to be the "home process" and it has been
   8378         // replaced by a third-party app, clear the package preferred activities from packages
   8379         // with a home activity running in the process to prevent a repeatedly crashing app
   8380         // from blocking the user to manually clear the list.
   8381         if (app == mHomeProcess && mHomeProcess.activities.size() > 0
   8382                     && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
   8383             Iterator it = mHomeProcess.activities.iterator();
   8384             while (it.hasNext()) {
   8385                 ActivityRecord r = (ActivityRecord)it.next();
   8386                 if (r.isHomeActivity) {
   8387                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
   8388                     try {
   8389                         ActivityThread.getPackageManager()
   8390                                 .clearPackagePreferredActivities(r.packageName);
   8391                     } catch (RemoteException c) {
   8392                         // pm is in same process, this will never happen.
   8393                     }
   8394                 }
   8395             }
   8396         }
   8397 
   8398         if (!app.isolated) {
   8399             // XXX Can't keep track of crash times for isolated processes,
   8400             // because they don't have a perisistent identity.
   8401             mProcessCrashTimes.put(app.info.processName, app.uid, now);
   8402         }
   8403 
   8404         return true;
   8405     }
   8406 
   8407     void startAppProblemLocked(ProcessRecord app) {
   8408         if (app.userId == mCurrentUserId) {
   8409             app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
   8410                     mContext, app.info.packageName, app.info.flags);
   8411         } else {
   8412             // If this app is not running under the current user, then we
   8413             // can't give it a report button because that would require
   8414             // launching the report UI under a different user.
   8415             app.errorReportReceiver = null;
   8416         }
   8417         skipCurrentReceiverLocked(app);
   8418     }
   8419 
   8420     void skipCurrentReceiverLocked(ProcessRecord app) {
   8421         for (BroadcastQueue queue : mBroadcastQueues) {
   8422             queue.skipCurrentReceiverLocked(app);
   8423         }
   8424     }
   8425 
   8426     /**
   8427      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
   8428      * The application process will exit immediately after this call returns.
   8429      * @param app object of the crashing app, null for the system server
   8430      * @param crashInfo describing the exception
   8431      */
   8432     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
   8433         ProcessRecord r = findAppProcess(app, "Crash");
   8434         final String processName = app == null ? "system_server"
   8435                 : (r == null ? "unknown" : r.processName);
   8436 
   8437         handleApplicationCrashInner("crash", r, processName, crashInfo);
   8438     }
   8439 
   8440     /* Native crash reporting uses this inner version because it needs to be somewhat
   8441      * decoupled from the AM-managed cleanup lifecycle
   8442      */
   8443     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
   8444             ApplicationErrorReport.CrashInfo crashInfo) {
   8445         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
   8446                 UserHandle.getUserId(Binder.getCallingUid()), processName,
   8447                 r == null ? -1 : r.info.flags,
   8448                 crashInfo.exceptionClassName,
   8449                 crashInfo.exceptionMessage,
   8450                 crashInfo.throwFileName,
   8451                 crashInfo.throwLineNumber);
   8452 
   8453         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
   8454 
   8455         crashApplication(r, crashInfo);
   8456     }
   8457 
   8458     public void handleApplicationStrictModeViolation(
   8459             IBinder app,
   8460             int violationMask,
   8461             StrictMode.ViolationInfo info) {
   8462         ProcessRecord r = findAppProcess(app, "StrictMode");
   8463         if (r == null) {
   8464             return;
   8465         }
   8466 
   8467         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
   8468             Integer stackFingerprint = info.hashCode();
   8469             boolean logIt = true;
   8470             synchronized (mAlreadyLoggedViolatedStacks) {
   8471                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
   8472                     logIt = false;
   8473                     // TODO: sub-sample into EventLog for these, with
   8474                     // the info.durationMillis?  Then we'd get
   8475                     // the relative pain numbers, without logging all
   8476                     // the stack traces repeatedly.  We'd want to do
   8477                     // likewise in the client code, which also does
   8478                     // dup suppression, before the Binder call.
   8479                 } else {
   8480                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
   8481                         mAlreadyLoggedViolatedStacks.clear();
   8482                     }
   8483                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
   8484                 }
   8485             }
   8486             if (logIt) {
   8487                 logStrictModeViolationToDropBox(r, info);
   8488             }
   8489         }
   8490 
   8491         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
   8492             AppErrorResult result = new AppErrorResult();
   8493             synchronized (this) {
   8494                 final long origId = Binder.clearCallingIdentity();
   8495 
   8496                 Message msg = Message.obtain();
   8497                 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
   8498                 HashMap<String, Object> data = new HashMap<String, Object>();
   8499                 data.put("result", result);
   8500                 data.put("app", r);
   8501                 data.put("violationMask", violationMask);
   8502                 data.put("info", info);
   8503                 msg.obj = data;
   8504                 mHandler.sendMessage(msg);
   8505 
   8506                 Binder.restoreCallingIdentity(origId);
   8507             }
   8508             int res = result.get();
   8509             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
   8510         }
   8511     }
   8512 
   8513     // Depending on the policy in effect, there could be a bunch of
   8514     // these in quick succession so we try to batch these together to
   8515     // minimize disk writes, number of dropbox entries, and maximize
   8516     // compression, by having more fewer, larger records.
   8517     private void logStrictModeViolationToDropBox(
   8518             ProcessRecord process,
   8519             StrictMode.ViolationInfo info) {
   8520         if (info == null) {
   8521             return;
   8522         }
   8523         final boolean isSystemApp = process == null ||
   8524                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
   8525                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
   8526         final String processName = process == null ? "unknown" : process.processName;
   8527         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
   8528         final DropBoxManager dbox = (DropBoxManager)
   8529                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   8530 
   8531         // Exit early if the dropbox isn't configured to accept this report type.
   8532         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   8533 
   8534         boolean bufferWasEmpty;
   8535         boolean needsFlush;
   8536         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
   8537         synchronized (sb) {
   8538             bufferWasEmpty = sb.length() == 0;
   8539             appendDropBoxProcessHeaders(process, processName, sb);
   8540             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   8541             sb.append("System-App: ").append(isSystemApp).append("\n");
   8542             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
   8543             if (info.violationNumThisLoop != 0) {
   8544                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
   8545             }
   8546             if (info.numAnimationsRunning != 0) {
   8547                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
   8548             }
   8549             if (info.broadcastIntentAction != null) {
   8550                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
   8551             }
   8552             if (info.durationMillis != -1) {
   8553                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
   8554             }
   8555             if (info.numInstances != -1) {
   8556                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
   8557             }
   8558             if (info.tags != null) {
   8559                 for (String tag : info.tags) {
   8560                     sb.append("Span-Tag: ").append(tag).append("\n");
   8561                 }
   8562             }
   8563             sb.append("\n");
   8564             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
   8565                 sb.append(info.crashInfo.stackTrace);
   8566             }
   8567             sb.append("\n");
   8568 
   8569             // Only buffer up to ~64k.  Various logging bits truncate
   8570             // things at 128k.
   8571             needsFlush = (sb.length() > 64 * 1024);
   8572         }
   8573 
   8574         // Flush immediately if the buffer's grown too large, or this
   8575         // is a non-system app.  Non-system apps are isolated with a
   8576         // different tag & policy and not batched.
   8577         //
   8578         // Batching is useful during internal testing with
   8579         // StrictMode settings turned up high.  Without batching,
   8580         // thousands of separate files could be created on boot.
   8581         if (!isSystemApp || needsFlush) {
   8582             new Thread("Error dump: " + dropboxTag) {
   8583                 @Override
   8584                 public void run() {
   8585                     String report;
   8586                     synchronized (sb) {
   8587                         report = sb.toString();
   8588                         sb.delete(0, sb.length());
   8589                         sb.trimToSize();
   8590                     }
   8591                     if (report.length() != 0) {
   8592                         dbox.addText(dropboxTag, report);
   8593                     }
   8594                 }
   8595             }.start();
   8596             return;
   8597         }
   8598 
   8599         // System app batching:
   8600         if (!bufferWasEmpty) {
   8601             // An existing dropbox-writing thread is outstanding, so
   8602             // we don't need to start it up.  The existing thread will
   8603             // catch the buffer appends we just did.
   8604             return;
   8605         }
   8606 
   8607         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
   8608         // (After this point, we shouldn't access AMS internal data structures.)
   8609         new Thread("Error dump: " + dropboxTag) {
   8610             @Override
   8611             public void run() {
   8612                 // 5 second sleep to let stacks arrive and be batched together
   8613                 try {
   8614                     Thread.sleep(5000);  // 5 seconds
   8615                 } catch (InterruptedException e) {}
   8616 
   8617                 String errorReport;
   8618                 synchronized (mStrictModeBuffer) {
   8619                     errorReport = mStrictModeBuffer.toString();
   8620                     if (errorReport.length() == 0) {
   8621                         return;
   8622                     }
   8623                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
   8624                     mStrictModeBuffer.trimToSize();
   8625                 }
   8626                 dbox.addText(dropboxTag, errorReport);
   8627             }
   8628         }.start();
   8629     }
   8630 
   8631     /**
   8632      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
   8633      * @param app object of the crashing app, null for the system server
   8634      * @param tag reported by the caller
   8635      * @param crashInfo describing the context of the error
   8636      * @return true if the process should exit immediately (WTF is fatal)
   8637      */
   8638     public boolean handleApplicationWtf(IBinder app, String tag,
   8639             ApplicationErrorReport.CrashInfo crashInfo) {
   8640         ProcessRecord r = findAppProcess(app, "WTF");
   8641         final String processName = app == null ? "system_server"
   8642                 : (r == null ? "unknown" : r.processName);
   8643 
   8644         EventLog.writeEvent(EventLogTags.AM_WTF,
   8645                 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
   8646                 processName,
   8647                 r == null ? -1 : r.info.flags,
   8648                 tag, crashInfo.exceptionMessage);
   8649 
   8650         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
   8651 
   8652         if (r != null && r.pid != Process.myPid() &&
   8653                 Settings.Global.getInt(mContext.getContentResolver(),
   8654                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
   8655             crashApplication(r, crashInfo);
   8656             return true;
   8657         } else {
   8658             return false;
   8659         }
   8660     }
   8661 
   8662     /**
   8663      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
   8664      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
   8665      */
   8666     private ProcessRecord findAppProcess(IBinder app, String reason) {
   8667         if (app == null) {
   8668             return null;
   8669         }
   8670 
   8671         synchronized (this) {
   8672             for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   8673                 final int NA = apps.size();
   8674                 for (int ia=0; ia<NA; ia++) {
   8675                     ProcessRecord p = apps.valueAt(ia);
   8676                     if (p.thread != null && p.thread.asBinder() == app) {
   8677                         return p;
   8678                     }
   8679                 }
   8680             }
   8681 
   8682             Slog.w(TAG, "Can't find mystery application for " + reason
   8683                     + " from pid=" + Binder.getCallingPid()
   8684                     + " uid=" + Binder.getCallingUid() + ": " + app);
   8685             return null;
   8686         }
   8687     }
   8688 
   8689     /**
   8690      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
   8691      * to append various headers to the dropbox log text.
   8692      */
   8693     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
   8694             StringBuilder sb) {
   8695         // Watchdog thread ends up invoking this function (with
   8696         // a null ProcessRecord) to add the stack file to dropbox.
   8697         // Do not acquire a lock on this (am) in such cases, as it
   8698         // could cause a potential deadlock, if and when watchdog
   8699         // is invoked due to unavailability of lock on am and it
   8700         // would prevent watchdog from killing system_server.
   8701         if (process == null) {
   8702             sb.append("Process: ").append(processName).append("\n");
   8703             return;
   8704         }
   8705         // Note: ProcessRecord 'process' is guarded by the service
   8706         // instance.  (notably process.pkgList, which could otherwise change
   8707         // concurrently during execution of this method)
   8708         synchronized (this) {
   8709             sb.append("Process: ").append(processName).append("\n");
   8710             int flags = process.info.flags;
   8711             IPackageManager pm = AppGlobals.getPackageManager();
   8712             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
   8713             for (String pkg : process.pkgList) {
   8714                 sb.append("Package: ").append(pkg);
   8715                 try {
   8716                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
   8717                     if (pi != null) {
   8718                         sb.append(" v").append(pi.versionCode);
   8719                         if (pi.versionName != null) {
   8720                             sb.append(" (").append(pi.versionName).append(")");
   8721                         }
   8722                     }
   8723                 } catch (RemoteException e) {
   8724                     Slog.e(TAG, "Error getting package info: " + pkg, e);
   8725                 }
   8726                 sb.append("\n");
   8727             }
   8728         }
   8729     }
   8730 
   8731     private static String processClass(ProcessRecord process) {
   8732         if (process == null || process.pid == MY_PID) {
   8733             return "system_server";
   8734         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   8735             return "system_app";
   8736         } else {
   8737             return "data_app";
   8738         }
   8739     }
   8740 
   8741     /**
   8742      * Write a description of an error (crash, WTF, ANR) to the drop box.
   8743      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
   8744      * @param process which caused the error, null means the system server
   8745      * @param activity which triggered the error, null if unknown
   8746      * @param parent activity related to the error, null if unknown
   8747      * @param subject line related to the error, null if absent
   8748      * @param report in long form describing the error, null if absent
   8749      * @param logFile to include in the report, null if none
   8750      * @param crashInfo giving an application stack trace, null if absent
   8751      */
   8752     public void addErrorToDropBox(String eventType,
   8753             ProcessRecord process, String processName, ActivityRecord activity,
   8754             ActivityRecord parent, String subject,
   8755             final String report, final File logFile,
   8756             final ApplicationErrorReport.CrashInfo crashInfo) {
   8757         // NOTE -- this must never acquire the ActivityManagerService lock,
   8758         // otherwise the watchdog may be prevented from resetting the system.
   8759 
   8760         final String dropboxTag = processClass(process) + "_" + eventType;
   8761         final DropBoxManager dbox = (DropBoxManager)
   8762                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   8763 
   8764         // Exit early if the dropbox isn't configured to accept this report type.
   8765         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   8766 
   8767         final StringBuilder sb = new StringBuilder(1024);
   8768         appendDropBoxProcessHeaders(process, processName, sb);
   8769         if (activity != null) {
   8770             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
   8771         }
   8772         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
   8773             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
   8774         }
   8775         if (parent != null && parent != activity) {
   8776             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
   8777         }
   8778         if (subject != null) {
   8779             sb.append("Subject: ").append(subject).append("\n");
   8780         }
   8781         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   8782         if (Debug.isDebuggerConnected()) {
   8783             sb.append("Debugger: Connected\n");
   8784         }
   8785         sb.append("\n");
   8786 
   8787         // Do the rest in a worker thread to avoid blocking the caller on I/O
   8788         // (After this point, we shouldn't access AMS internal data structures.)
   8789         Thread worker = new Thread("Error dump: " + dropboxTag) {
   8790             @Override
   8791             public void run() {
   8792                 if (report != null) {
   8793                     sb.append(report);
   8794                 }
   8795                 if (logFile != null) {
   8796                     try {
   8797                         sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
   8798                     } catch (IOException e) {
   8799                         Slog.e(TAG, "Error reading " + logFile, e);
   8800                     }
   8801                 }
   8802                 if (crashInfo != null && crashInfo.stackTrace != null) {
   8803                     sb.append(crashInfo.stackTrace);
   8804                 }
   8805 
   8806                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
   8807                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
   8808                 if (lines > 0) {
   8809                     sb.append("\n");
   8810 
   8811                     // Merge several logcat streams, and take the last N lines
   8812                     InputStreamReader input = null;
   8813                     try {
   8814                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
   8815                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
   8816                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
   8817 
   8818                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
   8819                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
   8820                         input = new InputStreamReader(logcat.getInputStream());
   8821 
   8822                         int num;
   8823                         char[] buf = new char[8192];
   8824                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
   8825                     } catch (IOException e) {
   8826                         Slog.e(TAG, "Error running logcat", e);
   8827                     } finally {
   8828                         if (input != null) try { input.close(); } catch (IOException e) {}
   8829                     }
   8830                 }
   8831 
   8832                 dbox.addText(dropboxTag, sb.toString());
   8833             }
   8834         };
   8835 
   8836         if (process == null) {
   8837             // If process is null, we are being called from some internal code
   8838             // and may be about to die -- run this synchronously.
   8839             worker.run();
   8840         } else {
   8841             worker.start();
   8842         }
   8843     }
   8844 
   8845     /**
   8846      * Bring up the "unexpected error" dialog box for a crashing app.
   8847      * Deal with edge cases (intercepts from instrumented applications,
   8848      * ActivityController, error intent receivers, that sort of thing).
   8849      * @param r the application crashing
   8850      * @param crashInfo describing the failure
   8851      */
   8852     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
   8853         long timeMillis = System.currentTimeMillis();
   8854         String shortMsg = crashInfo.exceptionClassName;
   8855         String longMsg = crashInfo.exceptionMessage;
   8856         String stackTrace = crashInfo.stackTrace;
   8857         if (shortMsg != null && longMsg != null) {
   8858             longMsg = shortMsg + ": " + longMsg;
   8859         } else if (shortMsg != null) {
   8860             longMsg = shortMsg;
   8861         }
   8862 
   8863         AppErrorResult result = new AppErrorResult();
   8864         synchronized (this) {
   8865             if (mController != null) {
   8866                 try {
   8867                     String name = r != null ? r.processName : null;
   8868                     int pid = r != null ? r.pid : Binder.getCallingPid();
   8869                     if (!mController.appCrashed(name, pid,
   8870                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
   8871                         Slog.w(TAG, "Force-killing crashed app " + name
   8872                                 + " at watcher's request");
   8873                         Process.killProcess(pid);
   8874                         return;
   8875                     }
   8876                 } catch (RemoteException e) {
   8877                     mController = null;
   8878                     Watchdog.getInstance().setActivityController(null);
   8879                 }
   8880             }
   8881 
   8882             final long origId = Binder.clearCallingIdentity();
   8883 
   8884             // If this process is running instrumentation, finish it.
   8885             if (r != null && r.instrumentationClass != null) {
   8886                 Slog.w(TAG, "Error in app " + r.processName
   8887                       + " running instrumentation " + r.instrumentationClass + ":");
   8888                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
   8889                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
   8890                 Bundle info = new Bundle();
   8891                 info.putString("shortMsg", shortMsg);
   8892                 info.putString("longMsg", longMsg);
   8893                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
   8894                 Binder.restoreCallingIdentity(origId);
   8895                 return;
   8896             }
   8897 
   8898             // If we can't identify the process or it's already exceeded its crash quota,
   8899             // quit right away without showing a crash dialog.
   8900             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
   8901                 Binder.restoreCallingIdentity(origId);
   8902                 return;
   8903             }
   8904 
   8905             Message msg = Message.obtain();
   8906             msg.what = SHOW_ERROR_MSG;
   8907             HashMap data = new HashMap();
   8908             data.put("result", result);
   8909             data.put("app", r);
   8910             msg.obj = data;
   8911             mHandler.sendMessage(msg);
   8912 
   8913             Binder.restoreCallingIdentity(origId);
   8914         }
   8915 
   8916         int res = result.get();
   8917 
   8918         Intent appErrorIntent = null;
   8919         synchronized (this) {
   8920             if (r != null && !r.isolated) {
   8921                 // XXX Can't keep track of crash time for isolated processes,
   8922                 // since they don't have a persistent identity.
   8923                 mProcessCrashTimes.put(r.info.processName, r.uid,
   8924                         SystemClock.uptimeMillis());
   8925             }
   8926             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
   8927                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
   8928             }
   8929         }
   8930 
   8931         if (appErrorIntent != null) {
   8932             try {
   8933                 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
   8934             } catch (ActivityNotFoundException e) {
   8935                 Slog.w(TAG, "bug report receiver dissappeared", e);
   8936             }
   8937         }
   8938     }
   8939 
   8940     Intent createAppErrorIntentLocked(ProcessRecord r,
   8941             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   8942         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
   8943         if (report == null) {
   8944             return null;
   8945         }
   8946         Intent result = new Intent(Intent.ACTION_APP_ERROR);
   8947         result.setComponent(r.errorReportReceiver);
   8948         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
   8949         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   8950         return result;
   8951     }
   8952 
   8953     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
   8954             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   8955         if (r.errorReportReceiver == null) {
   8956             return null;
   8957         }
   8958 
   8959         if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
   8960             return null;
   8961         }
   8962 
   8963         ApplicationErrorReport report = new ApplicationErrorReport();
   8964         report.packageName = r.info.packageName;
   8965         report.installerPackageName = r.errorReportReceiver.getPackageName();
   8966         report.processName = r.processName;
   8967         report.time = timeMillis;
   8968         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   8969 
   8970         if (r.crashing || r.forceCrashReport) {
   8971             report.type = ApplicationErrorReport.TYPE_CRASH;
   8972             report.crashInfo = crashInfo;
   8973         } else if (r.notResponding) {
   8974             report.type = ApplicationErrorReport.TYPE_ANR;
   8975             report.anrInfo = new ApplicationErrorReport.AnrInfo();
   8976 
   8977             report.anrInfo.activity = r.notRespondingReport.tag;
   8978             report.anrInfo.cause = r.notRespondingReport.shortMsg;
   8979             report.anrInfo.info = r.notRespondingReport.longMsg;
   8980         }
   8981 
   8982         return report;
   8983     }
   8984 
   8985     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
   8986         enforceNotIsolatedCaller("getProcessesInErrorState");
   8987         // assume our apps are happy - lazy create the list
   8988         List<ActivityManager.ProcessErrorStateInfo> errList = null;
   8989 
   8990         final boolean allUsers = ActivityManager.checkUidPermission(
   8991                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   8992                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
   8993         int userId = UserHandle.getUserId(Binder.getCallingUid());
   8994 
   8995         synchronized (this) {
   8996 
   8997             // iterate across all processes
   8998             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   8999                 ProcessRecord app = mLruProcesses.get(i);
   9000                 if (!allUsers && app.userId != userId) {
   9001                     continue;
   9002                 }
   9003                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
   9004                     // This one's in trouble, so we'll generate a report for it
   9005                     // crashes are higher priority (in case there's a crash *and* an anr)
   9006                     ActivityManager.ProcessErrorStateInfo report = null;
   9007                     if (app.crashing) {
   9008                         report = app.crashingReport;
   9009                     } else if (app.notResponding) {
   9010                         report = app.notRespondingReport;
   9011                     }
   9012 
   9013                     if (report != null) {
   9014                         if (errList == null) {
   9015                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
   9016                         }
   9017                         errList.add(report);
   9018                     } else {
   9019                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
   9020                                 " crashing = " + app.crashing +
   9021                                 " notResponding = " + app.notResponding);
   9022                     }
   9023                 }
   9024             }
   9025         }
   9026 
   9027         return errList;
   9028     }
   9029 
   9030     static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
   9031         if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   9032             if (currApp != null) {
   9033                 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
   9034             }
   9035             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   9036         } else if (adj >= ProcessList.SERVICE_B_ADJ) {
   9037             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   9038         } else if (adj >= ProcessList.HOME_APP_ADJ) {
   9039             if (currApp != null) {
   9040                 currApp.lru = 0;
   9041             }
   9042             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   9043         } else if (adj >= ProcessList.SERVICE_ADJ) {
   9044             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   9045         } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   9046             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
   9047         } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   9048             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
   9049         } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
   9050             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
   9051         } else {
   9052             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
   9053         }
   9054     }
   9055 
   9056     private void fillInProcMemInfo(ProcessRecord app,
   9057             ActivityManager.RunningAppProcessInfo outInfo) {
   9058         outInfo.pid = app.pid;
   9059         outInfo.uid = app.info.uid;
   9060         if (mHeavyWeightProcess == app) {
   9061             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
   9062         }
   9063         if (app.persistent) {
   9064             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
   9065         }
   9066         if (app.hasActivities) {
   9067             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
   9068         }
   9069         outInfo.lastTrimLevel = app.trimMemoryLevel;
   9070         int adj = app.curAdj;
   9071         outInfo.importance = oomAdjToImportance(adj, outInfo);
   9072         outInfo.importanceReasonCode = app.adjTypeCode;
   9073     }
   9074 
   9075     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
   9076         enforceNotIsolatedCaller("getRunningAppProcesses");
   9077         // Lazy instantiation of list
   9078         List<ActivityManager.RunningAppProcessInfo> runList = null;
   9079         final boolean allUsers = ActivityManager.checkUidPermission(
   9080                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   9081                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
   9082         int userId = UserHandle.getUserId(Binder.getCallingUid());
   9083         synchronized (this) {
   9084             // Iterate across all processes
   9085             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   9086                 ProcessRecord app = mLruProcesses.get(i);
   9087                 if (!allUsers && app.userId != userId) {
   9088                     continue;
   9089                 }
   9090                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
   9091                     // Generate process state info for running application
   9092                     ActivityManager.RunningAppProcessInfo currApp =
   9093                         new ActivityManager.RunningAppProcessInfo(app.processName,
   9094                                 app.pid, app.getPackageList());
   9095                     fillInProcMemInfo(app, currApp);
   9096                     if (app.adjSource instanceof ProcessRecord) {
   9097                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
   9098                         currApp.importanceReasonImportance = oomAdjToImportance(
   9099                                 app.adjSourceOom, null);
   9100                     } else if (app.adjSource instanceof ActivityRecord) {
   9101                         ActivityRecord r = (ActivityRecord)app.adjSource;
   9102                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
   9103                     }
   9104                     if (app.adjTarget instanceof ComponentName) {
   9105                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
   9106                     }
   9107                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
   9108                     //        + " lru=" + currApp.lru);
   9109                     if (runList == null) {
   9110                         runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
   9111                     }
   9112                     runList.add(currApp);
   9113                 }
   9114             }
   9115         }
   9116         return runList;
   9117     }
   9118 
   9119     public List<ApplicationInfo> getRunningExternalApplications() {
   9120         enforceNotIsolatedCaller("getRunningExternalApplications");
   9121         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
   9122         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
   9123         if (runningApps != null && runningApps.size() > 0) {
   9124             Set<String> extList = new HashSet<String>();
   9125             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
   9126                 if (app.pkgList != null) {
   9127                     for (String pkg : app.pkgList) {
   9128                         extList.add(pkg);
   9129                     }
   9130                 }
   9131             }
   9132             IPackageManager pm = AppGlobals.getPackageManager();
   9133             for (String pkg : extList) {
   9134                 try {
   9135                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
   9136                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
   9137                         retList.add(info);
   9138                     }
   9139                 } catch (RemoteException e) {
   9140                 }
   9141             }
   9142         }
   9143         return retList;
   9144     }
   9145 
   9146     @Override
   9147     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
   9148         enforceNotIsolatedCaller("getMyMemoryState");
   9149         synchronized (this) {
   9150             ProcessRecord proc;
   9151             synchronized (mPidsSelfLocked) {
   9152                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
   9153             }
   9154             fillInProcMemInfo(proc, outInfo);
   9155         }
   9156     }
   9157 
   9158     @Override
   9159     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   9160         if (checkCallingPermission(android.Manifest.permission.DUMP)
   9161                 != PackageManager.PERMISSION_GRANTED) {
   9162             pw.println("Permission Denial: can't dump ActivityManager from from pid="
   9163                     + Binder.getCallingPid()
   9164                     + ", uid=" + Binder.getCallingUid()
   9165                     + " without permission "
   9166                     + android.Manifest.permission.DUMP);
   9167             return;
   9168         }
   9169 
   9170         boolean dumpAll = false;
   9171         boolean dumpClient = false;
   9172         String dumpPackage = null;
   9173 
   9174         int opti = 0;
   9175         while (opti < args.length) {
   9176             String opt = args[opti];
   9177             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   9178                 break;
   9179             }
   9180             opti++;
   9181             if ("-a".equals(opt)) {
   9182                 dumpAll = true;
   9183             } else if ("-c".equals(opt)) {
   9184                 dumpClient = true;
   9185             } else if ("-h".equals(opt)) {
   9186                 pw.println("Activity manager dump options:");
   9187                 pw.println("  [-a] [-c] [-h] [cmd] ...");
   9188                 pw.println("  cmd may be one of:");
   9189                 pw.println("    a[ctivities]: activity stack state");
   9190                 pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
   9191                 pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
   9192                 pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
   9193                 pw.println("    o[om]: out of memory management");
   9194                 pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
   9195                 pw.println("    provider [COMP_SPEC]: provider client-side state");
   9196                 pw.println("    s[ervices] [COMP_SPEC ...]: service state");
   9197                 pw.println("    service [COMP_SPEC]: service client-side state");
   9198                 pw.println("    package [PACKAGE_NAME]: all state related to given package");
   9199                 pw.println("    all: dump all activities");
   9200                 pw.println("    top: dump the top activity");
   9201                 pw.println("  cmd may also be a COMP_SPEC to dump activities.");
   9202                 pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
   9203                 pw.println("    a partial substring in a component name, a");
   9204                 pw.println("    hex object identifier.");
   9205                 pw.println("  -a: include all available server state.");
   9206                 pw.println("  -c: include client state.");
   9207                 return;
   9208             } else {
   9209                 pw.println("Unknown argument: " + opt + "; use -h for help");
   9210             }
   9211         }
   9212 
   9213         long origId = Binder.clearCallingIdentity();
   9214         boolean more = false;
   9215         // Is the caller requesting to dump a particular piece of data?
   9216         if (opti < args.length) {
   9217             String cmd = args[opti];
   9218             opti++;
   9219             if ("activities".equals(cmd) || "a".equals(cmd)) {
   9220                 synchronized (this) {
   9221                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
   9222                 }
   9223             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
   9224                 String[] newArgs;
   9225                 String name;
   9226                 if (opti >= args.length) {
   9227                     name = null;
   9228                     newArgs = EMPTY_STRING_ARRAY;
   9229                 } else {
   9230                     name = args[opti];
   9231                     opti++;
   9232                     newArgs = new String[args.length - opti];
   9233                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   9234                             args.length - opti);
   9235                 }
   9236                 synchronized (this) {
   9237                     dumpBroadcastsLocked(fd, pw, args, opti, true, name);
   9238                 }
   9239             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
   9240                 String[] newArgs;
   9241                 String name;
   9242                 if (opti >= args.length) {
   9243                     name = null;
   9244                     newArgs = EMPTY_STRING_ARRAY;
   9245                 } else {
   9246                     name = args[opti];
   9247                     opti++;
   9248                     newArgs = new String[args.length - opti];
   9249                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   9250                             args.length - opti);
   9251                 }
   9252                 synchronized (this) {
   9253                     dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
   9254                 }
   9255             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
   9256                 String[] newArgs;
   9257                 String name;
   9258                 if (opti >= args.length) {
   9259                     name = null;
   9260                     newArgs = EMPTY_STRING_ARRAY;
   9261                 } else {
   9262                     name = args[opti];
   9263                     opti++;
   9264                     newArgs = new String[args.length - opti];
   9265                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   9266                             args.length - opti);
   9267                 }
   9268                 synchronized (this) {
   9269                     dumpProcessesLocked(fd, pw, args, opti, true, name);
   9270                 }
   9271             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
   9272                 synchronized (this) {
   9273                     dumpOomLocked(fd, pw, args, opti, true);
   9274                 }
   9275             } else if ("provider".equals(cmd)) {
   9276                 String[] newArgs;
   9277                 String name;
   9278                 if (opti >= args.length) {
   9279                     name = null;
   9280                     newArgs = EMPTY_STRING_ARRAY;
   9281                 } else {
   9282                     name = args[opti];
   9283                     opti++;
   9284                     newArgs = new String[args.length - opti];
   9285                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   9286                 }
   9287                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
   9288                     pw.println("No providers match: " + name);
   9289                     pw.println("Use -h for help.");
   9290                 }
   9291             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
   9292                 synchronized (this) {
   9293                     dumpProvidersLocked(fd, pw, args, opti, true, null);
   9294                 }
   9295             } else if ("service".equals(cmd)) {
   9296                 String[] newArgs;
   9297                 String name;
   9298                 if (opti >= args.length) {
   9299                     name = null;
   9300                     newArgs = EMPTY_STRING_ARRAY;
   9301                 } else {
   9302                     name = args[opti];
   9303                     opti++;
   9304                     newArgs = new String[args.length - opti];
   9305                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   9306                             args.length - opti);
   9307                 }
   9308                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
   9309                     pw.println("No services match: " + name);
   9310                     pw.println("Use -h for help.");
   9311                 }
   9312             } else if ("package".equals(cmd)) {
   9313                 String[] newArgs;
   9314                 if (opti >= args.length) {
   9315                     pw.println("package: no package name specified");
   9316                     pw.println("Use -h for help.");
   9317                 } else {
   9318                     dumpPackage = args[opti];
   9319                     opti++;
   9320                     newArgs = new String[args.length - opti];
   9321                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   9322                             args.length - opti);
   9323                     args = newArgs;
   9324                     opti = 0;
   9325                     more = true;
   9326                 }
   9327             } else if ("services".equals(cmd) || "s".equals(cmd)) {
   9328                 synchronized (this) {
   9329                     mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
   9330                 }
   9331             } else {
   9332                 // Dumping a single activity?
   9333                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
   9334                     pw.println("Bad activity command, or no activities match: " + cmd);
   9335                     pw.println("Use -h for help.");
   9336                 }
   9337             }
   9338             if (!more) {
   9339                 Binder.restoreCallingIdentity(origId);
   9340                 return;
   9341             }
   9342         }
   9343 
   9344         // No piece of data specified, dump everything.
   9345         synchronized (this) {
   9346             boolean needSep;
   9347             needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   9348             if (needSep) {
   9349                 pw.println(" ");
   9350             }
   9351             if (dumpAll) {
   9352                 pw.println("-------------------------------------------------------------------------------");
   9353             }
   9354             needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   9355             if (needSep) {
   9356                 pw.println(" ");
   9357             }
   9358             if (dumpAll) {
   9359                 pw.println("-------------------------------------------------------------------------------");
   9360             }
   9361             needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   9362             if (needSep) {
   9363                 pw.println(" ");
   9364             }
   9365             if (dumpAll) {
   9366                 pw.println("-------------------------------------------------------------------------------");
   9367             }
   9368             needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   9369             if (needSep) {
   9370                 pw.println(" ");
   9371             }
   9372             if (dumpAll) {
   9373                 pw.println("-------------------------------------------------------------------------------");
   9374             }
   9375             needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   9376             if (needSep) {
   9377                 pw.println(" ");
   9378             }
   9379             if (dumpAll) {
   9380                 pw.println("-------------------------------------------------------------------------------");
   9381             }
   9382             dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   9383         }
   9384         Binder.restoreCallingIdentity(origId);
   9385     }
   9386 
   9387     boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   9388             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   9389         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
   9390         pw.println("  Main stack:");
   9391         dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
   9392                 dumpPackage);
   9393         pw.println(" ");
   9394         pw.println("  Running activities (most recent first):");
   9395         dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
   9396                 dumpPackage);
   9397         if (mMainStack.mWaitingVisibleActivities.size() > 0) {
   9398             pw.println(" ");
   9399             pw.println("  Activities waiting for another to become visible:");
   9400             dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
   9401                     !dumpAll, false, dumpPackage);
   9402         }
   9403         if (mMainStack.mStoppingActivities.size() > 0) {
   9404             pw.println(" ");
   9405             pw.println("  Activities waiting to stop:");
   9406             dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
   9407                     !dumpAll, false, dumpPackage);
   9408         }
   9409         if (mMainStack.mGoingToSleepActivities.size() > 0) {
   9410             pw.println(" ");
   9411             pw.println("  Activities waiting to sleep:");
   9412             dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
   9413                     !dumpAll, false, dumpPackage);
   9414         }
   9415         if (mMainStack.mFinishingActivities.size() > 0) {
   9416             pw.println(" ");
   9417             pw.println("  Activities waiting to finish:");
   9418             dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
   9419                     !dumpAll, false, dumpPackage);
   9420         }
   9421 
   9422         pw.println(" ");
   9423         if (mMainStack.mPausingActivity != null) {
   9424             pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
   9425         }
   9426         pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
   9427         pw.println("  mFocusedActivity: " + mFocusedActivity);
   9428         if (dumpAll) {
   9429             pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
   9430             pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
   9431             pw.println("  mDismissKeyguardOnNextActivity: "
   9432                     + mMainStack.mDismissKeyguardOnNextActivity);
   9433         }
   9434 
   9435         if (mRecentTasks.size() > 0) {
   9436             pw.println();
   9437             pw.println("  Recent tasks:");
   9438 
   9439             final int N = mRecentTasks.size();
   9440             for (int i=0; i<N; i++) {
   9441                 TaskRecord tr = mRecentTasks.get(i);
   9442                 if (dumpPackage != null) {
   9443                     if (tr.realActivity == null ||
   9444                             !dumpPackage.equals(tr.realActivity)) {
   9445                         continue;
   9446                     }
   9447                 }
   9448                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
   9449                         pw.println(tr);
   9450                 if (dumpAll) {
   9451                     mRecentTasks.get(i).dump(pw, "    ");
   9452                 }
   9453             }
   9454         }
   9455 
   9456         if (dumpAll) {
   9457             pw.println(" ");
   9458             pw.println("  mCurTask: " + mCurTask);
   9459         }
   9460 
   9461         return true;
   9462     }
   9463 
   9464     boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   9465             int opti, boolean dumpAll, String dumpPackage) {
   9466         boolean needSep = false;
   9467         int numPers = 0;
   9468 
   9469         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
   9470 
   9471         if (dumpAll) {
   9472             for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
   9473                 final int NA = procs.size();
   9474                 for (int ia=0; ia<NA; ia++) {
   9475                     ProcessRecord r = procs.valueAt(ia);
   9476                     if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   9477                         continue;
   9478                     }
   9479                     if (!needSep) {
   9480                         pw.println("  All known processes:");
   9481                         needSep = true;
   9482                     }
   9483                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
   9484                         pw.print(" UID "); pw.print(procs.keyAt(ia));
   9485                         pw.print(" "); pw.println(r);
   9486                     r.dump(pw, "    ");
   9487                     if (r.persistent) {
   9488                         numPers++;
   9489                     }
   9490                 }
   9491             }
   9492         }
   9493 
   9494         if (mIsolatedProcesses.size() > 0) {
   9495             if (needSep) pw.println(" ");
   9496             needSep = true;
   9497             pw.println("  Isolated process list (sorted by uid):");
   9498             for (int i=0; i<mIsolatedProcesses.size(); i++) {
   9499                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
   9500                 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   9501                     continue;
   9502                 }
   9503                 pw.println(String.format("%sIsolated #%2d: %s",
   9504                         "    ", i, r.toString()));
   9505             }
   9506         }
   9507 
   9508         if (mLruProcesses.size() > 0) {
   9509             if (needSep) pw.println(" ");
   9510             needSep = true;
   9511             pw.println("  Process LRU list (sorted by oom_adj):");
   9512             dumpProcessOomList(pw, this, mLruProcesses, "    ",
   9513                     "Proc", "PERS", false, dumpPackage);
   9514             needSep = true;
   9515         }
   9516 
   9517         if (dumpAll) {
   9518             synchronized (mPidsSelfLocked) {
   9519                 boolean printed = false;
   9520                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   9521                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
   9522                     if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   9523                         continue;
   9524                     }
   9525                     if (!printed) {
   9526                         if (needSep) pw.println(" ");
   9527                         needSep = true;
   9528                         pw.println("  PID mappings:");
   9529                         printed = true;
   9530                     }
   9531                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
   9532                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
   9533                 }
   9534             }
   9535         }
   9536 
   9537         if (mForegroundProcesses.size() > 0) {
   9538             synchronized (mPidsSelfLocked) {
   9539                 boolean printed = false;
   9540                 for (int i=0; i<mForegroundProcesses.size(); i++) {
   9541                     ProcessRecord r = mPidsSelfLocked.get(
   9542                             mForegroundProcesses.valueAt(i).pid);
   9543                     if (dumpPackage != null && (r == null
   9544                             || !dumpPackage.equals(r.info.packageName))) {
   9545                         continue;
   9546                     }
   9547                     if (!printed) {
   9548                         if (needSep) pw.println(" ");
   9549                         needSep = true;
   9550                         pw.println("  Foreground Processes:");
   9551                         printed = true;
   9552                     }
   9553                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
   9554                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
   9555                 }
   9556             }
   9557         }
   9558 
   9559         if (mPersistentStartingProcesses.size() > 0) {
   9560             if (needSep) pw.println(" ");
   9561             needSep = true;
   9562             pw.println("  Persisent processes that are starting:");
   9563             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
   9564                     "Starting Norm", "Restarting PERS", dumpPackage);
   9565         }
   9566 
   9567         if (mRemovedProcesses.size() > 0) {
   9568             if (needSep) pw.println(" ");
   9569             needSep = true;
   9570             pw.println("  Processes that are being removed:");
   9571             dumpProcessList(pw, this, mRemovedProcesses, "    ",
   9572                     "Removed Norm", "Removed PERS", dumpPackage);
   9573         }
   9574 
   9575         if (mProcessesOnHold.size() > 0) {
   9576             if (needSep) pw.println(" ");
   9577             needSep = true;
   9578             pw.println("  Processes that are on old until the system is ready:");
   9579             dumpProcessList(pw, this, mProcessesOnHold, "    ",
   9580                     "OnHold Norm", "OnHold PERS", dumpPackage);
   9581         }
   9582 
   9583         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
   9584 
   9585         if (mProcessCrashTimes.getMap().size() > 0) {
   9586             boolean printed = false;
   9587             long now = SystemClock.uptimeMillis();
   9588             for (Map.Entry<String, SparseArray<Long>> procs
   9589                     : mProcessCrashTimes.getMap().entrySet()) {
   9590                 String pname = procs.getKey();
   9591                 SparseArray<Long> uids = procs.getValue();
   9592                 final int N = uids.size();
   9593                 for (int i=0; i<N; i++) {
   9594                     int puid = uids.keyAt(i);
   9595                     ProcessRecord r = mProcessNames.get(pname, puid);
   9596                     if (dumpPackage != null && (r == null
   9597                             || !dumpPackage.equals(r.info.packageName))) {
   9598                         continue;
   9599                     }
   9600                     if (!printed) {
   9601                         if (needSep) pw.println(" ");
   9602                         needSep = true;
   9603                         pw.println("  Time since processes crashed:");
   9604                         printed = true;
   9605                     }
   9606                     pw.print("    Process "); pw.print(pname);
   9607                             pw.print(" uid "); pw.print(puid);
   9608                             pw.print(": last crashed ");
   9609                             TimeUtils.formatDuration(now-uids.valueAt(i), pw);
   9610                             pw.println(" ago");
   9611                 }
   9612             }
   9613         }
   9614 
   9615         if (mBadProcesses.getMap().size() > 0) {
   9616             boolean printed = false;
   9617             for (Map.Entry<String, SparseArray<Long>> procs
   9618                     : mBadProcesses.getMap().entrySet()) {
   9619                 String pname = procs.getKey();
   9620                 SparseArray<Long> uids = procs.getValue();
   9621                 final int N = uids.size();
   9622                 for (int i=0; i<N; i++) {
   9623                     int puid = uids.keyAt(i);
   9624                     ProcessRecord r = mProcessNames.get(pname, puid);
   9625                     if (dumpPackage != null && (r == null
   9626                             || !dumpPackage.equals(r.info.packageName))) {
   9627                         continue;
   9628                     }
   9629                     if (!printed) {
   9630                         if (needSep) pw.println(" ");
   9631                         needSep = true;
   9632                         pw.println("  Bad processes:");
   9633                     }
   9634                     pw.print("    Bad process "); pw.print(pname);
   9635                             pw.print(" uid "); pw.print(puid);
   9636                             pw.print(": crashed at time ");
   9637                             pw.println(uids.valueAt(i));
   9638                 }
   9639             }
   9640         }
   9641 
   9642         pw.println();
   9643         pw.println("  mStartedUsers:");
   9644         for (int i=0; i<mStartedUsers.size(); i++) {
   9645             UserStartedState uss = mStartedUsers.valueAt(i);
   9646             pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
   9647                     pw.print(": "); uss.dump("", pw);
   9648         }
   9649         pw.print("  mStartedUserArray: [");
   9650         for (int i=0; i<mStartedUserArray.length; i++) {
   9651             if (i > 0) pw.print(", ");
   9652             pw.print(mStartedUserArray[i]);
   9653         }
   9654         pw.println("]");
   9655         pw.print("  mUserLru: [");
   9656         for (int i=0; i<mUserLru.size(); i++) {
   9657             if (i > 0) pw.print(", ");
   9658             pw.print(mUserLru.get(i));
   9659         }
   9660         pw.println("]");
   9661         if (dumpAll) {
   9662             pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
   9663         }
   9664         pw.println("  mHomeProcess: " + mHomeProcess);
   9665         pw.println("  mPreviousProcess: " + mPreviousProcess);
   9666         if (dumpAll) {
   9667             StringBuilder sb = new StringBuilder(128);
   9668             sb.append("  mPreviousProcessVisibleTime: ");
   9669             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
   9670             pw.println(sb);
   9671         }
   9672         if (mHeavyWeightProcess != null) {
   9673             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   9674         }
   9675         pw.println("  mConfiguration: " + mConfiguration);
   9676         if (dumpAll) {
   9677             pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
   9678             if (mCompatModePackages.getPackages().size() > 0) {
   9679                 boolean printed = false;
   9680                 for (Map.Entry<String, Integer> entry
   9681                         : mCompatModePackages.getPackages().entrySet()) {
   9682                     String pkg = entry.getKey();
   9683                     int mode = entry.getValue();
   9684                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
   9685                         continue;
   9686                     }
   9687                     if (!printed) {
   9688                         pw.println("  mScreenCompatPackages:");
   9689                         printed = true;
   9690                     }
   9691                     pw.print("    "); pw.print(pkg); pw.print(": ");
   9692                             pw.print(mode); pw.println();
   9693                 }
   9694             }
   9695         }
   9696         if (mSleeping || mWentToSleep || mLockScreenShown) {
   9697             pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
   9698                     + " mLockScreenShown " + mLockScreenShown);
   9699         }
   9700         if (mShuttingDown) {
   9701             pw.println("  mShuttingDown=" + mShuttingDown);
   9702         }
   9703         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
   9704                 || mOrigWaitForDebugger) {
   9705             pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
   9706                     + " mDebugTransient=" + mDebugTransient
   9707                     + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
   9708         }
   9709         if (mOpenGlTraceApp != null) {
   9710             pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
   9711         }
   9712         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
   9713                 || mProfileFd != null) {
   9714             pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
   9715             pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
   9716             pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
   9717                     + mAutoStopProfiler);
   9718         }
   9719         if (mAlwaysFinishActivities || mController != null) {
   9720             pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
   9721                     + " mController=" + mController);
   9722         }
   9723         if (dumpAll) {
   9724             pw.println("  Total persistent processes: " + numPers);
   9725             pw.println("  mStartRunning=" + mStartRunning
   9726                     + " mProcessesReady=" + mProcessesReady
   9727                     + " mSystemReady=" + mSystemReady);
   9728             pw.println("  mBooting=" + mBooting
   9729                     + " mBooted=" + mBooted
   9730                     + " mFactoryTest=" + mFactoryTest);
   9731             pw.print("  mLastPowerCheckRealtime=");
   9732                     TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
   9733                     pw.println("");
   9734             pw.print("  mLastPowerCheckUptime=");
   9735                     TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
   9736                     pw.println("");
   9737             pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
   9738             pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
   9739             pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
   9740             pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
   9741                     + " mNumHiddenProcs=" + mNumHiddenProcs
   9742                     + " mNumServiceProcs=" + mNumServiceProcs
   9743                     + " mNewNumServiceProcs=" + mNewNumServiceProcs);
   9744         }
   9745 
   9746         return true;
   9747     }
   9748 
   9749     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
   9750             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
   9751         if (mProcessesToGc.size() > 0) {
   9752             boolean printed = false;
   9753             long now = SystemClock.uptimeMillis();
   9754             for (int i=0; i<mProcessesToGc.size(); i++) {
   9755                 ProcessRecord proc = mProcessesToGc.get(i);
   9756                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
   9757                     continue;
   9758                 }
   9759                 if (!printed) {
   9760                     if (needSep) pw.println(" ");
   9761                     needSep = true;
   9762                     pw.println("  Processes that are waiting to GC:");
   9763                     printed = true;
   9764                 }
   9765                 pw.print("    Process "); pw.println(proc);
   9766                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
   9767                         pw.print(", last gced=");
   9768                         pw.print(now-proc.lastRequestedGc);
   9769                         pw.print(" ms ago, last lowMem=");
   9770                         pw.print(now-proc.lastLowMemory);
   9771                         pw.println(" ms ago");
   9772 
   9773             }
   9774         }
   9775         return needSep;
   9776     }
   9777 
   9778     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   9779             int opti, boolean dumpAll) {
   9780         boolean needSep = false;
   9781 
   9782         if (mLruProcesses.size() > 0) {
   9783             if (needSep) pw.println(" ");
   9784             needSep = true;
   9785             pw.println("  OOM levels:");
   9786             pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
   9787             pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
   9788             pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
   9789             pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
   9790             pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
   9791             pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
   9792             pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
   9793             pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
   9794             pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
   9795             pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
   9796             pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
   9797             pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
   9798             pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
   9799 
   9800             if (needSep) pw.println(" ");
   9801             needSep = true;
   9802             pw.println("  Process OOM control:");
   9803             dumpProcessOomList(pw, this, mLruProcesses, "    ",
   9804                     "Proc", "PERS", true, null);
   9805             needSep = true;
   9806         }
   9807 
   9808         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
   9809 
   9810         pw.println();
   9811         pw.println("  mHomeProcess: " + mHomeProcess);
   9812         pw.println("  mPreviousProcess: " + mPreviousProcess);
   9813         if (mHeavyWeightProcess != null) {
   9814             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   9815         }
   9816 
   9817         return true;
   9818     }
   9819 
   9820     /**
   9821      * There are three ways to call this:
   9822      *  - no provider specified: dump all the providers
   9823      *  - a flattened component name that matched an existing provider was specified as the
   9824      *    first arg: dump that one provider
   9825      *  - the first arg isn't the flattened component name of an existing provider:
   9826      *    dump all providers whose component contains the first arg as a substring
   9827      */
   9828     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   9829             int opti, boolean dumpAll) {
   9830         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
   9831     }
   9832 
   9833     static class ItemMatcher {
   9834         ArrayList<ComponentName> components;
   9835         ArrayList<String> strings;
   9836         ArrayList<Integer> objects;
   9837         boolean all;
   9838 
   9839         ItemMatcher() {
   9840             all = true;
   9841         }
   9842 
   9843         void build(String name) {
   9844             ComponentName componentName = ComponentName.unflattenFromString(name);
   9845             if (componentName != null) {
   9846                 if (components == null) {
   9847                     components = new ArrayList<ComponentName>();
   9848                 }
   9849                 components.add(componentName);
   9850                 all = false;
   9851             } else {
   9852                 int objectId = 0;
   9853                 // Not a '/' separated full component name; maybe an object ID?
   9854                 try {
   9855                     objectId = Integer.parseInt(name, 16);
   9856                     if (objects == null) {
   9857                         objects = new ArrayList<Integer>();
   9858                     }
   9859                     objects.add(objectId);
   9860                     all = false;
   9861                 } catch (RuntimeException e) {
   9862                     // Not an integer; just do string match.
   9863                     if (strings == null) {
   9864                         strings = new ArrayList<String>();
   9865                     }
   9866                     strings.add(name);
   9867                     all = false;
   9868                 }
   9869             }
   9870         }
   9871 
   9872         int build(String[] args, int opti) {
   9873             for (; opti<args.length; opti++) {
   9874                 String name = args[opti];
   9875                 if ("--".equals(name)) {
   9876                     return opti+1;
   9877                 }
   9878                 build(name);
   9879             }
   9880             return opti;
   9881         }
   9882 
   9883         boolean match(Object object, ComponentName comp) {
   9884             if (all) {
   9885                 return true;
   9886             }
   9887             if (components != null) {
   9888                 for (int i=0; i<components.size(); i++) {
   9889                     if (components.get(i).equals(comp)) {
   9890                         return true;
   9891                     }
   9892                 }
   9893             }
   9894             if (objects != null) {
   9895                 for (int i=0; i<objects.size(); i++) {
   9896                     if (System.identityHashCode(object) == objects.get(i)) {
   9897                         return true;
   9898                     }
   9899                 }
   9900             }
   9901             if (strings != null) {
   9902                 String flat = comp.flattenToString();
   9903                 for (int i=0; i<strings.size(); i++) {
   9904                     if (flat.contains(strings.get(i))) {
   9905                         return true;
   9906                     }
   9907                 }
   9908             }
   9909             return false;
   9910         }
   9911     }
   9912 
   9913     /**
   9914      * There are three things that cmd can be:
   9915      *  - a flattened component name that matches an existing activity
   9916      *  - the cmd arg isn't the flattened component name of an existing activity:
   9917      *    dump all activity whose component contains the cmd as a substring
   9918      *  - A hex number of the ActivityRecord object instance.
   9919      */
   9920     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   9921             int opti, boolean dumpAll) {
   9922         ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
   9923 
   9924         if ("all".equals(name)) {
   9925             synchronized (this) {
   9926                 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
   9927                     activities.add(r1);
   9928                 }
   9929             }
   9930         } else if ("top".equals(name)) {
   9931             synchronized (this) {
   9932                 final int N = mMainStack.mHistory.size();
   9933                 if (N > 0) {
   9934                     activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
   9935                 }
   9936             }
   9937         } else {
   9938             ItemMatcher matcher = new ItemMatcher();
   9939             matcher.build(name);
   9940 
   9941             synchronized (this) {
   9942                 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
   9943                     if (matcher.match(r1, r1.intent.getComponent())) {
   9944                         activities.add(r1);
   9945                     }
   9946                 }
   9947             }
   9948         }
   9949 
   9950         if (activities.size() <= 0) {
   9951             return false;
   9952         }
   9953 
   9954         String[] newArgs = new String[args.length - opti];
   9955         if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   9956 
   9957         TaskRecord lastTask = null;
   9958         boolean needSep = false;
   9959         for (int i=activities.size()-1; i>=0; i--) {
   9960             ActivityRecord r = (ActivityRecord)activities.get(i);
   9961             if (needSep) {
   9962                 pw.println();
   9963             }
   9964             needSep = true;
   9965             synchronized (this) {
   9966                 if (lastTask != r.task) {
   9967                     lastTask = r.task;
   9968                     pw.print("TASK "); pw.print(lastTask.affinity);
   9969                             pw.print(" id="); pw.println(lastTask.taskId);
   9970                     if (dumpAll) {
   9971                         lastTask.dump(pw, "  ");
   9972                     }
   9973                 }
   9974             }
   9975             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
   9976         }
   9977         return true;
   9978     }
   9979 
   9980     /**
   9981      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
   9982      * there is a thread associated with the activity.
   9983      */
   9984     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
   9985             final ActivityRecord r, String[] args, boolean dumpAll) {
   9986         String innerPrefix = prefix + "  ";
   9987         synchronized (this) {
   9988             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
   9989                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
   9990                     pw.print(" pid=");
   9991                     if (r.app != null) pw.println(r.app.pid);
   9992                     else pw.println("(not running)");
   9993             if (dumpAll) {
   9994                 r.dump(pw, innerPrefix);
   9995             }
   9996         }
   9997         if (r.app != null && r.app.thread != null) {
   9998             // flush anything that is already in the PrintWriter since the thread is going
   9999             // to write to the file descriptor directly
   10000             pw.flush();
   10001             try {
   10002                 TransferPipe tp = new TransferPipe();
   10003                 try {
   10004                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
   10005                             r.appToken, innerPrefix, args);
   10006                     tp.go(fd);
   10007                 } finally {
   10008                     tp.kill();
   10009                 }
   10010             } catch (IOException e) {
   10011                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   10012             } catch (RemoteException e) {
   10013                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   10014             }
   10015         }
   10016     }
   10017 
   10018     boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   10019             int opti, boolean dumpAll, String dumpPackage) {
   10020         boolean needSep = false;
   10021         boolean onlyHistory = false;
   10022 
   10023         if ("history".equals(dumpPackage)) {
   10024             if (opti < args.length && "-s".equals(args[opti])) {
   10025                 dumpAll = false;
   10026             }
   10027             onlyHistory = true;
   10028             dumpPackage = null;
   10029         }
   10030 
   10031         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
   10032         if (!onlyHistory && dumpAll) {
   10033             if (mRegisteredReceivers.size() > 0) {
   10034                 boolean printed = false;
   10035                 Iterator it = mRegisteredReceivers.values().iterator();
   10036                 while (it.hasNext()) {
   10037                     ReceiverList r = (ReceiverList)it.next();
   10038                     if (dumpPackage != null && (r.app == null ||
   10039                             !dumpPackage.equals(r.app.info.packageName))) {
   10040                         continue;
   10041                     }
   10042                     if (!printed) {
   10043                         pw.println("  Registered Receivers:");
   10044                         needSep = true;
   10045                         printed = true;
   10046                     }
   10047                     pw.print("  * "); pw.println(r);
   10048                     r.dump(pw, "    ");
   10049                 }
   10050             }
   10051 
   10052             if (mReceiverResolver.dump(pw, needSep ?
   10053                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
   10054                     "    ", dumpPackage, false)) {
   10055                 needSep = true;
   10056             }
   10057         }
   10058 
   10059         for (BroadcastQueue q : mBroadcastQueues) {
   10060             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
   10061         }
   10062 
   10063         needSep = true;
   10064 
   10065         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
   10066             for (int user=0; user<mStickyBroadcasts.size(); user++) {
   10067                 if (needSep) {
   10068                     pw.println();
   10069                 }
   10070                 needSep = true;
   10071                 pw.print("  Sticky broadcasts for user ");
   10072                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
   10073                 StringBuilder sb = new StringBuilder(128);
   10074                 for (Map.Entry<String, ArrayList<Intent>> ent
   10075                         : mStickyBroadcasts.valueAt(user).entrySet()) {
   10076                     pw.print("  * Sticky action "); pw.print(ent.getKey());
   10077                     if (dumpAll) {
   10078                         pw.println(":");
   10079                         ArrayList<Intent> intents = ent.getValue();
   10080                         final int N = intents.size();
   10081                         for (int i=0; i<N; i++) {
   10082                             sb.setLength(0);
   10083                             sb.append("    Intent: ");
   10084                             intents.get(i).toShortString(sb, false, true, false, false);
   10085                             pw.println(sb.toString());
   10086                             Bundle bundle = intents.get(i).getExtras();
   10087                             if (bundle != null) {
   10088                                 pw.print("      ");
   10089                                 pw.println(bundle.toString());
   10090                             }
   10091                         }
   10092                     } else {
   10093                         pw.println("");
   10094                     }
   10095                 }
   10096             }
   10097         }
   10098 
   10099         if (!onlyHistory && dumpAll) {
   10100             pw.println();
   10101             for (BroadcastQueue queue : mBroadcastQueues) {
   10102                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
   10103                         + queue.mBroadcastsScheduled);
   10104             }
   10105             pw.println("  mHandler:");
   10106             mHandler.dump(new PrintWriterPrinter(pw), "    ");
   10107             needSep = true;
   10108         }
   10109 
   10110         return needSep;
   10111     }
   10112 
   10113     boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   10114             int opti, boolean dumpAll, String dumpPackage) {
   10115         boolean needSep = true;
   10116 
   10117         ItemMatcher matcher = new ItemMatcher();
   10118         matcher.build(args, opti);
   10119 
   10120         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
   10121 
   10122         mProviderMap.dumpProvidersLocked(pw, dumpAll);
   10123 
   10124         if (mLaunchingProviders.size() > 0) {
   10125             boolean printed = false;
   10126             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
   10127                 ContentProviderRecord r = mLaunchingProviders.get(i);
   10128                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
   10129                     continue;
   10130                 }
   10131                 if (!printed) {
   10132                     if (needSep) pw.println(" ");
   10133                     needSep = true;
   10134                     pw.println("  Launching content providers:");
   10135                     printed = true;
   10136                 }
   10137                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
   10138                         pw.println(r);
   10139             }
   10140         }
   10141 
   10142         if (mGrantedUriPermissions.size() > 0) {
   10143             if (needSep) pw.println();
   10144             needSep = true;
   10145             pw.println("Granted Uri Permissions:");
   10146             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
   10147                 int uid = mGrantedUriPermissions.keyAt(i);
   10148                 HashMap<Uri, UriPermission> perms
   10149                         = mGrantedUriPermissions.valueAt(i);
   10150                 pw.print("  * UID "); pw.print(uid);
   10151                         pw.println(" holds:");
   10152                 for (UriPermission perm : perms.values()) {
   10153                     pw.print("    "); pw.println(perm);
   10154                     if (dumpAll) {
   10155                         perm.dump(pw, "      ");
   10156                     }
   10157                 }
   10158             }
   10159             needSep = true;
   10160         }
   10161 
   10162         return needSep;
   10163     }
   10164 
   10165     boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   10166             int opti, boolean dumpAll, String dumpPackage) {
   10167         boolean needSep = false;
   10168 
   10169         if (mIntentSenderRecords.size() > 0) {
   10170             boolean printed = false;
   10171             Iterator<WeakReference<PendingIntentRecord>> it
   10172                     = mIntentSenderRecords.values().iterator();
   10173             while (it.hasNext()) {
   10174                 WeakReference<PendingIntentRecord> ref = it.next();
   10175                 PendingIntentRecord rec = ref != null ? ref.get(): null;
   10176                 if (dumpPackage != null && (rec == null
   10177                         || !dumpPackage.equals(rec.key.packageName))) {
   10178                     continue;
   10179                 }
   10180                 if (!printed) {
   10181                     pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
   10182                     printed = true;
   10183                 }
   10184                 needSep = true;
   10185                 if (rec != null) {
   10186                     pw.print("  * "); pw.println(rec);
   10187                     if (dumpAll) {
   10188                         rec.dump(pw, "    ");
   10189                     }
   10190                 } else {
   10191                     pw.print("  * "); pw.println(ref);
   10192                 }
   10193             }
   10194         }
   10195 
   10196         return needSep;
   10197     }
   10198 
   10199     private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
   10200             String prefix, String label, boolean complete, boolean brief, boolean client,
   10201             String dumpPackage) {
   10202         TaskRecord lastTask = null;
   10203         boolean needNL = false;
   10204         final String innerPrefix = prefix + "      ";
   10205         final String[] args = new String[0];
   10206         for (int i=list.size()-1; i>=0; i--) {
   10207             final ActivityRecord r = (ActivityRecord)list.get(i);
   10208             if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
   10209                 continue;
   10210             }
   10211             final boolean full = !brief && (complete || !r.isInHistory());
   10212             if (needNL) {
   10213                 pw.println(" ");
   10214                 needNL = false;
   10215             }
   10216             if (lastTask != r.task) {
   10217                 lastTask = r.task;
   10218                 pw.print(prefix);
   10219                 pw.print(full ? "* " : "  ");
   10220                 pw.println(lastTask);
   10221                 if (full) {
   10222                     lastTask.dump(pw, prefix + "  ");
   10223                 } else if (complete) {
   10224                     // Complete + brief == give a summary.  Isn't that obvious?!?
   10225                     if (lastTask.intent != null) {
   10226                         pw.print(prefix); pw.print("  ");
   10227                                 pw.println(lastTask.intent.toInsecureStringWithClip());
   10228                     }
   10229                 }
   10230             }
   10231             pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
   10232             pw.print(" #"); pw.print(i); pw.print(": ");
   10233             pw.println(r);
   10234             if (full) {
   10235                 r.dump(pw, innerPrefix);
   10236             } else if (complete) {
   10237                 // Complete + brief == give a summary.  Isn't that obvious?!?
   10238                 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
   10239                 if (r.app != null) {
   10240                     pw.print(innerPrefix); pw.println(r.app);
   10241                 }
   10242             }
   10243             if (client && r.app != null && r.app.thread != null) {
   10244                 // flush anything that is already in the PrintWriter since the thread is going
   10245                 // to write to the file descriptor directly
   10246                 pw.flush();
   10247                 try {
   10248                     TransferPipe tp = new TransferPipe();
   10249                     try {
   10250                         r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
   10251                                 r.appToken, innerPrefix, args);
   10252                         // Short timeout, since blocking here can
   10253                         // deadlock with the application.
   10254                         tp.go(fd, 2000);
   10255                     } finally {
   10256                         tp.kill();
   10257                     }
   10258                 } catch (IOException e) {
   10259                     pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   10260                 } catch (RemoteException e) {
   10261                     pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   10262                 }
   10263                 needNL = true;
   10264             }
   10265         }
   10266     }
   10267 
   10268     private static String buildOomTag(String prefix, String space, int val, int base) {
   10269         if (val == base) {
   10270             if (space == null) return prefix;
   10271             return prefix + "  ";
   10272         }
   10273         return prefix + "+" + Integer.toString(val-base);
   10274     }
   10275 
   10276     private static final int dumpProcessList(PrintWriter pw,
   10277             ActivityManagerService service, List list,
   10278             String prefix, String normalLabel, String persistentLabel,
   10279             String dumpPackage) {
   10280         int numPers = 0;
   10281         final int N = list.size()-1;
   10282         for (int i=N; i>=0; i--) {
   10283             ProcessRecord r = (ProcessRecord)list.get(i);
   10284             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   10285                 continue;
   10286             }
   10287             pw.println(String.format("%s%s #%2d: %s",
   10288                     prefix, (r.persistent ? persistentLabel : normalLabel),
   10289                     i, r.toString()));
   10290             if (r.persistent) {
   10291                 numPers++;
   10292             }
   10293         }
   10294         return numPers;
   10295     }
   10296 
   10297     private static final boolean dumpProcessOomList(PrintWriter pw,
   10298             ActivityManagerService service, List<ProcessRecord> origList,
   10299             String prefix, String normalLabel, String persistentLabel,
   10300             boolean inclDetails, String dumpPackage) {
   10301 
   10302         ArrayList<Pair<ProcessRecord, Integer>> list
   10303                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
   10304         for (int i=0; i<origList.size(); i++) {
   10305             ProcessRecord r = origList.get(i);
   10306             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   10307                 continue;
   10308             }
   10309             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
   10310         }
   10311 
   10312         if (list.size() <= 0) {
   10313             return false;
   10314         }
   10315 
   10316         Comparator<Pair<ProcessRecord, Integer>> comparator
   10317                 = new Comparator<Pair<ProcessRecord, Integer>>() {
   10318             @Override
   10319             public int compare(Pair<ProcessRecord, Integer> object1,
   10320                     Pair<ProcessRecord, Integer> object2) {
   10321                 if (object1.first.setAdj != object2.first.setAdj) {
   10322                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
   10323                 }
   10324                 if (object1.second.intValue() != object2.second.intValue()) {
   10325                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
   10326                 }
   10327                 return 0;
   10328             }
   10329         };
   10330 
   10331         Collections.sort(list, comparator);
   10332 
   10333         final long curRealtime = SystemClock.elapsedRealtime();
   10334         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
   10335         final long curUptime = SystemClock.uptimeMillis();
   10336         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
   10337 
   10338         for (int i=list.size()-1; i>=0; i--) {
   10339             ProcessRecord r = list.get(i).first;
   10340             String oomAdj;
   10341             if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   10342                 oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
   10343             } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
   10344                 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
   10345             } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
   10346                 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
   10347             } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
   10348                 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
   10349             } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
   10350                 oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
   10351             } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
   10352                 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
   10353             } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   10354                 oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
   10355             } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   10356                 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
   10357             } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
   10358                 oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
   10359             } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
   10360                 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
   10361             } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
   10362                 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
   10363             } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
   10364                 oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
   10365             } else {
   10366                 oomAdj = Integer.toString(r.setAdj);
   10367             }
   10368             String schedGroup;
   10369             switch (r.setSchedGroup) {
   10370                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
   10371                     schedGroup = "B";
   10372                     break;
   10373                 case Process.THREAD_GROUP_DEFAULT:
   10374                     schedGroup = "F";
   10375                     break;
   10376                 default:
   10377                     schedGroup = Integer.toString(r.setSchedGroup);
   10378                     break;
   10379             }
   10380             String foreground;
   10381             if (r.foregroundActivities) {
   10382                 foreground = "A";
   10383             } else if (r.foregroundServices) {
   10384                 foreground = "S";
   10385             } else {
   10386                 foreground = " ";
   10387             }
   10388             pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
   10389                     prefix, (r.persistent ? persistentLabel : normalLabel),
   10390                     (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
   10391                     foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
   10392             if (r.adjSource != null || r.adjTarget != null) {
   10393                 pw.print(prefix);
   10394                 pw.print("    ");
   10395                 if (r.adjTarget instanceof ComponentName) {
   10396                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
   10397                 } else if (r.adjTarget != null) {
   10398                     pw.print(r.adjTarget.toString());
   10399                 } else {
   10400                     pw.print("{null}");
   10401                 }
   10402                 pw.print("<=");
   10403                 if (r.adjSource instanceof ProcessRecord) {
   10404                     pw.print("Proc{");
   10405                     pw.print(((ProcessRecord)r.adjSource).toShortString());
   10406                     pw.println("}");
   10407                 } else if (r.adjSource != null) {
   10408                     pw.println(r.adjSource.toString());
   10409                 } else {
   10410                     pw.println("{null}");
   10411                 }
   10412             }
   10413             if (inclDetails) {
   10414                 pw.print(prefix);
   10415                 pw.print("    ");
   10416                 pw.print("oom: max="); pw.print(r.maxAdj);
   10417                 pw.print(" hidden="); pw.print(r.hiddenAdj);
   10418                 pw.print(" client="); pw.print(r.clientHiddenAdj);
   10419                 pw.print(" empty="); pw.print(r.emptyAdj);
   10420                 pw.print(" curRaw="); pw.print(r.curRawAdj);
   10421                 pw.print(" setRaw="); pw.print(r.setRawAdj);
   10422                 pw.print(" cur="); pw.print(r.curAdj);
   10423                 pw.print(" set="); pw.println(r.setAdj);
   10424                 pw.print(prefix);
   10425                 pw.print("    ");
   10426                 pw.print("keeping="); pw.print(r.keeping);
   10427                 pw.print(" hidden="); pw.print(r.hidden);
   10428                 pw.print(" empty="); pw.print(r.empty);
   10429                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
   10430 
   10431                 if (!r.keeping) {
   10432                     if (r.lastWakeTime != 0) {
   10433                         long wtime;
   10434                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
   10435                         synchronized (stats) {
   10436                             wtime = stats.getProcessWakeTime(r.info.uid,
   10437                                     r.pid, curRealtime);
   10438                         }
   10439                         long timeUsed = wtime - r.lastWakeTime;
   10440                         pw.print(prefix);
   10441                         pw.print("    ");
   10442                         pw.print("keep awake over ");
   10443                         TimeUtils.formatDuration(realtimeSince, pw);
   10444                         pw.print(" used ");
   10445                         TimeUtils.formatDuration(timeUsed, pw);
   10446                         pw.print(" (");
   10447                         pw.print((timeUsed*100)/realtimeSince);
   10448                         pw.println("%)");
   10449                     }
   10450                     if (r.lastCpuTime != 0) {
   10451                         long timeUsed = r.curCpuTime - r.lastCpuTime;
   10452                         pw.print(prefix);
   10453                         pw.print("    ");
   10454                         pw.print("run cpu over ");
   10455                         TimeUtils.formatDuration(uptimeSince, pw);
   10456                         pw.print(" used ");
   10457                         TimeUtils.formatDuration(timeUsed, pw);
   10458                         pw.print(" (");
   10459                         pw.print((timeUsed*100)/uptimeSince);
   10460                         pw.println("%)");
   10461                     }
   10462                 }
   10463             }
   10464         }
   10465         return true;
   10466     }
   10467 
   10468     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
   10469         ArrayList<ProcessRecord> procs;
   10470         synchronized (this) {
   10471             if (args != null && args.length > start
   10472                     && args[start].charAt(0) != '-') {
   10473                 procs = new ArrayList<ProcessRecord>();
   10474                 int pid = -1;
   10475                 try {
   10476                     pid = Integer.parseInt(args[start]);
   10477                 } catch (NumberFormatException e) {
   10478 
   10479                 }
   10480                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   10481                     ProcessRecord proc = mLruProcesses.get(i);
   10482                     if (proc.pid == pid) {
   10483                         procs.add(proc);
   10484                     } else if (proc.processName.equals(args[start])) {
   10485                         procs.add(proc);
   10486                     }
   10487                 }
   10488                 if (procs.size() <= 0) {
   10489                     pw.println("No process found for: " + args[start]);
   10490                     return null;
   10491                 }
   10492             } else {
   10493                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
   10494             }
   10495         }
   10496         return procs;
   10497     }
   10498 
   10499     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
   10500             PrintWriter pw, String[] args) {
   10501         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
   10502         if (procs == null) {
   10503             return;
   10504         }
   10505 
   10506         long uptime = SystemClock.uptimeMillis();
   10507         long realtime = SystemClock.elapsedRealtime();
   10508         pw.println("Applications Graphics Acceleration Info:");
   10509         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   10510 
   10511         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   10512             ProcessRecord r = procs.get(i);
   10513             if (r.thread != null) {
   10514                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
   10515                 pw.flush();
   10516                 try {
   10517                     TransferPipe tp = new TransferPipe();
   10518                     try {
   10519                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
   10520                         tp.go(fd);
   10521                     } finally {
   10522                         tp.kill();
   10523                     }
   10524                 } catch (IOException e) {
   10525                     pw.println("Failure while dumping the app: " + r);
   10526                     pw.flush();
   10527                 } catch (RemoteException e) {
   10528                     pw.println("Got a RemoteException while dumping the app " + r);
   10529                     pw.flush();
   10530                 }
   10531             }
   10532         }
   10533     }
   10534 
   10535     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
   10536         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
   10537         if (procs == null) {
   10538             return;
   10539         }
   10540 
   10541         pw.println("Applications Database Info:");
   10542 
   10543         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   10544             ProcessRecord r = procs.get(i);
   10545             if (r.thread != null) {
   10546                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
   10547                 pw.flush();
   10548                 try {
   10549                     TransferPipe tp = new TransferPipe();
   10550                     try {
   10551                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
   10552                         tp.go(fd);
   10553                     } finally {
   10554                         tp.kill();
   10555                     }
   10556                 } catch (IOException e) {
   10557                     pw.println("Failure while dumping the app: " + r);
   10558                     pw.flush();
   10559                 } catch (RemoteException e) {
   10560                     pw.println("Got a RemoteException while dumping the app " + r);
   10561                     pw.flush();
   10562                 }
   10563             }
   10564         }
   10565     }
   10566 
   10567     final static class MemItem {
   10568         final String label;
   10569         final String shortLabel;
   10570         final long pss;
   10571         final int id;
   10572         ArrayList<MemItem> subitems;
   10573 
   10574         public MemItem(String _label, String _shortLabel, long _pss, int _id) {
   10575             label = _label;
   10576             shortLabel = _shortLabel;
   10577             pss = _pss;
   10578             id = _id;
   10579         }
   10580     }
   10581 
   10582     static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
   10583             boolean sort) {
   10584         if (sort) {
   10585             Collections.sort(items, new Comparator<MemItem>() {
   10586                 @Override
   10587                 public int compare(MemItem lhs, MemItem rhs) {
   10588                     if (lhs.pss < rhs.pss) {
   10589                         return 1;
   10590                     } else if (lhs.pss > rhs.pss) {
   10591                         return -1;
   10592                     }
   10593                     return 0;
   10594                 }
   10595             });
   10596         }
   10597 
   10598         for (int i=0; i<items.size(); i++) {
   10599             MemItem mi = items.get(i);
   10600             pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
   10601             if (mi.subitems != null) {
   10602                 dumpMemItems(pw, prefix + "           ", mi.subitems, true);
   10603             }
   10604         }
   10605     }
   10606 
   10607     // These are in KB.
   10608     static final long[] DUMP_MEM_BUCKETS = new long[] {
   10609         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
   10610         120*1024, 160*1024, 200*1024,
   10611         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
   10612         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
   10613     };
   10614 
   10615     static final void appendMemBucket(StringBuilder out, long memKB, String label,
   10616             boolean stackLike) {
   10617         int start = label.lastIndexOf('.');
   10618         if (start >= 0) start++;
   10619         else start = 0;
   10620         int end = label.length();
   10621         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
   10622             if (DUMP_MEM_BUCKETS[i] >= memKB) {
   10623                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
   10624                 out.append(bucket);
   10625                 out.append(stackLike ? "MB." : "MB ");
   10626                 out.append(label, start, end);
   10627                 return;
   10628             }
   10629         }
   10630         out.append(memKB/1024);
   10631         out.append(stackLike ? "MB." : "MB ");
   10632         out.append(label, start, end);
   10633     }
   10634 
   10635     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
   10636             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
   10637             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
   10638             ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
   10639             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
   10640     };
   10641     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
   10642             "System", "Persistent", "Foreground",
   10643             "Visible", "Perceptible", "Heavy Weight",
   10644             "Backup", "A Services", "Home", "Previous",
   10645             "B Services", "Background"
   10646     };
   10647 
   10648     final void dumpApplicationMemoryUsage(FileDescriptor fd,
   10649             PrintWriter pw, String prefix, String[] args, boolean brief,
   10650             PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
   10651         boolean dumpAll = false;
   10652         boolean oomOnly = false;
   10653 
   10654         int opti = 0;
   10655         while (opti < args.length) {
   10656             String opt = args[opti];
   10657             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   10658                 break;
   10659             }
   10660             opti++;
   10661             if ("-a".equals(opt)) {
   10662                 dumpAll = true;
   10663             } else if ("--oom".equals(opt)) {
   10664                 oomOnly = true;
   10665             } else if ("-h".equals(opt)) {
   10666                 pw.println("meminfo dump options: [-a] [--oom] [process]");
   10667                 pw.println("  -a: include all available information for each process.");
   10668                 pw.println("  --oom: only show processes organized by oom adj.");
   10669                 pw.println("If [process] is specified it can be the name or ");
   10670                 pw.println("pid of a specific process to dump.");
   10671                 return;
   10672             } else {
   10673                 pw.println("Unknown argument: " + opt + "; use -h for help");
   10674             }
   10675         }
   10676 
   10677         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
   10678         if (procs == null) {
   10679             return;
   10680         }
   10681 
   10682         final boolean isCheckinRequest = scanArgs(args, "--checkin");
   10683         long uptime = SystemClock.uptimeMillis();
   10684         long realtime = SystemClock.elapsedRealtime();
   10685 
   10686         if (procs.size() == 1 || isCheckinRequest) {
   10687             dumpAll = true;
   10688         }
   10689 
   10690         if (isCheckinRequest) {
   10691             // short checkin version
   10692             pw.println(uptime + "," + realtime);
   10693             pw.flush();
   10694         } else {
   10695             pw.println("Applications Memory Usage (kB):");
   10696             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   10697         }
   10698 
   10699         String[] innerArgs = new String[args.length-opti];
   10700         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
   10701 
   10702         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
   10703         long nativePss=0, dalvikPss=0, otherPss=0;
   10704         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
   10705 
   10706         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
   10707         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
   10708                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
   10709 
   10710         long totalPss = 0;
   10711 
   10712         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   10713             ProcessRecord r = procs.get(i);
   10714             if (r.thread != null) {
   10715                 if (!isCheckinRequest && dumpAll) {
   10716                     pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
   10717                     pw.flush();
   10718                 }
   10719                 Debug.MemoryInfo mi = null;
   10720                 if (dumpAll) {
   10721                     try {
   10722                         mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
   10723                     } catch (RemoteException e) {
   10724                         if (!isCheckinRequest) {
   10725                             pw.println("Got RemoteException!");
   10726                             pw.flush();
   10727                         }
   10728                     }
   10729                 } else {
   10730                     mi = new Debug.MemoryInfo();
   10731                     Debug.getMemoryInfo(r.pid, mi);
   10732                 }
   10733 
   10734                 if (!isCheckinRequest && mi != null) {
   10735                     long myTotalPss = mi.getTotalPss();
   10736                     totalPss += myTotalPss;
   10737                     MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
   10738                             r.processName, myTotalPss, 0);
   10739                     procMems.add(pssItem);
   10740 
   10741                     nativePss += mi.nativePss;
   10742                     dalvikPss += mi.dalvikPss;
   10743                     otherPss += mi.otherPss;
   10744                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   10745                         long mem = mi.getOtherPss(j);
   10746                         miscPss[j] += mem;
   10747                         otherPss -= mem;
   10748                     }
   10749 
   10750                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
   10751                         if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
   10752                                 || oomIndex == (oomPss.length-1)) {
   10753                             oomPss[oomIndex] += myTotalPss;
   10754                             if (oomProcs[oomIndex] == null) {
   10755                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
   10756                             }
   10757                             oomProcs[oomIndex].add(pssItem);
   10758                             break;
   10759                         }
   10760                     }
   10761                 }
   10762             }
   10763         }
   10764 
   10765         if (!isCheckinRequest && procs.size() > 1) {
   10766             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
   10767 
   10768             catMems.add(new MemItem("Native", "Native", nativePss, -1));
   10769             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
   10770             catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
   10771             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   10772                 String label = Debug.MemoryInfo.getOtherLabel(j);
   10773                 catMems.add(new MemItem(label, label, miscPss[j], j));
   10774             }
   10775 
   10776             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
   10777             for (int j=0; j<oomPss.length; j++) {
   10778                 if (oomPss[j] != 0) {
   10779                     String label = DUMP_MEM_OOM_LABEL[j];
   10780                     MemItem item = new MemItem(label, label, oomPss[j],
   10781                             DUMP_MEM_OOM_ADJ[j]);
   10782                     item.subitems = oomProcs[j];
   10783                     oomMems.add(item);
   10784                 }
   10785             }
   10786 
   10787             if (outTag != null || outStack != null) {
   10788                 if (outTag != null) {
   10789                     appendMemBucket(outTag, totalPss, "total", false);
   10790                 }
   10791                 if (outStack != null) {
   10792                     appendMemBucket(outStack, totalPss, "total", true);
   10793                 }
   10794                 boolean firstLine = true;
   10795                 for (int i=0; i<oomMems.size(); i++) {
   10796                     MemItem miCat = oomMems.get(i);
   10797                     if (miCat.subitems == null || miCat.subitems.size() < 1) {
   10798                         continue;
   10799                     }
   10800                     if (miCat.id < ProcessList.SERVICE_ADJ
   10801                             || miCat.id == ProcessList.HOME_APP_ADJ
   10802                             || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
   10803                         if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
   10804                             outTag.append(" / ");
   10805                         }
   10806                         if (outStack != null) {
   10807                             if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
   10808                                 if (firstLine) {
   10809                                     outStack.append(":");
   10810                                     firstLine = false;
   10811                                 }
   10812                                 outStack.append("\n\t at ");
   10813                             } else {
   10814                                 outStack.append("$");
   10815                             }
   10816                         }
   10817                         for (int j=0; j<miCat.subitems.size(); j++) {
   10818                             MemItem mi = miCat.subitems.get(j);
   10819                             if (j > 0) {
   10820                                 if (outTag != null) {
   10821                                     outTag.append(" ");
   10822                                 }
   10823                                 if (outStack != null) {
   10824                                     outStack.append("$");
   10825                                 }
   10826                             }
   10827                             if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
   10828                                 appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
   10829                             }
   10830                             if (outStack != null) {
   10831                                 appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
   10832                             }
   10833                         }
   10834                         if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
   10835                             outStack.append("(");
   10836                             for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
   10837                                 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
   10838                                     outStack.append(DUMP_MEM_OOM_LABEL[k]);
   10839                                     outStack.append(":");
   10840                                     outStack.append(DUMP_MEM_OOM_ADJ[k]);
   10841                                 }
   10842                             }
   10843                             outStack.append(")");
   10844                         }
   10845                     }
   10846                 }
   10847             }
   10848 
   10849             if (!brief && !oomOnly) {
   10850                 pw.println();
   10851                 pw.println("Total PSS by process:");
   10852                 dumpMemItems(pw, "  ", procMems, true);
   10853                 pw.println();
   10854             }
   10855             pw.println("Total PSS by OOM adjustment:");
   10856             dumpMemItems(pw, "  ", oomMems, false);
   10857             if (!oomOnly) {
   10858                 PrintWriter out = categoryPw != null ? categoryPw : pw;
   10859                 out.println();
   10860                 out.println("Total PSS by category:");
   10861                 dumpMemItems(out, "  ", catMems, true);
   10862             }
   10863             pw.println();
   10864             pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
   10865             final int[] SINGLE_LONG_FORMAT = new int[] {
   10866                 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
   10867             };
   10868             long[] longOut = new long[1];
   10869             Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
   10870                     SINGLE_LONG_FORMAT, null, longOut, null);
   10871             long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   10872             longOut[0] = 0;
   10873             Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
   10874                     SINGLE_LONG_FORMAT, null, longOut, null);
   10875             long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   10876             longOut[0] = 0;
   10877             Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
   10878                     SINGLE_LONG_FORMAT, null, longOut, null);
   10879             long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   10880             longOut[0] = 0;
   10881             Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
   10882                     SINGLE_LONG_FORMAT, null, longOut, null);
   10883             long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   10884             pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
   10885                     pw.print(shared); pw.println(" kB");
   10886             pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
   10887                     pw.print(voltile); pw.println(" kB volatile");
   10888         }
   10889     }
   10890 
   10891     /**
   10892      * Searches array of arguments for the specified string
   10893      * @param args array of argument strings
   10894      * @param value value to search for
   10895      * @return true if the value is contained in the array
   10896      */
   10897     private static boolean scanArgs(String[] args, String value) {
   10898         if (args != null) {
   10899             for (String arg : args) {
   10900                 if (value.equals(arg)) {
   10901                     return true;
   10902                 }
   10903             }
   10904         }
   10905         return false;
   10906     }
   10907 
   10908     private final boolean removeDyingProviderLocked(ProcessRecord proc,
   10909             ContentProviderRecord cpr, boolean always) {
   10910         final boolean inLaunching = mLaunchingProviders.contains(cpr);
   10911 
   10912         if (!inLaunching || always) {
   10913             synchronized (cpr) {
   10914                 cpr.launchingApp = null;
   10915                 cpr.notifyAll();
   10916             }
   10917             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
   10918             String names[] = cpr.info.authority.split(";");
   10919             for (int j = 0; j < names.length; j++) {
   10920                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
   10921             }
   10922         }
   10923 
   10924         for (int i=0; i<cpr.connections.size(); i++) {
   10925             ContentProviderConnection conn = cpr.connections.get(i);
   10926             if (conn.waiting) {
   10927                 // If this connection is waiting for the provider, then we don't
   10928                 // need to mess with its process unless we are always removing
   10929                 // or for some reason the provider is not currently launching.
   10930                 if (inLaunching && !always) {
   10931                     continue;
   10932                 }
   10933             }
   10934             ProcessRecord capp = conn.client;
   10935             conn.dead = true;
   10936             if (conn.stableCount > 0) {
   10937                 if (!capp.persistent && capp.thread != null
   10938                         && capp.pid != 0
   10939                         && capp.pid != MY_PID) {
   10940                     Slog.i(TAG, "Kill " + capp.processName
   10941                             + " (pid " + capp.pid + "): provider " + cpr.info.name
   10942                             + " in dying process " + (proc != null ? proc.processName : "??"));
   10943                     EventLog.writeEvent(EventLogTags.AM_KILL, capp.userId, capp.pid,
   10944                             capp.processName, capp.setAdj, "dying provider "
   10945                                     + cpr.name.toShortString());
   10946                     Process.killProcessQuiet(capp.pid);
   10947                 }
   10948             } else if (capp.thread != null && conn.provider.provider != null) {
   10949                 try {
   10950                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
   10951                 } catch (RemoteException e) {
   10952                 }
   10953                 // In the protocol here, we don't expect the client to correctly
   10954                 // clean up this connection, we'll just remove it.
   10955                 cpr.connections.remove(i);
   10956                 conn.client.conProviders.remove(conn);
   10957             }
   10958         }
   10959 
   10960         if (inLaunching && always) {
   10961             mLaunchingProviders.remove(cpr);
   10962         }
   10963         return inLaunching;
   10964     }
   10965 
   10966     /**
   10967      * Main code for cleaning up a process when it has gone away.  This is
   10968      * called both as a result of the process dying, or directly when stopping
   10969      * a process when running in single process mode.
   10970      */
   10971     private final void cleanUpApplicationRecordLocked(ProcessRecord app,
   10972             boolean restarting, boolean allowRestart, int index) {
   10973         if (index >= 0) {
   10974             mLruProcesses.remove(index);
   10975         }
   10976 
   10977         mProcessesToGc.remove(app);
   10978 
   10979         // Dismiss any open dialogs.
   10980         if (app.crashDialog != null && !app.forceCrashReport) {
   10981             app.crashDialog.dismiss();
   10982             app.crashDialog = null;
   10983         }
   10984         if (app.anrDialog != null) {
   10985             app.anrDialog.dismiss();
   10986             app.anrDialog = null;
   10987         }
   10988         if (app.waitDialog != null) {
   10989             app.waitDialog.dismiss();
   10990             app.waitDialog = null;
   10991         }
   10992 
   10993         app.crashing = false;
   10994         app.notResponding = false;
   10995 
   10996         app.resetPackageList();
   10997         app.unlinkDeathRecipient();
   10998         app.thread = null;
   10999         app.forcingToForeground = null;
   11000         app.foregroundServices = false;
   11001         app.foregroundActivities = false;
   11002         app.hasShownUi = false;
   11003         app.hasAboveClient = false;
   11004 
   11005         mServices.killServicesLocked(app, allowRestart);
   11006 
   11007         boolean restart = false;
   11008 
   11009         // Remove published content providers.
   11010         if (!app.pubProviders.isEmpty()) {
   11011             Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
   11012             while (it.hasNext()) {
   11013                 ContentProviderRecord cpr = it.next();
   11014 
   11015                 final boolean always = app.bad || !allowRestart;
   11016                 if (removeDyingProviderLocked(app, cpr, always) || always) {
   11017                     // We left the provider in the launching list, need to
   11018                     // restart it.
   11019                     restart = true;
   11020                 }
   11021 
   11022                 cpr.provider = null;
   11023                 cpr.proc = null;
   11024             }
   11025             app.pubProviders.clear();
   11026         }
   11027 
   11028         // Take care of any launching providers waiting for this process.
   11029         if (checkAppInLaunchingProvidersLocked(app, false)) {
   11030             restart = true;
   11031         }
   11032 
   11033         // Unregister from connected content providers.
   11034         if (!app.conProviders.isEmpty()) {
   11035             for (int i=0; i<app.conProviders.size(); i++) {
   11036                 ContentProviderConnection conn = app.conProviders.get(i);
   11037                 conn.provider.connections.remove(conn);
   11038             }
   11039             app.conProviders.clear();
   11040         }
   11041 
   11042         // At this point there may be remaining entries in mLaunchingProviders
   11043         // where we were the only one waiting, so they are no longer of use.
   11044         // Look for these and clean up if found.
   11045         // XXX Commented out for now.  Trying to figure out a way to reproduce
   11046         // the actual situation to identify what is actually going on.
   11047         if (false) {
   11048             for (int i=0; i<mLaunchingProviders.size(); i++) {
   11049                 ContentProviderRecord cpr = (ContentProviderRecord)
   11050                         mLaunchingProviders.get(i);
   11051                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
   11052                     synchronized (cpr) {
   11053                         cpr.launchingApp = null;
   11054                         cpr.notifyAll();
   11055                     }
   11056                 }
   11057             }
   11058         }
   11059 
   11060         skipCurrentReceiverLocked(app);
   11061 
   11062         // Unregister any receivers.
   11063         if (app.receivers.size() > 0) {
   11064             Iterator<ReceiverList> it = app.receivers.iterator();
   11065             while (it.hasNext()) {
   11066                 removeReceiverLocked(it.next());
   11067             }
   11068             app.receivers.clear();
   11069         }
   11070 
   11071         // If the app is undergoing backup, tell the backup manager about it
   11072         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
   11073             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
   11074                     + mBackupTarget.appInfo + " died during backup");
   11075             try {
   11076                 IBackupManager bm = IBackupManager.Stub.asInterface(
   11077                         ServiceManager.getService(Context.BACKUP_SERVICE));
   11078                 bm.agentDisconnected(app.info.packageName);
   11079             } catch (RemoteException e) {
   11080                 // can't happen; backup manager is local
   11081             }
   11082         }
   11083 
   11084         for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
   11085             ProcessChangeItem item = mPendingProcessChanges.get(i);
   11086             if (item.pid == app.pid) {
   11087                 mPendingProcessChanges.remove(i);
   11088                 mAvailProcessChanges.add(item);
   11089             }
   11090         }
   11091         mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
   11092 
   11093         // If the caller is restarting this app, then leave it in its
   11094         // current lists and let the caller take care of it.
   11095         if (restarting) {
   11096             return;
   11097         }
   11098 
   11099         if (!app.persistent || app.isolated) {
   11100             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
   11101                     "Removing non-persistent process during cleanup: " + app);
   11102             mProcessNames.remove(app.processName, app.uid);
   11103             mIsolatedProcesses.remove(app.uid);
   11104             if (mHeavyWeightProcess == app) {
   11105                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   11106                         mHeavyWeightProcess.userId, 0));
   11107                 mHeavyWeightProcess = null;
   11108             }
   11109         } else if (!app.removed) {
   11110             // This app is persistent, so we need to keep its record around.
   11111             // If it is not already on the pending app list, add it there
   11112             // and start a new process for it.
   11113             if (mPersistentStartingProcesses.indexOf(app) < 0) {
   11114                 mPersistentStartingProcesses.add(app);
   11115                 restart = true;
   11116             }
   11117         }
   11118         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
   11119                 "Clean-up removing on hold: " + app);
   11120         mProcessesOnHold.remove(app);
   11121 
   11122         if (app == mHomeProcess) {
   11123             mHomeProcess = null;
   11124         }
   11125         if (app == mPreviousProcess) {
   11126             mPreviousProcess = null;
   11127         }
   11128 
   11129         if (restart && !app.isolated) {
   11130             // We have components that still need to be running in the
   11131             // process, so re-launch it.
   11132             mProcessNames.put(app.processName, app.uid, app);
   11133             startProcessLocked(app, "restart", app.processName);
   11134         } else if (app.pid > 0 && app.pid != MY_PID) {
   11135             // Goodbye!
   11136             synchronized (mPidsSelfLocked) {
   11137                 mPidsSelfLocked.remove(app.pid);
   11138                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   11139             }
   11140             app.setPid(0);
   11141         }
   11142     }
   11143 
   11144     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
   11145         // Look through the content providers we are waiting to have launched,
   11146         // and if any run in this process then either schedule a restart of
   11147         // the process or kill the client waiting for it if this process has
   11148         // gone bad.
   11149         int NL = mLaunchingProviders.size();
   11150         boolean restart = false;
   11151         for (int i=0; i<NL; i++) {
   11152             ContentProviderRecord cpr = mLaunchingProviders.get(i);
   11153             if (cpr.launchingApp == app) {
   11154                 if (!alwaysBad && !app.bad) {
   11155                     restart = true;
   11156                 } else {
   11157                     removeDyingProviderLocked(app, cpr, true);
   11158                     // cpr should have been removed from mLaunchingProviders
   11159                     NL = mLaunchingProviders.size();
   11160                     i--;
   11161                 }
   11162             }
   11163         }
   11164         return restart;
   11165     }
   11166 
   11167     // =========================================================
   11168     // SERVICES
   11169     // =========================================================
   11170 
   11171     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
   11172             int flags) {
   11173         enforceNotIsolatedCaller("getServices");
   11174         synchronized (this) {
   11175             return mServices.getRunningServiceInfoLocked(maxNum, flags);
   11176         }
   11177     }
   11178 
   11179     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
   11180         enforceNotIsolatedCaller("getRunningServiceControlPanel");
   11181         synchronized (this) {
   11182             return mServices.getRunningServiceControlPanelLocked(name);
   11183         }
   11184     }
   11185 
   11186     public ComponentName startService(IApplicationThread caller, Intent service,
   11187             String resolvedType, int userId) {
   11188         enforceNotIsolatedCaller("startService");
   11189         // Refuse possible leaked file descriptors
   11190         if (service != null && service.hasFileDescriptors() == true) {
   11191             throw new IllegalArgumentException("File descriptors passed in Intent");
   11192         }
   11193 
   11194         if (DEBUG_SERVICE)
   11195             Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
   11196         synchronized(this) {
   11197             final int callingPid = Binder.getCallingPid();
   11198             final int callingUid = Binder.getCallingUid();
   11199             checkValidCaller(callingUid, userId);
   11200             final long origId = Binder.clearCallingIdentity();
   11201             ComponentName res = mServices.startServiceLocked(caller, service,
   11202                     resolvedType, callingPid, callingUid, userId);
   11203             Binder.restoreCallingIdentity(origId);
   11204             return res;
   11205         }
   11206     }
   11207 
   11208     ComponentName startServiceInPackage(int uid,
   11209             Intent service, String resolvedType, int userId) {
   11210         synchronized(this) {
   11211             if (DEBUG_SERVICE)
   11212                 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
   11213             final long origId = Binder.clearCallingIdentity();
   11214             ComponentName res = mServices.startServiceLocked(null, service,
   11215                     resolvedType, -1, uid, userId);
   11216             Binder.restoreCallingIdentity(origId);
   11217             return res;
   11218         }
   11219     }
   11220 
   11221     public int stopService(IApplicationThread caller, Intent service,
   11222             String resolvedType, int userId) {
   11223         enforceNotIsolatedCaller("stopService");
   11224         // Refuse possible leaked file descriptors
   11225         if (service != null && service.hasFileDescriptors() == true) {
   11226             throw new IllegalArgumentException("File descriptors passed in Intent");
   11227         }
   11228 
   11229         checkValidCaller(Binder.getCallingUid(), userId);
   11230 
   11231         synchronized(this) {
   11232             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
   11233         }
   11234     }
   11235 
   11236     public IBinder peekService(Intent service, String resolvedType) {
   11237         enforceNotIsolatedCaller("peekService");
   11238         // Refuse possible leaked file descriptors
   11239         if (service != null && service.hasFileDescriptors() == true) {
   11240             throw new IllegalArgumentException("File descriptors passed in Intent");
   11241         }
   11242         synchronized(this) {
   11243             return mServices.peekServiceLocked(service, resolvedType);
   11244         }
   11245     }
   11246 
   11247     public boolean stopServiceToken(ComponentName className, IBinder token,
   11248             int startId) {
   11249         synchronized(this) {
   11250             return mServices.stopServiceTokenLocked(className, token, startId);
   11251         }
   11252     }
   11253 
   11254     public void setServiceForeground(ComponentName className, IBinder token,
   11255             int id, Notification notification, boolean removeNotification) {
   11256         synchronized(this) {
   11257             mServices.setServiceForegroundLocked(className, token, id, notification,
   11258                     removeNotification);
   11259         }
   11260     }
   11261 
   11262     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
   11263             boolean requireFull, String name, String callerPackage) {
   11264         final int callingUserId = UserHandle.getUserId(callingUid);
   11265         if (callingUserId != userId) {
   11266             if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   11267                 if ((requireFull || checkComponentPermission(
   11268                         android.Manifest.permission.INTERACT_ACROSS_USERS,
   11269                         callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
   11270                         && checkComponentPermission(
   11271                                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   11272                                 callingPid, callingUid, -1, true)
   11273                                 != PackageManager.PERMISSION_GRANTED) {
   11274                     if (userId == UserHandle.USER_CURRENT_OR_SELF) {
   11275                         // In this case, they would like to just execute as their
   11276                         // owner user instead of failing.
   11277                         userId = callingUserId;
   11278                     } else {
   11279                         StringBuilder builder = new StringBuilder(128);
   11280                         builder.append("Permission Denial: ");
   11281                         builder.append(name);
   11282                         if (callerPackage != null) {
   11283                             builder.append(" from ");
   11284                             builder.append(callerPackage);
   11285                         }
   11286                         builder.append(" asks to run as user ");
   11287                         builder.append(userId);
   11288                         builder.append(" but is calling from user ");
   11289                         builder.append(UserHandle.getUserId(callingUid));
   11290                         builder.append("; this requires ");
   11291                         builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
   11292                         if (!requireFull) {
   11293                             builder.append(" or ");
   11294                             builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
   11295                         }
   11296                         String msg = builder.toString();
   11297                         Slog.w(TAG, msg);
   11298                         throw new SecurityException(msg);
   11299                     }
   11300                 }
   11301             }
   11302             if (userId == UserHandle.USER_CURRENT
   11303                     || userId == UserHandle.USER_CURRENT_OR_SELF) {
   11304                 // Note that we may be accessing this outside of a lock...
   11305                 // shouldn't be a big deal, if this is being called outside
   11306                 // of a locked context there is intrinsically a race with
   11307                 // the value the caller will receive and someone else changing it.
   11308                 userId = mCurrentUserId;
   11309             }
   11310             if (!allowAll && userId < 0) {
   11311                 throw new IllegalArgumentException(
   11312                         "Call does not support special user #" + userId);
   11313             }
   11314         }
   11315         return userId;
   11316     }
   11317 
   11318     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
   11319             String className, int flags) {
   11320         boolean result = false;
   11321         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
   11322             if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
   11323                 if (ActivityManager.checkUidPermission(
   11324                         android.Manifest.permission.INTERACT_ACROSS_USERS,
   11325                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
   11326                     ComponentName comp = new ComponentName(aInfo.packageName, className);
   11327                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
   11328                             + " requests FLAG_SINGLE_USER, but app does not hold "
   11329                             + android.Manifest.permission.INTERACT_ACROSS_USERS;
   11330                     Slog.w(TAG, msg);
   11331                     throw new SecurityException(msg);
   11332                 }
   11333                 result = true;
   11334             }
   11335         } else if (componentProcessName == aInfo.packageName) {
   11336             result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
   11337         } else if ("system".equals(componentProcessName)) {
   11338             result = true;
   11339         }
   11340         if (DEBUG_MU) {
   11341             Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
   11342                     + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
   11343         }
   11344         return result;
   11345     }
   11346 
   11347     public int bindService(IApplicationThread caller, IBinder token,
   11348             Intent service, String resolvedType,
   11349             IServiceConnection connection, int flags, int userId) {
   11350         enforceNotIsolatedCaller("bindService");
   11351         // Refuse possible leaked file descriptors
   11352         if (service != null && service.hasFileDescriptors() == true) {
   11353             throw new IllegalArgumentException("File descriptors passed in Intent");
   11354         }
   11355 
   11356         synchronized(this) {
   11357             return mServices.bindServiceLocked(caller, token, service, resolvedType,
   11358                     connection, flags, userId);
   11359         }
   11360     }
   11361 
   11362     public boolean unbindService(IServiceConnection connection) {
   11363         synchronized (this) {
   11364             return mServices.unbindServiceLocked(connection);
   11365         }
   11366     }
   11367 
   11368     public void publishService(IBinder token, Intent intent, IBinder service) {
   11369         // Refuse possible leaked file descriptors
   11370         if (intent != null && intent.hasFileDescriptors() == true) {
   11371             throw new IllegalArgumentException("File descriptors passed in Intent");
   11372         }
   11373 
   11374         synchronized(this) {
   11375             if (!(token instanceof ServiceRecord)) {
   11376                 throw new IllegalArgumentException("Invalid service token");
   11377             }
   11378             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
   11379         }
   11380     }
   11381 
   11382     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
   11383         // Refuse possible leaked file descriptors
   11384         if (intent != null && intent.hasFileDescriptors() == true) {
   11385             throw new IllegalArgumentException("File descriptors passed in Intent");
   11386         }
   11387 
   11388         synchronized(this) {
   11389             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
   11390         }
   11391     }
   11392 
   11393     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
   11394         synchronized(this) {
   11395             if (!(token instanceof ServiceRecord)) {
   11396                 throw new IllegalArgumentException("Invalid service token");
   11397             }
   11398             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
   11399         }
   11400     }
   11401 
   11402     // =========================================================
   11403     // BACKUP AND RESTORE
   11404     // =========================================================
   11405 
   11406     // Cause the target app to be launched if necessary and its backup agent
   11407     // instantiated.  The backup agent will invoke backupAgentCreated() on the
   11408     // activity manager to announce its creation.
   11409     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
   11410         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
   11411         enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
   11412 
   11413         synchronized(this) {
   11414             // !!! TODO: currently no check here that we're already bound
   11415             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   11416             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   11417             synchronized (stats) {
   11418                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
   11419             }
   11420 
   11421             // Backup agent is now in use, its package can't be stopped.
   11422             try {
   11423                 AppGlobals.getPackageManager().setPackageStoppedState(
   11424                         app.packageName, false, UserHandle.getUserId(app.uid));
   11425             } catch (RemoteException e) {
   11426             } catch (IllegalArgumentException e) {
   11427                 Slog.w(TAG, "Failed trying to unstop package "
   11428                         + app.packageName + ": " + e);
   11429             }
   11430 
   11431             BackupRecord r = new BackupRecord(ss, app, backupMode);
   11432             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
   11433                     ? new ComponentName(app.packageName, app.backupAgentName)
   11434                     : new ComponentName("android", "FullBackupAgent");
   11435             // startProcessLocked() returns existing proc's record if it's already running
   11436             ProcessRecord proc = startProcessLocked(app.processName, app,
   11437                     false, 0, "backup", hostingName, false, false);
   11438             if (proc == null) {
   11439                 Slog.e(TAG, "Unable to start backup agent process " + r);
   11440                 return false;
   11441             }
   11442 
   11443             r.app = proc;
   11444             mBackupTarget = r;
   11445             mBackupAppName = app.packageName;
   11446 
   11447             // Try not to kill the process during backup
   11448             updateOomAdjLocked(proc);
   11449 
   11450             // If the process is already attached, schedule the creation of the backup agent now.
   11451             // If it is not yet live, this will be done when it attaches to the framework.
   11452             if (proc.thread != null) {
   11453                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
   11454                 try {
   11455                     proc.thread.scheduleCreateBackupAgent(app,
   11456                             compatibilityInfoForPackageLocked(app), backupMode);
   11457                 } catch (RemoteException e) {
   11458                     // Will time out on the backup manager side
   11459                 }
   11460             } else {
   11461                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
   11462             }
   11463             // Invariants: at this point, the target app process exists and the application
   11464             // is either already running or in the process of coming up.  mBackupTarget and
   11465             // mBackupAppName describe the app, so that when it binds back to the AM we
   11466             // know that it's scheduled for a backup-agent operation.
   11467         }
   11468 
   11469         return true;
   11470     }
   11471 
   11472     @Override
   11473     public void clearPendingBackup() {
   11474         if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
   11475         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
   11476 
   11477         synchronized (this) {
   11478             mBackupTarget = null;
   11479             mBackupAppName = null;
   11480         }
   11481     }
   11482 
   11483     // A backup agent has just come up
   11484     public void backupAgentCreated(String agentPackageName, IBinder agent) {
   11485         if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
   11486                 + " = " + agent);
   11487 
   11488         synchronized(this) {
   11489             if (!agentPackageName.equals(mBackupAppName)) {
   11490                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
   11491                 return;
   11492             }
   11493         }
   11494 
   11495         long oldIdent = Binder.clearCallingIdentity();
   11496         try {
   11497             IBackupManager bm = IBackupManager.Stub.asInterface(
   11498                     ServiceManager.getService(Context.BACKUP_SERVICE));
   11499             bm.agentConnected(agentPackageName, agent);
   11500         } catch (RemoteException e) {
   11501             // can't happen; the backup manager service is local
   11502         } catch (Exception e) {
   11503             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
   11504             e.printStackTrace();
   11505         } finally {
   11506             Binder.restoreCallingIdentity(oldIdent);
   11507         }
   11508     }
   11509 
   11510     // done with this agent
   11511     public void unbindBackupAgent(ApplicationInfo appInfo) {
   11512         if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
   11513         if (appInfo == null) {
   11514             Slog.w(TAG, "unbind backup agent for null app");
   11515             return;
   11516         }
   11517 
   11518         synchronized(this) {
   11519             try {
   11520                 if (mBackupAppName == null) {
   11521                     Slog.w(TAG, "Unbinding backup agent with no active backup");
   11522                     return;
   11523                 }
   11524 
   11525                 if (!mBackupAppName.equals(appInfo.packageName)) {
   11526                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
   11527                     return;
   11528                 }
   11529 
   11530                 // Not backing this app up any more; reset its OOM adjustment
   11531                 final ProcessRecord proc = mBackupTarget.app;
   11532                 updateOomAdjLocked(proc);
   11533 
   11534                 // If the app crashed during backup, 'thread' will be null here
   11535                 if (proc.thread != null) {
   11536                     try {
   11537                         proc.thread.scheduleDestroyBackupAgent(appInfo,
   11538                                 compatibilityInfoForPackageLocked(appInfo));
   11539                     } catch (Exception e) {
   11540                         Slog.e(TAG, "Exception when unbinding backup agent:");
   11541                         e.printStackTrace();
   11542                     }
   11543                 }
   11544             } finally {
   11545                 mBackupTarget = null;
   11546                 mBackupAppName = null;
   11547             }
   11548         }
   11549     }
   11550     // =========================================================
   11551     // BROADCASTS
   11552     // =========================================================
   11553 
   11554     private final List getStickiesLocked(String action, IntentFilter filter,
   11555             List cur, int userId) {
   11556         final ContentResolver resolver = mContext.getContentResolver();
   11557         HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   11558         if (stickies == null) {
   11559             return cur;
   11560         }
   11561         final ArrayList<Intent> list = stickies.get(action);
   11562         if (list == null) {
   11563             return cur;
   11564         }
   11565         int N = list.size();
   11566         for (int i=0; i<N; i++) {
   11567             Intent intent = list.get(i);
   11568             if (filter.match(resolver, intent, true, TAG) >= 0) {
   11569                 if (cur == null) {
   11570                     cur = new ArrayList<Intent>();
   11571                 }
   11572                 cur.add(intent);
   11573             }
   11574         }
   11575         return cur;
   11576     }
   11577 
   11578     boolean isPendingBroadcastProcessLocked(int pid) {
   11579         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
   11580                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
   11581     }
   11582 
   11583     void skipPendingBroadcastLocked(int pid) {
   11584             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   11585             for (BroadcastQueue queue : mBroadcastQueues) {
   11586                 queue.skipPendingBroadcastLocked(pid);
   11587             }
   11588     }
   11589 
   11590     // The app just attached; send any pending broadcasts that it should receive
   11591     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
   11592         boolean didSomething = false;
   11593         for (BroadcastQueue queue : mBroadcastQueues) {
   11594             didSomething |= queue.sendPendingBroadcastsLocked(app);
   11595         }
   11596         return didSomething;
   11597     }
   11598 
   11599     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
   11600             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
   11601         enforceNotIsolatedCaller("registerReceiver");
   11602         int callingUid;
   11603         int callingPid;
   11604         synchronized(this) {
   11605             ProcessRecord callerApp = null;
   11606             if (caller != null) {
   11607                 callerApp = getRecordForAppLocked(caller);
   11608                 if (callerApp == null) {
   11609                     throw new SecurityException(
   11610                             "Unable to find app for caller " + caller
   11611                             + " (pid=" + Binder.getCallingPid()
   11612                             + ") when registering receiver " + receiver);
   11613                 }
   11614                 if (callerApp.info.uid != Process.SYSTEM_UID &&
   11615                         !callerApp.pkgList.contains(callerPackage)) {
   11616                     throw new SecurityException("Given caller package " + callerPackage
   11617                             + " is not running in process " + callerApp);
   11618                 }
   11619                 callingUid = callerApp.info.uid;
   11620                 callingPid = callerApp.pid;
   11621             } else {
   11622                 callerPackage = null;
   11623                 callingUid = Binder.getCallingUid();
   11624                 callingPid = Binder.getCallingPid();
   11625             }
   11626 
   11627             userId = this.handleIncomingUser(callingPid, callingUid, userId,
   11628                     true, true, "registerReceiver", callerPackage);
   11629 
   11630             List allSticky = null;
   11631 
   11632             // Look for any matching sticky broadcasts...
   11633             Iterator actions = filter.actionsIterator();
   11634             if (actions != null) {
   11635                 while (actions.hasNext()) {
   11636                     String action = (String)actions.next();
   11637                     allSticky = getStickiesLocked(action, filter, allSticky,
   11638                             UserHandle.USER_ALL);
   11639                     allSticky = getStickiesLocked(action, filter, allSticky,
   11640                             UserHandle.getUserId(callingUid));
   11641                 }
   11642             } else {
   11643                 allSticky = getStickiesLocked(null, filter, allSticky,
   11644                         UserHandle.USER_ALL);
   11645                 allSticky = getStickiesLocked(null, filter, allSticky,
   11646                         UserHandle.getUserId(callingUid));
   11647             }
   11648 
   11649             // The first sticky in the list is returned directly back to
   11650             // the client.
   11651             Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
   11652 
   11653             if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
   11654                     + ": " + sticky);
   11655 
   11656             if (receiver == null) {
   11657                 return sticky;
   11658             }
   11659 
   11660             ReceiverList rl
   11661                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   11662             if (rl == null) {
   11663                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
   11664                         userId, receiver);
   11665                 if (rl.app != null) {
   11666                     rl.app.receivers.add(rl);
   11667                 } else {
   11668                     try {
   11669                         receiver.asBinder().linkToDeath(rl, 0);
   11670                     } catch (RemoteException e) {
   11671                         return sticky;
   11672                     }
   11673                     rl.linkedToDeath = true;
   11674                 }
   11675                 mRegisteredReceivers.put(receiver.asBinder(), rl);
   11676             } else if (rl.uid != callingUid) {
   11677                 throw new IllegalArgumentException(
   11678                         "Receiver requested to register for uid " + callingUid
   11679                         + " was previously registered for uid " + rl.uid);
   11680             } else if (rl.pid != callingPid) {
   11681                 throw new IllegalArgumentException(
   11682                         "Receiver requested to register for pid " + callingPid
   11683                         + " was previously registered for pid " + rl.pid);
   11684             } else if (rl.userId != userId) {
   11685                 throw new IllegalArgumentException(
   11686                         "Receiver requested to register for user " + userId
   11687                         + " was previously registered for user " + rl.userId);
   11688             }
   11689             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
   11690                     permission, callingUid, userId);
   11691             rl.add(bf);
   11692             if (!bf.debugCheck()) {
   11693                 Slog.w(TAG, "==> For Dynamic broadast");
   11694             }
   11695             mReceiverResolver.addFilter(bf);
   11696 
   11697             // Enqueue broadcasts for all existing stickies that match
   11698             // this filter.
   11699             if (allSticky != null) {
   11700                 ArrayList receivers = new ArrayList();
   11701                 receivers.add(bf);
   11702 
   11703                 int N = allSticky.size();
   11704                 for (int i=0; i<N; i++) {
   11705                     Intent intent = (Intent)allSticky.get(i);
   11706                     BroadcastQueue queue = broadcastQueueForIntent(intent);
   11707                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
   11708                             null, -1, -1, null, AppOpsManager.OP_NONE, receivers, null, 0,
   11709                             null, null, false, true, true, -1);
   11710                     queue.enqueueParallelBroadcastLocked(r);
   11711                     queue.scheduleBroadcastsLocked();
   11712                 }
   11713             }
   11714 
   11715             return sticky;
   11716         }
   11717     }
   11718 
   11719     public void unregisterReceiver(IIntentReceiver receiver) {
   11720         if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
   11721 
   11722         final long origId = Binder.clearCallingIdentity();
   11723         try {
   11724             boolean doTrim = false;
   11725 
   11726             synchronized(this) {
   11727                 ReceiverList rl
   11728                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   11729                 if (rl != null) {
   11730                     if (rl.curBroadcast != null) {
   11731                         BroadcastRecord r = rl.curBroadcast;
   11732                         final boolean doNext = finishReceiverLocked(
   11733                                 receiver.asBinder(), r.resultCode, r.resultData,
   11734                                 r.resultExtras, r.resultAbort, true);
   11735                         if (doNext) {
   11736                             doTrim = true;
   11737                             r.queue.processNextBroadcast(false);
   11738                         }
   11739                     }
   11740 
   11741                     if (rl.app != null) {
   11742                         rl.app.receivers.remove(rl);
   11743                     }
   11744                     removeReceiverLocked(rl);
   11745                     if (rl.linkedToDeath) {
   11746                         rl.linkedToDeath = false;
   11747                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
   11748                     }
   11749                 }
   11750             }
   11751 
   11752             // If we actually concluded any broadcasts, we might now be able
   11753             // to trim the recipients' apps from our working set
   11754             if (doTrim) {
   11755                 trimApplications();
   11756                 return;
   11757             }
   11758 
   11759         } finally {
   11760             Binder.restoreCallingIdentity(origId);
   11761         }
   11762     }
   11763 
   11764     void removeReceiverLocked(ReceiverList rl) {
   11765         mRegisteredReceivers.remove(rl.receiver.asBinder());
   11766         int N = rl.size();
   11767         for (int i=0; i<N; i++) {
   11768             mReceiverResolver.removeFilter(rl.get(i));
   11769         }
   11770     }
   11771 
   11772     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
   11773         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   11774             ProcessRecord r = mLruProcesses.get(i);
   11775             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
   11776                 try {
   11777                     r.thread.dispatchPackageBroadcast(cmd, packages);
   11778                 } catch (RemoteException ex) {
   11779                 }
   11780             }
   11781         }
   11782     }
   11783 
   11784     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
   11785             int[] users) {
   11786         List<ResolveInfo> receivers = null;
   11787         try {
   11788             HashSet<ComponentName> singleUserReceivers = null;
   11789             boolean scannedFirstReceivers = false;
   11790             for (int user : users) {
   11791                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
   11792                         .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
   11793                 if (user != 0 && newReceivers != null) {
   11794                     // If this is not the primary user, we need to check for
   11795                     // any receivers that should be filtered out.
   11796                     for (int i=0; i<newReceivers.size(); i++) {
   11797                         ResolveInfo ri = newReceivers.get(i);
   11798                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
   11799                             newReceivers.remove(i);
   11800                             i--;
   11801                         }
   11802                     }
   11803                 }
   11804                 if (newReceivers != null && newReceivers.size() == 0) {
   11805                     newReceivers = null;
   11806                 }
   11807                 if (receivers == null) {
   11808                     receivers = newReceivers;
   11809                 } else if (newReceivers != null) {
   11810                     // We need to concatenate the additional receivers
   11811                     // found with what we have do far.  This would be easy,
   11812                     // but we also need to de-dup any receivers that are
   11813                     // singleUser.
   11814                     if (!scannedFirstReceivers) {
   11815                         // Collect any single user receivers we had already retrieved.
   11816                         scannedFirstReceivers = true;
   11817                         for (int i=0; i<receivers.size(); i++) {
   11818                             ResolveInfo ri = receivers.get(i);
   11819                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   11820                                 ComponentName cn = new ComponentName(
   11821                                         ri.activityInfo.packageName, ri.activityInfo.name);
   11822                                 if (singleUserReceivers == null) {
   11823                                     singleUserReceivers = new HashSet<ComponentName>();
   11824                                 }
   11825                                 singleUserReceivers.add(cn);
   11826                             }
   11827                         }
   11828                     }
   11829                     // Add the new results to the existing results, tracking
   11830                     // and de-dupping single user receivers.
   11831                     for (int i=0; i<newReceivers.size(); i++) {
   11832                         ResolveInfo ri = newReceivers.get(i);
   11833                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   11834                             ComponentName cn = new ComponentName(
   11835                                     ri.activityInfo.packageName, ri.activityInfo.name);
   11836                             if (singleUserReceivers == null) {
   11837                                 singleUserReceivers = new HashSet<ComponentName>();
   11838                             }
   11839                             if (!singleUserReceivers.contains(cn)) {
   11840                                 singleUserReceivers.add(cn);
   11841                                 receivers.add(ri);
   11842                             }
   11843                         } else {
   11844                             receivers.add(ri);
   11845                         }
   11846                     }
   11847                 }
   11848             }
   11849         } catch (RemoteException ex) {
   11850             // pm is in same process, this will never happen.
   11851         }
   11852         return receivers;
   11853     }
   11854 
   11855     private final int broadcastIntentLocked(ProcessRecord callerApp,
   11856             String callerPackage, Intent intent, String resolvedType,
   11857             IIntentReceiver resultTo, int resultCode, String resultData,
   11858             Bundle map, String requiredPermission, int appOp,
   11859             boolean ordered, boolean sticky, int callingPid, int callingUid,
   11860             int userId) {
   11861         intent = new Intent(intent);
   11862 
   11863         // By default broadcasts do not go to stopped apps.
   11864         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
   11865 
   11866         if (DEBUG_BROADCAST_LIGHT) Slog.v(
   11867             TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
   11868             + " ordered=" + ordered + " userid=" + userId);
   11869         if ((resultTo != null) && !ordered) {
   11870             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
   11871         }
   11872 
   11873         userId = handleIncomingUser(callingPid, callingUid, userId,
   11874                 true, false, "broadcast", callerPackage);
   11875 
   11876         // Make sure that the user who is receiving this broadcast is started.
   11877         // If not, we will just skip it.
   11878         if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
   11879             if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
   11880                     & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
   11881                 Slog.w(TAG, "Skipping broadcast of " + intent
   11882                         + ": user " + userId + " is stopped");
   11883                 return ActivityManager.BROADCAST_SUCCESS;
   11884             }
   11885         }
   11886 
   11887         /*
   11888          * Prevent non-system code (defined here to be non-persistent
   11889          * processes) from sending protected broadcasts.
   11890          */
   11891         int callingAppId = UserHandle.getAppId(callingUid);
   11892         if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
   11893             || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
   11894             callingUid == 0) {
   11895             // Always okay.
   11896         } else if (callerApp == null || !callerApp.persistent) {
   11897             try {
   11898                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
   11899                         intent.getAction())) {
   11900                     String msg = "Permission Denial: not allowed to send broadcast "
   11901                             + intent.getAction() + " from pid="
   11902                             + callingPid + ", uid=" + callingUid;
   11903                     Slog.w(TAG, msg);
   11904                     throw new SecurityException(msg);
   11905                 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
   11906                     // Special case for compatibility: we don't want apps to send this,
   11907                     // but historically it has not been protected and apps may be using it
   11908                     // to poke their own app widget.  So, instead of making it protected,
   11909                     // just limit it to the caller.
   11910                     if (callerApp == null) {
   11911                         String msg = "Permission Denial: not allowed to send broadcast "
   11912                                 + intent.getAction() + " from unknown caller.";
   11913                         Slog.w(TAG, msg);
   11914                         throw new SecurityException(msg);
   11915                     } else if (intent.getComponent() != null) {
   11916                         // They are good enough to send to an explicit component...  verify
   11917                         // it is being sent to the calling app.
   11918                         if (!intent.getComponent().getPackageName().equals(
   11919                                 callerApp.info.packageName)) {
   11920                             String msg = "Permission Denial: not allowed to send broadcast "
   11921                                     + intent.getAction() + " to "
   11922                                     + intent.getComponent().getPackageName() + " from "
   11923                                     + callerApp.info.packageName;
   11924                             Slog.w(TAG, msg);
   11925                             throw new SecurityException(msg);
   11926                         }
   11927                     } else {
   11928                         // Limit broadcast to their own package.
   11929                         intent.setPackage(callerApp.info.packageName);
   11930                     }
   11931                 }
   11932             } catch (RemoteException e) {
   11933                 Slog.w(TAG, "Remote exception", e);
   11934                 return ActivityManager.BROADCAST_SUCCESS;
   11935             }
   11936         }
   11937 
   11938         // Handle special intents: if this broadcast is from the package
   11939         // manager about a package being removed, we need to remove all of
   11940         // its activities from the history stack.
   11941         final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
   11942                 intent.getAction());
   11943         if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
   11944                 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
   11945                 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
   11946                 || uidRemoved) {
   11947             if (checkComponentPermission(
   11948                     android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
   11949                     callingPid, callingUid, -1, true)
   11950                     == PackageManager.PERMISSION_GRANTED) {
   11951                 if (uidRemoved) {
   11952                     final Bundle intentExtras = intent.getExtras();
   11953                     final int uid = intentExtras != null
   11954                             ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
   11955                     if (uid >= 0) {
   11956                         BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
   11957                         synchronized (bs) {
   11958                             bs.removeUidStatsLocked(uid);
   11959                         }
   11960                         mAppOpsService.uidRemoved(uid);
   11961                     }
   11962                 } else {
   11963                     // If resources are unavailable just force stop all
   11964                     // those packages and flush the attribute cache as well.
   11965                     if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
   11966                         String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   11967                         if (list != null && (list.length > 0)) {
   11968                             for (String pkg : list) {
   11969                                 forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
   11970                             }
   11971                             sendPackageBroadcastLocked(
   11972                                     IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
   11973                         }
   11974                     } else {
   11975                         Uri data = intent.getData();
   11976                         String ssp;
   11977                         if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   11978                             if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
   11979                                 forceStopPackageLocked(ssp,
   11980                                         intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
   11981                                         false, userId);
   11982                             }
   11983                             if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
   11984                                 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
   11985                                         new String[] {ssp}, userId);
   11986                                 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
   11987                                     mAppOpsService.packageRemoved(
   11988                                             intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
   11989                                 }
   11990                             }
   11991                         }
   11992                     }
   11993                 }
   11994             } else {
   11995                 String msg = "Permission Denial: " + intent.getAction()
   11996                         + " broadcast from " + callerPackage + " (pid=" + callingPid
   11997                         + ", uid=" + callingUid + ")"
   11998                         + " requires "
   11999                         + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
   12000                 Slog.w(TAG, msg);
   12001                 throw new SecurityException(msg);
   12002             }
   12003 
   12004         // Special case for adding a package: by default turn on compatibility
   12005         // mode.
   12006         } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
   12007             Uri data = intent.getData();
   12008             String ssp;
   12009             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   12010                 mCompatModePackages.handlePackageAddedLocked(ssp,
   12011                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
   12012             }
   12013         }
   12014 
   12015         /*
   12016          * If this is the time zone changed action, queue up a message that will reset the timezone
   12017          * of all currently running processes. This message will get queued up before the broadcast
   12018          * happens.
   12019          */
   12020         if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
   12021             mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
   12022         }
   12023 
   12024         if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
   12025             mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
   12026         }
   12027 
   12028         if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
   12029             ProxyProperties proxy = intent.getParcelableExtra("proxy");
   12030             mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
   12031         }
   12032 
   12033         // Add to the sticky list if requested.
   12034         if (sticky) {
   12035             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
   12036                     callingPid, callingUid)
   12037                     != PackageManager.PERMISSION_GRANTED) {
   12038                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
   12039                         + callingPid + ", uid=" + callingUid
   12040                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   12041                 Slog.w(TAG, msg);
   12042                 throw new SecurityException(msg);
   12043             }
   12044             if (requiredPermission != null) {
   12045                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
   12046                         + " and enforce permission " + requiredPermission);
   12047                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
   12048             }
   12049             if (intent.getComponent() != null) {
   12050                 throw new SecurityException(
   12051                         "Sticky broadcasts can't target a specific component");
   12052             }
   12053             // We use userId directly here, since the "all" target is maintained
   12054             // as a separate set of sticky broadcasts.
   12055             if (userId != UserHandle.USER_ALL) {
   12056                 // But first, if this is not a broadcast to all users, then
   12057                 // make sure it doesn't conflict with an existing broadcast to
   12058                 // all users.
   12059                 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
   12060                         UserHandle.USER_ALL);
   12061                 if (stickies != null) {
   12062                     ArrayList<Intent> list = stickies.get(intent.getAction());
   12063                     if (list != null) {
   12064                         int N = list.size();
   12065                         int i;
   12066                         for (i=0; i<N; i++) {
   12067                             if (intent.filterEquals(list.get(i))) {
   12068                                 throw new IllegalArgumentException(
   12069                                         "Sticky broadcast " + intent + " for user "
   12070                                         + userId + " conflicts with existing global broadcast");
   12071                             }
   12072                         }
   12073                     }
   12074                 }
   12075             }
   12076             HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   12077             if (stickies == null) {
   12078                 stickies = new HashMap<String, ArrayList<Intent>>();
   12079                 mStickyBroadcasts.put(userId, stickies);
   12080             }
   12081             ArrayList<Intent> list = stickies.get(intent.getAction());
   12082             if (list == null) {
   12083                 list = new ArrayList<Intent>();
   12084                 stickies.put(intent.getAction(), list);
   12085             }
   12086             int N = list.size();
   12087             int i;
   12088             for (i=0; i<N; i++) {
   12089                 if (intent.filterEquals(list.get(i))) {
   12090                     // This sticky already exists, replace it.
   12091                     list.set(i, new Intent(intent));
   12092                     break;
   12093                 }
   12094             }
   12095             if (i >= N) {
   12096                 list.add(new Intent(intent));
   12097             }
   12098         }
   12099 
   12100         int[] users;
   12101         if (userId == UserHandle.USER_ALL) {
   12102             // Caller wants broadcast to go to all started users.
   12103             users = mStartedUserArray;
   12104         } else {
   12105             // Caller wants broadcast to go to one specific user.
   12106             users = new int[] {userId};
   12107         }
   12108 
   12109         // Figure out who all will receive this broadcast.
   12110         List receivers = null;
   12111         List<BroadcastFilter> registeredReceivers = null;
   12112         // Need to resolve the intent to interested receivers...
   12113         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
   12114                  == 0) {
   12115             receivers = collectReceiverComponents(intent, resolvedType, users);
   12116         }
   12117         if (intent.getComponent() == null) {
   12118             registeredReceivers = mReceiverResolver.queryIntent(intent,
   12119                     resolvedType, false, userId);
   12120         }
   12121 
   12122         final boolean replacePending =
   12123                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
   12124 
   12125         if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
   12126                 + " replacePending=" + replacePending);
   12127 
   12128         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
   12129         if (!ordered && NR > 0) {
   12130             // If we are not serializing this broadcast, then send the
   12131             // registered receivers separately so they don't wait for the
   12132             // components to be launched.
   12133             final BroadcastQueue queue = broadcastQueueForIntent(intent);
   12134             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   12135                     callerPackage, callingPid, callingUid, requiredPermission, appOp,
   12136                     registeredReceivers, resultTo, resultCode, resultData, map,
   12137                     ordered, sticky, false, userId);
   12138             if (DEBUG_BROADCAST) Slog.v(
   12139                     TAG, "Enqueueing parallel broadcast " + r);
   12140             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
   12141             if (!replaced) {
   12142                 queue.enqueueParallelBroadcastLocked(r);
   12143                 queue.scheduleBroadcastsLocked();
   12144             }
   12145             registeredReceivers = null;
   12146             NR = 0;
   12147         }
   12148 
   12149         // Merge into one list.
   12150         int ir = 0;
   12151         if (receivers != null) {
   12152             // A special case for PACKAGE_ADDED: do not allow the package
   12153             // being added to see this broadcast.  This prevents them from
   12154             // using this as a back door to get run as soon as they are
   12155             // installed.  Maybe in the future we want to have a special install
   12156             // broadcast or such for apps, but we'd like to deliberately make
   12157             // this decision.
   12158             String skipPackages[] = null;
   12159             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
   12160                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
   12161                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
   12162                 Uri data = intent.getData();
   12163                 if (data != null) {
   12164                     String pkgName = data.getSchemeSpecificPart();
   12165                     if (pkgName != null) {
   12166                         skipPackages = new String[] { pkgName };
   12167                     }
   12168                 }
   12169             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
   12170                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   12171             }
   12172             if (skipPackages != null && (skipPackages.length > 0)) {
   12173                 for (String skipPackage : skipPackages) {
   12174                     if (skipPackage != null) {
   12175                         int NT = receivers.size();
   12176                         for (int it=0; it<NT; it++) {
   12177                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
   12178                             if (curt.activityInfo.packageName.equals(skipPackage)) {
   12179                                 receivers.remove(it);
   12180                                 it--;
   12181                                 NT--;
   12182                             }
   12183                         }
   12184                     }
   12185                 }
   12186             }
   12187 
   12188             int NT = receivers != null ? receivers.size() : 0;
   12189             int it = 0;
   12190             ResolveInfo curt = null;
   12191             BroadcastFilter curr = null;
   12192             while (it < NT && ir < NR) {
   12193                 if (curt == null) {
   12194                     curt = (ResolveInfo)receivers.get(it);
   12195                 }
   12196                 if (curr == null) {
   12197                     curr = registeredReceivers.get(ir);
   12198                 }
   12199                 if (curr.getPriority() >= curt.priority) {
   12200                     // Insert this broadcast record into the final list.
   12201                     receivers.add(it, curr);
   12202                     ir++;
   12203                     curr = null;
   12204                     it++;
   12205                     NT++;
   12206                 } else {
   12207                     // Skip to the next ResolveInfo in the final list.
   12208                     it++;
   12209                     curt = null;
   12210                 }
   12211             }
   12212         }
   12213         while (ir < NR) {
   12214             if (receivers == null) {
   12215                 receivers = new ArrayList();
   12216             }
   12217             receivers.add(registeredReceivers.get(ir));
   12218             ir++;
   12219         }
   12220 
   12221         if ((receivers != null && receivers.size() > 0)
   12222                 || resultTo != null) {
   12223             BroadcastQueue queue = broadcastQueueForIntent(intent);
   12224             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   12225                     callerPackage, callingPid, callingUid, requiredPermission, appOp,
   12226                     receivers, resultTo, resultCode, resultData, map, ordered,
   12227                     sticky, false, userId);
   12228             if (DEBUG_BROADCAST) Slog.v(
   12229                     TAG, "Enqueueing ordered broadcast " + r
   12230                     + ": prev had " + queue.mOrderedBroadcasts.size());
   12231             if (DEBUG_BROADCAST) {
   12232                 int seq = r.intent.getIntExtra("seq", -1);
   12233                 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
   12234             }
   12235             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
   12236             if (!replaced) {
   12237                 queue.enqueueOrderedBroadcastLocked(r);
   12238                 queue.scheduleBroadcastsLocked();
   12239             }
   12240         }
   12241 
   12242         return ActivityManager.BROADCAST_SUCCESS;
   12243     }
   12244 
   12245     final Intent verifyBroadcastLocked(Intent intent) {
   12246         // Refuse possible leaked file descriptors
   12247         if (intent != null && intent.hasFileDescriptors() == true) {
   12248             throw new IllegalArgumentException("File descriptors passed in Intent");
   12249         }
   12250 
   12251         int flags = intent.getFlags();
   12252 
   12253         if (!mProcessesReady) {
   12254             // if the caller really truly claims to know what they're doing, go
   12255             // ahead and allow the broadcast without launching any receivers
   12256             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
   12257                 intent = new Intent(intent);
   12258                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   12259             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
   12260                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
   12261                         + " before boot completion");
   12262                 throw new IllegalStateException("Cannot broadcast before boot completed");
   12263             }
   12264         }
   12265 
   12266         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   12267             throw new IllegalArgumentException(
   12268                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   12269         }
   12270 
   12271         return intent;
   12272     }
   12273 
   12274     public final int broadcastIntent(IApplicationThread caller,
   12275             Intent intent, String resolvedType, IIntentReceiver resultTo,
   12276             int resultCode, String resultData, Bundle map,
   12277             String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
   12278         enforceNotIsolatedCaller("broadcastIntent");
   12279         synchronized(this) {
   12280             intent = verifyBroadcastLocked(intent);
   12281 
   12282             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   12283             final int callingPid = Binder.getCallingPid();
   12284             final int callingUid = Binder.getCallingUid();
   12285             final long origId = Binder.clearCallingIdentity();
   12286             int res = broadcastIntentLocked(callerApp,
   12287                     callerApp != null ? callerApp.info.packageName : null,
   12288                     intent, resolvedType, resultTo,
   12289                     resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
   12290                     callingPid, callingUid, userId);
   12291             Binder.restoreCallingIdentity(origId);
   12292             return res;
   12293         }
   12294     }
   12295 
   12296     int broadcastIntentInPackage(String packageName, int uid,
   12297             Intent intent, String resolvedType, IIntentReceiver resultTo,
   12298             int resultCode, String resultData, Bundle map,
   12299             String requiredPermission, boolean serialized, boolean sticky, int userId) {
   12300         synchronized(this) {
   12301             intent = verifyBroadcastLocked(intent);
   12302 
   12303             final long origId = Binder.clearCallingIdentity();
   12304             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
   12305                     resultTo, resultCode, resultData, map, requiredPermission,
   12306                     AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
   12307             Binder.restoreCallingIdentity(origId);
   12308             return res;
   12309         }
   12310     }
   12311 
   12312     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
   12313         // Refuse possible leaked file descriptors
   12314         if (intent != null && intent.hasFileDescriptors() == true) {
   12315             throw new IllegalArgumentException("File descriptors passed in Intent");
   12316         }
   12317 
   12318         userId = handleIncomingUser(Binder.getCallingPid(),
   12319                 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
   12320 
   12321         synchronized(this) {
   12322             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
   12323                     != PackageManager.PERMISSION_GRANTED) {
   12324                 String msg = "Permission Denial: unbroadcastIntent() from pid="
   12325                         + Binder.getCallingPid()
   12326                         + ", uid=" + Binder.getCallingUid()
   12327                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   12328                 Slog.w(TAG, msg);
   12329                 throw new SecurityException(msg);
   12330             }
   12331             HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   12332             if (stickies != null) {
   12333                 ArrayList<Intent> list = stickies.get(intent.getAction());
   12334                 if (list != null) {
   12335                     int N = list.size();
   12336                     int i;
   12337                     for (i=0; i<N; i++) {
   12338                         if (intent.filterEquals(list.get(i))) {
   12339                             list.remove(i);
   12340                             break;
   12341                         }
   12342                     }
   12343                     if (list.size() <= 0) {
   12344                         stickies.remove(intent.getAction());
   12345                     }
   12346                 }
   12347                 if (stickies.size() <= 0) {
   12348                     mStickyBroadcasts.remove(userId);
   12349                 }
   12350             }
   12351         }
   12352     }
   12353 
   12354     private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
   12355             String resultData, Bundle resultExtras, boolean resultAbort,
   12356             boolean explicit) {
   12357         final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
   12358         if (r == null) {
   12359             Slog.w(TAG, "finishReceiver called but not found on queue");
   12360             return false;
   12361         }
   12362 
   12363         return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
   12364                 explicit);
   12365     }
   12366 
   12367     public void finishReceiver(IBinder who, int resultCode, String resultData,
   12368             Bundle resultExtras, boolean resultAbort) {
   12369         if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
   12370 
   12371         // Refuse possible leaked file descriptors
   12372         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
   12373             throw new IllegalArgumentException("File descriptors passed in Bundle");
   12374         }
   12375 
   12376         final long origId = Binder.clearCallingIdentity();
   12377         try {
   12378             boolean doNext = false;
   12379             BroadcastRecord r = null;
   12380 
   12381             synchronized(this) {
   12382                 r = broadcastRecordForReceiverLocked(who);
   12383                 if (r != null) {
   12384                     doNext = r.queue.finishReceiverLocked(r, resultCode,
   12385                         resultData, resultExtras, resultAbort, true);
   12386                 }
   12387             }
   12388 
   12389             if (doNext) {
   12390                 r.queue.processNextBroadcast(false);
   12391             }
   12392             trimApplications();
   12393         } finally {
   12394             Binder.restoreCallingIdentity(origId);
   12395         }
   12396     }
   12397 
   12398     // =========================================================
   12399     // INSTRUMENTATION
   12400     // =========================================================
   12401 
   12402     public boolean startInstrumentation(ComponentName className,
   12403             String profileFile, int flags, Bundle arguments,
   12404             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
   12405             int userId) {
   12406         enforceNotIsolatedCaller("startInstrumentation");
   12407         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   12408                 userId, false, true, "startInstrumentation", null);
   12409         // Refuse possible leaked file descriptors
   12410         if (arguments != null && arguments.hasFileDescriptors()) {
   12411             throw new IllegalArgumentException("File descriptors passed in Bundle");
   12412         }
   12413 
   12414         synchronized(this) {
   12415             InstrumentationInfo ii = null;
   12416             ApplicationInfo ai = null;
   12417             try {
   12418                 ii = mContext.getPackageManager().getInstrumentationInfo(
   12419                     className, STOCK_PM_FLAGS);
   12420                 ai = AppGlobals.getPackageManager().getApplicationInfo(
   12421                         ii.targetPackage, STOCK_PM_FLAGS, userId);
   12422             } catch (PackageManager.NameNotFoundException e) {
   12423             } catch (RemoteException e) {
   12424             }
   12425             if (ii == null) {
   12426                 reportStartInstrumentationFailure(watcher, className,
   12427                         "Unable to find instrumentation info for: " + className);
   12428                 return false;
   12429             }
   12430             if (ai == null) {
   12431                 reportStartInstrumentationFailure(watcher, className,
   12432                         "Unable to find instrumentation target package: " + ii.targetPackage);
   12433                 return false;
   12434             }
   12435 
   12436             int match = mContext.getPackageManager().checkSignatures(
   12437                     ii.targetPackage, ii.packageName);
   12438             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
   12439                 String msg = "Permission Denial: starting instrumentation "
   12440                         + className + " from pid="
   12441                         + Binder.getCallingPid()
   12442                         + ", uid=" + Binder.getCallingPid()
   12443                         + " not allowed because package " + ii.packageName
   12444                         + " does not have a signature matching the target "
   12445                         + ii.targetPackage;
   12446                 reportStartInstrumentationFailure(watcher, className, msg);
   12447                 throw new SecurityException(msg);
   12448             }
   12449 
   12450             final long origId = Binder.clearCallingIdentity();
   12451             // Instrumentation can kill and relaunch even persistent processes
   12452             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
   12453             ProcessRecord app = addAppLocked(ai, false);
   12454             app.instrumentationClass = className;
   12455             app.instrumentationInfo = ai;
   12456             app.instrumentationProfileFile = profileFile;
   12457             app.instrumentationArguments = arguments;
   12458             app.instrumentationWatcher = watcher;
   12459             app.instrumentationUiAutomationConnection = uiAutomationConnection;
   12460             app.instrumentationResultClass = className;
   12461             Binder.restoreCallingIdentity(origId);
   12462         }
   12463 
   12464         return true;
   12465     }
   12466 
   12467     /**
   12468      * Report errors that occur while attempting to start Instrumentation.  Always writes the
   12469      * error to the logs, but if somebody is watching, send the report there too.  This enables
   12470      * the "am" command to report errors with more information.
   12471      *
   12472      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
   12473      * @param cn The component name of the instrumentation.
   12474      * @param report The error report.
   12475      */
   12476     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
   12477             ComponentName cn, String report) {
   12478         Slog.w(TAG, report);
   12479         try {
   12480             if (watcher != null) {
   12481                 Bundle results = new Bundle();
   12482                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
   12483                 results.putString("Error", report);
   12484                 watcher.instrumentationStatus(cn, -1, results);
   12485             }
   12486         } catch (RemoteException e) {
   12487             Slog.w(TAG, e);
   12488         }
   12489     }
   12490 
   12491     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
   12492         if (app.instrumentationWatcher != null) {
   12493             try {
   12494                 // NOTE:  IInstrumentationWatcher *must* be oneway here
   12495                 app.instrumentationWatcher.instrumentationFinished(
   12496                     app.instrumentationClass,
   12497                     resultCode,
   12498                     results);
   12499             } catch (RemoteException e) {
   12500             }
   12501         }
   12502         if (app.instrumentationUiAutomationConnection != null) {
   12503             try {
   12504                 app.instrumentationUiAutomationConnection.shutdown();
   12505             } catch (RemoteException re) {
   12506                 /* ignore */
   12507             }
   12508             // Only a UiAutomation can set this flag and now that
   12509             // it is finished we make sure it is reset to its default.
   12510             mUserIsMonkey = false;
   12511         }
   12512         app.instrumentationWatcher = null;
   12513         app.instrumentationUiAutomationConnection = null;
   12514         app.instrumentationClass = null;
   12515         app.instrumentationInfo = null;
   12516         app.instrumentationProfileFile = null;
   12517         app.instrumentationArguments = null;
   12518 
   12519         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
   12520     }
   12521 
   12522     public void finishInstrumentation(IApplicationThread target,
   12523             int resultCode, Bundle results) {
   12524         int userId = UserHandle.getCallingUserId();
   12525         // Refuse possible leaked file descriptors
   12526         if (results != null && results.hasFileDescriptors()) {
   12527             throw new IllegalArgumentException("File descriptors passed in Intent");
   12528         }
   12529 
   12530         synchronized(this) {
   12531             ProcessRecord app = getRecordForAppLocked(target);
   12532             if (app == null) {
   12533                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
   12534                 return;
   12535             }
   12536             final long origId = Binder.clearCallingIdentity();
   12537             finishInstrumentationLocked(app, resultCode, results);
   12538             Binder.restoreCallingIdentity(origId);
   12539         }
   12540     }
   12541 
   12542     // =========================================================
   12543     // CONFIGURATION
   12544     // =========================================================
   12545 
   12546     public ConfigurationInfo getDeviceConfigurationInfo() {
   12547         ConfigurationInfo config = new ConfigurationInfo();
   12548         synchronized (this) {
   12549             config.reqTouchScreen = mConfiguration.touchscreen;
   12550             config.reqKeyboardType = mConfiguration.keyboard;
   12551             config.reqNavigation = mConfiguration.navigation;
   12552             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
   12553                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
   12554                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
   12555             }
   12556             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
   12557                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
   12558                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
   12559             }
   12560             config.reqGlEsVersion = GL_ES_VERSION;
   12561         }
   12562         return config;
   12563     }
   12564 
   12565     public Configuration getConfiguration() {
   12566         Configuration ci;
   12567         synchronized(this) {
   12568             ci = new Configuration(mConfiguration);
   12569         }
   12570         return ci;
   12571     }
   12572 
   12573     public void updatePersistentConfiguration(Configuration values) {
   12574         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   12575                 "updateConfiguration()");
   12576         enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
   12577                 "updateConfiguration()");
   12578         if (values == null) {
   12579             throw new NullPointerException("Configuration must not be null");
   12580         }
   12581 
   12582         synchronized(this) {
   12583             final long origId = Binder.clearCallingIdentity();
   12584             updateConfigurationLocked(values, null, true, false);
   12585             Binder.restoreCallingIdentity(origId);
   12586         }
   12587     }
   12588 
   12589     public void updateConfiguration(Configuration values) {
   12590         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   12591                 "updateConfiguration()");
   12592 
   12593         synchronized(this) {
   12594             if (values == null && mWindowManager != null) {
   12595                 // sentinel: fetch the current configuration from the window manager
   12596                 values = mWindowManager.computeNewConfiguration();
   12597             }
   12598 
   12599             if (mWindowManager != null) {
   12600                 mProcessList.applyDisplaySize(mWindowManager);
   12601             }
   12602 
   12603             final long origId = Binder.clearCallingIdentity();
   12604             if (values != null) {
   12605                 Settings.System.clearConfiguration(values);
   12606             }
   12607             updateConfigurationLocked(values, null, false, false);
   12608             Binder.restoreCallingIdentity(origId);
   12609         }
   12610     }
   12611 
   12612     /**
   12613      * Do either or both things: (1) change the current configuration, and (2)
   12614      * make sure the given activity is running with the (now) current
   12615      * configuration.  Returns true if the activity has been left running, or
   12616      * false if <var>starting</var> is being destroyed to match the new
   12617      * configuration.
   12618      * @param persistent TODO
   12619      */
   12620     boolean updateConfigurationLocked(Configuration values,
   12621             ActivityRecord starting, boolean persistent, boolean initLocale) {
   12622         // do nothing if we are headless
   12623         if (mHeadless) return true;
   12624 
   12625         int changes = 0;
   12626 
   12627         boolean kept = true;
   12628 
   12629         if (values != null) {
   12630             Configuration newConfig = new Configuration(mConfiguration);
   12631             changes = newConfig.updateFrom(values);
   12632             if (changes != 0) {
   12633                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
   12634                     Slog.i(TAG, "Updating configuration to: " + values);
   12635                 }
   12636 
   12637                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
   12638 
   12639                 if (values.locale != null && !initLocale) {
   12640                     saveLocaleLocked(values.locale,
   12641                                      !values.locale.equals(mConfiguration.locale),
   12642                                      values.userSetLocale);
   12643                 }
   12644 
   12645                 mConfigurationSeq++;
   12646                 if (mConfigurationSeq <= 0) {
   12647                     mConfigurationSeq = 1;
   12648                 }
   12649                 newConfig.seq = mConfigurationSeq;
   12650                 mConfiguration = newConfig;
   12651                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
   12652 
   12653                 final Configuration configCopy = new Configuration(mConfiguration);
   12654 
   12655                 // TODO: If our config changes, should we auto dismiss any currently
   12656                 // showing dialogs?
   12657                 mShowDialogs = shouldShowDialogs(newConfig);
   12658 
   12659                 AttributeCache ac = AttributeCache.instance();
   12660                 if (ac != null) {
   12661                     ac.updateConfiguration(configCopy);
   12662                 }
   12663 
   12664                 // Make sure all resources in our process are updated
   12665                 // right now, so that anyone who is going to retrieve
   12666                 // resource values after we return will be sure to get
   12667                 // the new ones.  This is especially important during
   12668                 // boot, where the first config change needs to guarantee
   12669                 // all resources have that config before following boot
   12670                 // code is executed.
   12671                 mSystemThread.applyConfigurationToResources(configCopy);
   12672 
   12673                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
   12674                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
   12675                     msg.obj = new Configuration(configCopy);
   12676                     mHandler.sendMessage(msg);
   12677                 }
   12678 
   12679                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   12680                     ProcessRecord app = mLruProcesses.get(i);
   12681                     try {
   12682                         if (app.thread != null) {
   12683                             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
   12684                                     + app.processName + " new config " + mConfiguration);
   12685                             app.thread.scheduleConfigurationChanged(configCopy);
   12686                         }
   12687                     } catch (Exception e) {
   12688                     }
   12689                 }
   12690                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
   12691                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   12692                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
   12693                         | Intent.FLAG_RECEIVER_FOREGROUND);
   12694                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
   12695                         null, AppOpsManager.OP_NONE, false, false, MY_PID,
   12696                         Process.SYSTEM_UID, UserHandle.USER_ALL);
   12697                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
   12698                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
   12699                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   12700                     broadcastIntentLocked(null, null, intent,
   12701                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   12702                             false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   12703                 }
   12704             }
   12705         }
   12706 
   12707         if (changes != 0 && starting == null) {
   12708             // If the configuration changed, and the caller is not already
   12709             // in the process of starting an activity, then find the top
   12710             // activity to check if its configuration needs to change.
   12711             starting = mMainStack.topRunningActivityLocked(null);
   12712         }
   12713 
   12714         if (starting != null) {
   12715             kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
   12716             // And we need to make sure at this point that all other activities
   12717             // are made visible with the correct configuration.
   12718             mMainStack.ensureActivitiesVisibleLocked(starting, changes);
   12719         }
   12720 
   12721         if (values != null && mWindowManager != null) {
   12722             mWindowManager.setNewConfiguration(mConfiguration);
   12723         }
   12724 
   12725         return kept;
   12726     }
   12727 
   12728     /**
   12729      * Decide based on the configuration whether we should shouw the ANR,
   12730      * crash, etc dialogs.  The idea is that if there is no affordnace to
   12731      * press the on-screen buttons, we shouldn't show the dialog.
   12732      *
   12733      * A thought: SystemUI might also want to get told about this, the Power
   12734      * dialog / global actions also might want different behaviors.
   12735      */
   12736     private static final boolean shouldShowDialogs(Configuration config) {
   12737         return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
   12738                 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
   12739     }
   12740 
   12741     /**
   12742      * Save the locale.  You must be inside a synchronized (this) block.
   12743      */
   12744     private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
   12745         if(isDiff) {
   12746             SystemProperties.set("user.language", l.getLanguage());
   12747             SystemProperties.set("user.region", l.getCountry());
   12748         }
   12749 
   12750         if(isPersist) {
   12751             SystemProperties.set("persist.sys.language", l.getLanguage());
   12752             SystemProperties.set("persist.sys.country", l.getCountry());
   12753             SystemProperties.set("persist.sys.localevar", l.getVariant());
   12754         }
   12755     }
   12756 
   12757     @Override
   12758     public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
   12759         ActivityRecord srec = ActivityRecord.forToken(token);
   12760         return srec != null && srec.task.affinity != null &&
   12761                 srec.task.affinity.equals(destAffinity);
   12762     }
   12763 
   12764     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
   12765             Intent resultData) {
   12766         ComponentName dest = destIntent.getComponent();
   12767 
   12768         synchronized (this) {
   12769             ActivityRecord srec = ActivityRecord.forToken(token);
   12770             if (srec == null) {
   12771                 return false;
   12772             }
   12773             ArrayList<ActivityRecord> history = srec.stack.mHistory;
   12774             final int start = history.indexOf(srec);
   12775             if (start < 0) {
   12776                 // Current activity is not in history stack; do nothing.
   12777                 return false;
   12778             }
   12779             int finishTo = start - 1;
   12780             ActivityRecord parent = null;
   12781             boolean foundParentInTask = false;
   12782             if (dest != null) {
   12783                 TaskRecord tr = srec.task;
   12784                 for (int i = start - 1; i >= 0; i--) {
   12785                     ActivityRecord r = history.get(i);
   12786                     if (tr != r.task) {
   12787                         // Couldn't find parent in the same task; stop at the one above this.
   12788                         // (Root of current task; in-app "home" behavior)
   12789                         // Always at least finish the current activity.
   12790                         finishTo = Math.min(start - 1, i + 1);
   12791                         parent = history.get(finishTo);
   12792                         break;
   12793                     } else if (r.info.packageName.equals(dest.getPackageName()) &&
   12794                             r.info.name.equals(dest.getClassName())) {
   12795                         finishTo = i;
   12796                         parent = r;
   12797                         foundParentInTask = true;
   12798                         break;
   12799                     }
   12800                 }
   12801             }
   12802 
   12803             if (mController != null) {
   12804                 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
   12805                 if (next != null) {
   12806                     // ask watcher if this is allowed
   12807                     boolean resumeOK = true;
   12808                     try {
   12809                         resumeOK = mController.activityResuming(next.packageName);
   12810                     } catch (RemoteException e) {
   12811                         mController = null;
   12812                         Watchdog.getInstance().setActivityController(null);
   12813                     }
   12814 
   12815                     if (!resumeOK) {
   12816                         return false;
   12817                     }
   12818                 }
   12819             }
   12820             final long origId = Binder.clearCallingIdentity();
   12821             for (int i = start; i > finishTo; i--) {
   12822                 ActivityRecord r = history.get(i);
   12823                 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
   12824                         "navigate-up", true);
   12825                 // Only return the supplied result for the first activity finished
   12826                 resultCode = Activity.RESULT_CANCELED;
   12827                 resultData = null;
   12828             }
   12829 
   12830             if (parent != null && foundParentInTask) {
   12831                 final int parentLaunchMode = parent.info.launchMode;
   12832                 final int destIntentFlags = destIntent.getFlags();
   12833                 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
   12834                         parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
   12835                         parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
   12836                         (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
   12837                     parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
   12838                 } else {
   12839                     try {
   12840                         ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
   12841                                 destIntent.getComponent(), 0, srec.userId);
   12842                         int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
   12843                                 null, aInfo, parent.appToken, null,
   12844                                 0, -1, parent.launchedFromUid, parent.launchedFromPackage,
   12845                                 0, null, true, null);
   12846                         foundParentInTask = res == ActivityManager.START_SUCCESS;
   12847                     } catch (RemoteException e) {
   12848                         foundParentInTask = false;
   12849                     }
   12850                     mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
   12851                             resultData, "navigate-up", true);
   12852                 }
   12853             }
   12854             Binder.restoreCallingIdentity(origId);
   12855             return foundParentInTask;
   12856         }
   12857     }
   12858 
   12859     public int getLaunchedFromUid(IBinder activityToken) {
   12860         ActivityRecord srec = ActivityRecord.forToken(activityToken);
   12861         if (srec == null) {
   12862             return -1;
   12863         }
   12864         return srec.launchedFromUid;
   12865     }
   12866 
   12867     public String getLaunchedFromPackage(IBinder activityToken) {
   12868         ActivityRecord srec = ActivityRecord.forToken(activityToken);
   12869         if (srec == null) {
   12870             return null;
   12871         }
   12872         return srec.launchedFromPackage;
   12873     }
   12874 
   12875     // =========================================================
   12876     // LIFETIME MANAGEMENT
   12877     // =========================================================
   12878 
   12879     // Returns which broadcast queue the app is the current [or imminent] receiver
   12880     // on, or 'null' if the app is not an active broadcast recipient.
   12881     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
   12882         BroadcastRecord r = app.curReceiver;
   12883         if (r != null) {
   12884             return r.queue;
   12885         }
   12886 
   12887         // It's not the current receiver, but it might be starting up to become one
   12888         synchronized (this) {
   12889             for (BroadcastQueue queue : mBroadcastQueues) {
   12890                 r = queue.mPendingBroadcast;
   12891                 if (r != null && r.curApp == app) {
   12892                     // found it; report which queue it's in
   12893                     return queue;
   12894                 }
   12895             }
   12896         }
   12897 
   12898         return null;
   12899     }
   12900 
   12901     private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj,
   12902             int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
   12903         if (mAdjSeq == app.adjSeq) {
   12904             // This adjustment has already been computed.  If we are calling
   12905             // from the top, we may have already computed our adjustment with
   12906             // an earlier hidden adjustment that isn't really for us... if
   12907             // so, use the new hidden adjustment.
   12908             if (!recursed && app.hidden) {
   12909                 if (app.hasActivities) {
   12910                     app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
   12911                 } else if (app.hasClientActivities) {
   12912                     app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj;
   12913                 } else {
   12914                     app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj;
   12915                 }
   12916             }
   12917             return app.curRawAdj;
   12918         }
   12919 
   12920         if (app.thread == null) {
   12921             app.adjSeq = mAdjSeq;
   12922             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   12923             return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
   12924         }
   12925 
   12926         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
   12927         app.adjSource = null;
   12928         app.adjTarget = null;
   12929         app.empty = false;
   12930         app.hidden = false;
   12931         app.hasClientActivities = false;
   12932 
   12933         final int activitiesSize = app.activities.size();
   12934 
   12935         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   12936             // The max adjustment doesn't allow this app to be anything
   12937             // below foreground, so it is not worth doing work for it.
   12938             app.adjType = "fixed";
   12939             app.adjSeq = mAdjSeq;
   12940             app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
   12941             app.hasActivities = false;
   12942             app.foregroundActivities = false;
   12943             app.keeping = true;
   12944             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
   12945             // System process can do UI, and when they do we want to have
   12946             // them trim their memory after the user leaves the UI.  To
   12947             // facilitate this, here we need to determine whether or not it
   12948             // is currently showing UI.
   12949             app.systemNoUi = true;
   12950             if (app == TOP_APP) {
   12951                 app.systemNoUi = false;
   12952                 app.hasActivities = true;
   12953             } else if (activitiesSize > 0) {
   12954                 for (int j = 0; j < activitiesSize; j++) {
   12955                     final ActivityRecord r = app.activities.get(j);
   12956                     if (r.visible) {
   12957                         app.systemNoUi = false;
   12958                     }
   12959                     if (r.app == app) {
   12960                         app.hasActivities = true;
   12961                     }
   12962                 }
   12963             }
   12964             return (app.curAdj=app.maxAdj);
   12965         }
   12966 
   12967         app.keeping = false;
   12968         app.systemNoUi = false;
   12969         app.hasActivities = false;
   12970 
   12971         // Determine the importance of the process, starting with most
   12972         // important to least, and assign an appropriate OOM adjustment.
   12973         int adj;
   12974         int schedGroup;
   12975         boolean foregroundActivities = false;
   12976         boolean interesting = false;
   12977         BroadcastQueue queue;
   12978         if (app == TOP_APP) {
   12979             // The last app on the list is the foreground app.
   12980             adj = ProcessList.FOREGROUND_APP_ADJ;
   12981             schedGroup = Process.THREAD_GROUP_DEFAULT;
   12982             app.adjType = "top-activity";
   12983             foregroundActivities = true;
   12984             interesting = true;
   12985             app.hasActivities = true;
   12986         } else if (app.instrumentationClass != null) {
   12987             // Don't want to kill running instrumentation.
   12988             adj = ProcessList.FOREGROUND_APP_ADJ;
   12989             schedGroup = Process.THREAD_GROUP_DEFAULT;
   12990             app.adjType = "instrumentation";
   12991             interesting = true;
   12992         } else if ((queue = isReceivingBroadcast(app)) != null) {
   12993             // An app that is currently receiving a broadcast also
   12994             // counts as being in the foreground for OOM killer purposes.
   12995             // It's placed in a sched group based on the nature of the
   12996             // broadcast as reflected by which queue it's active in.
   12997             adj = ProcessList.FOREGROUND_APP_ADJ;
   12998             schedGroup = (queue == mFgBroadcastQueue)
   12999                     ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13000             app.adjType = "broadcast";
   13001         } else if (app.executingServices.size() > 0) {
   13002             // An app that is currently executing a service callback also
   13003             // counts as being in the foreground.
   13004             adj = ProcessList.FOREGROUND_APP_ADJ;
   13005             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13006             app.adjType = "exec-service";
   13007         } else {
   13008             // Assume process is hidden (has activities); we will correct
   13009             // later if this is not the case.
   13010             adj = hiddenAdj;
   13011             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13012             app.hidden = true;
   13013             app.adjType = "bg-act";
   13014         }
   13015 
   13016         boolean hasStoppingActivities = false;
   13017 
   13018         // Examine all activities if not already foreground.
   13019         if (!foregroundActivities && activitiesSize > 0) {
   13020             for (int j = 0; j < activitiesSize; j++) {
   13021                 final ActivityRecord r = app.activities.get(j);
   13022                 if (r.visible) {
   13023                     // App has a visible activity; only upgrade adjustment.
   13024                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   13025                         adj = ProcessList.VISIBLE_APP_ADJ;
   13026                         app.adjType = "visible";
   13027                     }
   13028                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   13029                     app.hidden = false;
   13030                     app.hasActivities = true;
   13031                     foregroundActivities = true;
   13032                     break;
   13033                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
   13034                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   13035                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   13036                         app.adjType = "pausing";
   13037                     }
   13038                     app.hidden = false;
   13039                     foregroundActivities = true;
   13040                 } else if (r.state == ActivityState.STOPPING) {
   13041                     // We will apply the actual adjustment later, because
   13042                     // we want to allow this process to immediately go through
   13043                     // any memory trimming that is in effect.
   13044                     app.hidden = false;
   13045                     foregroundActivities = true;
   13046                     hasStoppingActivities = true;
   13047                 }
   13048                 if (r.app == app) {
   13049                     app.hasActivities = true;
   13050                 }
   13051             }
   13052         }
   13053 
   13054         if (adj == hiddenAdj && !app.hasActivities) {
   13055             if (app.hasClientActivities) {
   13056                 adj = clientHiddenAdj;
   13057                 app.adjType = "bg-client-act";
   13058             } else {
   13059                 // Whoops, this process is completely empty as far as we know
   13060                 // at this point.
   13061                 adj = emptyAdj;
   13062                 app.empty = true;
   13063                 app.adjType = "bg-empty";
   13064             }
   13065         }
   13066 
   13067         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   13068             if (app.foregroundServices) {
   13069                 // The user is aware of this app, so make it visible.
   13070                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   13071                 app.hidden = false;
   13072                 app.adjType = "fg-service";
   13073                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   13074             } else if (app.forcingToForeground != null) {
   13075                 // The user is aware of this app, so make it visible.
   13076                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   13077                 app.hidden = false;
   13078                 app.adjType = "force-fg";
   13079                 app.adjSource = app.forcingToForeground;
   13080                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   13081             }
   13082         }
   13083 
   13084         if (app.foregroundServices) {
   13085             interesting = true;
   13086         }
   13087 
   13088         if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
   13089             // We don't want to kill the current heavy-weight process.
   13090             adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
   13091             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13092             app.hidden = false;
   13093             app.adjType = "heavy";
   13094         }
   13095 
   13096         if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
   13097             // This process is hosting what we currently consider to be the
   13098             // home app, so we don't want to let it go into the background.
   13099             adj = ProcessList.HOME_APP_ADJ;
   13100             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13101             app.hidden = false;
   13102             app.adjType = "home";
   13103         }
   13104 
   13105         if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
   13106                 && app.activities.size() > 0) {
   13107             // This was the previous process that showed UI to the user.
   13108             // We want to try to keep it around more aggressively, to give
   13109             // a good experience around switching between two apps.
   13110             adj = ProcessList.PREVIOUS_APP_ADJ;
   13111             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13112             app.hidden = false;
   13113             app.adjType = "previous";
   13114         }
   13115 
   13116         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
   13117                 + " reason=" + app.adjType);
   13118 
   13119         // By default, we use the computed adjustment.  It may be changed if
   13120         // there are applications dependent on our services or providers, but
   13121         // this gives us a baseline and makes sure we don't get into an
   13122         // infinite recursion.
   13123         app.adjSeq = mAdjSeq;
   13124         app.curRawAdj = app.nonStoppingAdj = adj;
   13125 
   13126         if (mBackupTarget != null && app == mBackupTarget.app) {
   13127             // If possible we want to avoid killing apps while they're being backed up
   13128             if (adj > ProcessList.BACKUP_APP_ADJ) {
   13129                 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
   13130                 adj = ProcessList.BACKUP_APP_ADJ;
   13131                 app.adjType = "backup";
   13132                 app.hidden = false;
   13133             }
   13134         }
   13135 
   13136         if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   13137                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   13138             final long now = SystemClock.uptimeMillis();
   13139             // This process is more important if the top activity is
   13140             // bound to the service.
   13141             Iterator<ServiceRecord> jt = app.services.iterator();
   13142             while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
   13143                 ServiceRecord s = jt.next();
   13144                 if (s.startRequested) {
   13145                     if (app.hasShownUi && app != mHomeProcess) {
   13146                         // If this process has shown some UI, let it immediately
   13147                         // go to the LRU list because it may be pretty heavy with
   13148                         // UI stuff.  We'll tag it with a label just to help
   13149                         // debug and understand what is going on.
   13150                         if (adj > ProcessList.SERVICE_ADJ) {
   13151                             app.adjType = "started-bg-ui-services";
   13152                         }
   13153                     } else {
   13154                         if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
   13155                             // This service has seen some activity within
   13156                             // recent memory, so we will keep its process ahead
   13157                             // of the background processes.
   13158                             if (adj > ProcessList.SERVICE_ADJ) {
   13159                                 adj = ProcessList.SERVICE_ADJ;
   13160                                 app.adjType = "started-services";
   13161                                 app.hidden = false;
   13162                             }
   13163                         }
   13164                         // If we have let the service slide into the background
   13165                         // state, still have some text describing what it is doing
   13166                         // even though the service no longer has an impact.
   13167                         if (adj > ProcessList.SERVICE_ADJ) {
   13168                             app.adjType = "started-bg-services";
   13169                         }
   13170                     }
   13171                     // Don't kill this process because it is doing work; it
   13172                     // has said it is doing work.
   13173                     app.keeping = true;
   13174                 }
   13175                 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   13176                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   13177                     Iterator<ArrayList<ConnectionRecord>> kt
   13178                             = s.connections.values().iterator();
   13179                     while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
   13180                         ArrayList<ConnectionRecord> clist = kt.next();
   13181                         for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
   13182                             // XXX should compute this based on the max of
   13183                             // all connected clients.
   13184                             ConnectionRecord cr = clist.get(i);
   13185                             if (cr.binding.client == app) {
   13186                                 // Binding to ourself is not interesting.
   13187                                 continue;
   13188                             }
   13189                             if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
   13190                                 ProcessRecord client = cr.binding.client;
   13191                                 int clientAdj = adj;
   13192                                 int myHiddenAdj = hiddenAdj;
   13193                                 if (myHiddenAdj > client.hiddenAdj) {
   13194                                     if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
   13195                                         myHiddenAdj = client.hiddenAdj;
   13196                                     } else {
   13197                                         myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
   13198                                     }
   13199                                 }
   13200                                 int myClientHiddenAdj = clientHiddenAdj;
   13201                                 if (myClientHiddenAdj > client.clientHiddenAdj) {
   13202                                     if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
   13203                                         myClientHiddenAdj = client.clientHiddenAdj;
   13204                                     } else {
   13205                                         myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
   13206                                     }
   13207                                 }
   13208                                 int myEmptyAdj = emptyAdj;
   13209                                 if (myEmptyAdj > client.emptyAdj) {
   13210                                     if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
   13211                                         myEmptyAdj = client.emptyAdj;
   13212                                     } else {
   13213                                         myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
   13214                                     }
   13215                                 }
   13216                                 clientAdj = computeOomAdjLocked(client, myHiddenAdj,
   13217                                         myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
   13218                                 String adjType = null;
   13219                                 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
   13220                                     // Not doing bind OOM management, so treat
   13221                                     // this guy more like a started service.
   13222                                     if (app.hasShownUi && app != mHomeProcess) {
   13223                                         // If this process has shown some UI, let it immediately
   13224                                         // go to the LRU list because it may be pretty heavy with
   13225                                         // UI stuff.  We'll tag it with a label just to help
   13226                                         // debug and understand what is going on.
   13227                                         if (adj > clientAdj) {
   13228                                             adjType = "bound-bg-ui-services";
   13229                                         }
   13230                                         app.hidden = false;
   13231                                         clientAdj = adj;
   13232                                     } else {
   13233                                         if (now >= (s.lastActivity
   13234                                                 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
   13235                                             // This service has not seen activity within
   13236                                             // recent memory, so allow it to drop to the
   13237                                             // LRU list if there is no other reason to keep
   13238                                             // it around.  We'll also tag it with a label just
   13239                                             // to help debug and undertand what is going on.
   13240                                             if (adj > clientAdj) {
   13241                                                 adjType = "bound-bg-services";
   13242                                             }
   13243                                             clientAdj = adj;
   13244                                         }
   13245                                     }
   13246                                 } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
   13247                                     if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) {
   13248                                         // If this connection is keeping the service
   13249                                         // created, then we want to try to better follow
   13250                                         // its memory management semantics for activities.
   13251                                         // That is, if it is sitting in the background
   13252                                         // LRU list as a hidden process (with activities),
   13253                                         // we don't want the service it is connected to
   13254                                         // to go into the empty LRU and quickly get killed,
   13255                                         // because I'll we'll do is just end up restarting
   13256                                         // the service.
   13257                                         app.hasClientActivities |= client.hasActivities;
   13258                                     }
   13259                                 }
   13260                                 if (adj > clientAdj) {
   13261                                     // If this process has recently shown UI, and
   13262                                     // the process that is binding to it is less
   13263                                     // important than being visible, then we don't
   13264                                     // care about the binding as much as we care
   13265                                     // about letting this process get into the LRU
   13266                                     // list to be killed and restarted if needed for
   13267                                     // memory.
   13268                                     if (app.hasShownUi && app != mHomeProcess
   13269                                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   13270                                         adjType = "bound-bg-ui-services";
   13271                                     } else {
   13272                                         if ((cr.flags&(Context.BIND_ABOVE_CLIENT
   13273                                                 |Context.BIND_IMPORTANT)) != 0) {
   13274                                             adj = clientAdj;
   13275                                         } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
   13276                                                 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
   13277                                                 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   13278                                             adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   13279                                         } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
   13280                                             adj = clientAdj;
   13281                                         } else {
   13282                                             app.pendingUiClean = true;
   13283                                             if (adj > ProcessList.VISIBLE_APP_ADJ) {
   13284                                                 adj = ProcessList.VISIBLE_APP_ADJ;
   13285                                             }
   13286                                         }
   13287                                         if (!client.hidden) {
   13288                                             app.hidden = false;
   13289                                         }
   13290                                         if (client.keeping) {
   13291                                             app.keeping = true;
   13292                                         }
   13293                                         adjType = "service";
   13294                                     }
   13295                                 }
   13296                                 if (adjType != null) {
   13297                                     app.adjType = adjType;
   13298                                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   13299                                             .REASON_SERVICE_IN_USE;
   13300                                     app.adjSource = cr.binding.client;
   13301                                     app.adjSourceOom = clientAdj;
   13302                                     app.adjTarget = s.name;
   13303                                 }
   13304                                 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   13305                                     if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   13306                                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   13307                                     }
   13308                                 }
   13309                             }
   13310                             final ActivityRecord a = cr.activity;
   13311                             if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
   13312                                 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
   13313                                         (a.visible || a.state == ActivityState.RESUMED
   13314                                          || a.state == ActivityState.PAUSING)) {
   13315                                     adj = ProcessList.FOREGROUND_APP_ADJ;
   13316                                     if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   13317                                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   13318                                     }
   13319                                     app.hidden = false;
   13320                                     app.adjType = "service";
   13321                                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   13322                                             .REASON_SERVICE_IN_USE;
   13323                                     app.adjSource = a;
   13324                                     app.adjSourceOom = adj;
   13325                                     app.adjTarget = s.name;
   13326                                 }
   13327                             }
   13328                         }
   13329                     }
   13330                 }
   13331             }
   13332 
   13333             // Finally, if this process has active services running in it, we
   13334             // would like to avoid killing it unless it would prevent the current
   13335             // application from running.  By default we put the process in
   13336             // with the rest of the background processes; as we scan through
   13337             // its services we may bump it up from there.
   13338             if (adj > hiddenAdj) {
   13339                 adj = hiddenAdj;
   13340                 app.hidden = false;
   13341                 app.adjType = "bg-services";
   13342             }
   13343         }
   13344 
   13345         if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   13346                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   13347             Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
   13348             while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
   13349                     || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   13350                 ContentProviderRecord cpr = jt.next();
   13351                 for (int i = cpr.connections.size()-1;
   13352                         i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   13353                                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
   13354                         i--) {
   13355                     ContentProviderConnection conn = cpr.connections.get(i);
   13356                     ProcessRecord client = conn.client;
   13357                     if (client == app) {
   13358                         // Being our own client is not interesting.
   13359                         continue;
   13360                     }
   13361                     int myHiddenAdj = hiddenAdj;
   13362                     if (myHiddenAdj > client.hiddenAdj) {
   13363                         if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
   13364                             myHiddenAdj = client.hiddenAdj;
   13365                         } else {
   13366                             myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
   13367                         }
   13368                     }
   13369                     int myClientHiddenAdj = clientHiddenAdj;
   13370                     if (myClientHiddenAdj > client.clientHiddenAdj) {
   13371                         if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) {
   13372                             myClientHiddenAdj = client.clientHiddenAdj;
   13373                         } else {
   13374                             myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
   13375                         }
   13376                     }
   13377                     int myEmptyAdj = emptyAdj;
   13378                     if (myEmptyAdj > client.emptyAdj) {
   13379                         if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
   13380                             myEmptyAdj = client.emptyAdj;
   13381                         } else {
   13382                             myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
   13383                         }
   13384                     }
   13385                     int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
   13386                             myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
   13387                     if (adj > clientAdj) {
   13388                         if (app.hasShownUi && app != mHomeProcess
   13389                                 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   13390                             app.adjType = "bg-ui-provider";
   13391                         } else {
   13392                             adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
   13393                                     ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
   13394                             app.adjType = "provider";
   13395                         }
   13396                         if (!client.hidden) {
   13397                             app.hidden = false;
   13398                         }
   13399                         if (client.keeping) {
   13400                             app.keeping = true;
   13401                         }
   13402                         app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   13403                                 .REASON_PROVIDER_IN_USE;
   13404                         app.adjSource = client;
   13405                         app.adjSourceOom = clientAdj;
   13406                         app.adjTarget = cpr.name;
   13407                     }
   13408                     if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   13409                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   13410                     }
   13411                 }
   13412                 // If the provider has external (non-framework) process
   13413                 // dependencies, ensure that its adjustment is at least
   13414                 // FOREGROUND_APP_ADJ.
   13415                 if (cpr.hasExternalProcessHandles()) {
   13416                     if (adj > ProcessList.FOREGROUND_APP_ADJ) {
   13417                         adj = ProcessList.FOREGROUND_APP_ADJ;
   13418                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   13419                         app.hidden = false;
   13420                         app.keeping = true;
   13421                         app.adjType = "provider";
   13422                         app.adjTarget = cpr.name;
   13423                     }
   13424                 }
   13425             }
   13426         }
   13427 
   13428         if (adj == ProcessList.SERVICE_ADJ) {
   13429             if (doingAll) {
   13430                 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
   13431                 mNewNumServiceProcs++;
   13432             }
   13433             if (app.serviceb) {
   13434                 adj = ProcessList.SERVICE_B_ADJ;
   13435             }
   13436         } else {
   13437             app.serviceb = false;
   13438         }
   13439 
   13440         app.nonStoppingAdj = adj;
   13441 
   13442         if (hasStoppingActivities) {
   13443             // Only upgrade adjustment.
   13444             if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   13445                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   13446                 app.adjType = "stopping";
   13447             }
   13448         }
   13449 
   13450         app.curRawAdj = adj;
   13451 
   13452         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
   13453         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
   13454         if (adj > app.maxAdj) {
   13455             adj = app.maxAdj;
   13456             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   13457                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   13458             }
   13459         }
   13460         if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
   13461             app.keeping = true;
   13462         }
   13463 
   13464         if (app.hasAboveClient) {
   13465             // If this process has bound to any services with BIND_ABOVE_CLIENT,
   13466             // then we need to drop its adjustment to be lower than the service's
   13467             // in order to honor the request.  We want to drop it by one adjustment
   13468             // level...  but there is special meaning applied to various levels so
   13469             // we will skip some of them.
   13470             if (adj < ProcessList.FOREGROUND_APP_ADJ) {
   13471                 // System process will not get dropped, ever
   13472             } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
   13473                 adj = ProcessList.VISIBLE_APP_ADJ;
   13474             } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
   13475                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   13476             } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
   13477                 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
   13478             } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
   13479                 adj++;
   13480             }
   13481         }
   13482 
   13483         int importance = app.memImportance;
   13484         if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
   13485             app.curAdj = adj;
   13486             app.curSchedGroup = schedGroup;
   13487             if (!interesting) {
   13488                 // For this reporting, if there is not something explicitly
   13489                 // interesting in this process then we will push it to the
   13490                 // background importance.
   13491                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   13492             } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   13493                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   13494             } else if (adj >= ProcessList.SERVICE_B_ADJ) {
   13495                 importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   13496             } else if (adj >= ProcessList.HOME_APP_ADJ) {
   13497                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   13498             } else if (adj >= ProcessList.SERVICE_ADJ) {
   13499                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   13500             } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   13501                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
   13502             } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   13503                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
   13504             } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
   13505                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
   13506             } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
   13507                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
   13508             } else {
   13509                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
   13510             }
   13511         }
   13512 
   13513         int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
   13514         if (foregroundActivities != app.foregroundActivities) {
   13515             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
   13516         }
   13517         if (changes != 0) {
   13518             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
   13519             app.memImportance = importance;
   13520             app.foregroundActivities = foregroundActivities;
   13521             int i = mPendingProcessChanges.size()-1;
   13522             ProcessChangeItem item = null;
   13523             while (i >= 0) {
   13524                 item = mPendingProcessChanges.get(i);
   13525                 if (item.pid == app.pid) {
   13526                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
   13527                     break;
   13528                 }
   13529                 i--;
   13530             }
   13531             if (i < 0) {
   13532                 // No existing item in pending changes; need a new one.
   13533                 final int NA = mAvailProcessChanges.size();
   13534                 if (NA > 0) {
   13535                     item = mAvailProcessChanges.remove(NA-1);
   13536                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
   13537                 } else {
   13538                     item = new ProcessChangeItem();
   13539                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
   13540                 }
   13541                 item.changes = 0;
   13542                 item.pid = app.pid;
   13543                 item.uid = app.info.uid;
   13544                 if (mPendingProcessChanges.size() == 0) {
   13545                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
   13546                             "*** Enqueueing dispatch processes changed!");
   13547                     mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
   13548                 }
   13549                 mPendingProcessChanges.add(item);
   13550             }
   13551             item.changes |= changes;
   13552             item.importance = importance;
   13553             item.foregroundActivities = foregroundActivities;
   13554             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
   13555                     + Integer.toHexString(System.identityHashCode(item))
   13556                     + " " + app.toShortString() + ": changes=" + item.changes
   13557                     + " importance=" + item.importance
   13558                     + " foreground=" + item.foregroundActivities
   13559                     + " type=" + app.adjType + " source=" + app.adjSource
   13560                     + " target=" + app.adjTarget);
   13561         }
   13562 
   13563         return app.curRawAdj;
   13564     }
   13565 
   13566     /**
   13567      * Ask a given process to GC right now.
   13568      */
   13569     final void performAppGcLocked(ProcessRecord app) {
   13570         try {
   13571             app.lastRequestedGc = SystemClock.uptimeMillis();
   13572             if (app.thread != null) {
   13573                 if (app.reportLowMemory) {
   13574                     app.reportLowMemory = false;
   13575                     app.thread.scheduleLowMemory();
   13576                 } else {
   13577                     app.thread.processInBackground();
   13578                 }
   13579             }
   13580         } catch (Exception e) {
   13581             // whatever.
   13582         }
   13583     }
   13584 
   13585     /**
   13586      * Returns true if things are idle enough to perform GCs.
   13587      */
   13588     private final boolean canGcNowLocked() {
   13589         boolean processingBroadcasts = false;
   13590         for (BroadcastQueue q : mBroadcastQueues) {
   13591             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
   13592                 processingBroadcasts = true;
   13593             }
   13594         }
   13595         return !processingBroadcasts
   13596                 && (mSleeping || (mMainStack.mResumedActivity != null &&
   13597                         mMainStack.mResumedActivity.idle));
   13598     }
   13599 
   13600     /**
   13601      * Perform GCs on all processes that are waiting for it, but only
   13602      * if things are idle.
   13603      */
   13604     final void performAppGcsLocked() {
   13605         final int N = mProcessesToGc.size();
   13606         if (N <= 0) {
   13607             return;
   13608         }
   13609         if (canGcNowLocked()) {
   13610             while (mProcessesToGc.size() > 0) {
   13611                 ProcessRecord proc = mProcessesToGc.remove(0);
   13612                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
   13613                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
   13614                             <= SystemClock.uptimeMillis()) {
   13615                         // To avoid spamming the system, we will GC processes one
   13616                         // at a time, waiting a few seconds between each.
   13617                         performAppGcLocked(proc);
   13618                         scheduleAppGcsLocked();
   13619                         return;
   13620                     } else {
   13621                         // It hasn't been long enough since we last GCed this
   13622                         // process...  put it in the list to wait for its time.
   13623                         addProcessToGcListLocked(proc);
   13624                         break;
   13625                     }
   13626                 }
   13627             }
   13628 
   13629             scheduleAppGcsLocked();
   13630         }
   13631     }
   13632 
   13633     /**
   13634      * If all looks good, perform GCs on all processes waiting for them.
   13635      */
   13636     final void performAppGcsIfAppropriateLocked() {
   13637         if (canGcNowLocked()) {
   13638             performAppGcsLocked();
   13639             return;
   13640         }
   13641         // Still not idle, wait some more.
   13642         scheduleAppGcsLocked();
   13643     }
   13644 
   13645     /**
   13646      * Schedule the execution of all pending app GCs.
   13647      */
   13648     final void scheduleAppGcsLocked() {
   13649         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
   13650 
   13651         if (mProcessesToGc.size() > 0) {
   13652             // Schedule a GC for the time to the next process.
   13653             ProcessRecord proc = mProcessesToGc.get(0);
   13654             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
   13655 
   13656             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
   13657             long now = SystemClock.uptimeMillis();
   13658             if (when < (now+GC_TIMEOUT)) {
   13659                 when = now + GC_TIMEOUT;
   13660             }
   13661             mHandler.sendMessageAtTime(msg, when);
   13662         }
   13663     }
   13664 
   13665     /**
   13666      * Add a process to the array of processes waiting to be GCed.  Keeps the
   13667      * list in sorted order by the last GC time.  The process can't already be
   13668      * on the list.
   13669      */
   13670     final void addProcessToGcListLocked(ProcessRecord proc) {
   13671         boolean added = false;
   13672         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
   13673             if (mProcessesToGc.get(i).lastRequestedGc <
   13674                     proc.lastRequestedGc) {
   13675                 added = true;
   13676                 mProcessesToGc.add(i+1, proc);
   13677                 break;
   13678             }
   13679         }
   13680         if (!added) {
   13681             mProcessesToGc.add(0, proc);
   13682         }
   13683     }
   13684 
   13685     /**
   13686      * Set up to ask a process to GC itself.  This will either do it
   13687      * immediately, or put it on the list of processes to gc the next
   13688      * time things are idle.
   13689      */
   13690     final void scheduleAppGcLocked(ProcessRecord app) {
   13691         long now = SystemClock.uptimeMillis();
   13692         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
   13693             return;
   13694         }
   13695         if (!mProcessesToGc.contains(app)) {
   13696             addProcessToGcListLocked(app);
   13697             scheduleAppGcsLocked();
   13698         }
   13699     }
   13700 
   13701     final void checkExcessivePowerUsageLocked(boolean doKills) {
   13702         updateCpuStatsNow();
   13703 
   13704         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   13705         boolean doWakeKills = doKills;
   13706         boolean doCpuKills = doKills;
   13707         if (mLastPowerCheckRealtime == 0) {
   13708             doWakeKills = false;
   13709         }
   13710         if (mLastPowerCheckUptime == 0) {
   13711             doCpuKills = false;
   13712         }
   13713         if (stats.isScreenOn()) {
   13714             doWakeKills = false;
   13715         }
   13716         final long curRealtime = SystemClock.elapsedRealtime();
   13717         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
   13718         final long curUptime = SystemClock.uptimeMillis();
   13719         final long uptimeSince = curUptime - mLastPowerCheckUptime;
   13720         mLastPowerCheckRealtime = curRealtime;
   13721         mLastPowerCheckUptime = curUptime;
   13722         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
   13723             doWakeKills = false;
   13724         }
   13725         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
   13726             doCpuKills = false;
   13727         }
   13728         int i = mLruProcesses.size();
   13729         while (i > 0) {
   13730             i--;
   13731             ProcessRecord app = mLruProcesses.get(i);
   13732             if (!app.keeping) {
   13733                 long wtime;
   13734                 synchronized (stats) {
   13735                     wtime = stats.getProcessWakeTime(app.info.uid,
   13736                             app.pid, curRealtime);
   13737                 }
   13738                 long wtimeUsed = wtime - app.lastWakeTime;
   13739                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
   13740                 if (DEBUG_POWER) {
   13741                     StringBuilder sb = new StringBuilder(128);
   13742                     sb.append("Wake for ");
   13743                     app.toShortString(sb);
   13744                     sb.append(": over ");
   13745                     TimeUtils.formatDuration(realtimeSince, sb);
   13746                     sb.append(" used ");
   13747                     TimeUtils.formatDuration(wtimeUsed, sb);
   13748                     sb.append(" (");
   13749                     sb.append((wtimeUsed*100)/realtimeSince);
   13750                     sb.append("%)");
   13751                     Slog.i(TAG, sb.toString());
   13752                     sb.setLength(0);
   13753                     sb.append("CPU for ");
   13754                     app.toShortString(sb);
   13755                     sb.append(": over ");
   13756                     TimeUtils.formatDuration(uptimeSince, sb);
   13757                     sb.append(" used ");
   13758                     TimeUtils.formatDuration(cputimeUsed, sb);
   13759                     sb.append(" (");
   13760                     sb.append((cputimeUsed*100)/uptimeSince);
   13761                     sb.append("%)");
   13762                     Slog.i(TAG, sb.toString());
   13763                 }
   13764                 // If a process has held a wake lock for more
   13765                 // than 50% of the time during this period,
   13766                 // that sounds bad.  Kill!
   13767                 if (doWakeKills && realtimeSince > 0
   13768                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
   13769                     synchronized (stats) {
   13770                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
   13771                                 realtimeSince, wtimeUsed);
   13772                     }
   13773                     Slog.w(TAG, "Excessive wake lock in " + app.processName
   13774                             + " (pid " + app.pid + "): held " + wtimeUsed
   13775                             + " during " + realtimeSince);
   13776                     EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
   13777                             app.processName, app.setAdj, "excessive wake lock");
   13778                     Process.killProcessQuiet(app.pid);
   13779                 } else if (doCpuKills && uptimeSince > 0
   13780                         && ((cputimeUsed*100)/uptimeSince) >= 50) {
   13781                     synchronized (stats) {
   13782                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
   13783                                 uptimeSince, cputimeUsed);
   13784                     }
   13785                     Slog.w(TAG, "Excessive CPU in " + app.processName
   13786                             + " (pid " + app.pid + "): used " + cputimeUsed
   13787                             + " during " + uptimeSince);
   13788                     EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
   13789                             app.processName, app.setAdj, "excessive cpu");
   13790                     Process.killProcessQuiet(app.pid);
   13791                 } else {
   13792                     app.lastWakeTime = wtime;
   13793                     app.lastCpuTime = app.curCpuTime;
   13794                 }
   13795             }
   13796         }
   13797     }
   13798 
   13799     private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
   13800             int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
   13801         app.hiddenAdj = hiddenAdj;
   13802         app.clientHiddenAdj = clientHiddenAdj;
   13803         app.emptyAdj = emptyAdj;
   13804 
   13805         if (app.thread == null) {
   13806             return false;
   13807         }
   13808 
   13809         final boolean wasKeeping = app.keeping;
   13810 
   13811         boolean success = true;
   13812 
   13813         computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll);
   13814 
   13815         if (app.curRawAdj != app.setRawAdj) {
   13816             if (wasKeeping && !app.keeping) {
   13817                 // This app is no longer something we want to keep.  Note
   13818                 // its current wake lock time to later know to kill it if
   13819                 // it is not behaving well.
   13820                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   13821                 synchronized (stats) {
   13822                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
   13823                             app.pid, SystemClock.elapsedRealtime());
   13824                 }
   13825                 app.lastCpuTime = app.curCpuTime;
   13826             }
   13827 
   13828             app.setRawAdj = app.curRawAdj;
   13829         }
   13830 
   13831         if (app.curAdj != app.setAdj) {
   13832             if (Process.setOomAdj(app.pid, app.curAdj)) {
   13833                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
   13834                     TAG, "Set " + app.pid + " " + app.processName +
   13835                     " adj " + app.curAdj + ": " + app.adjType);
   13836                 app.setAdj = app.curAdj;
   13837             } else {
   13838                 success = false;
   13839                 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
   13840             }
   13841         }
   13842         if (app.setSchedGroup != app.curSchedGroup) {
   13843             app.setSchedGroup = app.curSchedGroup;
   13844             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   13845                     "Setting process group of " + app.processName
   13846                     + " to " + app.curSchedGroup);
   13847             if (app.waitingToKill != null &&
   13848                     app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
   13849                 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
   13850                 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
   13851                         app.processName, app.setAdj, app.waitingToKill);
   13852                 app.killedBackground = true;
   13853                 Process.killProcessQuiet(app.pid);
   13854                 success = false;
   13855             } else {
   13856                 if (true) {
   13857                     long oldId = Binder.clearCallingIdentity();
   13858                     try {
   13859                         Process.setProcessGroup(app.pid, app.curSchedGroup);
   13860                     } catch (Exception e) {
   13861                         Slog.w(TAG, "Failed setting process group of " + app.pid
   13862                                 + " to " + app.curSchedGroup);
   13863                         e.printStackTrace();
   13864                     } finally {
   13865                         Binder.restoreCallingIdentity(oldId);
   13866                     }
   13867                 } else {
   13868                     if (app.thread != null) {
   13869                         try {
   13870                             app.thread.setSchedulingGroup(app.curSchedGroup);
   13871                         } catch (RemoteException e) {
   13872                         }
   13873                     }
   13874                 }
   13875             }
   13876         }
   13877         return success;
   13878     }
   13879 
   13880     private final ActivityRecord resumedAppLocked() {
   13881         ActivityRecord resumedActivity = mMainStack.mResumedActivity;
   13882         if (resumedActivity == null || resumedActivity.app == null) {
   13883             resumedActivity = mMainStack.mPausingActivity;
   13884             if (resumedActivity == null || resumedActivity.app == null) {
   13885                 resumedActivity = mMainStack.topRunningActivityLocked(null);
   13886             }
   13887         }
   13888         return resumedActivity;
   13889     }
   13890 
   13891     final boolean updateOomAdjLocked(ProcessRecord app) {
   13892         final ActivityRecord TOP_ACT = resumedAppLocked();
   13893         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   13894         int curAdj = app.curAdj;
   13895         final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
   13896             && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
   13897 
   13898         mAdjSeq++;
   13899 
   13900         boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj,
   13901                 app.emptyAdj, TOP_APP, false);
   13902         final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
   13903             && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
   13904         if (nowHidden != wasHidden) {
   13905             // Changed to/from hidden state, so apps after it in the LRU
   13906             // list may also be changed.
   13907             updateOomAdjLocked();
   13908         }
   13909         return success;
   13910     }
   13911 
   13912     final void updateOomAdjLocked() {
   13913         final ActivityRecord TOP_ACT = resumedAppLocked();
   13914         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   13915         final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME;
   13916 
   13917         if (false) {
   13918             RuntimeException e = new RuntimeException();
   13919             e.fillInStackTrace();
   13920             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
   13921         }
   13922 
   13923         mAdjSeq++;
   13924         mNewNumServiceProcs = 0;
   13925 
   13926         final int emptyProcessLimit;
   13927         final int hiddenProcessLimit;
   13928         if (mProcessLimit <= 0) {
   13929             emptyProcessLimit = hiddenProcessLimit = 0;
   13930         } else if (mProcessLimit == 1) {
   13931             emptyProcessLimit = 1;
   13932             hiddenProcessLimit = 0;
   13933         } else {
   13934             emptyProcessLimit = (mProcessLimit*2)/3;
   13935             hiddenProcessLimit = mProcessLimit - emptyProcessLimit;
   13936         }
   13937 
   13938         // Let's determine how many processes we have running vs.
   13939         // how many slots we have for background processes; we may want
   13940         // to put multiple processes in a slot of there are enough of
   13941         // them.
   13942         int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
   13943                 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
   13944         int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs;
   13945         if (numEmptyProcs > hiddenProcessLimit) {
   13946             // If there are more empty processes than our limit on hidden
   13947             // processes, then use the hidden process limit for the factor.
   13948             // This ensures that the really old empty processes get pushed
   13949             // down to the bottom, so if we are running low on memory we will
   13950             // have a better chance at keeping around more hidden processes
   13951             // instead of a gazillion empty processes.
   13952             numEmptyProcs = hiddenProcessLimit;
   13953         }
   13954         int emptyFactor = numEmptyProcs/numSlots;
   13955         if (emptyFactor < 1) emptyFactor = 1;
   13956         int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
   13957         if (hiddenFactor < 1) hiddenFactor = 1;
   13958         int stepHidden = 0;
   13959         int stepEmpty = 0;
   13960         int numHidden = 0;
   13961         int numEmpty = 0;
   13962         int numTrimming = 0;
   13963 
   13964         mNumNonHiddenProcs = 0;
   13965         mNumHiddenProcs = 0;
   13966 
   13967         // First update the OOM adjustment for each of the
   13968         // application processes based on their current state.
   13969         int i = mLruProcesses.size();
   13970         int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
   13971         int nextHiddenAdj = curHiddenAdj+1;
   13972         int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
   13973         int nextEmptyAdj = curEmptyAdj+2;
   13974         int curClientHiddenAdj = curEmptyAdj;
   13975         while (i > 0) {
   13976             i--;
   13977             ProcessRecord app = mLruProcesses.get(i);
   13978             //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
   13979             updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true);
   13980             if (!app.killedBackground) {
   13981                 if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
   13982                     // This process was assigned as a hidden process...  step the
   13983                     // hidden level.
   13984                     mNumHiddenProcs++;
   13985                     if (curHiddenAdj != nextHiddenAdj) {
   13986                         stepHidden++;
   13987                         if (stepHidden >= hiddenFactor) {
   13988                             stepHidden = 0;
   13989                             curHiddenAdj = nextHiddenAdj;
   13990                             nextHiddenAdj += 2;
   13991                             if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
   13992                                 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
   13993                             }
   13994                             if (curClientHiddenAdj <= curHiddenAdj) {
   13995                                 curClientHiddenAdj = curHiddenAdj + 1;
   13996                                 if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
   13997                                     curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
   13998                                 }
   13999                             }
   14000                         }
   14001                     }
   14002                     numHidden++;
   14003                     if (numHidden > hiddenProcessLimit) {
   14004                         Slog.i(TAG, "No longer want " + app.processName
   14005                                 + " (pid " + app.pid + "): hidden #" + numHidden);
   14006                         EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
   14007                                 app.processName, app.setAdj, "too many background");
   14008                         app.killedBackground = true;
   14009                         Process.killProcessQuiet(app.pid);
   14010                     }
   14011                 } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) {
   14012                     // This process has a client that has activities.  We will have
   14013                     // given it the current hidden adj; here we will just leave it
   14014                     // without stepping the hidden adj.
   14015                     curClientHiddenAdj++;
   14016                     if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
   14017                         curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
   14018                     }
   14019                 } else {
   14020                     if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
   14021                         // This process was assigned as an empty process...  step the
   14022                         // empty level.
   14023                         if (curEmptyAdj != nextEmptyAdj) {
   14024                             stepEmpty++;
   14025                             if (stepEmpty >= emptyFactor) {
   14026                                 stepEmpty = 0;
   14027                                 curEmptyAdj = nextEmptyAdj;
   14028                                 nextEmptyAdj += 2;
   14029                                 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
   14030                                     nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
   14031                                 }
   14032                             }
   14033                         }
   14034                     } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
   14035                         mNumNonHiddenProcs++;
   14036                     }
   14037                     if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
   14038                             && !app.hasClientActivities) {
   14039                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
   14040                                 && app.lastActivityTime < oldTime) {
   14041                             Slog.i(TAG, "No longer want " + app.processName
   14042                                     + " (pid " + app.pid + "): empty for "
   14043                                     + ((oldTime+ProcessList.MAX_EMPTY_TIME-app.lastActivityTime)
   14044                                             / 1000) + "s");
   14045                             EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
   14046                                     app.processName, app.setAdj, "old background process");
   14047                             app.killedBackground = true;
   14048                             Process.killProcessQuiet(app.pid);
   14049                         } else {
   14050                             numEmpty++;
   14051                             if (numEmpty > emptyProcessLimit) {
   14052                                 Slog.i(TAG, "No longer want " + app.processName
   14053                                         + " (pid " + app.pid + "): empty #" + numEmpty);
   14054                                 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
   14055                                         app.processName, app.setAdj, "too many background");
   14056                                 app.killedBackground = true;
   14057                                 Process.killProcessQuiet(app.pid);
   14058                             }
   14059                         }
   14060                     }
   14061                 }
   14062                 if (app.isolated && app.services.size() <= 0) {
   14063                     // If this is an isolated process, and there are no
   14064                     // services running in it, then the process is no longer
   14065                     // needed.  We agressively kill these because we can by
   14066                     // definition not re-use the same process again, and it is
   14067                     // good to avoid having whatever code was running in them
   14068                     // left sitting around after no longer needed.
   14069                     Slog.i(TAG, "Isolated process " + app.processName
   14070                             + " (pid " + app.pid + ") no longer needed");
   14071                     EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
   14072                             app.processName, app.setAdj, "isolated not needed");
   14073                     app.killedBackground = true;
   14074                     Process.killProcessQuiet(app.pid);
   14075                 }
   14076                 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
   14077                         && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
   14078                         && !app.killedBackground) {
   14079                     numTrimming++;
   14080                 }
   14081             }
   14082         }
   14083 
   14084         mNumServiceProcs = mNewNumServiceProcs;
   14085 
   14086         // Now determine the memory trimming level of background processes.
   14087         // Unfortunately we need to start at the back of the list to do this
   14088         // properly.  We only do this if the number of background apps we
   14089         // are managing to keep around is less than half the maximum we desire;
   14090         // if we are keeping a good number around, we'll let them use whatever
   14091         // memory they want.
   14092         if (numHidden <= ProcessList.TRIM_HIDDEN_APPS
   14093                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
   14094             final int numHiddenAndEmpty = numHidden + numEmpty;
   14095             final int N = mLruProcesses.size();
   14096             int factor = numTrimming/3;
   14097             int minFactor = 2;
   14098             if (mHomeProcess != null) minFactor++;
   14099             if (mPreviousProcess != null) minFactor++;
   14100             if (factor < minFactor) factor = minFactor;
   14101             int step = 0;
   14102             int fgTrimLevel;
   14103             if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
   14104                 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
   14105             } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
   14106                 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
   14107             } else {
   14108                 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
   14109             }
   14110             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
   14111             for (i=0; i<N; i++) {
   14112                 ProcessRecord app = mLruProcesses.get(i);
   14113                 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
   14114                         && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
   14115                         && !app.killedBackground) {
   14116                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
   14117                         try {
   14118                             app.thread.scheduleTrimMemory(curLevel);
   14119                         } catch (RemoteException e) {
   14120                         }
   14121                         if (false) {
   14122                             // For now we won't do this; our memory trimming seems
   14123                             // to be good enough at this point that destroying
   14124                             // activities causes more harm than good.
   14125                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
   14126                                     && app != mHomeProcess && app != mPreviousProcess) {
   14127                                 // Need to do this on its own message because the stack may not
   14128                                 // be in a consistent state at this point.
   14129                                 // For these apps we will also finish their activities
   14130                                 // to help them free memory.
   14131                                 mMainStack.scheduleDestroyActivities(app, false, "trim");
   14132                             }
   14133                         }
   14134                     }
   14135                     app.trimMemoryLevel = curLevel;
   14136                     step++;
   14137                     if (step >= factor) {
   14138                         step = 0;
   14139                         switch (curLevel) {
   14140                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
   14141                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
   14142                                 break;
   14143                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
   14144                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   14145                                 break;
   14146                         }
   14147                     }
   14148                 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   14149                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
   14150                             && app.thread != null) {
   14151                         try {
   14152                             app.thread.scheduleTrimMemory(
   14153                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   14154                         } catch (RemoteException e) {
   14155                         }
   14156                     }
   14157                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   14158                 } else {
   14159                     if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
   14160                             && app.pendingUiClean) {
   14161                         // If this application is now in the background and it
   14162                         // had done UI, then give it the special trim level to
   14163                         // have it free UI resources.
   14164                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
   14165                         if (app.trimMemoryLevel < level && app.thread != null) {
   14166                             try {
   14167                                 app.thread.scheduleTrimMemory(level);
   14168                             } catch (RemoteException e) {
   14169                             }
   14170                         }
   14171                         app.pendingUiClean = false;
   14172                     }
   14173                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
   14174                         try {
   14175                             app.thread.scheduleTrimMemory(fgTrimLevel);
   14176                         } catch (RemoteException e) {
   14177                         }
   14178                     }
   14179                     app.trimMemoryLevel = fgTrimLevel;
   14180                 }
   14181             }
   14182         } else {
   14183             final int N = mLruProcesses.size();
   14184             for (i=0; i<N; i++) {
   14185                 ProcessRecord app = mLruProcesses.get(i);
   14186                 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
   14187                         && app.pendingUiClean) {
   14188                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
   14189                             && app.thread != null) {
   14190                         try {
   14191                             app.thread.scheduleTrimMemory(
   14192                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   14193                         } catch (RemoteException e) {
   14194                         }
   14195                     }
   14196                     app.pendingUiClean = false;
   14197                 }
   14198                 app.trimMemoryLevel = 0;
   14199             }
   14200         }
   14201 
   14202         if (mAlwaysFinishActivities) {
   14203             // Need to do this on its own message because the stack may not
   14204             // be in a consistent state at this point.
   14205             mMainStack.scheduleDestroyActivities(null, false, "always-finish");
   14206         }
   14207     }
   14208 
   14209     final void trimApplications() {
   14210         synchronized (this) {
   14211             int i;
   14212 
   14213             // First remove any unused application processes whose package
   14214             // has been removed.
   14215             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
   14216                 final ProcessRecord app = mRemovedProcesses.get(i);
   14217                 if (app.activities.size() == 0
   14218                         && app.curReceiver == null && app.services.size() == 0) {
   14219                     Slog.i(
   14220                         TAG, "Exiting empty application process "
   14221                         + app.processName + " ("
   14222                         + (app.thread != null ? app.thread.asBinder() : null)
   14223                         + ")\n");
   14224                     if (app.pid > 0 && app.pid != MY_PID) {
   14225                         EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
   14226                                 app.processName, app.setAdj, "empty");
   14227                         Process.killProcessQuiet(app.pid);
   14228                     } else {
   14229                         try {
   14230                             app.thread.scheduleExit();
   14231                         } catch (Exception e) {
   14232                             // Ignore exceptions.
   14233                         }
   14234                     }
   14235                     cleanUpApplicationRecordLocked(app, false, true, -1);
   14236                     mRemovedProcesses.remove(i);
   14237 
   14238                     if (app.persistent) {
   14239                         if (app.persistent) {
   14240                             addAppLocked(app.info, false);
   14241                         }
   14242                     }
   14243                 }
   14244             }
   14245 
   14246             // Now update the oom adj for all processes.
   14247             updateOomAdjLocked();
   14248         }
   14249     }
   14250 
   14251     /** This method sends the specified signal to each of the persistent apps */
   14252     public void signalPersistentProcesses(int sig) throws RemoteException {
   14253         if (sig != Process.SIGNAL_USR1) {
   14254             throw new SecurityException("Only SIGNAL_USR1 is allowed");
   14255         }
   14256 
   14257         synchronized (this) {
   14258             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
   14259                     != PackageManager.PERMISSION_GRANTED) {
   14260                 throw new SecurityException("Requires permission "
   14261                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
   14262             }
   14263 
   14264             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   14265                 ProcessRecord r = mLruProcesses.get(i);
   14266                 if (r.thread != null && r.persistent) {
   14267                     Process.sendSignal(r.pid, sig);
   14268                 }
   14269             }
   14270         }
   14271     }
   14272 
   14273     private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
   14274         if (proc == null || proc == mProfileProc) {
   14275             proc = mProfileProc;
   14276             path = mProfileFile;
   14277             profileType = mProfileType;
   14278             clearProfilerLocked();
   14279         }
   14280         if (proc == null) {
   14281             return;
   14282         }
   14283         try {
   14284             proc.thread.profilerControl(false, path, null, profileType);
   14285         } catch (RemoteException e) {
   14286             throw new IllegalStateException("Process disappeared");
   14287         }
   14288     }
   14289 
   14290     private void clearProfilerLocked() {
   14291         if (mProfileFd != null) {
   14292             try {
   14293                 mProfileFd.close();
   14294             } catch (IOException e) {
   14295             }
   14296         }
   14297         mProfileApp = null;
   14298         mProfileProc = null;
   14299         mProfileFile = null;
   14300         mProfileType = 0;
   14301         mAutoStopProfiler = false;
   14302     }
   14303 
   14304     public boolean profileControl(String process, int userId, boolean start,
   14305             String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
   14306 
   14307         try {
   14308             synchronized (this) {
   14309                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   14310                 // its own permission.
   14311                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   14312                         != PackageManager.PERMISSION_GRANTED) {
   14313                     throw new SecurityException("Requires permission "
   14314                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   14315                 }
   14316 
   14317                 if (start && fd == null) {
   14318                     throw new IllegalArgumentException("null fd");
   14319                 }
   14320 
   14321                 ProcessRecord proc = null;
   14322                 if (process != null) {
   14323                     proc = findProcessLocked(process, userId, "profileControl");
   14324                 }
   14325 
   14326                 if (start && (proc == null || proc.thread == null)) {
   14327                     throw new IllegalArgumentException("Unknown process: " + process);
   14328                 }
   14329 
   14330                 if (start) {
   14331                     stopProfilerLocked(null, null, 0);
   14332                     setProfileApp(proc.info, proc.processName, path, fd, false);
   14333                     mProfileProc = proc;
   14334                     mProfileType = profileType;
   14335                     try {
   14336                         fd = fd.dup();
   14337                     } catch (IOException e) {
   14338                         fd = null;
   14339                     }
   14340                     proc.thread.profilerControl(start, path, fd, profileType);
   14341                     fd = null;
   14342                     mProfileFd = null;
   14343                 } else {
   14344                     stopProfilerLocked(proc, path, profileType);
   14345                     if (fd != null) {
   14346                         try {
   14347                             fd.close();
   14348                         } catch (IOException e) {
   14349                         }
   14350                     }
   14351                 }
   14352 
   14353                 return true;
   14354             }
   14355         } catch (RemoteException e) {
   14356             throw new IllegalStateException("Process disappeared");
   14357         } finally {
   14358             if (fd != null) {
   14359                 try {
   14360                     fd.close();
   14361                 } catch (IOException e) {
   14362                 }
   14363             }
   14364         }
   14365     }
   14366 
   14367     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
   14368         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   14369                 userId, true, true, callName, null);
   14370         ProcessRecord proc = null;
   14371         try {
   14372             int pid = Integer.parseInt(process);
   14373             synchronized (mPidsSelfLocked) {
   14374                 proc = mPidsSelfLocked.get(pid);
   14375             }
   14376         } catch (NumberFormatException e) {
   14377         }
   14378 
   14379         if (proc == null) {
   14380             HashMap<String, SparseArray<ProcessRecord>> all
   14381                     = mProcessNames.getMap();
   14382             SparseArray<ProcessRecord> procs = all.get(process);
   14383             if (procs != null && procs.size() > 0) {
   14384                 proc = procs.valueAt(0);
   14385                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
   14386                     for (int i=1; i<procs.size(); i++) {
   14387                         ProcessRecord thisProc = procs.valueAt(i);
   14388                         if (thisProc.userId == userId) {
   14389                             proc = thisProc;
   14390                             break;
   14391                         }
   14392                     }
   14393                 }
   14394             }
   14395         }
   14396 
   14397         return proc;
   14398     }
   14399 
   14400     public boolean dumpHeap(String process, int userId, boolean managed,
   14401             String path, ParcelFileDescriptor fd) throws RemoteException {
   14402 
   14403         try {
   14404             synchronized (this) {
   14405                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   14406                 // its own permission (same as profileControl).
   14407                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   14408                         != PackageManager.PERMISSION_GRANTED) {
   14409                     throw new SecurityException("Requires permission "
   14410                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   14411                 }
   14412 
   14413                 if (fd == null) {
   14414                     throw new IllegalArgumentException("null fd");
   14415                 }
   14416 
   14417                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
   14418                 if (proc == null || proc.thread == null) {
   14419                     throw new IllegalArgumentException("Unknown process: " + process);
   14420                 }
   14421 
   14422                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   14423                 if (!isDebuggable) {
   14424                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   14425                         throw new SecurityException("Process not debuggable: " + proc);
   14426                     }
   14427                 }
   14428 
   14429                 proc.thread.dumpHeap(managed, path, fd);
   14430                 fd = null;
   14431                 return true;
   14432             }
   14433         } catch (RemoteException e) {
   14434             throw new IllegalStateException("Process disappeared");
   14435         } finally {
   14436             if (fd != null) {
   14437                 try {
   14438                     fd.close();
   14439                 } catch (IOException e) {
   14440                 }
   14441             }
   14442         }
   14443     }
   14444 
   14445     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
   14446     public void monitor() {
   14447         synchronized (this) { }
   14448     }
   14449 
   14450     void onCoreSettingsChange(Bundle settings) {
   14451         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   14452             ProcessRecord processRecord = mLruProcesses.get(i);
   14453             try {
   14454                 if (processRecord.thread != null) {
   14455                     processRecord.thread.setCoreSettings(settings);
   14456                 }
   14457             } catch (RemoteException re) {
   14458                 /* ignore */
   14459             }
   14460         }
   14461     }
   14462 
   14463     // Multi-user methods
   14464 
   14465     @Override
   14466     public boolean switchUser(final int userId) {
   14467         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
   14468                 != PackageManager.PERMISSION_GRANTED) {
   14469             String msg = "Permission Denial: switchUser() from pid="
   14470                     + Binder.getCallingPid()
   14471                     + ", uid=" + Binder.getCallingUid()
   14472                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
   14473             Slog.w(TAG, msg);
   14474             throw new SecurityException(msg);
   14475         }
   14476 
   14477         final long ident = Binder.clearCallingIdentity();
   14478         try {
   14479             synchronized (this) {
   14480                 final int oldUserId = mCurrentUserId;
   14481                 if (oldUserId == userId) {
   14482                     return true;
   14483                 }
   14484 
   14485                 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
   14486                 if (userInfo == null) {
   14487                     Slog.w(TAG, "No user info for user #" + userId);
   14488                     return false;
   14489                 }
   14490 
   14491                 mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
   14492                         R.anim.screen_user_enter);
   14493 
   14494                 boolean needStart = false;
   14495 
   14496                 // If the user we are switching to is not currently started, then
   14497                 // we need to start it now.
   14498                 if (mStartedUsers.get(userId) == null) {
   14499                     mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
   14500                     updateStartedUserArrayLocked();
   14501                     needStart = true;
   14502                 }
   14503 
   14504                 mCurrentUserId = userId;
   14505                 mCurrentUserArray = new int[] { userId };
   14506                 final Integer userIdInt = Integer.valueOf(userId);
   14507                 mUserLru.remove(userIdInt);
   14508                 mUserLru.add(userIdInt);
   14509 
   14510                 mWindowManager.setCurrentUser(userId);
   14511 
   14512                 // Once the internal notion of the active user has switched, we lock the device
   14513                 // with the option to show the user switcher on the keyguard.
   14514                 mWindowManager.lockNow(null);
   14515 
   14516                 final UserStartedState uss = mStartedUsers.get(userId);
   14517 
   14518                 // Make sure user is in the started state.  If it is currently
   14519                 // stopping, we need to knock that off.
   14520                 if (uss.mState == UserStartedState.STATE_STOPPING) {
   14521                     // If we are stopping, we haven't sent ACTION_SHUTDOWN,
   14522                     // so we can just fairly silently bring the user back from
   14523                     // the almost-dead.
   14524                     uss.mState = UserStartedState.STATE_RUNNING;
   14525                     updateStartedUserArrayLocked();
   14526                     needStart = true;
   14527                 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
   14528                     // This means ACTION_SHUTDOWN has been sent, so we will
   14529                     // need to treat this as a new boot of the user.
   14530                     uss.mState = UserStartedState.STATE_BOOTING;
   14531                     updateStartedUserArrayLocked();
   14532                     needStart = true;
   14533                 }
   14534 
   14535                 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
   14536                 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
   14537                 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
   14538                         oldUserId, userId, uss));
   14539                 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
   14540                         oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
   14541                 if (needStart) {
   14542                     Intent intent = new Intent(Intent.ACTION_USER_STARTED);
   14543                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   14544                             | Intent.FLAG_RECEIVER_FOREGROUND);
   14545                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   14546                     broadcastIntentLocked(null, null, intent,
   14547                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   14548                             false, false, MY_PID, Process.SYSTEM_UID, userId);
   14549                 }
   14550 
   14551                 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
   14552                     if (userId != 0) {
   14553                         Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
   14554                         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   14555                         broadcastIntentLocked(null, null, intent, null,
   14556                                 new IIntentReceiver.Stub() {
   14557                                     public void performReceive(Intent intent, int resultCode,
   14558                                             String data, Bundle extras, boolean ordered,
   14559                                             boolean sticky, int sendingUser) {
   14560                                         userInitialized(uss, userId);
   14561                                     }
   14562                                 }, 0, null, null, null, AppOpsManager.OP_NONE,
   14563                                 true, false, MY_PID, Process.SYSTEM_UID,
   14564                                 userId);
   14565                         uss.initializing = true;
   14566                     } else {
   14567                         getUserManagerLocked().makeInitialized(userInfo.id);
   14568                     }
   14569                 }
   14570 
   14571                 boolean haveActivities = mMainStack.switchUserLocked(userId, uss);
   14572                 if (!haveActivities) {
   14573                     startHomeActivityLocked(userId);
   14574                 }
   14575 
   14576                 EventLogTags.writeAmSwitchUser(userId);
   14577                 getUserManagerLocked().userForeground(userId);
   14578                 sendUserSwitchBroadcastsLocked(oldUserId, userId);
   14579                 if (needStart) {
   14580                     Intent intent = new Intent(Intent.ACTION_USER_STARTING);
   14581                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   14582                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   14583                     broadcastIntentLocked(null, null, intent,
   14584                             null, new IIntentReceiver.Stub() {
   14585                                 @Override
   14586                                 public void performReceive(Intent intent, int resultCode, String data,
   14587                                         Bundle extras, boolean ordered, boolean sticky, int sendingUser)
   14588                                         throws RemoteException {
   14589                                 }
   14590                             }, 0, null, null,
   14591                             android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
   14592                             true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   14593                 }
   14594             }
   14595         } finally {
   14596             Binder.restoreCallingIdentity(ident);
   14597         }
   14598 
   14599         return true;
   14600     }
   14601 
   14602     void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
   14603         long ident = Binder.clearCallingIdentity();
   14604         try {
   14605             Intent intent;
   14606             if (oldUserId >= 0) {
   14607                 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
   14608                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   14609                         | Intent.FLAG_RECEIVER_FOREGROUND);
   14610                 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
   14611                 broadcastIntentLocked(null, null, intent,
   14612                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   14613                         false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
   14614             }
   14615             if (newUserId >= 0) {
   14616                 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
   14617                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   14618                         | Intent.FLAG_RECEIVER_FOREGROUND);
   14619                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
   14620                 broadcastIntentLocked(null, null, intent,
   14621                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   14622                         false, false, MY_PID, Process.SYSTEM_UID, newUserId);
   14623                 intent = new Intent(Intent.ACTION_USER_SWITCHED);
   14624                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   14625                         | Intent.FLAG_RECEIVER_FOREGROUND);
   14626                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
   14627                 broadcastIntentLocked(null, null, intent,
   14628                         null, null, 0, null, null,
   14629                         android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
   14630                         false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   14631             }
   14632         } finally {
   14633             Binder.restoreCallingIdentity(ident);
   14634         }
   14635     }
   14636 
   14637     void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
   14638             final int newUserId) {
   14639         final int N = mUserSwitchObservers.beginBroadcast();
   14640         if (N > 0) {
   14641             final IRemoteCallback callback = new IRemoteCallback.Stub() {
   14642                 int mCount = 0;
   14643                 @Override
   14644                 public void sendResult(Bundle data) throws RemoteException {
   14645                     synchronized (ActivityManagerService.this) {
   14646                         if (mCurUserSwitchCallback == this) {
   14647                             mCount++;
   14648                             if (mCount == N) {
   14649                                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
   14650                             }
   14651                         }
   14652                     }
   14653                 }
   14654             };
   14655             synchronized (this) {
   14656                 uss.switching = true;
   14657                 mCurUserSwitchCallback = callback;
   14658             }
   14659             for (int i=0; i<N; i++) {
   14660                 try {
   14661                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
   14662                             newUserId, callback);
   14663                 } catch (RemoteException e) {
   14664                 }
   14665             }
   14666         } else {
   14667             synchronized (this) {
   14668                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
   14669             }
   14670         }
   14671         mUserSwitchObservers.finishBroadcast();
   14672     }
   14673 
   14674     void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
   14675         synchronized (this) {
   14676             Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
   14677             sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
   14678         }
   14679     }
   14680 
   14681     void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
   14682         mCurUserSwitchCallback = null;
   14683         mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
   14684         mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
   14685                 oldUserId, newUserId, uss));
   14686     }
   14687 
   14688     void userInitialized(UserStartedState uss, int newUserId) {
   14689         completeSwitchAndInitalize(uss, newUserId, true, false);
   14690     }
   14691 
   14692     void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
   14693         completeSwitchAndInitalize(uss, newUserId, false, true);
   14694     }
   14695 
   14696     void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
   14697             boolean clearInitializing, boolean clearSwitching) {
   14698         boolean unfrozen = false;
   14699         synchronized (this) {
   14700             if (clearInitializing) {
   14701                 uss.initializing = false;
   14702                 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
   14703             }
   14704             if (clearSwitching) {
   14705                 uss.switching = false;
   14706             }
   14707             if (!uss.switching && !uss.initializing) {
   14708                 mWindowManager.stopFreezingScreen();
   14709                 unfrozen = true;
   14710             }
   14711         }
   14712         if (unfrozen) {
   14713             final int N = mUserSwitchObservers.beginBroadcast();
   14714             for (int i=0; i<N; i++) {
   14715                 try {
   14716                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
   14717                 } catch (RemoteException e) {
   14718                 }
   14719             }
   14720             mUserSwitchObservers.finishBroadcast();
   14721         }
   14722     }
   14723 
   14724     void finishUserSwitch(UserStartedState uss) {
   14725         synchronized (this) {
   14726             if (uss.mState == UserStartedState.STATE_BOOTING
   14727                     && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
   14728                 uss.mState = UserStartedState.STATE_RUNNING;
   14729                 final int userId = uss.mHandle.getIdentifier();
   14730                 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
   14731                 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   14732                 broadcastIntentLocked(null, null, intent,
   14733                         null, null, 0, null, null,
   14734                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
   14735                         false, false, MY_PID, Process.SYSTEM_UID, userId);
   14736             }
   14737             int num = mUserLru.size();
   14738             int i = 0;
   14739             while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
   14740                 Integer oldUserId = mUserLru.get(i);
   14741                 UserStartedState oldUss = mStartedUsers.get(oldUserId);
   14742                 if (oldUss == null) {
   14743                     // Shouldn't happen, but be sane if it does.
   14744                     mUserLru.remove(i);
   14745                     num--;
   14746                     continue;
   14747                 }
   14748                 if (oldUss.mState == UserStartedState.STATE_STOPPING
   14749                         || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
   14750                     // This user is already stopping, doesn't count.
   14751                     num--;
   14752                     i++;
   14753                     continue;
   14754                 }
   14755                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
   14756                     // Owner and current can't be stopped, but count as running.
   14757                     i++;
   14758                     continue;
   14759                 }
   14760                 // This is a user to be stopped.
   14761                 stopUserLocked(oldUserId, null);
   14762                 num--;
   14763                 i++;
   14764             }
   14765         }
   14766     }
   14767 
   14768     @Override
   14769     public int stopUser(final int userId, final IStopUserCallback callback) {
   14770         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
   14771                 != PackageManager.PERMISSION_GRANTED) {
   14772             String msg = "Permission Denial: switchUser() from pid="
   14773                     + Binder.getCallingPid()
   14774                     + ", uid=" + Binder.getCallingUid()
   14775                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
   14776             Slog.w(TAG, msg);
   14777             throw new SecurityException(msg);
   14778         }
   14779         if (userId <= 0) {
   14780             throw new IllegalArgumentException("Can't stop primary user " + userId);
   14781         }
   14782         synchronized (this) {
   14783             return stopUserLocked(userId, callback);
   14784         }
   14785     }
   14786 
   14787     private int stopUserLocked(final int userId, final IStopUserCallback callback) {
   14788         if (mCurrentUserId == userId) {
   14789             return ActivityManager.USER_OP_IS_CURRENT;
   14790         }
   14791 
   14792         final UserStartedState uss = mStartedUsers.get(userId);
   14793         if (uss == null) {
   14794             // User is not started, nothing to do...  but we do need to
   14795             // callback if requested.
   14796             if (callback != null) {
   14797                 mHandler.post(new Runnable() {
   14798                     @Override
   14799                     public void run() {
   14800                         try {
   14801                             callback.userStopped(userId);
   14802                         } catch (RemoteException e) {
   14803                         }
   14804                     }
   14805                 });
   14806             }
   14807             return ActivityManager.USER_OP_SUCCESS;
   14808         }
   14809 
   14810         if (callback != null) {
   14811             uss.mStopCallbacks.add(callback);
   14812         }
   14813 
   14814         if (uss.mState != UserStartedState.STATE_STOPPING
   14815                 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
   14816             uss.mState = UserStartedState.STATE_STOPPING;
   14817             updateStartedUserArrayLocked();
   14818 
   14819             long ident = Binder.clearCallingIdentity();
   14820             try {
   14821                 // We are going to broadcast ACTION_USER_STOPPING and then
   14822                 // once that is done send a final ACTION_SHUTDOWN and then
   14823                 // stop the user.
   14824                 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
   14825                 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   14826                 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   14827                 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
   14828                 // This is the result receiver for the final shutdown broadcast.
   14829                 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
   14830                     @Override
   14831                     public void performReceive(Intent intent, int resultCode, String data,
   14832                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
   14833                         finishUserStop(uss);
   14834                     }
   14835                 };
   14836                 // This is the result receiver for the initial stopping broadcast.
   14837                 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
   14838                     @Override
   14839                     public void performReceive(Intent intent, int resultCode, String data,
   14840                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
   14841                         // On to the next.
   14842                         synchronized (ActivityManagerService.this) {
   14843                             if (uss.mState != UserStartedState.STATE_STOPPING) {
   14844                                 // Whoops, we are being started back up.  Abort, abort!
   14845                                 return;
   14846                             }
   14847                             uss.mState = UserStartedState.STATE_SHUTDOWN;
   14848                         }
   14849                         broadcastIntentLocked(null, null, shutdownIntent,
   14850                                 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
   14851                                 true, false, MY_PID, Process.SYSTEM_UID, userId);
   14852                     }
   14853                 };
   14854                 // Kick things off.
   14855                 broadcastIntentLocked(null, null, stoppingIntent,
   14856                         null, stoppingReceiver, 0, null, null,
   14857                         android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
   14858                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   14859             } finally {
   14860                 Binder.restoreCallingIdentity(ident);
   14861             }
   14862         }
   14863 
   14864         return ActivityManager.USER_OP_SUCCESS;
   14865     }
   14866 
   14867     void finishUserStop(UserStartedState uss) {
   14868         final int userId = uss.mHandle.getIdentifier();
   14869         boolean stopped;
   14870         ArrayList<IStopUserCallback> callbacks;
   14871         synchronized (this) {
   14872             callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
   14873             if (mStartedUsers.get(userId) != uss) {
   14874                 stopped = false;
   14875             } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
   14876                 stopped = false;
   14877             } else {
   14878                 stopped = true;
   14879                 // User can no longer run.
   14880                 mStartedUsers.remove(userId);
   14881                 mUserLru.remove(Integer.valueOf(userId));
   14882                 updateStartedUserArrayLocked();
   14883 
   14884                 // Clean up all state and processes associated with the user.
   14885                 // Kill all the processes for the user.
   14886                 forceStopUserLocked(userId);
   14887             }
   14888         }
   14889 
   14890         for (int i=0; i<callbacks.size(); i++) {
   14891             try {
   14892                 if (stopped) callbacks.get(i).userStopped(userId);
   14893                 else callbacks.get(i).userStopAborted(userId);
   14894             } catch (RemoteException e) {
   14895             }
   14896         }
   14897     }
   14898 
   14899     @Override
   14900     public UserInfo getCurrentUser() {
   14901         if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
   14902                 != PackageManager.PERMISSION_GRANTED) && (
   14903                 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
   14904                 != PackageManager.PERMISSION_GRANTED)) {
   14905             String msg = "Permission Denial: getCurrentUser() from pid="
   14906                     + Binder.getCallingPid()
   14907                     + ", uid=" + Binder.getCallingUid()
   14908                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
   14909             Slog.w(TAG, msg);
   14910             throw new SecurityException(msg);
   14911         }
   14912         synchronized (this) {
   14913             return getUserManagerLocked().getUserInfo(mCurrentUserId);
   14914         }
   14915     }
   14916 
   14917     int getCurrentUserIdLocked() {
   14918         return mCurrentUserId;
   14919     }
   14920 
   14921     @Override
   14922     public boolean isUserRunning(int userId, boolean orStopped) {
   14923         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
   14924                 != PackageManager.PERMISSION_GRANTED) {
   14925             String msg = "Permission Denial: isUserRunning() from pid="
   14926                     + Binder.getCallingPid()
   14927                     + ", uid=" + Binder.getCallingUid()
   14928                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
   14929             Slog.w(TAG, msg);
   14930             throw new SecurityException(msg);
   14931         }
   14932         synchronized (this) {
   14933             return isUserRunningLocked(userId, orStopped);
   14934         }
   14935     }
   14936 
   14937     boolean isUserRunningLocked(int userId, boolean orStopped) {
   14938         UserStartedState state = mStartedUsers.get(userId);
   14939         if (state == null) {
   14940             return false;
   14941         }
   14942         if (orStopped) {
   14943             return true;
   14944         }
   14945         return state.mState != UserStartedState.STATE_STOPPING
   14946                 && state.mState != UserStartedState.STATE_SHUTDOWN;
   14947     }
   14948 
   14949     @Override
   14950     public int[] getRunningUserIds() {
   14951         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
   14952                 != PackageManager.PERMISSION_GRANTED) {
   14953             String msg = "Permission Denial: isUserRunning() from pid="
   14954                     + Binder.getCallingPid()
   14955                     + ", uid=" + Binder.getCallingUid()
   14956                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
   14957             Slog.w(TAG, msg);
   14958             throw new SecurityException(msg);
   14959         }
   14960         synchronized (this) {
   14961             return mStartedUserArray;
   14962         }
   14963     }
   14964 
   14965     private void updateStartedUserArrayLocked() {
   14966         int num = 0;
   14967         for (int i=0; i<mStartedUsers.size();  i++) {
   14968             UserStartedState uss = mStartedUsers.valueAt(i);
   14969             // This list does not include stopping users.
   14970             if (uss.mState != UserStartedState.STATE_STOPPING
   14971                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
   14972                 num++;
   14973             }
   14974         }
   14975         mStartedUserArray = new int[num];
   14976         num = 0;
   14977         for (int i=0; i<mStartedUsers.size();  i++) {
   14978             UserStartedState uss = mStartedUsers.valueAt(i);
   14979             if (uss.mState != UserStartedState.STATE_STOPPING
   14980                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
   14981                 mStartedUserArray[num] = mStartedUsers.keyAt(i);
   14982                 num++;
   14983             }
   14984         }
   14985     }
   14986 
   14987     @Override
   14988     public void registerUserSwitchObserver(IUserSwitchObserver observer) {
   14989         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
   14990                 != PackageManager.PERMISSION_GRANTED) {
   14991             String msg = "Permission Denial: registerUserSwitchObserver() from pid="
   14992                     + Binder.getCallingPid()
   14993                     + ", uid=" + Binder.getCallingUid()
   14994                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
   14995             Slog.w(TAG, msg);
   14996             throw new SecurityException(msg);
   14997         }
   14998 
   14999         mUserSwitchObservers.register(observer);
   15000     }
   15001 
   15002     @Override
   15003     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
   15004         mUserSwitchObservers.unregister(observer);
   15005     }
   15006 
   15007     private boolean userExists(int userId) {
   15008         if (userId == 0) {
   15009             return true;
   15010         }
   15011         UserManagerService ums = getUserManagerLocked();
   15012         return ums != null ? (ums.getUserInfo(userId) != null) : false;
   15013     }
   15014 
   15015     int[] getUsersLocked() {
   15016         UserManagerService ums = getUserManagerLocked();
   15017         return ums != null ? ums.getUserIds() : new int[] { 0 };
   15018     }
   15019 
   15020     UserManagerService getUserManagerLocked() {
   15021         if (mUserManager == null) {
   15022             IBinder b = ServiceManager.getService(Context.USER_SERVICE);
   15023             mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
   15024         }
   15025         return mUserManager;
   15026     }
   15027 
   15028     private void checkValidCaller(int uid, int userId) {
   15029         if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
   15030 
   15031         throw new SecurityException("Caller uid=" + uid
   15032                 + " is not privileged to communicate with user=" + userId);
   15033     }
   15034 
   15035     private int applyUserId(int uid, int userId) {
   15036         return UserHandle.getUid(userId, uid);
   15037     }
   15038 
   15039     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
   15040         if (info == null) return null;
   15041         ApplicationInfo newInfo = new ApplicationInfo(info);
   15042         newInfo.uid = applyUserId(info.uid, userId);
   15043         newInfo.dataDir = USER_DATA_DIR + userId + "/"
   15044                 + info.packageName;
   15045         return newInfo;
   15046     }
   15047 
   15048     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
   15049         if (aInfo == null
   15050                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
   15051             return aInfo;
   15052         }
   15053 
   15054         ActivityInfo info = new ActivityInfo(aInfo);
   15055         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
   15056         return info;
   15057     }
   15058 }
   15059