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 com.android.internal.R;
     20 import com.android.internal.os.BatteryStatsImpl;
     21 import com.android.server.AttributeCache;
     22 import com.android.server.IntentResolver;
     23 import com.android.server.ProcessMap;
     24 import com.android.server.ProcessStats;
     25 import com.android.server.SystemServer;
     26 import com.android.server.Watchdog;
     27 import com.android.server.WindowManagerService;
     28 import com.android.server.am.ActivityStack.ActivityState;
     29 
     30 import dalvik.system.Zygote;
     31 
     32 import android.app.Activity;
     33 import android.app.ActivityManager;
     34 import android.app.ActivityManagerNative;
     35 import android.app.ActivityThread;
     36 import android.app.AlertDialog;
     37 import android.app.AppGlobals;
     38 import android.app.ApplicationErrorReport;
     39 import android.app.Dialog;
     40 import android.app.IActivityController;
     41 import android.app.IActivityWatcher;
     42 import android.app.IApplicationThread;
     43 import android.app.IInstrumentationWatcher;
     44 import android.app.INotificationManager;
     45 import android.app.IServiceConnection;
     46 import android.app.IThumbnailReceiver;
     47 import android.app.Instrumentation;
     48 import android.app.Notification;
     49 import android.app.NotificationManager;
     50 import android.app.PendingIntent;
     51 import android.app.Service;
     52 import android.app.backup.IBackupManager;
     53 import android.content.ActivityNotFoundException;
     54 import android.content.BroadcastReceiver;
     55 import android.content.ComponentName;
     56 import android.content.ContentResolver;
     57 import android.content.Context;
     58 import android.content.Intent;
     59 import android.content.IntentFilter;
     60 import android.content.IIntentReceiver;
     61 import android.content.IIntentSender;
     62 import android.content.IntentSender;
     63 import android.content.pm.ActivityInfo;
     64 import android.content.pm.ApplicationInfo;
     65 import android.content.pm.ConfigurationInfo;
     66 import android.content.pm.IPackageDataObserver;
     67 import android.content.pm.IPackageManager;
     68 import android.content.pm.InstrumentationInfo;
     69 import android.content.pm.PackageInfo;
     70 import android.content.pm.PackageManager;
     71 import android.content.pm.PathPermission;
     72 import android.content.pm.ProviderInfo;
     73 import android.content.pm.ResolveInfo;
     74 import android.content.pm.ServiceInfo;
     75 import android.content.pm.PackageManager.NameNotFoundException;
     76 import android.content.res.Configuration;
     77 import android.graphics.Bitmap;
     78 import android.net.Uri;
     79 import android.os.Binder;
     80 import android.os.Build;
     81 import android.os.Bundle;
     82 import android.os.Debug;
     83 import android.os.DropBoxManager;
     84 import android.os.Environment;
     85 import android.os.FileObserver;
     86 import android.os.FileUtils;
     87 import android.os.Handler;
     88 import android.os.IBinder;
     89 import android.os.IPermissionController;
     90 import android.os.Looper;
     91 import android.os.Message;
     92 import android.os.Parcel;
     93 import android.os.ParcelFileDescriptor;
     94 import android.os.Process;
     95 import android.os.RemoteCallbackList;
     96 import android.os.RemoteException;
     97 import android.os.ServiceManager;
     98 import android.os.StrictMode;
     99 import android.os.SystemClock;
    100 import android.os.SystemProperties;
    101 import android.provider.Settings;
    102 import android.util.Config;
    103 import android.util.EventLog;
    104 import android.util.Slog;
    105 import android.util.Log;
    106 import android.util.PrintWriterPrinter;
    107 import android.util.SparseArray;
    108 import android.util.TimeUtils;
    109 import android.view.Gravity;
    110 import android.view.LayoutInflater;
    111 import android.view.View;
    112 import android.view.WindowManager;
    113 import android.view.WindowManagerPolicy;
    114 
    115 import java.io.BufferedInputStream;
    116 import java.io.BufferedOutputStream;
    117 import java.io.DataInputStream;
    118 import java.io.DataOutputStream;
    119 import java.io.File;
    120 import java.io.FileDescriptor;
    121 import java.io.FileInputStream;
    122 import java.io.FileNotFoundException;
    123 import java.io.FileOutputStream;
    124 import java.io.IOException;
    125 import java.io.InputStreamReader;
    126 import java.io.PrintWriter;
    127 import java.lang.IllegalStateException;
    128 import java.lang.ref.WeakReference;
    129 import java.util.ArrayList;
    130 import java.util.Collections;
    131 import java.util.Comparator;
    132 import java.util.HashMap;
    133 import java.util.HashSet;
    134 import java.util.Iterator;
    135 import java.util.List;
    136 import java.util.Locale;
    137 import java.util.Map;
    138 import java.util.Set;
    139 import java.util.concurrent.atomic.AtomicBoolean;
    140 import java.util.concurrent.atomic.AtomicLong;
    141 
    142 public final class ActivityManagerService extends ActivityManagerNative
    143         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    144     static final String TAG = "ActivityManager";
    145     static final boolean DEBUG = false;
    146     static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
    147     static final boolean DEBUG_SWITCH = localLOGV || false;
    148     static final boolean DEBUG_TASKS = localLOGV || false;
    149     static final boolean DEBUG_PAUSE = localLOGV || false;
    150     static final boolean DEBUG_OOM_ADJ = localLOGV || false;
    151     static final boolean DEBUG_TRANSITION = localLOGV || false;
    152     static final boolean DEBUG_BROADCAST = localLOGV || false;
    153     static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
    154     static final boolean DEBUG_SERVICE = localLOGV || false;
    155     static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
    156     static final boolean DEBUG_VISBILITY = localLOGV || false;
    157     static final boolean DEBUG_PROCESSES = localLOGV || false;
    158     static final boolean DEBUG_PROVIDER = localLOGV || false;
    159     static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
    160     static final boolean DEBUG_USER_LEAVING = localLOGV || false;
    161     static final boolean DEBUG_RESULTS = localLOGV || false;
    162     static final boolean DEBUG_BACKUP = localLOGV || false;
    163     static final boolean DEBUG_CONFIGURATION = localLOGV || false;
    164     static final boolean DEBUG_POWER = localLOGV || false;
    165     static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
    166     static final boolean VALIDATE_TOKENS = false;
    167     static final boolean SHOW_ACTIVITY_START_TIME = true;
    168 
    169     // Control over CPU and battery monitoring.
    170     static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
    171     static final boolean MONITOR_CPU_USAGE = true;
    172     static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
    173     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
    174     static final boolean MONITOR_THREAD_CPU_USAGE = false;
    175 
    176     // The flags that are set for all calls we make to the package manager.
    177     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
    178 
    179     private static final String SYSTEM_SECURE = "ro.secure";
    180 
    181     // This is the maximum number of application processes we would like
    182     // to have running.  Due to the asynchronous nature of things, we can
    183     // temporarily go beyond this limit.
    184     static final int MAX_PROCESSES = 2;
    185 
    186     // Set to false to leave processes running indefinitely, relying on
    187     // the kernel killing them as resources are required.
    188     static final boolean ENFORCE_PROCESS_LIMIT = false;
    189 
    190     // This is the maximum number of activities that we would like to have
    191     // running at a given time.
    192     static final int MAX_ACTIVITIES = 20;
    193 
    194     // Maximum number of recent tasks that we can remember.
    195     static final int MAX_RECENT_TASKS = 20;
    196 
    197     // Amount of time after a call to stopAppSwitches() during which we will
    198     // prevent further untrusted switches from happening.
    199     static final long APP_SWITCH_DELAY_TIME = 5*1000;
    200 
    201     // How long we wait for a launched process to attach to the activity manager
    202     // before we decide it's never going to come up for real.
    203     static final int PROC_START_TIMEOUT = 10*1000;
    204 
    205     // How long to wait after going idle before forcing apps to GC.
    206     static final int GC_TIMEOUT = 5*1000;
    207 
    208     // The minimum amount of time between successive GC requests for a process.
    209     static final int GC_MIN_INTERVAL = 60*1000;
    210 
    211     // The rate at which we check for apps using excessive power -- 15 mins.
    212     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
    213 
    214     // The minimum sample duration we will allow before deciding we have
    215     // enough data on wake locks to start killing things.
    216     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    217 
    218     // The minimum sample duration we will allow before deciding we have
    219     // enough data on CPU usage to start killing things.
    220     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    221 
    222     // How long we allow a receiver to run before giving up on it.
    223     static final int BROADCAST_TIMEOUT = 10*1000;
    224 
    225     // How long we wait for a service to finish executing.
    226     static final int SERVICE_TIMEOUT = 20*1000;
    227 
    228     // How long a service needs to be running until restarting its process
    229     // is no longer considered to be a relaunch of the service.
    230     static final int SERVICE_RESTART_DURATION = 5*1000;
    231 
    232     // How long a service needs to be running until it will start back at
    233     // SERVICE_RESTART_DURATION after being killed.
    234     static final int SERVICE_RESET_RUN_DURATION = 60*1000;
    235 
    236     // Multiplying factor to increase restart duration time by, for each time
    237     // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
    238     static final int SERVICE_RESTART_DURATION_FACTOR = 4;
    239 
    240     // The minimum amount of time between restarting services that we allow.
    241     // That is, when multiple services are restarting, we won't allow each
    242     // to restart less than this amount of time from the last one.
    243     static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
    244 
    245     // Maximum amount of time for there to be no activity on a service before
    246     // we consider it non-essential and allow its process to go on the
    247     // LRU background list.
    248     static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
    249 
    250     // How long we wait until we timeout on key dispatching.
    251     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
    252 
    253     // The minimum time we allow between crashes, for us to consider this
    254     // application to be bad and stop and its services and reject broadcasts.
    255     static final int MIN_CRASH_INTERVAL = 60*1000;
    256 
    257     // How long we wait until we timeout on key dispatching during instrumentation.
    258     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
    259 
    260     // OOM adjustments for processes in various states:
    261 
    262     // This is a process without anything currently running in it.  Definitely
    263     // the first to go! Value set in system/rootdir/init.rc on startup.
    264     // This value is initalized in the constructor, careful when refering to
    265     // this static variable externally.
    266     static final int EMPTY_APP_ADJ;
    267 
    268     // This is a process only hosting activities that are not visible,
    269     // so it can be killed without any disruption. Value set in
    270     // system/rootdir/init.rc on startup.
    271     static final int HIDDEN_APP_MAX_ADJ;
    272     static int HIDDEN_APP_MIN_ADJ;
    273 
    274     // This is a process holding the home application -- we want to try
    275     // avoiding killing it, even if it would normally be in the background,
    276     // because the user interacts with it so much.
    277     static final int HOME_APP_ADJ;
    278 
    279     // This is a process currently hosting a backup operation.  Killing it
    280     // is not entirely fatal but is generally a bad idea.
    281     static final int BACKUP_APP_ADJ;
    282 
    283     // This is a process holding a secondary server -- killing it will not
    284     // have much of an impact as far as the user is concerned. Value set in
    285     // system/rootdir/init.rc on startup.
    286     static final int SECONDARY_SERVER_ADJ;
    287 
    288     // This is a process with a heavy-weight application.  It is in the
    289     // background, but we want to try to avoid killing it.  Value set in
    290     // system/rootdir/init.rc on startup.
    291     static final int HEAVY_WEIGHT_APP_ADJ;
    292 
    293     // This is a process only hosting components that are perceptible to the
    294     // user, and we really want to avoid killing them, but they are not
    295     // immediately visible. An example is background music playback.  Value set in
    296     // system/rootdir/init.rc on startup.
    297     static final int PERCEPTIBLE_APP_ADJ;
    298 
    299     // This is a process only hosting activities that are visible to the
    300     // user, so we'd prefer they don't disappear. Value set in
    301     // system/rootdir/init.rc on startup.
    302     static final int VISIBLE_APP_ADJ;
    303 
    304     // This is the process running the current foreground app.  We'd really
    305     // rather not kill it! Value set in system/rootdir/init.rc on startup.
    306     static final int FOREGROUND_APP_ADJ;
    307 
    308     // This is a process running a core server, such as telephony.  Definitely
    309     // don't want to kill it, but doing so is not completely fatal.
    310     static final int CORE_SERVER_ADJ = -12;
    311 
    312     // The system process runs at the default adjustment.
    313     static final int SYSTEM_ADJ = -16;
    314 
    315     // Memory pages are 4K.
    316     static final int PAGE_SIZE = 4*1024;
    317 
    318     // Corresponding memory levels for above adjustments.
    319     static final int EMPTY_APP_MEM;
    320     static final int HIDDEN_APP_MEM;
    321     static final int HOME_APP_MEM;
    322     static final int BACKUP_APP_MEM;
    323     static final int SECONDARY_SERVER_MEM;
    324     static final int HEAVY_WEIGHT_APP_MEM;
    325     static final int PERCEPTIBLE_APP_MEM;
    326     static final int VISIBLE_APP_MEM;
    327     static final int FOREGROUND_APP_MEM;
    328 
    329     // The minimum number of hidden apps we want to be able to keep around,
    330     // without empty apps being able to push them out of memory.
    331     static final int MIN_HIDDEN_APPS = 2;
    332 
    333     // The maximum number of hidden processes we will keep around before
    334     // killing them; this is just a control to not let us go too crazy with
    335     // keeping around processes on devices with large amounts of RAM.
    336     static final int MAX_HIDDEN_APPS = 15;
    337 
    338     // We put empty content processes after any hidden processes that have
    339     // been idle for less than 15 seconds.
    340     static final long CONTENT_APP_IDLE_OFFSET = 15*1000;
    341 
    342     // We put empty content processes after any hidden processes that have
    343     // been idle for less than 120 seconds.
    344     static final long EMPTY_APP_IDLE_OFFSET = 120*1000;
    345 
    346     static int getIntProp(String name, boolean allowZero) {
    347         String str = SystemProperties.get(name);
    348         if (str == null) {
    349             throw new IllegalArgumentException("Property not defined: " + name);
    350         }
    351         int val = Integer.valueOf(str);
    352         if (val == 0 && !allowZero) {
    353             throw new IllegalArgumentException("Property must not be zero: " + name);
    354         }
    355         return val;
    356     }
    357 
    358     static {
    359         // These values are set in system/rootdir/init.rc on startup.
    360         FOREGROUND_APP_ADJ = getIntProp("ro.FOREGROUND_APP_ADJ", true);
    361         VISIBLE_APP_ADJ = getIntProp("ro.VISIBLE_APP_ADJ", true);
    362         PERCEPTIBLE_APP_ADJ = getIntProp("ro.PERCEPTIBLE_APP_ADJ", true);
    363         HEAVY_WEIGHT_APP_ADJ = getIntProp("ro.HEAVY_WEIGHT_APP_ADJ", true);
    364         SECONDARY_SERVER_ADJ = getIntProp("ro.SECONDARY_SERVER_ADJ", true);
    365         BACKUP_APP_ADJ = getIntProp("ro.BACKUP_APP_ADJ", true);
    366         HOME_APP_ADJ = getIntProp("ro.HOME_APP_ADJ", true);
    367         HIDDEN_APP_MIN_ADJ = getIntProp("ro.HIDDEN_APP_MIN_ADJ", true);
    368         EMPTY_APP_ADJ = getIntProp("ro.EMPTY_APP_ADJ", true);
    369         // These days we use the last empty slot for hidden apps as well.
    370         HIDDEN_APP_MAX_ADJ = EMPTY_APP_ADJ;
    371         FOREGROUND_APP_MEM = getIntProp("ro.FOREGROUND_APP_MEM", false)*PAGE_SIZE;
    372         VISIBLE_APP_MEM = getIntProp("ro.VISIBLE_APP_MEM", false)*PAGE_SIZE;
    373         PERCEPTIBLE_APP_MEM = getIntProp("ro.PERCEPTIBLE_APP_MEM", false)*PAGE_SIZE;
    374         HEAVY_WEIGHT_APP_MEM = getIntProp("ro.HEAVY_WEIGHT_APP_MEM", false)*PAGE_SIZE;
    375         SECONDARY_SERVER_MEM = getIntProp("ro.SECONDARY_SERVER_MEM", false)*PAGE_SIZE;
    376         BACKUP_APP_MEM = getIntProp("ro.BACKUP_APP_MEM", false)*PAGE_SIZE;
    377         HOME_APP_MEM = getIntProp("ro.HOME_APP_MEM", false)*PAGE_SIZE;
    378         HIDDEN_APP_MEM = getIntProp("ro.HIDDEN_APP_MEM", false)*PAGE_SIZE;
    379         EMPTY_APP_MEM = getIntProp("ro.EMPTY_APP_MEM", false)*PAGE_SIZE;
    380     }
    381 
    382     static final int MY_PID = Process.myPid();
    383 
    384     static final String[] EMPTY_STRING_ARRAY = new String[0];
    385 
    386     public ActivityStack mMainStack;
    387 
    388     /**
    389      * Description of a request to start a new activity, which has been held
    390      * due to app switches being disabled.
    391      */
    392     static class PendingActivityLaunch {
    393         ActivityRecord r;
    394         ActivityRecord sourceRecord;
    395         Uri[] grantedUriPermissions;
    396         int grantedMode;
    397         boolean onlyIfNeeded;
    398     }
    399 
    400     final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
    401             = new ArrayList<PendingActivityLaunch>();
    402 
    403     /**
    404      * List of all active broadcasts that are to be executed immediately
    405      * (without waiting for another broadcast to finish).  Currently this only
    406      * contains broadcasts to registered receivers, to avoid spinning up
    407      * a bunch of processes to execute IntentReceiver components.
    408      */
    409     final ArrayList<BroadcastRecord> mParallelBroadcasts
    410             = new ArrayList<BroadcastRecord>();
    411 
    412     /**
    413      * List of all active broadcasts that are to be executed one at a time.
    414      * The object at the top of the list is the currently activity broadcasts;
    415      * those after it are waiting for the top to finish..
    416      */
    417     final ArrayList<BroadcastRecord> mOrderedBroadcasts
    418             = new ArrayList<BroadcastRecord>();
    419 
    420     /**
    421      * Historical data of past broadcasts, for debugging.
    422      */
    423     static final int MAX_BROADCAST_HISTORY = 100;
    424     final BroadcastRecord[] mBroadcastHistory
    425             = new BroadcastRecord[MAX_BROADCAST_HISTORY];
    426 
    427     /**
    428      * Set when we current have a BROADCAST_INTENT_MSG in flight.
    429      */
    430     boolean mBroadcastsScheduled = false;
    431 
    432     /**
    433      * Activity we have told the window manager to have key focus.
    434      */
    435     ActivityRecord mFocusedActivity = null;
    436     /**
    437      * List of intents that were used to start the most recent tasks.
    438      */
    439     final ArrayList<TaskRecord> mRecentTasks
    440             = new ArrayList<TaskRecord>();
    441 
    442     /**
    443      * All of the applications we currently have running organized by name.
    444      * The keys are strings of the application package name (as
    445      * returned by the package manager), and the keys are ApplicationRecord
    446      * objects.
    447      */
    448     final ProcessMap<ProcessRecord> mProcessNames
    449             = new ProcessMap<ProcessRecord>();
    450 
    451     /**
    452      * The currently running heavy-weight process, if any.
    453      */
    454     ProcessRecord mHeavyWeightProcess = null;
    455 
    456     /**
    457      * The last time that various processes have crashed.
    458      */
    459     final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
    460 
    461     /**
    462      * Set of applications that we consider to be bad, and will reject
    463      * incoming broadcasts from (which the user has no control over).
    464      * Processes are added to this set when they have crashed twice within
    465      * a minimum amount of time; they are removed from it when they are
    466      * later restarted (hopefully due to some user action).  The value is the
    467      * time it was added to the list.
    468      */
    469     final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
    470 
    471     /**
    472      * All of the processes we currently have running organized by pid.
    473      * The keys are the pid running the application.
    474      *
    475      * <p>NOTE: This object is protected by its own lock, NOT the global
    476      * activity manager lock!
    477      */
    478     final SparseArray<ProcessRecord> mPidsSelfLocked
    479             = new SparseArray<ProcessRecord>();
    480 
    481     /**
    482      * All of the processes that have been forced to be foreground.  The key
    483      * is the pid of the caller who requested it (we hold a death
    484      * link on it).
    485      */
    486     abstract class ForegroundToken implements IBinder.DeathRecipient {
    487         int pid;
    488         IBinder token;
    489     }
    490     final SparseArray<ForegroundToken> mForegroundProcesses
    491             = new SparseArray<ForegroundToken>();
    492 
    493     /**
    494      * List of records for processes that someone had tried to start before the
    495      * system was ready.  We don't start them at that point, but ensure they
    496      * are started by the time booting is complete.
    497      */
    498     final ArrayList<ProcessRecord> mProcessesOnHold
    499             = new ArrayList<ProcessRecord>();
    500 
    501     /**
    502      * List of records for processes that we have started and are waiting
    503      * for them to call back.  This is really only needed when running in
    504      * single processes mode, in which case we do not have a unique pid for
    505      * each process.
    506      */
    507     final ArrayList<ProcessRecord> mStartingProcesses
    508             = new ArrayList<ProcessRecord>();
    509 
    510     /**
    511      * List of persistent applications that are in the process
    512      * of being started.
    513      */
    514     final ArrayList<ProcessRecord> mPersistentStartingProcesses
    515             = new ArrayList<ProcessRecord>();
    516 
    517     /**
    518      * Processes that are being forcibly torn down.
    519      */
    520     final ArrayList<ProcessRecord> mRemovedProcesses
    521             = new ArrayList<ProcessRecord>();
    522 
    523     /**
    524      * List of running applications, sorted by recent usage.
    525      * The first entry in the list is the least recently used.
    526      * It contains ApplicationRecord objects.  This list does NOT include
    527      * any persistent application records (since we never want to exit them).
    528      */
    529     final ArrayList<ProcessRecord> mLruProcesses
    530             = new ArrayList<ProcessRecord>();
    531 
    532     /**
    533      * List of processes that should gc as soon as things are idle.
    534      */
    535     final ArrayList<ProcessRecord> mProcessesToGc
    536             = new ArrayList<ProcessRecord>();
    537 
    538     /**
    539      * This is the process holding what we currently consider to be
    540      * the "home" activity.
    541      */
    542     ProcessRecord mHomeProcess;
    543 
    544     /**
    545      * Set of PendingResultRecord objects that are currently active.
    546      */
    547     final HashSet mPendingResultRecords = new HashSet();
    548 
    549     /**
    550      * Set of IntentSenderRecord objects that are currently active.
    551      */
    552     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
    553             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
    554 
    555     /**
    556      * Fingerprints (String.hashCode()) of stack traces that we've
    557      * already logged DropBox entries for.  Guarded by itself.  If
    558      * something (rogue user app) forces this over
    559      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
    560      */
    561     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
    562     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
    563 
    564     /**
    565      * Strict Mode background batched logging state.
    566      *
    567      * The string buffer is guarded by itself, and its lock is also
    568      * used to determine if another batched write is already
    569      * in-flight.
    570      */
    571     private final StringBuilder mStrictModeBuffer = new StringBuilder();
    572 
    573     /**
    574      * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
    575      */
    576     private boolean mPendingBroadcastTimeoutMessage;
    577 
    578     /**
    579      * Intent broadcast that we have tried to start, but are
    580      * waiting for its application's process to be created.  We only
    581      * need one (instead of a list) because we always process broadcasts
    582      * one at a time, so no others can be started while waiting for this
    583      * one.
    584      */
    585     BroadcastRecord mPendingBroadcast = null;
    586 
    587     /**
    588      * The receiver index that is pending, to restart the broadcast if needed.
    589      */
    590     int mPendingBroadcastRecvIndex;
    591 
    592     /**
    593      * Keeps track of all IIntentReceivers that have been registered for
    594      * broadcasts.  Hash keys are the receiver IBinder, hash value is
    595      * a ReceiverList.
    596      */
    597     final HashMap mRegisteredReceivers = new HashMap();
    598 
    599     /**
    600      * Resolver for broadcast intents to registered receivers.
    601      * Holds BroadcastFilter (subclass of IntentFilter).
    602      */
    603     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
    604             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
    605         @Override
    606         protected boolean allowFilterResult(
    607                 BroadcastFilter filter, List<BroadcastFilter> dest) {
    608             IBinder target = filter.receiverList.receiver.asBinder();
    609             for (int i=dest.size()-1; i>=0; i--) {
    610                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
    611                     return false;
    612                 }
    613             }
    614             return true;
    615         }
    616     };
    617 
    618     /**
    619      * State of all active sticky broadcasts.  Keys are the action of the
    620      * sticky Intent, values are an ArrayList of all broadcasted intents with
    621      * that action (which should usually be one).
    622      */
    623     final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
    624             new HashMap<String, ArrayList<Intent>>();
    625 
    626     /**
    627      * All currently running services.
    628      */
    629     final HashMap<ComponentName, ServiceRecord> mServices =
    630         new HashMap<ComponentName, ServiceRecord>();
    631 
    632     /**
    633      * All currently running services indexed by the Intent used to start them.
    634      */
    635     final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
    636         new HashMap<Intent.FilterComparison, ServiceRecord>();
    637 
    638     /**
    639      * All currently bound service connections.  Keys are the IBinder of
    640      * the client's IServiceConnection.
    641      */
    642     final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
    643             = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
    644 
    645     /**
    646      * List of services that we have been asked to start,
    647      * but haven't yet been able to.  It is used to hold start requests
    648      * while waiting for their corresponding application thread to get
    649      * going.
    650      */
    651     final ArrayList<ServiceRecord> mPendingServices
    652             = new ArrayList<ServiceRecord>();
    653 
    654     /**
    655      * List of services that are scheduled to restart following a crash.
    656      */
    657     final ArrayList<ServiceRecord> mRestartingServices
    658             = new ArrayList<ServiceRecord>();
    659 
    660     /**
    661      * List of services that are in the process of being stopped.
    662      */
    663     final ArrayList<ServiceRecord> mStoppingServices
    664             = new ArrayList<ServiceRecord>();
    665 
    666     /**
    667      * Backup/restore process management
    668      */
    669     String mBackupAppName = null;
    670     BackupRecord mBackupTarget = null;
    671 
    672     /**
    673      * List of PendingThumbnailsRecord objects of clients who are still
    674      * waiting to receive all of the thumbnails for a task.
    675      */
    676     final ArrayList mPendingThumbnails = new ArrayList();
    677 
    678     /**
    679      * List of HistoryRecord objects that have been finished and must
    680      * still report back to a pending thumbnail receiver.
    681      */
    682     final ArrayList mCancelledThumbnails = new ArrayList();
    683 
    684     /**
    685      * All of the currently running global content providers.  Keys are a
    686      * string containing the provider name and values are a
    687      * ContentProviderRecord object containing the data about it.  Note
    688      * that a single provider may be published under multiple names, so
    689      * there may be multiple entries here for a single one in mProvidersByClass.
    690      */
    691     final HashMap<String, ContentProviderRecord> mProvidersByName
    692             = new HashMap<String, ContentProviderRecord>();
    693 
    694     /**
    695      * All of the currently running global content providers.  Keys are a
    696      * string containing the provider's implementation class and values are a
    697      * ContentProviderRecord object containing the data about it.
    698      */
    699     final HashMap<String, ContentProviderRecord> mProvidersByClass
    700             = new HashMap<String, ContentProviderRecord>();
    701 
    702     /**
    703      * List of content providers who have clients waiting for them.  The
    704      * application is currently being launched and the provider will be
    705      * removed from this list once it is published.
    706      */
    707     final ArrayList<ContentProviderRecord> mLaunchingProviders
    708             = new ArrayList<ContentProviderRecord>();
    709 
    710     /**
    711      * Global set of specific Uri permissions that have been granted.
    712      */
    713     final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
    714             = new SparseArray<HashMap<Uri, UriPermission>>();
    715 
    716     /**
    717      * Thread-local storage used to carry caller permissions over through
    718      * indirect content-provider access.
    719      * @see #ActivityManagerService.openContentUri()
    720      */
    721     private class Identity {
    722         public int pid;
    723         public int uid;
    724 
    725         Identity(int _pid, int _uid) {
    726             pid = _pid;
    727             uid = _uid;
    728         }
    729     }
    730     private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
    731 
    732     /**
    733      * All information we have collected about the runtime performance of
    734      * any user id that can impact battery performance.
    735      */
    736     final BatteryStatsService mBatteryStatsService;
    737 
    738     /**
    739      * information about component usage
    740      */
    741     final UsageStatsService mUsageStatsService;
    742 
    743     /**
    744      * Current configuration information.  HistoryRecord objects are given
    745      * a reference to this object to indicate which configuration they are
    746      * currently running in, so this object must be kept immutable.
    747      */
    748     Configuration mConfiguration = new Configuration();
    749 
    750     /**
    751      * Current sequencing integer of the configuration, for skipping old
    752      * configurations.
    753      */
    754     int mConfigurationSeq = 0;
    755 
    756     /**
    757      * Hardware-reported OpenGLES version.
    758      */
    759     final int GL_ES_VERSION;
    760 
    761     /**
    762      * List of initialization arguments to pass to all processes when binding applications to them.
    763      * For example, references to the commonly used services.
    764      */
    765     HashMap<String, IBinder> mAppBindArgs;
    766 
    767     /**
    768      * Temporary to avoid allocations.  Protected by main lock.
    769      */
    770     final StringBuilder mStringBuilder = new StringBuilder(256);
    771 
    772     /**
    773      * Used to control how we initialize the service.
    774      */
    775     boolean mStartRunning = false;
    776     ComponentName mTopComponent;
    777     String mTopAction;
    778     String mTopData;
    779     boolean mProcessesReady = false;
    780     boolean mSystemReady = false;
    781     boolean mBooting = false;
    782     boolean mWaitingUpdate = false;
    783     boolean mDidUpdate = false;
    784     boolean mOnBattery = false;
    785     boolean mLaunchWarningShown = false;
    786 
    787     Context mContext;
    788 
    789     int mFactoryTest;
    790 
    791     boolean mCheckedForSetup;
    792 
    793     /**
    794      * The time at which we will allow normal application switches again,
    795      * after a call to {@link #stopAppSwitches()}.
    796      */
    797     long mAppSwitchesAllowedTime;
    798 
    799     /**
    800      * This is set to true after the first switch after mAppSwitchesAllowedTime
    801      * is set; any switches after that will clear the time.
    802      */
    803     boolean mDidAppSwitch;
    804 
    805     /**
    806      * Last time (in realtime) at which we checked for power usage.
    807      */
    808     long mLastPowerCheckRealtime;
    809 
    810     /**
    811      * Last time (in uptime) at which we checked for power usage.
    812      */
    813     long mLastPowerCheckUptime;
    814 
    815     /**
    816      * Set while we are wanting to sleep, to prevent any
    817      * activities from being started/resumed.
    818      */
    819     boolean mSleeping = false;
    820 
    821     /**
    822      * Set if we are shutting down the system, similar to sleeping.
    823      */
    824     boolean mShuttingDown = false;
    825 
    826     /**
    827      * Task identifier that activities are currently being started
    828      * in.  Incremented each time a new task is created.
    829      * todo: Replace this with a TokenSpace class that generates non-repeating
    830      * integers that won't wrap.
    831      */
    832     int mCurTask = 1;
    833 
    834     /**
    835      * Current sequence id for oom_adj computation traversal.
    836      */
    837     int mAdjSeq = 0;
    838 
    839     /**
    840      * Current sequence id for process LRU updating.
    841      */
    842     int mLruSeq = 0;
    843 
    844     /**
    845      * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar
    846      * is set, indicating the user wants processes started in such a way
    847      * that they can use ANDROID_PROCESS_WRAPPER and know what will be
    848      * running in each process (thus no pre-initialized process, etc).
    849      */
    850     boolean mSimpleProcessManagement = false;
    851 
    852     /**
    853      * System monitoring: number of processes that died since the last
    854      * N procs were started.
    855      */
    856     int[] mProcDeaths = new int[20];
    857 
    858     /**
    859      * This is set if we had to do a delayed dexopt of an app before launching
    860      * it, to increasing the ANR timeouts in that case.
    861      */
    862     boolean mDidDexOpt;
    863 
    864     String mDebugApp = null;
    865     boolean mWaitForDebugger = false;
    866     boolean mDebugTransient = false;
    867     String mOrigDebugApp = null;
    868     boolean mOrigWaitForDebugger = false;
    869     boolean mAlwaysFinishActivities = false;
    870     IActivityController mController = null;
    871 
    872     final RemoteCallbackList<IActivityWatcher> mWatchers
    873             = new RemoteCallbackList<IActivityWatcher>();
    874 
    875     /**
    876      * Callback of last caller to {@link #requestPss}.
    877      */
    878     Runnable mRequestPssCallback;
    879 
    880     /**
    881      * Remaining processes for which we are waiting results from the last
    882      * call to {@link #requestPss}.
    883      */
    884     final ArrayList<ProcessRecord> mRequestPssList
    885             = new ArrayList<ProcessRecord>();
    886 
    887     /**
    888      * Runtime statistics collection thread.  This object's lock is used to
    889      * protect all related state.
    890      */
    891     final Thread mProcessStatsThread;
    892 
    893     /**
    894      * Used to collect process stats when showing not responding dialog.
    895      * Protected by mProcessStatsThread.
    896      */
    897     final ProcessStats mProcessStats = new ProcessStats(
    898             MONITOR_THREAD_CPU_USAGE);
    899     final AtomicLong mLastCpuTime = new AtomicLong(0);
    900     final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
    901 
    902     long mLastWriteTime = 0;
    903 
    904     /**
    905      * Set to true after the system has finished booting.
    906      */
    907     boolean mBooted = false;
    908 
    909     int mProcessLimit = 0;
    910 
    911     WindowManagerService mWindowManager;
    912 
    913     static ActivityManagerService mSelf;
    914     static ActivityThread mSystemThread;
    915 
    916     private final class AppDeathRecipient implements IBinder.DeathRecipient {
    917         final ProcessRecord mApp;
    918         final int mPid;
    919         final IApplicationThread mAppThread;
    920 
    921         AppDeathRecipient(ProcessRecord app, int pid,
    922                 IApplicationThread thread) {
    923             if (localLOGV) Slog.v(
    924                 TAG, "New death recipient " + this
    925                 + " for thread " + thread.asBinder());
    926             mApp = app;
    927             mPid = pid;
    928             mAppThread = thread;
    929         }
    930 
    931         public void binderDied() {
    932             if (localLOGV) Slog.v(
    933                 TAG, "Death received in " + this
    934                 + " for thread " + mAppThread.asBinder());
    935             synchronized(ActivityManagerService.this) {
    936                 appDiedLocked(mApp, mPid, mAppThread);
    937             }
    938         }
    939     }
    940 
    941     static final int SHOW_ERROR_MSG = 1;
    942     static final int SHOW_NOT_RESPONDING_MSG = 2;
    943     static final int SHOW_FACTORY_ERROR_MSG = 3;
    944     static final int UPDATE_CONFIGURATION_MSG = 4;
    945     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
    946     static final int WAIT_FOR_DEBUGGER_MSG = 6;
    947     static final int BROADCAST_INTENT_MSG = 7;
    948     static final int BROADCAST_TIMEOUT_MSG = 8;
    949     static final int SERVICE_TIMEOUT_MSG = 12;
    950     static final int UPDATE_TIME_ZONE = 13;
    951     static final int SHOW_UID_ERROR_MSG = 14;
    952     static final int IM_FEELING_LUCKY_MSG = 15;
    953     static final int PROC_START_TIMEOUT_MSG = 20;
    954     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
    955     static final int KILL_APPLICATION_MSG = 22;
    956     static final int FINALIZE_PENDING_INTENT_MSG = 23;
    957     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
    958     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
    959     static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
    960     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
    961 
    962     AlertDialog mUidAlert;
    963 
    964     final Handler mHandler = new Handler() {
    965         //public Handler() {
    966         //    if (localLOGV) Slog.v(TAG, "Handler started!");
    967         //}
    968 
    969         public void handleMessage(Message msg) {
    970             switch (msg.what) {
    971             case SHOW_ERROR_MSG: {
    972                 HashMap data = (HashMap) msg.obj;
    973                 synchronized (ActivityManagerService.this) {
    974                     ProcessRecord proc = (ProcessRecord)data.get("app");
    975                     if (proc != null && proc.crashDialog != null) {
    976                         Slog.e(TAG, "App already has crash dialog: " + proc);
    977                         return;
    978                     }
    979                     AppErrorResult res = (AppErrorResult) data.get("result");
    980                     if (!mSleeping && !mShuttingDown) {
    981                         Dialog d = new AppErrorDialog(mContext, res, proc);
    982                         d.show();
    983                         proc.crashDialog = d;
    984                     } else {
    985                         // The device is asleep, so just pretend that the user
    986                         // saw a crash dialog and hit "force quit".
    987                         res.set(0);
    988                     }
    989                 }
    990 
    991                 ensureBootCompleted();
    992             } break;
    993             case SHOW_NOT_RESPONDING_MSG: {
    994                 synchronized (ActivityManagerService.this) {
    995                     HashMap data = (HashMap) msg.obj;
    996                     ProcessRecord proc = (ProcessRecord)data.get("app");
    997                     if (proc != null && proc.anrDialog != null) {
    998                         Slog.e(TAG, "App already has anr dialog: " + proc);
    999                         return;
   1000                     }
   1001 
   1002                     Intent intent = new Intent("android.intent.action.ANR");
   1003                     if (!mProcessesReady) {
   1004                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   1005                     }
   1006                     broadcastIntentLocked(null, null, intent,
   1007                             null, null, 0, null, null, null,
   1008                             false, false, MY_PID, Process.SYSTEM_UID);
   1009 
   1010                     Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
   1011                             mContext, proc, (ActivityRecord)data.get("activity"));
   1012                     d.show();
   1013                     proc.anrDialog = d;
   1014                 }
   1015 
   1016                 ensureBootCompleted();
   1017             } break;
   1018             case SHOW_STRICT_MODE_VIOLATION_MSG: {
   1019                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
   1020                 synchronized (ActivityManagerService.this) {
   1021                     ProcessRecord proc = (ProcessRecord) data.get("app");
   1022                     if (proc == null) {
   1023                         Slog.e(TAG, "App not found when showing strict mode dialog.");
   1024                         break;
   1025                     }
   1026                     if (proc.crashDialog != null) {
   1027                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
   1028                         return;
   1029                     }
   1030                     AppErrorResult res = (AppErrorResult) data.get("result");
   1031                     if (!mSleeping && !mShuttingDown) {
   1032                         Dialog d = new StrictModeViolationDialog(mContext, res, proc);
   1033                         d.show();
   1034                         proc.crashDialog = d;
   1035                     } else {
   1036                         // The device is asleep, so just pretend that the user
   1037                         // saw a crash dialog and hit "force quit".
   1038                         res.set(0);
   1039                     }
   1040                 }
   1041                 ensureBootCompleted();
   1042             } break;
   1043             case SHOW_FACTORY_ERROR_MSG: {
   1044                 Dialog d = new FactoryErrorDialog(
   1045                     mContext, msg.getData().getCharSequence("msg"));
   1046                 d.show();
   1047                 ensureBootCompleted();
   1048             } break;
   1049             case UPDATE_CONFIGURATION_MSG: {
   1050                 final ContentResolver resolver = mContext.getContentResolver();
   1051                 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
   1052             } break;
   1053             case GC_BACKGROUND_PROCESSES_MSG: {
   1054                 synchronized (ActivityManagerService.this) {
   1055                     performAppGcsIfAppropriateLocked();
   1056                 }
   1057             } break;
   1058             case WAIT_FOR_DEBUGGER_MSG: {
   1059                 synchronized (ActivityManagerService.this) {
   1060                     ProcessRecord app = (ProcessRecord)msg.obj;
   1061                     if (msg.arg1 != 0) {
   1062                         if (!app.waitedForDebugger) {
   1063                             Dialog d = new AppWaitingForDebuggerDialog(
   1064                                     ActivityManagerService.this,
   1065                                     mContext, app);
   1066                             app.waitDialog = d;
   1067                             app.waitedForDebugger = true;
   1068                             d.show();
   1069                         }
   1070                     } else {
   1071                         if (app.waitDialog != null) {
   1072                             app.waitDialog.dismiss();
   1073                             app.waitDialog = null;
   1074                         }
   1075                     }
   1076                 }
   1077             } break;
   1078             case BROADCAST_INTENT_MSG: {
   1079                 if (DEBUG_BROADCAST) Slog.v(
   1080                         TAG, "Received BROADCAST_INTENT_MSG");
   1081                 processNextBroadcast(true);
   1082             } break;
   1083             case BROADCAST_TIMEOUT_MSG: {
   1084                 synchronized (ActivityManagerService.this) {
   1085                     broadcastTimeoutLocked(true);
   1086                 }
   1087             } break;
   1088             case SERVICE_TIMEOUT_MSG: {
   1089                 if (mDidDexOpt) {
   1090                     mDidDexOpt = false;
   1091                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   1092                     nmsg.obj = msg.obj;
   1093                     mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
   1094                     return;
   1095                 }
   1096                 serviceTimeout((ProcessRecord)msg.obj);
   1097             } break;
   1098             case UPDATE_TIME_ZONE: {
   1099                 synchronized (ActivityManagerService.this) {
   1100                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1101                         ProcessRecord r = mLruProcesses.get(i);
   1102                         if (r.thread != null) {
   1103                             try {
   1104                                 r.thread.updateTimeZone();
   1105                             } catch (RemoteException ex) {
   1106                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
   1107                             }
   1108                         }
   1109                     }
   1110                 }
   1111             } break;
   1112             case SHOW_UID_ERROR_MSG: {
   1113                 // XXX This is a temporary dialog, no need to localize.
   1114                 AlertDialog d = new BaseErrorDialog(mContext);
   1115                 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
   1116                 d.setCancelable(false);
   1117                 d.setTitle("System UIDs Inconsistent");
   1118                 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
   1119                 d.setButton("I'm Feeling Lucky",
   1120                         mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
   1121                 mUidAlert = d;
   1122                 d.show();
   1123             } break;
   1124             case IM_FEELING_LUCKY_MSG: {
   1125                 if (mUidAlert != null) {
   1126                     mUidAlert.dismiss();
   1127                     mUidAlert = null;
   1128                 }
   1129             } break;
   1130             case PROC_START_TIMEOUT_MSG: {
   1131                 if (mDidDexOpt) {
   1132                     mDidDexOpt = false;
   1133                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   1134                     nmsg.obj = msg.obj;
   1135                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
   1136                     return;
   1137                 }
   1138                 ProcessRecord app = (ProcessRecord)msg.obj;
   1139                 synchronized (ActivityManagerService.this) {
   1140                     processStartTimedOutLocked(app);
   1141                 }
   1142             } break;
   1143             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
   1144                 synchronized (ActivityManagerService.this) {
   1145                     doPendingActivityLaunchesLocked(true);
   1146                 }
   1147             } break;
   1148             case KILL_APPLICATION_MSG: {
   1149                 synchronized (ActivityManagerService.this) {
   1150                     int uid = msg.arg1;
   1151                     boolean restart = (msg.arg2 == 1);
   1152                     String pkg = (String) msg.obj;
   1153                     forceStopPackageLocked(pkg, uid, restart, false, true);
   1154                 }
   1155             } break;
   1156             case FINALIZE_PENDING_INTENT_MSG: {
   1157                 ((PendingIntentRecord)msg.obj).completeFinalize();
   1158             } break;
   1159             case POST_HEAVY_NOTIFICATION_MSG: {
   1160                 INotificationManager inm = NotificationManager.getService();
   1161                 if (inm == null) {
   1162                     return;
   1163                 }
   1164 
   1165                 ActivityRecord root = (ActivityRecord)msg.obj;
   1166                 ProcessRecord process = root.app;
   1167                 if (process == null) {
   1168                     return;
   1169                 }
   1170 
   1171                 try {
   1172                     Context context = mContext.createPackageContext(process.info.packageName, 0);
   1173                     String text = mContext.getString(R.string.heavy_weight_notification,
   1174                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
   1175                     Notification notification = new Notification();
   1176                     notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
   1177                     notification.when = 0;
   1178                     notification.flags = Notification.FLAG_ONGOING_EVENT;
   1179                     notification.tickerText = text;
   1180                     notification.defaults = 0; // please be quiet
   1181                     notification.sound = null;
   1182                     notification.vibrate = null;
   1183                     notification.setLatestEventInfo(context, text,
   1184                             mContext.getText(R.string.heavy_weight_notification_detail),
   1185                             PendingIntent.getActivity(mContext, 0, root.intent,
   1186                                     PendingIntent.FLAG_CANCEL_CURRENT));
   1187 
   1188                     try {
   1189                         int[] outId = new int[1];
   1190                         inm.enqueueNotification("android", R.string.heavy_weight_notification,
   1191                                 notification, outId);
   1192                     } catch (RuntimeException e) {
   1193                         Slog.w(ActivityManagerService.TAG,
   1194                                 "Error showing notification for heavy-weight app", e);
   1195                     } catch (RemoteException e) {
   1196                     }
   1197                 } catch (NameNotFoundException e) {
   1198                     Slog.w(TAG, "Unable to create context for heavy notification", e);
   1199                 }
   1200             } break;
   1201             case CANCEL_HEAVY_NOTIFICATION_MSG: {
   1202                 INotificationManager inm = NotificationManager.getService();
   1203                 if (inm == null) {
   1204                     return;
   1205                 }
   1206                 try {
   1207                     inm.cancelNotification("android",
   1208                             R.string.heavy_weight_notification);
   1209                 } catch (RuntimeException e) {
   1210                     Slog.w(ActivityManagerService.TAG,
   1211                             "Error canceling notification for service", e);
   1212                 } catch (RemoteException e) {
   1213                 }
   1214             } break;
   1215             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
   1216                 synchronized (ActivityManagerService.this) {
   1217                     checkExcessivePowerUsageLocked(true);
   1218                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1219                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1220                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   1221                 }
   1222             } break;
   1223             }
   1224         }
   1225     };
   1226 
   1227     public static void setSystemProcess() {
   1228         try {
   1229             ActivityManagerService m = mSelf;
   1230 
   1231             ServiceManager.addService("activity", m);
   1232             ServiceManager.addService("meminfo", new MemBinder(m));
   1233             if (MONITOR_CPU_USAGE) {
   1234                 ServiceManager.addService("cpuinfo", new CpuBinder(m));
   1235             }
   1236             ServiceManager.addService("permission", new PermissionController(m));
   1237 
   1238             ApplicationInfo info =
   1239                 mSelf.mContext.getPackageManager().getApplicationInfo(
   1240                         "android", STOCK_PM_FLAGS);
   1241             mSystemThread.installSystemApplicationInfo(info);
   1242 
   1243             synchronized (mSelf) {
   1244                 ProcessRecord app = mSelf.newProcessRecordLocked(
   1245                         mSystemThread.getApplicationThread(), info,
   1246                         info.processName);
   1247                 app.persistent = true;
   1248                 app.pid = MY_PID;
   1249                 app.maxAdj = SYSTEM_ADJ;
   1250                 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
   1251                 synchronized (mSelf.mPidsSelfLocked) {
   1252                     mSelf.mPidsSelfLocked.put(app.pid, app);
   1253                 }
   1254                 mSelf.updateLruProcessLocked(app, true, true);
   1255             }
   1256         } catch (PackageManager.NameNotFoundException e) {
   1257             throw new RuntimeException(
   1258                     "Unable to find android system package", e);
   1259         }
   1260     }
   1261 
   1262     public void setWindowManager(WindowManagerService wm) {
   1263         mWindowManager = wm;
   1264     }
   1265 
   1266     public static final Context main(int factoryTest) {
   1267         AThread thr = new AThread();
   1268         thr.start();
   1269 
   1270         synchronized (thr) {
   1271             while (thr.mService == null) {
   1272                 try {
   1273                     thr.wait();
   1274                 } catch (InterruptedException e) {
   1275                 }
   1276             }
   1277         }
   1278 
   1279         ActivityManagerService m = thr.mService;
   1280         mSelf = m;
   1281         ActivityThread at = ActivityThread.systemMain();
   1282         mSystemThread = at;
   1283         Context context = at.getSystemContext();
   1284         m.mContext = context;
   1285         m.mFactoryTest = factoryTest;
   1286         m.mMainStack = new ActivityStack(m, context, true);
   1287 
   1288         m.mBatteryStatsService.publish(context);
   1289         m.mUsageStatsService.publish(context);
   1290 
   1291         synchronized (thr) {
   1292             thr.mReady = true;
   1293             thr.notifyAll();
   1294         }
   1295 
   1296         m.startRunning(null, null, null, null);
   1297 
   1298         return context;
   1299     }
   1300 
   1301     public static ActivityManagerService self() {
   1302         return mSelf;
   1303     }
   1304 
   1305     static class AThread extends Thread {
   1306         ActivityManagerService mService;
   1307         boolean mReady = false;
   1308 
   1309         public AThread() {
   1310             super("ActivityManager");
   1311         }
   1312 
   1313         public void run() {
   1314             Looper.prepare();
   1315 
   1316             android.os.Process.setThreadPriority(
   1317                     android.os.Process.THREAD_PRIORITY_FOREGROUND);
   1318             android.os.Process.setCanSelfBackground(false);
   1319 
   1320             ActivityManagerService m = new ActivityManagerService();
   1321 
   1322             synchronized (this) {
   1323                 mService = m;
   1324                 notifyAll();
   1325             }
   1326 
   1327             synchronized (this) {
   1328                 while (!mReady) {
   1329                     try {
   1330                         wait();
   1331                     } catch (InterruptedException e) {
   1332                     }
   1333                 }
   1334             }
   1335 
   1336             Looper.loop();
   1337         }
   1338     }
   1339 
   1340     static class MemBinder extends Binder {
   1341         ActivityManagerService mActivityManagerService;
   1342         MemBinder(ActivityManagerService activityManagerService) {
   1343             mActivityManagerService = activityManagerService;
   1344         }
   1345 
   1346         @Override
   1347         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1348             ActivityManagerService service = mActivityManagerService;
   1349             ArrayList<ProcessRecord> procs;
   1350             synchronized (mActivityManagerService) {
   1351                 if (args != null && args.length > 0
   1352                         && args[0].charAt(0) != '-') {
   1353                     procs = new ArrayList<ProcessRecord>();
   1354                     int pid = -1;
   1355                     try {
   1356                         pid = Integer.parseInt(args[0]);
   1357                     } catch (NumberFormatException e) {
   1358 
   1359                     }
   1360                     for (int i=service.mLruProcesses.size()-1; i>=0; i--) {
   1361                         ProcessRecord proc = service.mLruProcesses.get(i);
   1362                         if (proc.pid == pid) {
   1363                             procs.add(proc);
   1364                         } else if (proc.processName.equals(args[0])) {
   1365                             procs.add(proc);
   1366                         }
   1367                     }
   1368                     if (procs.size() <= 0) {
   1369                         pw.println("No process found for: " + args[0]);
   1370                         return;
   1371                     }
   1372                 } else {
   1373                     procs = new ArrayList<ProcessRecord>(service.mLruProcesses);
   1374                 }
   1375             }
   1376             dumpApplicationMemoryUsage(fd, pw, procs, "  ", args);
   1377         }
   1378     }
   1379 
   1380     static class CpuBinder extends Binder {
   1381         ActivityManagerService mActivityManagerService;
   1382         CpuBinder(ActivityManagerService activityManagerService) {
   1383             mActivityManagerService = activityManagerService;
   1384         }
   1385 
   1386         @Override
   1387         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1388             synchronized (mActivityManagerService.mProcessStatsThread) {
   1389                 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
   1390                 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
   1391                         SystemClock.uptimeMillis()));
   1392             }
   1393         }
   1394     }
   1395 
   1396     private ActivityManagerService() {
   1397         String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT");
   1398         if (v != null && Integer.getInteger(v) != 0) {
   1399             mSimpleProcessManagement = true;
   1400         }
   1401         v = System.getenv("ANDROID_DEBUG_APP");
   1402         if (v != null) {
   1403             mSimpleProcessManagement = true;
   1404         }
   1405 
   1406         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
   1407 
   1408         File dataDir = Environment.getDataDirectory();
   1409         File systemDir = new File(dataDir, "system");
   1410         systemDir.mkdirs();
   1411         mBatteryStatsService = new BatteryStatsService(new File(
   1412                 systemDir, "batterystats.bin").toString());
   1413         mBatteryStatsService.getActiveStatistics().readLocked();
   1414         mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
   1415         mOnBattery = DEBUG_POWER ? true
   1416                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
   1417         mBatteryStatsService.getActiveStatistics().setCallback(this);
   1418 
   1419         mUsageStatsService = new UsageStatsService(new File(
   1420                 systemDir, "usagestats").toString());
   1421 
   1422         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
   1423             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
   1424 
   1425         mConfiguration.setToDefaults();
   1426         mConfiguration.locale = Locale.getDefault();
   1427         mProcessStats.init();
   1428 
   1429         // Add ourself to the Watchdog monitors.
   1430         Watchdog.getInstance().addMonitor(this);
   1431 
   1432         mProcessStatsThread = new Thread("ProcessStats") {
   1433             public void run() {
   1434                 while (true) {
   1435                     try {
   1436                         try {
   1437                             synchronized(this) {
   1438                                 final long now = SystemClock.uptimeMillis();
   1439                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
   1440                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
   1441                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
   1442                                 //        + ", write delay=" + nextWriteDelay);
   1443                                 if (nextWriteDelay < nextCpuDelay) {
   1444                                     nextCpuDelay = nextWriteDelay;
   1445                                 }
   1446                                 if (nextCpuDelay > 0) {
   1447                                     mProcessStatsMutexFree.set(true);
   1448                                     this.wait(nextCpuDelay);
   1449                                 }
   1450                             }
   1451                         } catch (InterruptedException e) {
   1452                         }
   1453                         updateCpuStatsNow();
   1454                     } catch (Exception e) {
   1455                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
   1456                     }
   1457                 }
   1458             }
   1459         };
   1460         mProcessStatsThread.start();
   1461     }
   1462 
   1463     @Override
   1464     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   1465             throws RemoteException {
   1466         try {
   1467             return super.onTransact(code, data, reply, flags);
   1468         } catch (RuntimeException e) {
   1469             // The activity manager only throws security exceptions, so let's
   1470             // log all others.
   1471             if (!(e instanceof SecurityException)) {
   1472                 Slog.e(TAG, "Activity Manager Crash", e);
   1473             }
   1474             throw e;
   1475         }
   1476     }
   1477 
   1478     void updateCpuStats() {
   1479         final long now = SystemClock.uptimeMillis();
   1480         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
   1481             return;
   1482         }
   1483         if (mProcessStatsMutexFree.compareAndSet(true, false)) {
   1484             synchronized (mProcessStatsThread) {
   1485                 mProcessStatsThread.notify();
   1486             }
   1487         }
   1488     }
   1489 
   1490     void updateCpuStatsNow() {
   1491         synchronized (mProcessStatsThread) {
   1492             mProcessStatsMutexFree.set(false);
   1493             final long now = SystemClock.uptimeMillis();
   1494             boolean haveNewCpuStats = false;
   1495 
   1496             if (MONITOR_CPU_USAGE &&
   1497                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
   1498                 mLastCpuTime.set(now);
   1499                 haveNewCpuStats = true;
   1500                 mProcessStats.update();
   1501                 //Slog.i(TAG, mProcessStats.printCurrentState());
   1502                 //Slog.i(TAG, "Total CPU usage: "
   1503                 //        + mProcessStats.getTotalCpuPercent() + "%");
   1504 
   1505                 // Slog the cpu usage if the property is set.
   1506                 if ("true".equals(SystemProperties.get("events.cpu"))) {
   1507                     int user = mProcessStats.getLastUserTime();
   1508                     int system = mProcessStats.getLastSystemTime();
   1509                     int iowait = mProcessStats.getLastIoWaitTime();
   1510                     int irq = mProcessStats.getLastIrqTime();
   1511                     int softIrq = mProcessStats.getLastSoftIrqTime();
   1512                     int idle = mProcessStats.getLastIdleTime();
   1513 
   1514                     int total = user + system + iowait + irq + softIrq + idle;
   1515                     if (total == 0) total = 1;
   1516 
   1517                     EventLog.writeEvent(EventLogTags.CPU,
   1518                             ((user+system+iowait+irq+softIrq) * 100) / total,
   1519                             (user * 100) / total,
   1520                             (system * 100) / total,
   1521                             (iowait * 100) / total,
   1522                             (irq * 100) / total,
   1523                             (softIrq * 100) / total);
   1524                 }
   1525             }
   1526 
   1527             long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
   1528             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
   1529             synchronized(bstats) {
   1530                 synchronized(mPidsSelfLocked) {
   1531                     if (haveNewCpuStats) {
   1532                         if (mOnBattery) {
   1533                             int perc = bstats.startAddingCpuLocked();
   1534                             int totalUTime = 0;
   1535                             int totalSTime = 0;
   1536                             final int N = mProcessStats.countStats();
   1537                             for (int i=0; i<N; i++) {
   1538                                 ProcessStats.Stats st = mProcessStats.getStats(i);
   1539                                 if (!st.working) {
   1540                                     continue;
   1541                                 }
   1542                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
   1543                                 int otherUTime = (st.rel_utime*perc)/100;
   1544                                 int otherSTime = (st.rel_stime*perc)/100;
   1545                                 totalUTime += otherUTime;
   1546                                 totalSTime += otherSTime;
   1547                                 if (pr != null) {
   1548                                     BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
   1549                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
   1550                                             st.rel_stime-otherSTime);
   1551                                     ps.addSpeedStepTimes(cpuSpeedTimes);
   1552                                     pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
   1553                                 } else {
   1554                                     BatteryStatsImpl.Uid.Proc ps =
   1555                                             bstats.getProcessStatsLocked(st.name, st.pid);
   1556                                     if (ps != null) {
   1557                                         ps.addCpuTimeLocked(st.rel_utime-otherUTime,
   1558                                                 st.rel_stime-otherSTime);
   1559                                         ps.addSpeedStepTimes(cpuSpeedTimes);
   1560                                     }
   1561                                 }
   1562                             }
   1563                             bstats.finishAddingCpuLocked(perc, totalUTime,
   1564                                     totalSTime, cpuSpeedTimes);
   1565                         }
   1566                     }
   1567                 }
   1568 
   1569                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
   1570                     mLastWriteTime = now;
   1571                     mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
   1572                 }
   1573             }
   1574         }
   1575     }
   1576 
   1577     @Override
   1578     public void batteryNeedsCpuUpdate() {
   1579         updateCpuStatsNow();
   1580     }
   1581 
   1582     @Override
   1583     public void batteryPowerChanged(boolean onBattery) {
   1584         // When plugging in, update the CPU stats first before changing
   1585         // the plug state.
   1586         updateCpuStatsNow();
   1587         synchronized (this) {
   1588             synchronized(mPidsSelfLocked) {
   1589                 mOnBattery = DEBUG_POWER ? true : onBattery;
   1590             }
   1591         }
   1592     }
   1593 
   1594     /**
   1595      * Initialize the application bind args. These are passed to each
   1596      * process when the bindApplication() IPC is sent to the process. They're
   1597      * lazily setup to make sure the services are running when they're asked for.
   1598      */
   1599     private HashMap<String, IBinder> getCommonServicesLocked() {
   1600         if (mAppBindArgs == null) {
   1601             mAppBindArgs = new HashMap<String, IBinder>();
   1602 
   1603             // Setup the application init args
   1604             mAppBindArgs.put("package", ServiceManager.getService("package"));
   1605             mAppBindArgs.put("window", ServiceManager.getService("window"));
   1606             mAppBindArgs.put(Context.ALARM_SERVICE,
   1607                     ServiceManager.getService(Context.ALARM_SERVICE));
   1608         }
   1609         return mAppBindArgs;
   1610     }
   1611 
   1612     final void setFocusedActivityLocked(ActivityRecord r) {
   1613         if (mFocusedActivity != r) {
   1614             mFocusedActivity = r;
   1615             mWindowManager.setFocusedApp(r, true);
   1616         }
   1617     }
   1618 
   1619     private final void updateLruProcessInternalLocked(ProcessRecord app,
   1620             boolean oomAdj, boolean updateActivityTime, int bestPos) {
   1621         // put it on the LRU to keep track of when it should be exited.
   1622         int lrui = mLruProcesses.indexOf(app);
   1623         if (lrui >= 0) mLruProcesses.remove(lrui);
   1624 
   1625         int i = mLruProcesses.size()-1;
   1626         int skipTop = 0;
   1627 
   1628         app.lruSeq = mLruSeq;
   1629 
   1630         // compute the new weight for this process.
   1631         if (updateActivityTime) {
   1632             app.lastActivityTime = SystemClock.uptimeMillis();
   1633         }
   1634         if (app.activities.size() > 0) {
   1635             // If this process has activities, we more strongly want to keep
   1636             // it around.
   1637             app.lruWeight = app.lastActivityTime;
   1638         } else if (app.pubProviders.size() > 0) {
   1639             // If this process contains content providers, we want to keep
   1640             // it a little more strongly.
   1641             app.lruWeight = app.lastActivityTime - CONTENT_APP_IDLE_OFFSET;
   1642             // Also don't let it kick out the first few "real" hidden processes.
   1643             skipTop = MIN_HIDDEN_APPS;
   1644         } else {
   1645             // If this process doesn't have activities, we less strongly
   1646             // want to keep it around, and generally want to avoid getting
   1647             // in front of any very recently used activities.
   1648             app.lruWeight = app.lastActivityTime - EMPTY_APP_IDLE_OFFSET;
   1649             // Also don't let it kick out the first few "real" hidden processes.
   1650             skipTop = MIN_HIDDEN_APPS;
   1651         }
   1652 
   1653         while (i >= 0) {
   1654             ProcessRecord p = mLruProcesses.get(i);
   1655             // If this app shouldn't be in front of the first N background
   1656             // apps, then skip over that many that are currently hidden.
   1657             if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) {
   1658                 skipTop--;
   1659             }
   1660             if (p.lruWeight <= app.lruWeight || i < bestPos) {
   1661                 mLruProcesses.add(i+1, app);
   1662                 break;
   1663             }
   1664             i--;
   1665         }
   1666         if (i < 0) {
   1667             mLruProcesses.add(0, app);
   1668         }
   1669 
   1670         // If the app is currently using a content provider or service,
   1671         // bump those processes as well.
   1672         if (app.connections.size() > 0) {
   1673             for (ConnectionRecord cr : app.connections) {
   1674                 if (cr.binding != null && cr.binding.service != null
   1675                         && cr.binding.service.app != null
   1676                         && cr.binding.service.app.lruSeq != mLruSeq) {
   1677                     updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
   1678                             updateActivityTime, i+1);
   1679                 }
   1680             }
   1681         }
   1682         if (app.conProviders.size() > 0) {
   1683             for (ContentProviderRecord cpr : app.conProviders.keySet()) {
   1684                 if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
   1685                     updateLruProcessInternalLocked(cpr.app, oomAdj,
   1686                             updateActivityTime, i+1);
   1687                 }
   1688             }
   1689         }
   1690 
   1691         //Slog.i(TAG, "Putting proc to front: " + app.processName);
   1692         if (oomAdj) {
   1693             updateOomAdjLocked();
   1694         }
   1695     }
   1696 
   1697     final void updateLruProcessLocked(ProcessRecord app,
   1698             boolean oomAdj, boolean updateActivityTime) {
   1699         mLruSeq++;
   1700         updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
   1701     }
   1702 
   1703     final ProcessRecord getProcessRecordLocked(
   1704             String processName, int uid) {
   1705         if (uid == Process.SYSTEM_UID) {
   1706             // The system gets to run in any process.  If there are multiple
   1707             // processes with the same uid, just pick the first (this
   1708             // should never happen).
   1709             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
   1710                     processName);
   1711             return procs != null ? procs.valueAt(0) : null;
   1712         }
   1713         ProcessRecord proc = mProcessNames.get(processName, uid);
   1714         return proc;
   1715     }
   1716 
   1717     void ensurePackageDexOpt(String packageName) {
   1718         IPackageManager pm = AppGlobals.getPackageManager();
   1719         try {
   1720             if (pm.performDexOpt(packageName)) {
   1721                 mDidDexOpt = true;
   1722             }
   1723         } catch (RemoteException e) {
   1724         }
   1725     }
   1726 
   1727     boolean isNextTransitionForward() {
   1728         int transit = mWindowManager.getPendingAppTransition();
   1729         return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
   1730                 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
   1731                 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
   1732     }
   1733 
   1734     final ProcessRecord startProcessLocked(String processName,
   1735             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
   1736             String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
   1737         ProcessRecord app = getProcessRecordLocked(processName, info.uid);
   1738         // We don't have to do anything more if:
   1739         // (1) There is an existing application record; and
   1740         // (2) The caller doesn't think it is dead, OR there is no thread
   1741         //     object attached to it so we know it couldn't have crashed; and
   1742         // (3) There is a pid assigned to it, so it is either starting or
   1743         //     already running.
   1744         if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
   1745                 + " app=" + app + " knownToBeDead=" + knownToBeDead
   1746                 + " thread=" + (app != null ? app.thread : null)
   1747                 + " pid=" + (app != null ? app.pid : -1));
   1748         if (app != null && app.pid > 0) {
   1749             if (!knownToBeDead || app.thread == null) {
   1750                 // We already have the app running, or are waiting for it to
   1751                 // come up (we have a pid but not yet its thread), so keep it.
   1752                 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
   1753                 return app;
   1754             } else {
   1755                 // An application record is attached to a previous process,
   1756                 // clean it up now.
   1757                 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
   1758                 handleAppDiedLocked(app, true);
   1759             }
   1760         }
   1761 
   1762         String hostingNameStr = hostingName != null
   1763                 ? hostingName.flattenToShortString() : null;
   1764 
   1765         if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
   1766             // If we are in the background, then check to see if this process
   1767             // is bad.  If so, we will just silently fail.
   1768             if (mBadProcesses.get(info.processName, info.uid) != null) {
   1769                 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
   1770                         + "/" + info.processName);
   1771                 return null;
   1772             }
   1773         } else {
   1774             // When the user is explicitly starting a process, then clear its
   1775             // crash count so that we won't make it bad until they see at
   1776             // least one crash dialog again, and make the process good again
   1777             // if it had been bad.
   1778             if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
   1779                     + "/" + info.processName);
   1780             mProcessCrashTimes.remove(info.processName, info.uid);
   1781             if (mBadProcesses.get(info.processName, info.uid) != null) {
   1782                 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
   1783                         info.processName);
   1784                 mBadProcesses.remove(info.processName, info.uid);
   1785                 if (app != null) {
   1786                     app.bad = false;
   1787                 }
   1788             }
   1789         }
   1790 
   1791         if (app == null) {
   1792             app = newProcessRecordLocked(null, info, processName);
   1793             mProcessNames.put(processName, info.uid, app);
   1794         } else {
   1795             // If this is a new package in the process, add the package to the list
   1796             app.addPackage(info.packageName);
   1797         }
   1798 
   1799         // If the system is not ready yet, then hold off on starting this
   1800         // process until it is.
   1801         if (!mProcessesReady
   1802                 && !isAllowedWhileBooting(info)
   1803                 && !allowWhileBooting) {
   1804             if (!mProcessesOnHold.contains(app)) {
   1805                 mProcessesOnHold.add(app);
   1806             }
   1807             if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
   1808             return app;
   1809         }
   1810 
   1811         startProcessLocked(app, hostingType, hostingNameStr);
   1812         return (app.pid != 0) ? app : null;
   1813     }
   1814 
   1815     boolean isAllowedWhileBooting(ApplicationInfo ai) {
   1816         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
   1817     }
   1818 
   1819     private final void startProcessLocked(ProcessRecord app,
   1820             String hostingType, String hostingNameStr) {
   1821         if (app.pid > 0 && app.pid != MY_PID) {
   1822             synchronized (mPidsSelfLocked) {
   1823                 mPidsSelfLocked.remove(app.pid);
   1824                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   1825             }
   1826             app.pid = 0;
   1827         }
   1828 
   1829         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   1830                 "startProcessLocked removing on hold: " + app);
   1831         mProcessesOnHold.remove(app);
   1832 
   1833         updateCpuStats();
   1834 
   1835         System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
   1836         mProcDeaths[0] = 0;
   1837 
   1838         try {
   1839             int uid = app.info.uid;
   1840             int[] gids = null;
   1841             try {
   1842                 gids = mContext.getPackageManager().getPackageGids(
   1843                         app.info.packageName);
   1844             } catch (PackageManager.NameNotFoundException e) {
   1845                 Slog.w(TAG, "Unable to retrieve gids", e);
   1846             }
   1847             if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
   1848                 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
   1849                         && mTopComponent != null
   1850                         && app.processName.equals(mTopComponent.getPackageName())) {
   1851                     uid = 0;
   1852                 }
   1853                 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
   1854                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
   1855                     uid = 0;
   1856                 }
   1857             }
   1858             int debugFlags = 0;
   1859             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   1860                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
   1861             }
   1862             // Run the app in safe mode if its manifest requests so or the
   1863             // system is booted in safe mode.
   1864             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
   1865                 Zygote.systemInSafeMode == true) {
   1866                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
   1867             }
   1868             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
   1869                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   1870             }
   1871             if ("1".equals(SystemProperties.get("debug.assert"))) {
   1872                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
   1873             }
   1874             int pid = Process.start("android.app.ActivityThread",
   1875                     mSimpleProcessManagement ? app.processName : null, uid, uid,
   1876                     gids, debugFlags, null);
   1877             BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
   1878             synchronized (bs) {
   1879                 if (bs.isOnBattery()) {
   1880                     app.batteryStats.incStartsLocked();
   1881                 }
   1882             }
   1883 
   1884             EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid,
   1885                     app.processName, hostingType,
   1886                     hostingNameStr != null ? hostingNameStr : "");
   1887 
   1888             if (app.persistent) {
   1889                 Watchdog.getInstance().processStarted(app.processName, pid);
   1890             }
   1891 
   1892             StringBuilder buf = mStringBuilder;
   1893             buf.setLength(0);
   1894             buf.append("Start proc ");
   1895             buf.append(app.processName);
   1896             buf.append(" for ");
   1897             buf.append(hostingType);
   1898             if (hostingNameStr != null) {
   1899                 buf.append(" ");
   1900                 buf.append(hostingNameStr);
   1901             }
   1902             buf.append(": pid=");
   1903             buf.append(pid);
   1904             buf.append(" uid=");
   1905             buf.append(uid);
   1906             buf.append(" gids={");
   1907             if (gids != null) {
   1908                 for (int gi=0; gi<gids.length; gi++) {
   1909                     if (gi != 0) buf.append(", ");
   1910                     buf.append(gids[gi]);
   1911 
   1912                 }
   1913             }
   1914             buf.append("}");
   1915             Slog.i(TAG, buf.toString());
   1916             if (pid == 0 || pid == MY_PID) {
   1917                 // Processes are being emulated with threads.
   1918                 app.pid = MY_PID;
   1919                 app.removed = false;
   1920                 mStartingProcesses.add(app);
   1921             } else if (pid > 0) {
   1922                 app.pid = pid;
   1923                 app.removed = false;
   1924                 synchronized (mPidsSelfLocked) {
   1925                     this.mPidsSelfLocked.put(pid, app);
   1926                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   1927                     msg.obj = app;
   1928                     mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
   1929                 }
   1930             } else {
   1931                 app.pid = 0;
   1932                 RuntimeException e = new RuntimeException(
   1933                         "Failure starting process " + app.processName
   1934                         + ": returned pid=" + pid);
   1935                 Slog.e(TAG, e.getMessage(), e);
   1936             }
   1937         } catch (RuntimeException e) {
   1938             // XXX do better error recovery.
   1939             app.pid = 0;
   1940             Slog.e(TAG, "Failure starting process " + app.processName, e);
   1941         }
   1942     }
   1943 
   1944     void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
   1945         if (resumed) {
   1946             mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
   1947         } else {
   1948             mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
   1949         }
   1950     }
   1951 
   1952     boolean startHomeActivityLocked() {
   1953         if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
   1954                 && mTopAction == null) {
   1955             // We are running in factory test mode, but unable to find
   1956             // the factory test app, so just sit around displaying the
   1957             // error message and don't try to start anything.
   1958             return false;
   1959         }
   1960         Intent intent = new Intent(
   1961             mTopAction,
   1962             mTopData != null ? Uri.parse(mTopData) : null);
   1963         intent.setComponent(mTopComponent);
   1964         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   1965             intent.addCategory(Intent.CATEGORY_HOME);
   1966         }
   1967         ActivityInfo aInfo =
   1968             intent.resolveActivityInfo(mContext.getPackageManager(),
   1969                     STOCK_PM_FLAGS);
   1970         if (aInfo != null) {
   1971             intent.setComponent(new ComponentName(
   1972                     aInfo.applicationInfo.packageName, aInfo.name));
   1973             // Don't do this if the home app is currently being
   1974             // instrumented.
   1975             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
   1976                     aInfo.applicationInfo.uid);
   1977             if (app == null || app.instrumentationClass == null) {
   1978                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
   1979                 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
   1980                         null, null, 0, 0, 0, false, false);
   1981             }
   1982         }
   1983 
   1984 
   1985         return true;
   1986     }
   1987 
   1988     /**
   1989      * Starts the "new version setup screen" if appropriate.
   1990      */
   1991     void startSetupActivityLocked() {
   1992         // Only do this once per boot.
   1993         if (mCheckedForSetup) {
   1994             return;
   1995         }
   1996 
   1997         // We will show this screen if the current one is a different
   1998         // version than the last one shown, and we are not running in
   1999         // low-level factory test mode.
   2000         final ContentResolver resolver = mContext.getContentResolver();
   2001         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
   2002                 Settings.Secure.getInt(resolver,
   2003                         Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
   2004             mCheckedForSetup = true;
   2005 
   2006             // See if we should be showing the platform update setup UI.
   2007             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
   2008             List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
   2009                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
   2010 
   2011             // We don't allow third party apps to replace this.
   2012             ResolveInfo ri = null;
   2013             for (int i=0; ris != null && i<ris.size(); i++) {
   2014                 if ((ris.get(i).activityInfo.applicationInfo.flags
   2015                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
   2016                     ri = ris.get(i);
   2017                     break;
   2018                 }
   2019             }
   2020 
   2021             if (ri != null) {
   2022                 String vers = ri.activityInfo.metaData != null
   2023                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
   2024                         : null;
   2025                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
   2026                     vers = ri.activityInfo.applicationInfo.metaData.getString(
   2027                             Intent.METADATA_SETUP_VERSION);
   2028                 }
   2029                 String lastVers = Settings.Secure.getString(
   2030                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
   2031                 if (vers != null && !vers.equals(lastVers)) {
   2032                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   2033                     intent.setComponent(new ComponentName(
   2034                             ri.activityInfo.packageName, ri.activityInfo.name));
   2035                     mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
   2036                             null, null, 0, 0, 0, false, false);
   2037                 }
   2038             }
   2039         }
   2040     }
   2041 
   2042     void reportResumedActivityLocked(ActivityRecord r) {
   2043         //Slog.i(TAG, "**** REPORT RESUME: " + r);
   2044 
   2045         final int identHash = System.identityHashCode(r);
   2046         updateUsageStats(r, true);
   2047 
   2048         int i = mWatchers.beginBroadcast();
   2049         while (i > 0) {
   2050             i--;
   2051             IActivityWatcher w = mWatchers.getBroadcastItem(i);
   2052             if (w != null) {
   2053                 try {
   2054                     w.activityResuming(identHash);
   2055                 } catch (RemoteException e) {
   2056                 }
   2057             }
   2058         }
   2059         mWatchers.finishBroadcast();
   2060     }
   2061 
   2062     final void doPendingActivityLaunchesLocked(boolean doResume) {
   2063         final int N = mPendingActivityLaunches.size();
   2064         if (N <= 0) {
   2065             return;
   2066         }
   2067         for (int i=0; i<N; i++) {
   2068             PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
   2069             mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
   2070                     pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
   2071                     doResume && i == (N-1));
   2072         }
   2073         mPendingActivityLaunches.clear();
   2074     }
   2075 
   2076     public final int startActivity(IApplicationThread caller,
   2077             Intent intent, String resolvedType, Uri[] grantedUriPermissions,
   2078             int grantedMode, IBinder resultTo,
   2079             String resultWho, int requestCode, boolean onlyIfNeeded,
   2080             boolean debug) {
   2081         return mMainStack.startActivityMayWait(caller, intent, resolvedType,
   2082                 grantedUriPermissions, grantedMode, resultTo, resultWho,
   2083                 requestCode, onlyIfNeeded, debug, null, null);
   2084     }
   2085 
   2086     public final WaitResult startActivityAndWait(IApplicationThread caller,
   2087             Intent intent, String resolvedType, Uri[] grantedUriPermissions,
   2088             int grantedMode, IBinder resultTo,
   2089             String resultWho, int requestCode, boolean onlyIfNeeded,
   2090             boolean debug) {
   2091         WaitResult res = new WaitResult();
   2092         mMainStack.startActivityMayWait(caller, intent, resolvedType,
   2093                 grantedUriPermissions, grantedMode, resultTo, resultWho,
   2094                 requestCode, onlyIfNeeded, debug, res, null);
   2095         return res;
   2096     }
   2097 
   2098     public final int startActivityWithConfig(IApplicationThread caller,
   2099             Intent intent, String resolvedType, Uri[] grantedUriPermissions,
   2100             int grantedMode, IBinder resultTo,
   2101             String resultWho, int requestCode, boolean onlyIfNeeded,
   2102             boolean debug, Configuration config) {
   2103         return mMainStack.startActivityMayWait(caller, intent, resolvedType,
   2104                 grantedUriPermissions, grantedMode, resultTo, resultWho,
   2105                 requestCode, onlyIfNeeded, debug, null, config);
   2106     }
   2107 
   2108      public int startActivityIntentSender(IApplicationThread caller,
   2109             IntentSender intent, Intent fillInIntent, String resolvedType,
   2110             IBinder resultTo, String resultWho, int requestCode,
   2111             int flagsMask, int flagsValues) {
   2112         // Refuse possible leaked file descriptors
   2113         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
   2114             throw new IllegalArgumentException("File descriptors passed in Intent");
   2115         }
   2116 
   2117         IIntentSender sender = intent.getTarget();
   2118         if (!(sender instanceof PendingIntentRecord)) {
   2119             throw new IllegalArgumentException("Bad PendingIntent object");
   2120         }
   2121 
   2122         PendingIntentRecord pir = (PendingIntentRecord)sender;
   2123 
   2124         synchronized (this) {
   2125             // If this is coming from the currently resumed activity, it is
   2126             // effectively saying that app switches are allowed at this point.
   2127             if (mMainStack.mResumedActivity != null
   2128                     && mMainStack.mResumedActivity.info.applicationInfo.uid ==
   2129                             Binder.getCallingUid()) {
   2130                 mAppSwitchesAllowedTime = 0;
   2131             }
   2132         }
   2133 
   2134         return pir.sendInner(0, fillInIntent, resolvedType,
   2135                 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
   2136     }
   2137 
   2138     public boolean startNextMatchingActivity(IBinder callingActivity,
   2139             Intent intent) {
   2140         // Refuse possible leaked file descriptors
   2141         if (intent != null && intent.hasFileDescriptors() == true) {
   2142             throw new IllegalArgumentException("File descriptors passed in Intent");
   2143         }
   2144 
   2145         synchronized (this) {
   2146             int index = mMainStack.indexOfTokenLocked(callingActivity);
   2147             if (index < 0) {
   2148                 return false;
   2149             }
   2150             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
   2151             if (r.app == null || r.app.thread == null) {
   2152                 // The caller is not running...  d'oh!
   2153                 return false;
   2154             }
   2155             intent = new Intent(intent);
   2156             // The caller is not allowed to change the data.
   2157             intent.setDataAndType(r.intent.getData(), r.intent.getType());
   2158             // And we are resetting to find the next component...
   2159             intent.setComponent(null);
   2160 
   2161             ActivityInfo aInfo = null;
   2162             try {
   2163                 List<ResolveInfo> resolves =
   2164                     AppGlobals.getPackageManager().queryIntentActivities(
   2165                             intent, r.resolvedType,
   2166                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
   2167 
   2168                 // Look for the original activity in the list...
   2169                 final int N = resolves != null ? resolves.size() : 0;
   2170                 for (int i=0; i<N; i++) {
   2171                     ResolveInfo rInfo = resolves.get(i);
   2172                     if (rInfo.activityInfo.packageName.equals(r.packageName)
   2173                             && rInfo.activityInfo.name.equals(r.info.name)) {
   2174                         // We found the current one...  the next matching is
   2175                         // after it.
   2176                         i++;
   2177                         if (i<N) {
   2178                             aInfo = resolves.get(i).activityInfo;
   2179                         }
   2180                         break;
   2181                     }
   2182                 }
   2183             } catch (RemoteException e) {
   2184             }
   2185 
   2186             if (aInfo == null) {
   2187                 // Nobody who is next!
   2188                 return false;
   2189             }
   2190 
   2191             intent.setComponent(new ComponentName(
   2192                     aInfo.applicationInfo.packageName, aInfo.name));
   2193             intent.setFlags(intent.getFlags()&~(
   2194                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
   2195                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
   2196                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
   2197                     Intent.FLAG_ACTIVITY_NEW_TASK));
   2198 
   2199             // Okay now we need to start the new activity, replacing the
   2200             // currently running activity.  This is a little tricky because
   2201             // we want to start the new one as if the current one is finished,
   2202             // but not finish the current one first so that there is no flicker.
   2203             // And thus...
   2204             final boolean wasFinishing = r.finishing;
   2205             r.finishing = true;
   2206 
   2207             // Propagate reply information over to the new activity.
   2208             final ActivityRecord resultTo = r.resultTo;
   2209             final String resultWho = r.resultWho;
   2210             final int requestCode = r.requestCode;
   2211             r.resultTo = null;
   2212             if (resultTo != null) {
   2213                 resultTo.removeResultsLocked(r, resultWho, requestCode);
   2214             }
   2215 
   2216             final long origId = Binder.clearCallingIdentity();
   2217             // XXX we are not dealing with propagating grantedUriPermissions...
   2218             // those are not yet exposed to user code, so there is no need.
   2219             int res = mMainStack.startActivityLocked(r.app.thread, intent,
   2220                     r.resolvedType, null, 0, aInfo, resultTo, resultWho,
   2221                     requestCode, -1, r.launchedFromUid, false, false);
   2222             Binder.restoreCallingIdentity(origId);
   2223 
   2224             r.finishing = wasFinishing;
   2225             if (res != START_SUCCESS) {
   2226                 return false;
   2227             }
   2228             return true;
   2229         }
   2230     }
   2231 
   2232     public final int startActivityInPackage(int uid,
   2233             Intent intent, String resolvedType, IBinder resultTo,
   2234             String resultWho, int requestCode, boolean onlyIfNeeded) {
   2235 
   2236         // This is so super not safe, that only the system (or okay root)
   2237         // can do it.
   2238         final int callingUid = Binder.getCallingUid();
   2239         if (callingUid != 0 && callingUid != Process.myUid()) {
   2240             throw new SecurityException(
   2241                     "startActivityInPackage only available to the system");
   2242         }
   2243 
   2244         final boolean componentSpecified = intent.getComponent() != null;
   2245 
   2246         // Don't modify the client's object!
   2247         intent = new Intent(intent);
   2248 
   2249         // Collect information about the target of the Intent.
   2250         ActivityInfo aInfo;
   2251         try {
   2252             ResolveInfo rInfo =
   2253                 AppGlobals.getPackageManager().resolveIntent(
   2254                         intent, resolvedType,
   2255                         PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
   2256             aInfo = rInfo != null ? rInfo.activityInfo : null;
   2257         } catch (RemoteException e) {
   2258             aInfo = null;
   2259         }
   2260 
   2261         if (aInfo != null) {
   2262             // Store the found target back into the intent, because now that
   2263             // we have it we never want to do this again.  For example, if the
   2264             // user navigates back to this point in the history, we should
   2265             // always restart the exact same activity.
   2266             intent.setComponent(new ComponentName(
   2267                     aInfo.applicationInfo.packageName, aInfo.name));
   2268         }
   2269 
   2270         synchronized(this) {
   2271             return mMainStack.startActivityLocked(null, intent, resolvedType,
   2272                     null, 0, aInfo, resultTo, resultWho, requestCode, -1, uid,
   2273                     onlyIfNeeded, componentSpecified);
   2274         }
   2275     }
   2276 
   2277     final void addRecentTaskLocked(TaskRecord task) {
   2278         // Remove any existing entries that are the same kind of task.
   2279         int N = mRecentTasks.size();
   2280         for (int i=0; i<N; i++) {
   2281             TaskRecord tr = mRecentTasks.get(i);
   2282             if ((task.affinity != null && task.affinity.equals(tr.affinity))
   2283                     || (task.intent != null && task.intent.filterEquals(tr.intent))) {
   2284                 mRecentTasks.remove(i);
   2285                 i--;
   2286                 N--;
   2287                 if (task.intent == null) {
   2288                     // If the new recent task we are adding is not fully
   2289                     // specified, then replace it with the existing recent task.
   2290                     task = tr;
   2291                 }
   2292             }
   2293         }
   2294         if (N >= MAX_RECENT_TASKS) {
   2295             mRecentTasks.remove(N-1);
   2296         }
   2297         mRecentTasks.add(0, task);
   2298     }
   2299 
   2300     public void setRequestedOrientation(IBinder token,
   2301             int requestedOrientation) {
   2302         synchronized (this) {
   2303             int index = mMainStack.indexOfTokenLocked(token);
   2304             if (index < 0) {
   2305                 return;
   2306             }
   2307             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
   2308             final long origId = Binder.clearCallingIdentity();
   2309             mWindowManager.setAppOrientation(r, requestedOrientation);
   2310             Configuration config = mWindowManager.updateOrientationFromAppTokens(
   2311                     mConfiguration,
   2312                     r.mayFreezeScreenLocked(r.app) ? r : null);
   2313             if (config != null) {
   2314                 r.frozenBeforeDestroy = true;
   2315                 if (!updateConfigurationLocked(config, r)) {
   2316                     mMainStack.resumeTopActivityLocked(null);
   2317                 }
   2318             }
   2319             Binder.restoreCallingIdentity(origId);
   2320         }
   2321     }
   2322 
   2323     public int getRequestedOrientation(IBinder token) {
   2324         synchronized (this) {
   2325             int index = mMainStack.indexOfTokenLocked(token);
   2326             if (index < 0) {
   2327                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
   2328             }
   2329             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
   2330             return mWindowManager.getAppOrientation(r);
   2331         }
   2332     }
   2333 
   2334     /**
   2335      * This is the internal entry point for handling Activity.finish().
   2336      *
   2337      * @param token The Binder token referencing the Activity we want to finish.
   2338      * @param resultCode Result code, if any, from this Activity.
   2339      * @param resultData Result data (Intent), if any, from this Activity.
   2340      *
   2341      * @return Returns true if the activity successfully finished, or false if it is still running.
   2342      */
   2343     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
   2344         // Refuse possible leaked file descriptors
   2345         if (resultData != null && resultData.hasFileDescriptors() == true) {
   2346             throw new IllegalArgumentException("File descriptors passed in Intent");
   2347         }
   2348 
   2349         synchronized(this) {
   2350             if (mController != null) {
   2351                 // Find the first activity that is not finishing.
   2352                 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
   2353                 if (next != null) {
   2354                     // ask watcher if this is allowed
   2355                     boolean resumeOK = true;
   2356                     try {
   2357                         resumeOK = mController.activityResuming(next.packageName);
   2358                     } catch (RemoteException e) {
   2359                         mController = null;
   2360                     }
   2361 
   2362                     if (!resumeOK) {
   2363                         return false;
   2364                     }
   2365                 }
   2366             }
   2367             final long origId = Binder.clearCallingIdentity();
   2368             boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
   2369                     resultData, "app-request");
   2370             Binder.restoreCallingIdentity(origId);
   2371             return res;
   2372         }
   2373     }
   2374 
   2375     public final void finishHeavyWeightApp() {
   2376         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   2377                 != PackageManager.PERMISSION_GRANTED) {
   2378             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
   2379                     + Binder.getCallingPid()
   2380                     + ", uid=" + Binder.getCallingUid()
   2381                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   2382             Slog.w(TAG, msg);
   2383             throw new SecurityException(msg);
   2384         }
   2385 
   2386         synchronized(this) {
   2387             if (mHeavyWeightProcess == null) {
   2388                 return;
   2389             }
   2390 
   2391             ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
   2392                     mHeavyWeightProcess.activities);
   2393             for (int i=0; i<activities.size(); i++) {
   2394                 ActivityRecord r = activities.get(i);
   2395                 if (!r.finishing) {
   2396                     int index = mMainStack.indexOfTokenLocked(r);
   2397                     if (index >= 0) {
   2398                         mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
   2399                                 null, "finish-heavy");
   2400                     }
   2401                 }
   2402             }
   2403 
   2404             mHeavyWeightProcess = null;
   2405             mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
   2406         }
   2407     }
   2408 
   2409     public void crashApplication(int uid, int initialPid, String packageName,
   2410             String message) {
   2411         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   2412                 != PackageManager.PERMISSION_GRANTED) {
   2413             String msg = "Permission Denial: crashApplication() from pid="
   2414                     + Binder.getCallingPid()
   2415                     + ", uid=" + Binder.getCallingUid()
   2416                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   2417             Slog.w(TAG, msg);
   2418             throw new SecurityException(msg);
   2419         }
   2420 
   2421         synchronized(this) {
   2422             ProcessRecord proc = null;
   2423 
   2424             // Figure out which process to kill.  We don't trust that initialPid
   2425             // still has any relation to current pids, so must scan through the
   2426             // list.
   2427             synchronized (mPidsSelfLocked) {
   2428                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   2429                     ProcessRecord p = mPidsSelfLocked.valueAt(i);
   2430                     if (p.info.uid != uid) {
   2431                         continue;
   2432                     }
   2433                     if (p.pid == initialPid) {
   2434                         proc = p;
   2435                         break;
   2436                     }
   2437                     for (String str : p.pkgList) {
   2438                         if (str.equals(packageName)) {
   2439                             proc = p;
   2440                         }
   2441                     }
   2442                 }
   2443             }
   2444 
   2445             if (proc == null) {
   2446                 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
   2447                         + " initialPid=" + initialPid
   2448                         + " packageName=" + packageName);
   2449                 return;
   2450             }
   2451 
   2452             if (proc.thread != null) {
   2453                 long ident = Binder.clearCallingIdentity();
   2454                 try {
   2455                     proc.thread.scheduleCrash(message);
   2456                 } catch (RemoteException e) {
   2457                 }
   2458                 Binder.restoreCallingIdentity(ident);
   2459             }
   2460         }
   2461     }
   2462 
   2463     public final void finishSubActivity(IBinder token, String resultWho,
   2464             int requestCode) {
   2465         synchronized(this) {
   2466             int index = mMainStack.indexOfTokenLocked(token);
   2467             if (index < 0) {
   2468                 return;
   2469             }
   2470             ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
   2471 
   2472             final long origId = Binder.clearCallingIdentity();
   2473 
   2474             int i;
   2475             for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
   2476                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   2477                 if (r.resultTo == self && r.requestCode == requestCode) {
   2478                     if ((r.resultWho == null && resultWho == null) ||
   2479                         (r.resultWho != null && r.resultWho.equals(resultWho))) {
   2480                         mMainStack.finishActivityLocked(r, i,
   2481                                 Activity.RESULT_CANCELED, null, "request-sub");
   2482                     }
   2483                 }
   2484             }
   2485 
   2486             Binder.restoreCallingIdentity(origId);
   2487         }
   2488     }
   2489 
   2490     public boolean willActivityBeVisible(IBinder token) {
   2491         synchronized(this) {
   2492             int i;
   2493             for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
   2494                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   2495                 if (r == token) {
   2496                     return true;
   2497                 }
   2498                 if (r.fullscreen && !r.finishing) {
   2499                     return false;
   2500                 }
   2501             }
   2502             return true;
   2503         }
   2504     }
   2505 
   2506     public void overridePendingTransition(IBinder token, String packageName,
   2507             int enterAnim, int exitAnim) {
   2508         synchronized(this) {
   2509             int index = mMainStack.indexOfTokenLocked(token);
   2510             if (index < 0) {
   2511                 return;
   2512             }
   2513             ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
   2514 
   2515             final long origId = Binder.clearCallingIdentity();
   2516 
   2517             if (self.state == ActivityState.RESUMED
   2518                     || self.state == ActivityState.PAUSING) {
   2519                 mWindowManager.overridePendingAppTransition(packageName,
   2520                         enterAnim, exitAnim);
   2521             }
   2522 
   2523             Binder.restoreCallingIdentity(origId);
   2524         }
   2525     }
   2526 
   2527     /**
   2528      * Main function for removing an existing process from the activity manager
   2529      * as a result of that process going away.  Clears out all connections
   2530      * to the process.
   2531      */
   2532     private final void handleAppDiedLocked(ProcessRecord app,
   2533             boolean restarting) {
   2534         cleanUpApplicationRecordLocked(app, restarting, -1);
   2535         if (!restarting) {
   2536             mLruProcesses.remove(app);
   2537         }
   2538 
   2539         // Just in case...
   2540         if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
   2541             if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
   2542             mMainStack.mPausingActivity = null;
   2543         }
   2544         if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
   2545             mMainStack.mLastPausedActivity = null;
   2546         }
   2547 
   2548         // Remove this application's activities from active lists.
   2549         mMainStack.removeHistoryRecordsForAppLocked(app);
   2550 
   2551         boolean atTop = true;
   2552         boolean hasVisibleActivities = false;
   2553 
   2554         // Clean out the history list.
   2555         int i = mMainStack.mHistory.size();
   2556         if (localLOGV) Slog.v(
   2557             TAG, "Removing app " + app + " from history with " + i + " entries");
   2558         while (i > 0) {
   2559             i--;
   2560             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   2561             if (localLOGV) Slog.v(
   2562                 TAG, "Record #" + i + " " + r + ": app=" + r.app);
   2563             if (r.app == app) {
   2564                 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
   2565                     if (localLOGV) Slog.v(
   2566                         TAG, "Removing this entry!  frozen=" + r.haveState
   2567                         + " finishing=" + r.finishing);
   2568                     mMainStack.mHistory.remove(i);
   2569 
   2570                     r.inHistory = false;
   2571                     mWindowManager.removeAppToken(r);
   2572                     if (VALIDATE_TOKENS) {
   2573                         mWindowManager.validateAppTokens(mMainStack.mHistory);
   2574                     }
   2575                     r.removeUriPermissionsLocked();
   2576 
   2577                 } else {
   2578                     // We have the current state for this activity, so
   2579                     // it can be restarted later when needed.
   2580                     if (localLOGV) Slog.v(
   2581                         TAG, "Keeping entry, setting app to null");
   2582                     if (r.visible) {
   2583                         hasVisibleActivities = true;
   2584                     }
   2585                     r.app = null;
   2586                     r.nowVisible = false;
   2587                     if (!r.haveState) {
   2588                         r.icicle = null;
   2589                     }
   2590                 }
   2591 
   2592                 r.stack.cleanUpActivityLocked(r, true);
   2593                 r.state = ActivityState.STOPPED;
   2594             }
   2595             atTop = false;
   2596         }
   2597 
   2598         app.activities.clear();
   2599 
   2600         if (app.instrumentationClass != null) {
   2601             Slog.w(TAG, "Crash of app " + app.processName
   2602                   + " running instrumentation " + app.instrumentationClass);
   2603             Bundle info = new Bundle();
   2604             info.putString("shortMsg", "Process crashed.");
   2605             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
   2606         }
   2607 
   2608         if (!restarting) {
   2609             if (!mMainStack.resumeTopActivityLocked(null)) {
   2610                 // If there was nothing to resume, and we are not already
   2611                 // restarting this process, but there is a visible activity that
   2612                 // is hosted by the process...  then make sure all visible
   2613                 // activities are running, taking care of restarting this
   2614                 // process.
   2615                 if (hasVisibleActivities) {
   2616                     mMainStack.ensureActivitiesVisibleLocked(null, 0);
   2617                 }
   2618             }
   2619         }
   2620     }
   2621 
   2622     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
   2623         IBinder threadBinder = thread.asBinder();
   2624 
   2625         // Find the application record.
   2626         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   2627             ProcessRecord rec = mLruProcesses.get(i);
   2628             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
   2629                 return i;
   2630             }
   2631         }
   2632         return -1;
   2633     }
   2634 
   2635     final ProcessRecord getRecordForAppLocked(
   2636             IApplicationThread thread) {
   2637         if (thread == null) {
   2638             return null;
   2639         }
   2640 
   2641         int appIndex = getLRURecordIndexForAppLocked(thread);
   2642         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
   2643     }
   2644 
   2645     final void appDiedLocked(ProcessRecord app, int pid,
   2646             IApplicationThread thread) {
   2647 
   2648         mProcDeaths[0]++;
   2649 
   2650         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   2651         synchronized (stats) {
   2652             stats.noteProcessDiedLocked(app.info.uid, pid);
   2653         }
   2654 
   2655         // Clean up already done if the process has been re-started.
   2656         if (app.pid == pid && app.thread != null &&
   2657                 app.thread.asBinder() == thread.asBinder()) {
   2658             if (!app.killedBackground) {
   2659                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   2660                         + ") has died.");
   2661             }
   2662             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
   2663             if (localLOGV) Slog.v(
   2664                 TAG, "Dying app: " + app + ", pid: " + pid
   2665                 + ", thread: " + thread.asBinder());
   2666             boolean doLowMem = app.instrumentationClass == null;
   2667             handleAppDiedLocked(app, false);
   2668 
   2669             if (doLowMem) {
   2670                 // If there are no longer any background processes running,
   2671                 // and the app that died was not running instrumentation,
   2672                 // then tell everyone we are now low on memory.
   2673                 boolean haveBg = false;
   2674                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   2675                     ProcessRecord rec = mLruProcesses.get(i);
   2676                     if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
   2677                         haveBg = true;
   2678                         break;
   2679                     }
   2680                 }
   2681 
   2682                 if (!haveBg) {
   2683                     Slog.i(TAG, "Low Memory: No more background processes.");
   2684                     EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
   2685                     long now = SystemClock.uptimeMillis();
   2686                     for (int i=mLruProcesses.size()-1; i>=0; i--) {
   2687                         ProcessRecord rec = mLruProcesses.get(i);
   2688                         if (rec != app && rec.thread != null &&
   2689                                 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
   2690                             // The low memory report is overriding any current
   2691                             // state for a GC request.  Make sure to do
   2692                             // heavy/important/visible/foreground processes first.
   2693                             if (rec.setAdj <= HEAVY_WEIGHT_APP_ADJ) {
   2694                                 rec.lastRequestedGc = 0;
   2695                             } else {
   2696                                 rec.lastRequestedGc = rec.lastLowMemory;
   2697                             }
   2698                             rec.reportLowMemory = true;
   2699                             rec.lastLowMemory = now;
   2700                             mProcessesToGc.remove(rec);
   2701                             addProcessToGcListLocked(rec);
   2702                         }
   2703                     }
   2704                     scheduleAppGcsLocked();
   2705                 }
   2706             }
   2707         } else if (app.pid != pid) {
   2708             // A new process has already been started.
   2709             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   2710                     + ") has died and restarted (pid " + app.pid + ").");
   2711             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
   2712         } else if (DEBUG_PROCESSES) {
   2713             Slog.d(TAG, "Received spurious death notification for thread "
   2714                     + thread.asBinder());
   2715         }
   2716     }
   2717 
   2718     /**
   2719      * If a stack trace dump file is configured, dump process stack traces.
   2720      * @param clearTraces causes the dump file to be erased prior to the new
   2721      *    traces being written, if true; when false, the new traces will be
   2722      *    appended to any existing file content.
   2723      * @param firstPids of dalvik VM processes to dump stack traces for first
   2724      * @param lastPids of dalvik VM processes to dump stack traces for last
   2725      * @return file containing stack traces, or null if no dump file is configured
   2726      */
   2727     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
   2728             ProcessStats processStats, SparseArray<Boolean> lastPids) {
   2729         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   2730         if (tracesPath == null || tracesPath.length() == 0) {
   2731             return null;
   2732         }
   2733 
   2734         File tracesFile = new File(tracesPath);
   2735         try {
   2736             File tracesDir = tracesFile.getParentFile();
   2737             if (!tracesDir.exists()) tracesFile.mkdirs();
   2738             FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
   2739 
   2740             if (clearTraces && tracesFile.exists()) tracesFile.delete();
   2741             tracesFile.createNewFile();
   2742             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   2743         } catch (IOException e) {
   2744             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
   2745             return null;
   2746         }
   2747 
   2748         // Use a FileObserver to detect when traces finish writing.
   2749         // The order of traces is considered important to maintain for legibility.
   2750         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
   2751             public synchronized void onEvent(int event, String path) { notify(); }
   2752         };
   2753 
   2754         try {
   2755             observer.startWatching();
   2756 
   2757             // First collect all of the stacks of the most important pids.
   2758             try {
   2759                 int num = firstPids.size();
   2760                 for (int i = 0; i < num; i++) {
   2761                     synchronized (observer) {
   2762                         Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
   2763                         observer.wait(200);  // Wait for write-close, give up after 200msec
   2764                     }
   2765                 }
   2766             } catch (InterruptedException e) {
   2767                 Log.wtf(TAG, e);
   2768             }
   2769 
   2770             // Next measure CPU usage.
   2771             if (processStats != null) {
   2772                 processStats.init();
   2773                 System.gc();
   2774                 processStats.update();
   2775                 try {
   2776                     synchronized (processStats) {
   2777                         processStats.wait(500); // measure over 1/2 second.
   2778                     }
   2779                 } catch (InterruptedException e) {
   2780                 }
   2781                 processStats.update();
   2782 
   2783                 // We'll take the stack crawls of just the top apps using CPU.
   2784                 final int N = processStats.countWorkingStats();
   2785                 int numProcs = 0;
   2786                 for (int i=0; i<N && numProcs<5; i++) {
   2787                     ProcessStats.Stats stats = processStats.getWorkingStats(i);
   2788                     if (lastPids.indexOfKey(stats.pid) >= 0) {
   2789                         numProcs++;
   2790                         try {
   2791                             synchronized (observer) {
   2792                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
   2793                                 observer.wait(200);  // Wait for write-close, give up after 200msec
   2794                             }
   2795                         } catch (InterruptedException e) {
   2796                             Log.wtf(TAG, e);
   2797                         }
   2798 
   2799                     }
   2800                 }
   2801             }
   2802 
   2803             return tracesFile;
   2804 
   2805         } finally {
   2806             observer.stopWatching();
   2807         }
   2808     }
   2809 
   2810     private final class AppNotResponding implements Runnable {
   2811         private final ProcessRecord mApp;
   2812         private final String mAnnotation;
   2813 
   2814         public AppNotResponding(ProcessRecord app, String annotation) {
   2815             mApp = app;
   2816             mAnnotation = annotation;
   2817         }
   2818 
   2819         @Override
   2820         public void run() {
   2821             appNotResponding(mApp, null, null, mAnnotation);
   2822         }
   2823     }
   2824 
   2825     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
   2826             ActivityRecord parent, final String annotation) {
   2827         ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
   2828         SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
   2829 
   2830         if (mController != null) {
   2831             try {
   2832                 // 0 == continue, -1 = kill process immediately
   2833                 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
   2834                 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
   2835             } catch (RemoteException e) {
   2836                 mController = null;
   2837             }
   2838         }
   2839 
   2840         long anrTime = SystemClock.uptimeMillis();
   2841         if (MONITOR_CPU_USAGE) {
   2842             updateCpuStatsNow();
   2843         }
   2844 
   2845         synchronized (this) {
   2846             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
   2847             if (mShuttingDown) {
   2848                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
   2849                 return;
   2850             } else if (app.notResponding) {
   2851                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
   2852                 return;
   2853             } else if (app.crashing) {
   2854                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
   2855                 return;
   2856             }
   2857 
   2858             // In case we come through here for the same app before completing
   2859             // this one, mark as anring now so we will bail out.
   2860             app.notResponding = true;
   2861 
   2862             // Log the ANR to the event log.
   2863             EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
   2864                     annotation);
   2865 
   2866             // Dump thread traces as quickly as we can, starting with "interesting" processes.
   2867             firstPids.add(app.pid);
   2868 
   2869             int parentPid = app.pid;
   2870             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
   2871             if (parentPid != app.pid) firstPids.add(parentPid);
   2872 
   2873             if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
   2874 
   2875             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   2876                 ProcessRecord r = mLruProcesses.get(i);
   2877                 if (r != null && r.thread != null) {
   2878                     int pid = r.pid;
   2879                     if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
   2880                         if (r.persistent) {
   2881                             firstPids.add(pid);
   2882                         } else {
   2883                             lastPids.put(pid, Boolean.TRUE);
   2884                         }
   2885                     }
   2886                 }
   2887             }
   2888         }
   2889 
   2890         // Log the ANR to the main log.
   2891         StringBuilder info = mStringBuilder;
   2892         info.setLength(0);
   2893         info.append("ANR in ").append(app.processName);
   2894         if (activity != null && activity.shortComponentName != null) {
   2895             info.append(" (").append(activity.shortComponentName).append(")");
   2896         }
   2897         info.append("\n");
   2898         if (annotation != null) {
   2899             info.append("Reason: ").append(annotation).append("\n");
   2900         }
   2901         if (parent != null && parent != activity) {
   2902             info.append("Parent: ").append(parent.shortComponentName).append("\n");
   2903         }
   2904 
   2905         final ProcessStats processStats = new ProcessStats(true);
   2906 
   2907         File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
   2908 
   2909         String cpuInfo = null;
   2910         if (MONITOR_CPU_USAGE) {
   2911             updateCpuStatsNow();
   2912             synchronized (mProcessStatsThread) {
   2913                 cpuInfo = mProcessStats.printCurrentState(anrTime);
   2914             }
   2915             info.append(processStats.printCurrentLoad());
   2916             info.append(cpuInfo);
   2917         }
   2918 
   2919         info.append(processStats.printCurrentState(anrTime));
   2920 
   2921         Slog.e(TAG, info.toString());
   2922         if (tracesFile == null) {
   2923             // There is no trace file, so dump (only) the alleged culprit's threads to the log
   2924             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
   2925         }
   2926 
   2927         addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
   2928 
   2929         if (mController != null) {
   2930             try {
   2931                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
   2932                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
   2933                 if (res != 0) {
   2934                     if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
   2935                     return;
   2936                 }
   2937             } catch (RemoteException e) {
   2938                 mController = null;
   2939             }
   2940         }
   2941 
   2942         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
   2943         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
   2944                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
   2945 
   2946         synchronized (this) {
   2947             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
   2948                 Process.killProcess(app.pid);
   2949                 return;
   2950             }
   2951 
   2952             // Set the app's notResponding state, and look up the errorReportReceiver
   2953             makeAppNotRespondingLocked(app,
   2954                     activity != null ? activity.shortComponentName : null,
   2955                     annotation != null ? "ANR " + annotation : "ANR",
   2956                     info.toString());
   2957 
   2958             // Bring up the infamous App Not Responding dialog
   2959             Message msg = Message.obtain();
   2960             HashMap map = new HashMap();
   2961             msg.what = SHOW_NOT_RESPONDING_MSG;
   2962             msg.obj = map;
   2963             map.put("app", app);
   2964             if (activity != null) {
   2965                 map.put("activity", activity);
   2966             }
   2967 
   2968             mHandler.sendMessage(msg);
   2969         }
   2970     }
   2971 
   2972     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
   2973         if (!mLaunchWarningShown) {
   2974             mLaunchWarningShown = true;
   2975             mHandler.post(new Runnable() {
   2976                 @Override
   2977                 public void run() {
   2978                     synchronized (ActivityManagerService.this) {
   2979                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
   2980                         d.show();
   2981                         mHandler.postDelayed(new Runnable() {
   2982                             @Override
   2983                             public void run() {
   2984                                 synchronized (ActivityManagerService.this) {
   2985                                     d.dismiss();
   2986                                     mLaunchWarningShown = false;
   2987                                 }
   2988                             }
   2989                         }, 4000);
   2990                     }
   2991                 }
   2992             });
   2993         }
   2994     }
   2995 
   2996     public boolean clearApplicationUserData(final String packageName,
   2997             final IPackageDataObserver observer) {
   2998         int uid = Binder.getCallingUid();
   2999         int pid = Binder.getCallingPid();
   3000         long callingId = Binder.clearCallingIdentity();
   3001         try {
   3002             IPackageManager pm = AppGlobals.getPackageManager();
   3003             int pkgUid = -1;
   3004             synchronized(this) {
   3005                 try {
   3006                     pkgUid = pm.getPackageUid(packageName);
   3007                 } catch (RemoteException e) {
   3008                 }
   3009                 if (pkgUid == -1) {
   3010                     Slog.w(TAG, "Invalid packageName:" + packageName);
   3011                     return false;
   3012                 }
   3013                 if (uid == pkgUid || checkComponentPermission(
   3014                         android.Manifest.permission.CLEAR_APP_USER_DATA,
   3015                         pid, uid, -1)
   3016                         == PackageManager.PERMISSION_GRANTED) {
   3017                     forceStopPackageLocked(packageName, pkgUid);
   3018                 } else {
   3019                     throw new SecurityException(pid+" does not have permission:"+
   3020                             android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
   3021                                     "for process:"+packageName);
   3022                 }
   3023             }
   3024 
   3025             try {
   3026                 //clear application user data
   3027                 pm.clearApplicationUserData(packageName, observer);
   3028                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
   3029                         Uri.fromParts("package", packageName, null));
   3030                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
   3031                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
   3032                         null, null, 0, null, null, null, false, false);
   3033             } catch (RemoteException e) {
   3034             }
   3035         } finally {
   3036             Binder.restoreCallingIdentity(callingId);
   3037         }
   3038         return true;
   3039     }
   3040 
   3041     public void killBackgroundProcesses(final String packageName) {
   3042         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   3043                 != PackageManager.PERMISSION_GRANTED &&
   3044                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
   3045                         != PackageManager.PERMISSION_GRANTED) {
   3046             String msg = "Permission Denial: killBackgroundProcesses() from pid="
   3047                     + Binder.getCallingPid()
   3048                     + ", uid=" + Binder.getCallingUid()
   3049                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   3050             Slog.w(TAG, msg);
   3051             throw new SecurityException(msg);
   3052         }
   3053 
   3054         long callingId = Binder.clearCallingIdentity();
   3055         try {
   3056             IPackageManager pm = AppGlobals.getPackageManager();
   3057             int pkgUid = -1;
   3058             synchronized(this) {
   3059                 try {
   3060                     pkgUid = pm.getPackageUid(packageName);
   3061                 } catch (RemoteException e) {
   3062                 }
   3063                 if (pkgUid == -1) {
   3064                     Slog.w(TAG, "Invalid packageName: " + packageName);
   3065                     return;
   3066                 }
   3067                 killPackageProcessesLocked(packageName, pkgUid,
   3068                         SECONDARY_SERVER_ADJ, false, true);
   3069             }
   3070         } finally {
   3071             Binder.restoreCallingIdentity(callingId);
   3072         }
   3073     }
   3074 
   3075     public void forceStopPackage(final String packageName) {
   3076         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   3077                 != PackageManager.PERMISSION_GRANTED) {
   3078             String msg = "Permission Denial: forceStopPackage() from pid="
   3079                     + Binder.getCallingPid()
   3080                     + ", uid=" + Binder.getCallingUid()
   3081                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   3082             Slog.w(TAG, msg);
   3083             throw new SecurityException(msg);
   3084         }
   3085 
   3086         long callingId = Binder.clearCallingIdentity();
   3087         try {
   3088             IPackageManager pm = AppGlobals.getPackageManager();
   3089             int pkgUid = -1;
   3090             synchronized(this) {
   3091                 try {
   3092                     pkgUid = pm.getPackageUid(packageName);
   3093                 } catch (RemoteException e) {
   3094                 }
   3095                 if (pkgUid == -1) {
   3096                     Slog.w(TAG, "Invalid packageName: " + packageName);
   3097                     return;
   3098                 }
   3099                 forceStopPackageLocked(packageName, pkgUid);
   3100             }
   3101         } finally {
   3102             Binder.restoreCallingIdentity(callingId);
   3103         }
   3104     }
   3105 
   3106     /*
   3107      * The pkg name and uid have to be specified.
   3108      * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
   3109      */
   3110     public void killApplicationWithUid(String pkg, int uid) {
   3111         if (pkg == null) {
   3112             return;
   3113         }
   3114         // Make sure the uid is valid.
   3115         if (uid < 0) {
   3116             Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
   3117             return;
   3118         }
   3119         int callerUid = Binder.getCallingUid();
   3120         // Only the system server can kill an application
   3121         if (callerUid == Process.SYSTEM_UID) {
   3122             // Post an aysnc message to kill the application
   3123             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
   3124             msg.arg1 = uid;
   3125             msg.arg2 = 0;
   3126             msg.obj = pkg;
   3127             mHandler.sendMessage(msg);
   3128         } else {
   3129             throw new SecurityException(callerUid + " cannot kill pkg: " +
   3130                     pkg);
   3131         }
   3132     }
   3133 
   3134     public void closeSystemDialogs(String reason) {
   3135         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
   3136         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   3137         if (reason != null) {
   3138             intent.putExtra("reason", reason);
   3139         }
   3140 
   3141         final int uid = Binder.getCallingUid();
   3142         final long origId = Binder.clearCallingIdentity();
   3143         synchronized (this) {
   3144             int i = mWatchers.beginBroadcast();
   3145             while (i > 0) {
   3146                 i--;
   3147                 IActivityWatcher w = mWatchers.getBroadcastItem(i);
   3148                 if (w != null) {
   3149                     try {
   3150                         w.closingSystemDialogs(reason);
   3151                     } catch (RemoteException e) {
   3152                     }
   3153                 }
   3154             }
   3155             mWatchers.finishBroadcast();
   3156 
   3157             mWindowManager.closeSystemDialogs(reason);
   3158 
   3159             for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
   3160                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   3161                 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
   3162                     r.stack.finishActivityLocked(r, i,
   3163                             Activity.RESULT_CANCELED, null, "close-sys");
   3164                 }
   3165             }
   3166 
   3167             broadcastIntentLocked(null, null, intent, null,
   3168                     null, 0, null, null, null, false, false, -1, uid);
   3169         }
   3170         Binder.restoreCallingIdentity(origId);
   3171     }
   3172 
   3173     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
   3174             throws RemoteException {
   3175         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
   3176         for (int i=pids.length-1; i>=0; i--) {
   3177             infos[i] = new Debug.MemoryInfo();
   3178             Debug.getMemoryInfo(pids[i], infos[i]);
   3179         }
   3180         return infos;
   3181     }
   3182 
   3183     public void killApplicationProcess(String processName, int uid) {
   3184         if (processName == null) {
   3185             return;
   3186         }
   3187 
   3188         int callerUid = Binder.getCallingUid();
   3189         // Only the system server can kill an application
   3190         if (callerUid == Process.SYSTEM_UID) {
   3191             synchronized (this) {
   3192                 ProcessRecord app = getProcessRecordLocked(processName, uid);
   3193                 if (app != null) {
   3194                     try {
   3195                         app.thread.scheduleSuicide();
   3196                     } catch (RemoteException e) {
   3197                         // If the other end already died, then our work here is done.
   3198                     }
   3199                 } else {
   3200                     Slog.w(TAG, "Process/uid not found attempting kill of "
   3201                             + processName + " / " + uid);
   3202                 }
   3203             }
   3204         } else {
   3205             throw new SecurityException(callerUid + " cannot kill app process: " +
   3206                     processName);
   3207         }
   3208     }
   3209 
   3210     private void forceStopPackageLocked(final String packageName, int uid) {
   3211         forceStopPackageLocked(packageName, uid, false, false, true);
   3212         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
   3213                 Uri.fromParts("package", packageName, null));
   3214         if (!mProcessesReady) {
   3215             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   3216         }
   3217         intent.putExtra(Intent.EXTRA_UID, uid);
   3218         broadcastIntentLocked(null, null, intent,
   3219                 null, null, 0, null, null, null,
   3220                 false, false, MY_PID, Process.SYSTEM_UID);
   3221     }
   3222 
   3223     private final boolean killPackageProcessesLocked(String packageName, int uid,
   3224             int minOomAdj, boolean callerWillRestart, boolean doit) {
   3225         ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   3226 
   3227         // Remove all processes this package may have touched: all with the
   3228         // same UID (except for the system or root user), and all whose name
   3229         // matches the package name.
   3230         final String procNamePrefix = packageName + ":";
   3231         for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   3232             final int NA = apps.size();
   3233             for (int ia=0; ia<NA; ia++) {
   3234                 ProcessRecord app = apps.valueAt(ia);
   3235                 if (app.removed) {
   3236                     if (doit) {
   3237                         procs.add(app);
   3238                     }
   3239                 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
   3240                         || app.processName.equals(packageName)
   3241                         || app.processName.startsWith(procNamePrefix)) {
   3242                     if (app.setAdj >= minOomAdj) {
   3243                         if (!doit) {
   3244                             return true;
   3245                         }
   3246                         app.removed = true;
   3247                         procs.add(app);
   3248                     }
   3249                 }
   3250             }
   3251         }
   3252 
   3253         int N = procs.size();
   3254         for (int i=0; i<N; i++) {
   3255             removeProcessLocked(procs.get(i), callerWillRestart);
   3256         }
   3257         return N > 0;
   3258     }
   3259 
   3260     private final boolean forceStopPackageLocked(String name, int uid,
   3261             boolean callerWillRestart, boolean purgeCache, boolean doit) {
   3262         int i, N;
   3263 
   3264         if (uid < 0) {
   3265             try {
   3266                 uid = AppGlobals.getPackageManager().getPackageUid(name);
   3267             } catch (RemoteException e) {
   3268             }
   3269         }
   3270 
   3271         if (doit) {
   3272             Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
   3273 
   3274             Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
   3275             while (badApps.hasNext()) {
   3276                 SparseArray<Long> ba = badApps.next();
   3277                 if (ba.get(uid) != null) {
   3278                     badApps.remove();
   3279                 }
   3280             }
   3281         }
   3282 
   3283         boolean didSomething = killPackageProcessesLocked(name, uid, -100,
   3284                 callerWillRestart, doit);
   3285 
   3286         for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
   3287             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   3288             if (r.packageName.equals(name)) {
   3289                 if (!doit) {
   3290                     return true;
   3291                 }
   3292                 didSomething = true;
   3293                 Slog.i(TAG, "  Force finishing activity " + r);
   3294                 if (r.app != null) {
   3295                     r.app.removed = true;
   3296                 }
   3297                 r.app = null;
   3298                 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
   3299             }
   3300         }
   3301 
   3302         ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
   3303         for (ServiceRecord service : mServices.values()) {
   3304             if (service.packageName.equals(name)) {
   3305                 if (!doit) {
   3306                     return true;
   3307                 }
   3308                 didSomething = true;
   3309                 Slog.i(TAG, "  Force stopping service " + service);
   3310                 if (service.app != null) {
   3311                     service.app.removed = true;
   3312                 }
   3313                 service.app = null;
   3314                 services.add(service);
   3315             }
   3316         }
   3317 
   3318         N = services.size();
   3319         for (i=0; i<N; i++) {
   3320             bringDownServiceLocked(services.get(i), true);
   3321         }
   3322 
   3323         if (doit) {
   3324             if (purgeCache) {
   3325                 AttributeCache ac = AttributeCache.instance();
   3326                 if (ac != null) {
   3327                     ac.removePackage(name);
   3328                 }
   3329             }
   3330             mMainStack.resumeTopActivityLocked(null);
   3331         }
   3332 
   3333         return didSomething;
   3334     }
   3335 
   3336     private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
   3337         final String name = app.processName;
   3338         final int uid = app.info.uid;
   3339         if (DEBUG_PROCESSES) Slog.d(
   3340             TAG, "Force removing process " + app + " (" + name
   3341             + "/" + uid + ")");
   3342 
   3343         mProcessNames.remove(name, uid);
   3344         if (mHeavyWeightProcess == app) {
   3345             mHeavyWeightProcess = null;
   3346             mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
   3347         }
   3348         boolean needRestart = false;
   3349         if (app.pid > 0 && app.pid != MY_PID) {
   3350             int pid = app.pid;
   3351             synchronized (mPidsSelfLocked) {
   3352                 mPidsSelfLocked.remove(pid);
   3353                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   3354             }
   3355             handleAppDiedLocked(app, true);
   3356             mLruProcesses.remove(app);
   3357             Process.killProcess(pid);
   3358 
   3359             if (app.persistent) {
   3360                 if (!callerWillRestart) {
   3361                     addAppLocked(app.info);
   3362                 } else {
   3363                     needRestart = true;
   3364                 }
   3365             }
   3366         } else {
   3367             mRemovedProcesses.add(app);
   3368         }
   3369 
   3370         return needRestart;
   3371     }
   3372 
   3373     private final void processStartTimedOutLocked(ProcessRecord app) {
   3374         final int pid = app.pid;
   3375         boolean gone = false;
   3376         synchronized (mPidsSelfLocked) {
   3377             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
   3378             if (knownApp != null && knownApp.thread == null) {
   3379                 mPidsSelfLocked.remove(pid);
   3380                 gone = true;
   3381             }
   3382         }
   3383 
   3384         if (gone) {
   3385             Slog.w(TAG, "Process " + app + " failed to attach");
   3386             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
   3387                     app.processName);
   3388             mProcessNames.remove(app.processName, app.info.uid);
   3389             if (mHeavyWeightProcess == app) {
   3390                 mHeavyWeightProcess = null;
   3391                 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
   3392             }
   3393             // Take care of any launching providers waiting for this process.
   3394             checkAppInLaunchingProvidersLocked(app, true);
   3395             // Take care of any services that are waiting for the process.
   3396             for (int i=0; i<mPendingServices.size(); i++) {
   3397                 ServiceRecord sr = mPendingServices.get(i);
   3398                 if (app.info.uid == sr.appInfo.uid
   3399                         && app.processName.equals(sr.processName)) {
   3400                     Slog.w(TAG, "Forcing bringing down service: " + sr);
   3401                     mPendingServices.remove(i);
   3402                     i--;
   3403                     bringDownServiceLocked(sr, true);
   3404                 }
   3405             }
   3406             Process.killProcess(pid);
   3407             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
   3408                 Slog.w(TAG, "Unattached app died before backup, skipping");
   3409                 try {
   3410                     IBackupManager bm = IBackupManager.Stub.asInterface(
   3411                             ServiceManager.getService(Context.BACKUP_SERVICE));
   3412                     bm.agentDisconnected(app.info.packageName);
   3413                 } catch (RemoteException e) {
   3414                     // Can't happen; the backup manager is local
   3415                 }
   3416             }
   3417             if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
   3418                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   3419                 mPendingBroadcast.state = BroadcastRecord.IDLE;
   3420                 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
   3421                 mPendingBroadcast = null;
   3422                 scheduleBroadcastsLocked();
   3423             }
   3424         } else {
   3425             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
   3426         }
   3427     }
   3428 
   3429     private final boolean attachApplicationLocked(IApplicationThread thread,
   3430             int pid) {
   3431 
   3432         // Find the application record that is being attached...  either via
   3433         // the pid if we are running in multiple processes, or just pull the
   3434         // next app record if we are emulating process with anonymous threads.
   3435         ProcessRecord app;
   3436         if (pid != MY_PID && pid >= 0) {
   3437             synchronized (mPidsSelfLocked) {
   3438                 app = mPidsSelfLocked.get(pid);
   3439             }
   3440         } else if (mStartingProcesses.size() > 0) {
   3441             app = mStartingProcesses.remove(0);
   3442             app.setPid(pid);
   3443         } else {
   3444             app = null;
   3445         }
   3446 
   3447         if (app == null) {
   3448             Slog.w(TAG, "No pending application record for pid " + pid
   3449                     + " (IApplicationThread " + thread + "); dropping process");
   3450             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
   3451             if (pid > 0 && pid != MY_PID) {
   3452                 Process.killProcess(pid);
   3453             } else {
   3454                 try {
   3455                     thread.scheduleExit();
   3456                 } catch (Exception e) {
   3457                     // Ignore exceptions.
   3458                 }
   3459             }
   3460             return false;
   3461         }
   3462 
   3463         // If this application record is still attached to a previous
   3464         // process, clean it up now.
   3465         if (app.thread != null) {
   3466             handleAppDiedLocked(app, true);
   3467         }
   3468 
   3469         // Tell the process all about itself.
   3470 
   3471         if (localLOGV) Slog.v(
   3472                 TAG, "Binding process pid " + pid + " to record " + app);
   3473 
   3474         String processName = app.processName;
   3475         try {
   3476             thread.asBinder().linkToDeath(new AppDeathRecipient(
   3477                     app, pid, thread), 0);
   3478         } catch (RemoteException e) {
   3479             app.resetPackageList();
   3480             startProcessLocked(app, "link fail", processName);
   3481             return false;
   3482         }
   3483 
   3484         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
   3485 
   3486         app.thread = thread;
   3487         app.curAdj = app.setAdj = -100;
   3488         app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
   3489         app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   3490         app.forcingToForeground = null;
   3491         app.foregroundServices = false;
   3492         app.debugging = false;
   3493 
   3494         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   3495 
   3496         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
   3497         List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
   3498 
   3499         if (!normalMode) {
   3500             Slog.i(TAG, "Launching preboot mode app: " + app);
   3501         }
   3502 
   3503         if (localLOGV) Slog.v(
   3504             TAG, "New app record " + app
   3505             + " thread=" + thread.asBinder() + " pid=" + pid);
   3506         try {
   3507             int testMode = IApplicationThread.DEBUG_OFF;
   3508             if (mDebugApp != null && mDebugApp.equals(processName)) {
   3509                 testMode = mWaitForDebugger
   3510                     ? IApplicationThread.DEBUG_WAIT
   3511                     : IApplicationThread.DEBUG_ON;
   3512                 app.debugging = true;
   3513                 if (mDebugTransient) {
   3514                     mDebugApp = mOrigDebugApp;
   3515                     mWaitForDebugger = mOrigWaitForDebugger;
   3516                 }
   3517             }
   3518 
   3519             // If the app is being launched for restore or full backup, set it up specially
   3520             boolean isRestrictedBackupMode = false;
   3521             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
   3522                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
   3523                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
   3524             }
   3525 
   3526             ensurePackageDexOpt(app.instrumentationInfo != null
   3527                     ? app.instrumentationInfo.packageName
   3528                     : app.info.packageName);
   3529             if (app.instrumentationClass != null) {
   3530                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
   3531             }
   3532             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
   3533                     + processName + " with config " + mConfiguration);
   3534             thread.bindApplication(processName, app.instrumentationInfo != null
   3535                     ? app.instrumentationInfo : app.info, providers,
   3536                     app.instrumentationClass, app.instrumentationProfileFile,
   3537                     app.instrumentationArguments, app.instrumentationWatcher, testMode,
   3538                     isRestrictedBackupMode || !normalMode,
   3539                     mConfiguration, getCommonServicesLocked());
   3540             updateLruProcessLocked(app, false, true);
   3541             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
   3542         } catch (Exception e) {
   3543             // todo: Yikes!  What should we do?  For now we will try to
   3544             // start another process, but that could easily get us in
   3545             // an infinite loop of restarting processes...
   3546             Slog.w(TAG, "Exception thrown during bind!", e);
   3547 
   3548             app.resetPackageList();
   3549             startProcessLocked(app, "bind fail", processName);
   3550             return false;
   3551         }
   3552 
   3553         // Remove this record from the list of starting applications.
   3554         mPersistentStartingProcesses.remove(app);
   3555         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   3556                 "Attach application locked removing on hold: " + app);
   3557         mProcessesOnHold.remove(app);
   3558 
   3559         boolean badApp = false;
   3560         boolean didSomething = false;
   3561 
   3562         // See if the top visible activity is waiting to run in this process...
   3563         ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
   3564         if (hr != null && normalMode) {
   3565             if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
   3566                     && processName.equals(hr.processName)) {
   3567                 try {
   3568                     if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
   3569                         didSomething = true;
   3570                     }
   3571                 } catch (Exception e) {
   3572                     Slog.w(TAG, "Exception in new application when starting activity "
   3573                           + hr.intent.getComponent().flattenToShortString(), e);
   3574                     badApp = true;
   3575                 }
   3576             } else {
   3577                 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
   3578             }
   3579         }
   3580 
   3581         // Find any services that should be running in this process...
   3582         if (!badApp && mPendingServices.size() > 0) {
   3583             ServiceRecord sr = null;
   3584             try {
   3585                 for (int i=0; i<mPendingServices.size(); i++) {
   3586                     sr = mPendingServices.get(i);
   3587                     if (app.info.uid != sr.appInfo.uid
   3588                             || !processName.equals(sr.processName)) {
   3589                         continue;
   3590                     }
   3591 
   3592                     mPendingServices.remove(i);
   3593                     i--;
   3594                     realStartServiceLocked(sr, app);
   3595                     didSomething = true;
   3596                 }
   3597             } catch (Exception e) {
   3598                 Slog.w(TAG, "Exception in new application when starting service "
   3599                       + sr.shortName, e);
   3600                 badApp = true;
   3601             }
   3602         }
   3603 
   3604         // Check if the next broadcast receiver is in this process...
   3605         BroadcastRecord br = mPendingBroadcast;
   3606         if (!badApp && br != null && br.curApp == app) {
   3607             try {
   3608                 mPendingBroadcast = null;
   3609                 processCurBroadcastLocked(br, app);
   3610                 didSomething = true;
   3611             } catch (Exception e) {
   3612                 Slog.w(TAG, "Exception in new application when starting receiver "
   3613                       + br.curComponent.flattenToShortString(), e);
   3614                 badApp = true;
   3615                 logBroadcastReceiverDiscardLocked(br);
   3616                 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
   3617                         br.resultExtras, br.resultAbort, true);
   3618                 scheduleBroadcastsLocked();
   3619                 // We need to reset the state if we fails to start the receiver.
   3620                 br.state = BroadcastRecord.IDLE;
   3621             }
   3622         }
   3623 
   3624         // Check whether the next backup agent is in this process...
   3625         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
   3626             if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
   3627             ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
   3628             try {
   3629                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, mBackupTarget.backupMode);
   3630             } catch (Exception e) {
   3631                 Slog.w(TAG, "Exception scheduling backup agent creation: ");
   3632                 e.printStackTrace();
   3633             }
   3634         }
   3635 
   3636         if (badApp) {
   3637             // todo: Also need to kill application to deal with all
   3638             // kinds of exceptions.
   3639             handleAppDiedLocked(app, false);
   3640             return false;
   3641         }
   3642 
   3643         if (!didSomething) {
   3644             updateOomAdjLocked();
   3645         }
   3646 
   3647         return true;
   3648     }
   3649 
   3650     public final void attachApplication(IApplicationThread thread) {
   3651         synchronized (this) {
   3652             int callingPid = Binder.getCallingPid();
   3653             final long origId = Binder.clearCallingIdentity();
   3654             attachApplicationLocked(thread, callingPid);
   3655             Binder.restoreCallingIdentity(origId);
   3656         }
   3657     }
   3658 
   3659     public final void activityIdle(IBinder token, Configuration config) {
   3660         final long origId = Binder.clearCallingIdentity();
   3661         mMainStack.activityIdleInternal(token, false, config);
   3662         Binder.restoreCallingIdentity(origId);
   3663     }
   3664 
   3665     void enableScreenAfterBoot() {
   3666         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
   3667                 SystemClock.uptimeMillis());
   3668         mWindowManager.enableScreenAfterBoot();
   3669     }
   3670 
   3671     final void finishBooting() {
   3672         IntentFilter pkgFilter = new IntentFilter();
   3673         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
   3674         pkgFilter.addDataScheme("package");
   3675         mContext.registerReceiver(new BroadcastReceiver() {
   3676             @Override
   3677             public void onReceive(Context context, Intent intent) {
   3678                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
   3679                 if (pkgs != null) {
   3680                     for (String pkg : pkgs) {
   3681                         if (forceStopPackageLocked(pkg, -1, false, false, false)) {
   3682                             setResultCode(Activity.RESULT_OK);
   3683                             return;
   3684                         }
   3685                     }
   3686                 }
   3687             }
   3688         }, pkgFilter);
   3689 
   3690         synchronized (this) {
   3691             // Ensure that any processes we had put on hold are now started
   3692             // up.
   3693             final int NP = mProcessesOnHold.size();
   3694             if (NP > 0) {
   3695                 ArrayList<ProcessRecord> procs =
   3696                     new ArrayList<ProcessRecord>(mProcessesOnHold);
   3697                 for (int ip=0; ip<NP; ip++) {
   3698                     if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
   3699                             + procs.get(ip));
   3700                     startProcessLocked(procs.get(ip), "on-hold", null);
   3701                 }
   3702             }
   3703 
   3704             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   3705                 // Start looking for apps that are abusing wake locks.
   3706                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   3707                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   3708                 // Tell anyone interested that we are done booting!
   3709                 SystemProperties.set("sys.boot_completed", "1");
   3710                 broadcastIntentLocked(null, null,
   3711                         new Intent(Intent.ACTION_BOOT_COMPLETED, null),
   3712                         null, null, 0, null, null,
   3713                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
   3714                         false, false, MY_PID, Process.SYSTEM_UID);
   3715             }
   3716         }
   3717     }
   3718 
   3719     final void ensureBootCompleted() {
   3720         boolean booting;
   3721         boolean enableScreen;
   3722         synchronized (this) {
   3723             booting = mBooting;
   3724             mBooting = false;
   3725             enableScreen = !mBooted;
   3726             mBooted = true;
   3727         }
   3728 
   3729         if (booting) {
   3730             finishBooting();
   3731         }
   3732 
   3733         if (enableScreen) {
   3734             enableScreenAfterBoot();
   3735         }
   3736     }
   3737 
   3738     public final void activityPaused(IBinder token, Bundle icicle) {
   3739         // Refuse possible leaked file descriptors
   3740         if (icicle != null && icicle.hasFileDescriptors()) {
   3741             throw new IllegalArgumentException("File descriptors passed in Bundle");
   3742         }
   3743 
   3744         final long origId = Binder.clearCallingIdentity();
   3745         mMainStack.activityPaused(token, icicle, false);
   3746         Binder.restoreCallingIdentity(origId);
   3747     }
   3748 
   3749     public final void activityStopped(IBinder token, Bitmap thumbnail,
   3750             CharSequence description) {
   3751         if (localLOGV) Slog.v(
   3752             TAG, "Activity stopped: token=" + token);
   3753 
   3754         ActivityRecord r = null;
   3755 
   3756         final long origId = Binder.clearCallingIdentity();
   3757 
   3758         synchronized (this) {
   3759             int index = mMainStack.indexOfTokenLocked(token);
   3760             if (index >= 0) {
   3761                 r = (ActivityRecord)mMainStack.mHistory.get(index);
   3762                 r.thumbnail = thumbnail;
   3763                 r.description = description;
   3764                 r.stopped = true;
   3765                 r.state = ActivityState.STOPPED;
   3766                 if (!r.finishing) {
   3767                     if (r.configDestroy) {
   3768                         r.stack.destroyActivityLocked(r, true);
   3769                         r.stack.resumeTopActivityLocked(null);
   3770                     }
   3771                 }
   3772             }
   3773         }
   3774 
   3775         if (r != null) {
   3776             sendPendingThumbnail(r, null, null, null, false);
   3777         }
   3778 
   3779         trimApplications();
   3780 
   3781         Binder.restoreCallingIdentity(origId);
   3782     }
   3783 
   3784     public final void activityDestroyed(IBinder token) {
   3785         if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
   3786         mMainStack.activityDestroyed(token);
   3787     }
   3788 
   3789     public String getCallingPackage(IBinder token) {
   3790         synchronized (this) {
   3791             ActivityRecord r = getCallingRecordLocked(token);
   3792             return r != null && r.app != null ? r.info.packageName : null;
   3793         }
   3794     }
   3795 
   3796     public ComponentName getCallingActivity(IBinder token) {
   3797         synchronized (this) {
   3798             ActivityRecord r = getCallingRecordLocked(token);
   3799             return r != null ? r.intent.getComponent() : null;
   3800         }
   3801     }
   3802 
   3803     private ActivityRecord getCallingRecordLocked(IBinder token) {
   3804         int index = mMainStack.indexOfTokenLocked(token);
   3805         if (index >= 0) {
   3806             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
   3807             if (r != null) {
   3808                 return r.resultTo;
   3809             }
   3810         }
   3811         return null;
   3812     }
   3813 
   3814     public ComponentName getActivityClassForToken(IBinder token) {
   3815         synchronized(this) {
   3816             int index = mMainStack.indexOfTokenLocked(token);
   3817             if (index >= 0) {
   3818                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
   3819                 return r.intent.getComponent();
   3820             }
   3821             return null;
   3822         }
   3823     }
   3824 
   3825     public String getPackageForToken(IBinder token) {
   3826         synchronized(this) {
   3827             int index = mMainStack.indexOfTokenLocked(token);
   3828             if (index >= 0) {
   3829                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
   3830                 return r.packageName;
   3831             }
   3832             return null;
   3833         }
   3834     }
   3835 
   3836     public IIntentSender getIntentSender(int type,
   3837             String packageName, IBinder token, String resultWho,
   3838             int requestCode, Intent intent, String resolvedType, int flags) {
   3839         // Refuse possible leaked file descriptors
   3840         if (intent != null && intent.hasFileDescriptors() == true) {
   3841             throw new IllegalArgumentException("File descriptors passed in Intent");
   3842         }
   3843 
   3844         if (type == INTENT_SENDER_BROADCAST) {
   3845             if ((intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   3846                 throw new IllegalArgumentException(
   3847                         "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   3848             }
   3849         }
   3850 
   3851         synchronized(this) {
   3852             int callingUid = Binder.getCallingUid();
   3853             try {
   3854                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
   3855                         Process.supportsProcesses()) {
   3856                     int uid = AppGlobals.getPackageManager()
   3857                             .getPackageUid(packageName);
   3858                     if (uid != Binder.getCallingUid()) {
   3859                         String msg = "Permission Denial: getIntentSender() from pid="
   3860                             + Binder.getCallingPid()
   3861                             + ", uid=" + Binder.getCallingUid()
   3862                             + ", (need uid=" + uid + ")"
   3863                             + " is not allowed to send as package " + packageName;
   3864                         Slog.w(TAG, msg);
   3865                         throw new SecurityException(msg);
   3866                     }
   3867                 }
   3868 
   3869                 return getIntentSenderLocked(type, packageName, callingUid,
   3870                         token, resultWho, requestCode, intent, resolvedType, flags);
   3871 
   3872             } catch (RemoteException e) {
   3873                 throw new SecurityException(e);
   3874             }
   3875         }
   3876     }
   3877 
   3878     IIntentSender getIntentSenderLocked(int type,
   3879             String packageName, int callingUid, IBinder token, String resultWho,
   3880             int requestCode, Intent intent, String resolvedType, int flags) {
   3881         ActivityRecord activity = null;
   3882         if (type == INTENT_SENDER_ACTIVITY_RESULT) {
   3883             int index = mMainStack.indexOfTokenLocked(token);
   3884             if (index < 0) {
   3885                 return null;
   3886             }
   3887             activity = (ActivityRecord)mMainStack.mHistory.get(index);
   3888             if (activity.finishing) {
   3889                 return null;
   3890             }
   3891         }
   3892 
   3893         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
   3894         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
   3895         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
   3896         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
   3897                 |PendingIntent.FLAG_UPDATE_CURRENT);
   3898 
   3899         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
   3900                 type, packageName, activity, resultWho,
   3901                 requestCode, intent, resolvedType, flags);
   3902         WeakReference<PendingIntentRecord> ref;
   3903         ref = mIntentSenderRecords.get(key);
   3904         PendingIntentRecord rec = ref != null ? ref.get() : null;
   3905         if (rec != null) {
   3906             if (!cancelCurrent) {
   3907                 if (updateCurrent) {
   3908                     rec.key.requestIntent.replaceExtras(intent);
   3909                 }
   3910                 return rec;
   3911             }
   3912             rec.canceled = true;
   3913             mIntentSenderRecords.remove(key);
   3914         }
   3915         if (noCreate) {
   3916             return rec;
   3917         }
   3918         rec = new PendingIntentRecord(this, key, callingUid);
   3919         mIntentSenderRecords.put(key, rec.ref);
   3920         if (type == INTENT_SENDER_ACTIVITY_RESULT) {
   3921             if (activity.pendingResults == null) {
   3922                 activity.pendingResults
   3923                         = new HashSet<WeakReference<PendingIntentRecord>>();
   3924             }
   3925             activity.pendingResults.add(rec.ref);
   3926         }
   3927         return rec;
   3928     }
   3929 
   3930     public void cancelIntentSender(IIntentSender sender) {
   3931         if (!(sender instanceof PendingIntentRecord)) {
   3932             return;
   3933         }
   3934         synchronized(this) {
   3935             PendingIntentRecord rec = (PendingIntentRecord)sender;
   3936             try {
   3937                 int uid = AppGlobals.getPackageManager()
   3938                         .getPackageUid(rec.key.packageName);
   3939                 if (uid != Binder.getCallingUid()) {
   3940                     String msg = "Permission Denial: cancelIntentSender() from pid="
   3941                         + Binder.getCallingPid()
   3942                         + ", uid=" + Binder.getCallingUid()
   3943                         + " is not allowed to cancel packges "
   3944                         + rec.key.packageName;
   3945                     Slog.w(TAG, msg);
   3946                     throw new SecurityException(msg);
   3947                 }
   3948             } catch (RemoteException e) {
   3949                 throw new SecurityException(e);
   3950             }
   3951             cancelIntentSenderLocked(rec, true);
   3952         }
   3953     }
   3954 
   3955     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
   3956         rec.canceled = true;
   3957         mIntentSenderRecords.remove(rec.key);
   3958         if (cleanActivity && rec.key.activity != null) {
   3959             rec.key.activity.pendingResults.remove(rec.ref);
   3960         }
   3961     }
   3962 
   3963     public String getPackageForIntentSender(IIntentSender pendingResult) {
   3964         if (!(pendingResult instanceof PendingIntentRecord)) {
   3965             return null;
   3966         }
   3967         try {
   3968             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   3969             return res.key.packageName;
   3970         } catch (ClassCastException e) {
   3971         }
   3972         return null;
   3973     }
   3974 
   3975     public void setProcessLimit(int max) {
   3976         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   3977                 "setProcessLimit()");
   3978         mProcessLimit = max;
   3979     }
   3980 
   3981     public int getProcessLimit() {
   3982         return mProcessLimit;
   3983     }
   3984 
   3985     void foregroundTokenDied(ForegroundToken token) {
   3986         synchronized (ActivityManagerService.this) {
   3987             synchronized (mPidsSelfLocked) {
   3988                 ForegroundToken cur
   3989                     = mForegroundProcesses.get(token.pid);
   3990                 if (cur != token) {
   3991                     return;
   3992                 }
   3993                 mForegroundProcesses.remove(token.pid);
   3994                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
   3995                 if (pr == null) {
   3996                     return;
   3997                 }
   3998                 pr.forcingToForeground = null;
   3999                 pr.foregroundServices = false;
   4000             }
   4001             updateOomAdjLocked();
   4002         }
   4003     }
   4004 
   4005     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
   4006         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   4007                 "setProcessForeground()");
   4008         synchronized(this) {
   4009             boolean changed = false;
   4010 
   4011             synchronized (mPidsSelfLocked) {
   4012                 ProcessRecord pr = mPidsSelfLocked.get(pid);
   4013                 if (pr == null) {
   4014                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
   4015                     return;
   4016                 }
   4017                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
   4018                 if (oldToken != null) {
   4019                     oldToken.token.unlinkToDeath(oldToken, 0);
   4020                     mForegroundProcesses.remove(pid);
   4021                     pr.forcingToForeground = null;
   4022                     changed = true;
   4023                 }
   4024                 if (isForeground && token != null) {
   4025                     ForegroundToken newToken = new ForegroundToken() {
   4026                         public void binderDied() {
   4027                             foregroundTokenDied(this);
   4028                         }
   4029                     };
   4030                     newToken.pid = pid;
   4031                     newToken.token = token;
   4032                     try {
   4033                         token.linkToDeath(newToken, 0);
   4034                         mForegroundProcesses.put(pid, newToken);
   4035                         pr.forcingToForeground = token;
   4036                         changed = true;
   4037                     } catch (RemoteException e) {
   4038                         // If the process died while doing this, we will later
   4039                         // do the cleanup with the process death link.
   4040                     }
   4041                 }
   4042             }
   4043 
   4044             if (changed) {
   4045                 updateOomAdjLocked();
   4046             }
   4047         }
   4048     }
   4049 
   4050     // =========================================================
   4051     // PERMISSIONS
   4052     // =========================================================
   4053 
   4054     static class PermissionController extends IPermissionController.Stub {
   4055         ActivityManagerService mActivityManagerService;
   4056         PermissionController(ActivityManagerService activityManagerService) {
   4057             mActivityManagerService = activityManagerService;
   4058         }
   4059 
   4060         public boolean checkPermission(String permission, int pid, int uid) {
   4061             return mActivityManagerService.checkPermission(permission, pid,
   4062                     uid) == PackageManager.PERMISSION_GRANTED;
   4063         }
   4064     }
   4065 
   4066     /**
   4067      * This can be called with or without the global lock held.
   4068      */
   4069     int checkComponentPermission(String permission, int pid, int uid,
   4070             int reqUid) {
   4071         // We might be performing an operation on behalf of an indirect binder
   4072         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
   4073         // client identity accordingly before proceeding.
   4074         Identity tlsIdentity = sCallerIdentity.get();
   4075         if (tlsIdentity != null) {
   4076             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
   4077                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
   4078             uid = tlsIdentity.uid;
   4079             pid = tlsIdentity.pid;
   4080         }
   4081 
   4082         // Root, system server and our own process get to do everything.
   4083         if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
   4084             !Process.supportsProcesses()) {
   4085             return PackageManager.PERMISSION_GRANTED;
   4086         }
   4087         // If the target requires a specific UID, always fail for others.
   4088         if (reqUid >= 0 && uid != reqUid) {
   4089             Slog.w(TAG, "Permission denied: checkComponentPermission() reqUid=" + reqUid);
   4090             return PackageManager.PERMISSION_DENIED;
   4091         }
   4092         if (permission == null) {
   4093             return PackageManager.PERMISSION_GRANTED;
   4094         }
   4095         try {
   4096             return AppGlobals.getPackageManager()
   4097                     .checkUidPermission(permission, uid);
   4098         } catch (RemoteException e) {
   4099             // Should never happen, but if it does... deny!
   4100             Slog.e(TAG, "PackageManager is dead?!?", e);
   4101         }
   4102         return PackageManager.PERMISSION_DENIED;
   4103     }
   4104 
   4105     /**
   4106      * As the only public entry point for permissions checking, this method
   4107      * can enforce the semantic that requesting a check on a null global
   4108      * permission is automatically denied.  (Internally a null permission
   4109      * string is used when calling {@link #checkComponentPermission} in cases
   4110      * when only uid-based security is needed.)
   4111      *
   4112      * This can be called with or without the global lock held.
   4113      */
   4114     public int checkPermission(String permission, int pid, int uid) {
   4115         if (permission == null) {
   4116             return PackageManager.PERMISSION_DENIED;
   4117         }
   4118         return checkComponentPermission(permission, pid, uid, -1);
   4119     }
   4120 
   4121     /**
   4122      * Binder IPC calls go through the public entry point.
   4123      * This can be called with or without the global lock held.
   4124      */
   4125     int checkCallingPermission(String permission) {
   4126         return checkPermission(permission,
   4127                 Binder.getCallingPid(),
   4128                 Binder.getCallingUid());
   4129     }
   4130 
   4131     /**
   4132      * This can be called with or without the global lock held.
   4133      */
   4134     void enforceCallingPermission(String permission, String func) {
   4135         if (checkCallingPermission(permission)
   4136                 == PackageManager.PERMISSION_GRANTED) {
   4137             return;
   4138         }
   4139 
   4140         String msg = "Permission Denial: " + func + " from pid="
   4141                 + Binder.getCallingPid()
   4142                 + ", uid=" + Binder.getCallingUid()
   4143                 + " requires " + permission;
   4144         Slog.w(TAG, msg);
   4145         throw new SecurityException(msg);
   4146     }
   4147 
   4148     private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
   4149             ProviderInfo pi, Uri uri, int uid, int modeFlags) {
   4150         boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
   4151         boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
   4152         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4153                 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
   4154         try {
   4155             // Is the component private from the target uid?
   4156             final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
   4157 
   4158             // Acceptable if the there is no read permission needed from the
   4159             // target or the target is holding the read permission.
   4160             if (!readPerm) {
   4161                 if ((!prv && pi.readPermission == null) ||
   4162                         (pm.checkUidPermission(pi.readPermission, uid)
   4163                                 == PackageManager.PERMISSION_GRANTED)) {
   4164                     readPerm = true;
   4165                 }
   4166             }
   4167 
   4168             // Acceptable if the there is no write permission needed from the
   4169             // target or the target is holding the read permission.
   4170             if (!writePerm) {
   4171                 if (!prv && (pi.writePermission == null) ||
   4172                         (pm.checkUidPermission(pi.writePermission, uid)
   4173                                 == PackageManager.PERMISSION_GRANTED)) {
   4174                     writePerm = true;
   4175                 }
   4176             }
   4177 
   4178             // Acceptable if there is a path permission matching the URI that
   4179             // the target holds the permission on.
   4180             PathPermission[] pps = pi.pathPermissions;
   4181             if (pps != null && (!readPerm || !writePerm)) {
   4182                 final String path = uri.getPath();
   4183                 int i = pps.length;
   4184                 while (i > 0 && (!readPerm || !writePerm)) {
   4185                     i--;
   4186                     PathPermission pp = pps[i];
   4187                     if (!readPerm) {
   4188                         final String pprperm = pp.getReadPermission();
   4189                         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
   4190                                 + pprperm + " for " + pp.getPath()
   4191                                 + ": match=" + pp.match(path)
   4192                                 + " check=" + pm.checkUidPermission(pprperm, uid));
   4193                         if (pprperm != null && pp.match(path) &&
   4194                                 (pm.checkUidPermission(pprperm, uid)
   4195                                         == PackageManager.PERMISSION_GRANTED)) {
   4196                             readPerm = true;
   4197                         }
   4198                     }
   4199                     if (!writePerm) {
   4200                         final String ppwperm = pp.getWritePermission();
   4201                         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
   4202                                 + ppwperm + " for " + pp.getPath()
   4203                                 + ": match=" + pp.match(path)
   4204                                 + " check=" + pm.checkUidPermission(ppwperm, uid));
   4205                         if (ppwperm != null && pp.match(path) &&
   4206                                 (pm.checkUidPermission(ppwperm, uid)
   4207                                         == PackageManager.PERMISSION_GRANTED)) {
   4208                             writePerm = true;
   4209                         }
   4210                     }
   4211                 }
   4212             }
   4213         } catch (RemoteException e) {
   4214             return false;
   4215         }
   4216 
   4217         return readPerm && writePerm;
   4218     }
   4219 
   4220     private final boolean checkUriPermissionLocked(Uri uri, int uid,
   4221             int modeFlags) {
   4222         // Root gets to do everything.
   4223         if (uid == 0 || !Process.supportsProcesses()) {
   4224             return true;
   4225         }
   4226         HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   4227         if (perms == null) return false;
   4228         UriPermission perm = perms.get(uri);
   4229         if (perm == null) return false;
   4230         return (modeFlags&perm.modeFlags) == modeFlags;
   4231     }
   4232 
   4233     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
   4234         // Another redirected-binder-call permissions check as in
   4235         // {@link checkComponentPermission}.
   4236         Identity tlsIdentity = sCallerIdentity.get();
   4237         if (tlsIdentity != null) {
   4238             uid = tlsIdentity.uid;
   4239             pid = tlsIdentity.pid;
   4240         }
   4241 
   4242         // Our own process gets to do everything.
   4243         if (pid == MY_PID) {
   4244             return PackageManager.PERMISSION_GRANTED;
   4245         }
   4246         synchronized(this) {
   4247             return checkUriPermissionLocked(uri, uid, modeFlags)
   4248                     ? PackageManager.PERMISSION_GRANTED
   4249                     : PackageManager.PERMISSION_DENIED;
   4250         }
   4251     }
   4252 
   4253     /**
   4254      * Check if the targetPkg can be granted permission to access uri by
   4255      * the callingUid using the given modeFlags.  Throws a security exception
   4256      * if callingUid is not allowed to do this.  Returns the uid of the target
   4257      * if the URI permission grant should be performed; returns -1 if it is not
   4258      * needed (for example targetPkg already has permission to access the URI).
   4259      */
   4260     int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
   4261             Uri uri, int modeFlags) {
   4262         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   4263                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   4264         if (modeFlags == 0) {
   4265             return -1;
   4266         }
   4267 
   4268         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4269                 "Checking grant " + targetPkg + " permission to " + uri);
   4270 
   4271         final IPackageManager pm = AppGlobals.getPackageManager();
   4272 
   4273         // If this is not a content: uri, we can't do anything with it.
   4274         if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
   4275             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4276                     "Can't grant URI permission for non-content URI: " + uri);
   4277             return -1;
   4278         }
   4279 
   4280         String name = uri.getAuthority();
   4281         ProviderInfo pi = null;
   4282         ContentProviderRecord cpr = mProvidersByName.get(name);
   4283         if (cpr != null) {
   4284             pi = cpr.info;
   4285         } else {
   4286             try {
   4287                 pi = pm.resolveContentProvider(name,
   4288                         PackageManager.GET_URI_PERMISSION_PATTERNS);
   4289             } catch (RemoteException ex) {
   4290             }
   4291         }
   4292         if (pi == null) {
   4293             Slog.w(TAG, "No content provider found for: " + name);
   4294             return -1;
   4295         }
   4296 
   4297         int targetUid;
   4298         try {
   4299             targetUid = pm.getPackageUid(targetPkg);
   4300             if (targetUid < 0) {
   4301                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4302                         "Can't grant URI permission no uid for: " + targetPkg);
   4303                 return -1;
   4304             }
   4305         } catch (RemoteException ex) {
   4306             return -1;
   4307         }
   4308 
   4309         // First...  does the target actually need this permission?
   4310         if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
   4311             // No need to grant the target this permission.
   4312             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4313                     "Target " + targetPkg + " already has full permission to " + uri);
   4314             return -1;
   4315         }
   4316 
   4317         // Second...  is the provider allowing granting of URI permissions?
   4318         if (!pi.grantUriPermissions) {
   4319             throw new SecurityException("Provider " + pi.packageName
   4320                     + "/" + pi.name
   4321                     + " does not allow granting of Uri permissions (uri "
   4322                     + uri + ")");
   4323         }
   4324         if (pi.uriPermissionPatterns != null) {
   4325             final int N = pi.uriPermissionPatterns.length;
   4326             boolean allowed = false;
   4327             for (int i=0; i<N; i++) {
   4328                 if (pi.uriPermissionPatterns[i] != null
   4329                         && pi.uriPermissionPatterns[i].match(uri.getPath())) {
   4330                     allowed = true;
   4331                     break;
   4332                 }
   4333             }
   4334             if (!allowed) {
   4335                 throw new SecurityException("Provider " + pi.packageName
   4336                         + "/" + pi.name
   4337                         + " does not allow granting of permission to path of Uri "
   4338                         + uri);
   4339             }
   4340         }
   4341 
   4342         // Third...  does the caller itself have permission to access
   4343         // this uri?
   4344         if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
   4345             if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
   4346                 throw new SecurityException("Uid " + callingUid
   4347                         + " does not have permission to uri " + uri);
   4348             }
   4349         }
   4350 
   4351         return targetUid;
   4352     }
   4353 
   4354     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
   4355             Uri uri, int modeFlags, UriPermissionOwner owner) {
   4356         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   4357                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   4358         if (modeFlags == 0) {
   4359             return;
   4360         }
   4361 
   4362         // So here we are: the caller has the assumed permission
   4363         // to the uri, and the target doesn't.  Let's now give this to
   4364         // the target.
   4365 
   4366         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4367                 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
   4368 
   4369         HashMap<Uri, UriPermission> targetUris
   4370                 = mGrantedUriPermissions.get(targetUid);
   4371         if (targetUris == null) {
   4372             targetUris = new HashMap<Uri, UriPermission>();
   4373             mGrantedUriPermissions.put(targetUid, targetUris);
   4374         }
   4375 
   4376         UriPermission perm = targetUris.get(uri);
   4377         if (perm == null) {
   4378             perm = new UriPermission(targetUid, uri);
   4379             targetUris.put(uri, perm);
   4380         }
   4381 
   4382         perm.modeFlags |= modeFlags;
   4383         if (owner == null) {
   4384             perm.globalModeFlags |= modeFlags;
   4385         } else if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   4386             perm.readOwners.add(owner);
   4387             owner.addReadPermission(perm);
   4388         } else if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   4389             perm.writeOwners.add(owner);
   4390             owner.addWritePermission(perm);
   4391         }
   4392     }
   4393 
   4394     void grantUriPermissionLocked(int callingUid,
   4395             String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
   4396         int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
   4397         if (targetUid < 0) {
   4398             return;
   4399         }
   4400 
   4401         grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
   4402     }
   4403 
   4404     /**
   4405      * Like checkGrantUriPermissionLocked, but takes an Intent.
   4406      */
   4407     int checkGrantUriPermissionFromIntentLocked(int callingUid,
   4408             String targetPkg, Intent intent) {
   4409         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4410                 "Checking URI perm to " + (intent != null ? intent.getData() : null)
   4411                 + " from " + intent + "; flags=0x"
   4412                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
   4413 
   4414         if (intent == null) {
   4415             return -1;
   4416         }
   4417         Uri data = intent.getData();
   4418         if (data == null) {
   4419             return -1;
   4420         }
   4421         return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
   4422                 intent.getFlags());
   4423     }
   4424 
   4425     /**
   4426      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
   4427      */
   4428     void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
   4429             String targetPkg, Intent intent, UriPermissionOwner owner) {
   4430         grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
   4431                 intent.getFlags(), owner);
   4432     }
   4433 
   4434     void grantUriPermissionFromIntentLocked(int callingUid,
   4435             String targetPkg, Intent intent, UriPermissionOwner owner) {
   4436         int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
   4437         if (targetUid < 0) {
   4438             return;
   4439         }
   4440 
   4441         grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
   4442     }
   4443 
   4444     public void grantUriPermission(IApplicationThread caller, String targetPkg,
   4445             Uri uri, int modeFlags) {
   4446         synchronized(this) {
   4447             final ProcessRecord r = getRecordForAppLocked(caller);
   4448             if (r == null) {
   4449                 throw new SecurityException("Unable to find app for caller "
   4450                         + caller
   4451                         + " when granting permission to uri " + uri);
   4452             }
   4453             if (targetPkg == null) {
   4454                 throw new IllegalArgumentException("null target");
   4455             }
   4456             if (uri == null) {
   4457                 throw new IllegalArgumentException("null uri");
   4458             }
   4459 
   4460             grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
   4461                     null);
   4462         }
   4463     }
   4464 
   4465     void removeUriPermissionIfNeededLocked(UriPermission perm) {
   4466         if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
   4467                 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
   4468             HashMap<Uri, UriPermission> perms
   4469                     = mGrantedUriPermissions.get(perm.uid);
   4470             if (perms != null) {
   4471                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4472                         "Removing " + perm.uid + " permission to " + perm.uri);
   4473                 perms.remove(perm.uri);
   4474                 if (perms.size() == 0) {
   4475                     mGrantedUriPermissions.remove(perm.uid);
   4476                 }
   4477             }
   4478         }
   4479     }
   4480 
   4481     private void revokeUriPermissionLocked(int callingUid, Uri uri,
   4482             int modeFlags) {
   4483         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   4484                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   4485         if (modeFlags == 0) {
   4486             return;
   4487         }
   4488 
   4489         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4490                 "Revoking all granted permissions to " + uri);
   4491 
   4492         final IPackageManager pm = AppGlobals.getPackageManager();
   4493 
   4494         final String authority = uri.getAuthority();
   4495         ProviderInfo pi = null;
   4496         ContentProviderRecord cpr = mProvidersByName.get(authority);
   4497         if (cpr != null) {
   4498             pi = cpr.info;
   4499         } else {
   4500             try {
   4501                 pi = pm.resolveContentProvider(authority,
   4502                         PackageManager.GET_URI_PERMISSION_PATTERNS);
   4503             } catch (RemoteException ex) {
   4504             }
   4505         }
   4506         if (pi == null) {
   4507             Slog.w(TAG, "No content provider found for: " + authority);
   4508             return;
   4509         }
   4510 
   4511         // Does the caller have this permission on the URI?
   4512         if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
   4513             // Right now, if you are not the original owner of the permission,
   4514             // you are not allowed to revoke it.
   4515             //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
   4516                 throw new SecurityException("Uid " + callingUid
   4517                         + " does not have permission to uri " + uri);
   4518             //}
   4519         }
   4520 
   4521         // Go through all of the permissions and remove any that match.
   4522         final List<String> SEGMENTS = uri.getPathSegments();
   4523         if (SEGMENTS != null) {
   4524             final int NS = SEGMENTS.size();
   4525             int N = mGrantedUriPermissions.size();
   4526             for (int i=0; i<N; i++) {
   4527                 HashMap<Uri, UriPermission> perms
   4528                         = mGrantedUriPermissions.valueAt(i);
   4529                 Iterator<UriPermission> it = perms.values().iterator();
   4530             toploop:
   4531                 while (it.hasNext()) {
   4532                     UriPermission perm = it.next();
   4533                     Uri targetUri = perm.uri;
   4534                     if (!authority.equals(targetUri.getAuthority())) {
   4535                         continue;
   4536                     }
   4537                     List<String> targetSegments = targetUri.getPathSegments();
   4538                     if (targetSegments == null) {
   4539                         continue;
   4540                     }
   4541                     if (targetSegments.size() < NS) {
   4542                         continue;
   4543                     }
   4544                     for (int j=0; j<NS; j++) {
   4545                         if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
   4546                             continue toploop;
   4547                         }
   4548                     }
   4549                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4550                             "Revoking " + perm.uid + " permission to " + perm.uri);
   4551                     perm.clearModes(modeFlags);
   4552                     if (perm.modeFlags == 0) {
   4553                         it.remove();
   4554                     }
   4555                 }
   4556                 if (perms.size() == 0) {
   4557                     mGrantedUriPermissions.remove(
   4558                             mGrantedUriPermissions.keyAt(i));
   4559                     N--;
   4560                     i--;
   4561                 }
   4562             }
   4563         }
   4564     }
   4565 
   4566     public void revokeUriPermission(IApplicationThread caller, Uri uri,
   4567             int modeFlags) {
   4568         synchronized(this) {
   4569             final ProcessRecord r = getRecordForAppLocked(caller);
   4570             if (r == null) {
   4571                 throw new SecurityException("Unable to find app for caller "
   4572                         + caller
   4573                         + " when revoking permission to uri " + uri);
   4574             }
   4575             if (uri == null) {
   4576                 Slog.w(TAG, "revokeUriPermission: null uri");
   4577                 return;
   4578             }
   4579 
   4580             modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   4581                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   4582             if (modeFlags == 0) {
   4583                 return;
   4584             }
   4585 
   4586             final IPackageManager pm = AppGlobals.getPackageManager();
   4587 
   4588             final String authority = uri.getAuthority();
   4589             ProviderInfo pi = null;
   4590             ContentProviderRecord cpr = mProvidersByName.get(authority);
   4591             if (cpr != null) {
   4592                 pi = cpr.info;
   4593             } else {
   4594                 try {
   4595                     pi = pm.resolveContentProvider(authority,
   4596                             PackageManager.GET_URI_PERMISSION_PATTERNS);
   4597                 } catch (RemoteException ex) {
   4598                 }
   4599             }
   4600             if (pi == null) {
   4601                 Slog.w(TAG, "No content provider found for: " + authority);
   4602                 return;
   4603             }
   4604 
   4605             revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
   4606         }
   4607     }
   4608 
   4609     @Override
   4610     public IBinder newUriPermissionOwner(String name) {
   4611         synchronized(this) {
   4612             UriPermissionOwner owner = new UriPermissionOwner(this, name);
   4613             return owner.getExternalTokenLocked();
   4614         }
   4615     }
   4616 
   4617     @Override
   4618     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
   4619             Uri uri, int modeFlags) {
   4620         synchronized(this) {
   4621             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   4622             if (owner == null) {
   4623                 throw new IllegalArgumentException("Unknown owner: " + token);
   4624             }
   4625             if (fromUid != Binder.getCallingUid()) {
   4626                 if (Binder.getCallingUid() != Process.myUid()) {
   4627                     // Only system code can grant URI permissions on behalf
   4628                     // of other users.
   4629                     throw new SecurityException("nice try");
   4630                 }
   4631             }
   4632             if (targetPkg == null) {
   4633                 throw new IllegalArgumentException("null target");
   4634             }
   4635             if (uri == null) {
   4636                 throw new IllegalArgumentException("null uri");
   4637             }
   4638 
   4639             grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
   4640         }
   4641     }
   4642 
   4643     @Override
   4644     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
   4645         synchronized(this) {
   4646             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   4647             if (owner == null) {
   4648                 throw new IllegalArgumentException("Unknown owner: " + token);
   4649             }
   4650 
   4651             if (uri == null) {
   4652                 owner.removeUriPermissionsLocked(mode);
   4653             } else {
   4654                 owner.removeUriPermissionLocked(uri, mode);
   4655             }
   4656         }
   4657     }
   4658 
   4659     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
   4660         synchronized (this) {
   4661             ProcessRecord app =
   4662                 who != null ? getRecordForAppLocked(who) : null;
   4663             if (app == null) return;
   4664 
   4665             Message msg = Message.obtain();
   4666             msg.what = WAIT_FOR_DEBUGGER_MSG;
   4667             msg.obj = app;
   4668             msg.arg1 = waiting ? 1 : 0;
   4669             mHandler.sendMessage(msg);
   4670         }
   4671     }
   4672 
   4673     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
   4674         outInfo.availMem = Process.getFreeMemory();
   4675         outInfo.threshold = HOME_APP_MEM;
   4676         outInfo.lowMemory = outInfo.availMem <
   4677                 (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
   4678     }
   4679 
   4680     // =========================================================
   4681     // TASK MANAGEMENT
   4682     // =========================================================
   4683 
   4684     public List getTasks(int maxNum, int flags,
   4685                          IThumbnailReceiver receiver) {
   4686         ArrayList list = new ArrayList();
   4687 
   4688         PendingThumbnailsRecord pending = null;
   4689         IApplicationThread topThumbnail = null;
   4690         ActivityRecord topRecord = null;
   4691 
   4692         synchronized(this) {
   4693             if (localLOGV) Slog.v(
   4694                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
   4695                 + ", receiver=" + receiver);
   4696 
   4697             if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
   4698                     != PackageManager.PERMISSION_GRANTED) {
   4699                 if (receiver != null) {
   4700                     // If the caller wants to wait for pending thumbnails,
   4701                     // it ain't gonna get them.
   4702                     try {
   4703                         receiver.finished();
   4704                     } catch (RemoteException ex) {
   4705                     }
   4706                 }
   4707                 String msg = "Permission Denial: getTasks() from pid="
   4708                         + Binder.getCallingPid()
   4709                         + ", uid=" + Binder.getCallingUid()
   4710                         + " requires " + android.Manifest.permission.GET_TASKS;
   4711                 Slog.w(TAG, msg);
   4712                 throw new SecurityException(msg);
   4713             }
   4714 
   4715             int pos = mMainStack.mHistory.size()-1;
   4716             ActivityRecord next =
   4717                 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
   4718             ActivityRecord top = null;
   4719             CharSequence topDescription = null;
   4720             TaskRecord curTask = null;
   4721             int numActivities = 0;
   4722             int numRunning = 0;
   4723             while (pos >= 0 && maxNum > 0) {
   4724                 final ActivityRecord r = next;
   4725                 pos--;
   4726                 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
   4727 
   4728                 // Initialize state for next task if needed.
   4729                 if (top == null ||
   4730                         (top.state == ActivityState.INITIALIZING
   4731                             && top.task == r.task)) {
   4732                     top = r;
   4733                     topDescription = r.description;
   4734                     curTask = r.task;
   4735                     numActivities = numRunning = 0;
   4736                 }
   4737 
   4738                 // Add 'r' into the current task.
   4739                 numActivities++;
   4740                 if (r.app != null && r.app.thread != null) {
   4741                     numRunning++;
   4742                 }
   4743                 if (topDescription == null) {
   4744                     topDescription = r.description;
   4745                 }
   4746 
   4747                 if (localLOGV) Slog.v(
   4748                     TAG, r.intent.getComponent().flattenToShortString()
   4749                     + ": task=" + r.task);
   4750 
   4751                 // If the next one is a different task, generate a new
   4752                 // TaskInfo entry for what we have.
   4753                 if (next == null || next.task != curTask) {
   4754                     ActivityManager.RunningTaskInfo ci
   4755                             = new ActivityManager.RunningTaskInfo();
   4756                     ci.id = curTask.taskId;
   4757                     ci.baseActivity = r.intent.getComponent();
   4758                     ci.topActivity = top.intent.getComponent();
   4759                     ci.thumbnail = top.thumbnail;
   4760                     ci.description = topDescription;
   4761                     ci.numActivities = numActivities;
   4762                     ci.numRunning = numRunning;
   4763                     //System.out.println(
   4764                     //    "#" + maxNum + ": " + " descr=" + ci.description);
   4765                     if (ci.thumbnail == null && receiver != null) {
   4766                         if (localLOGV) Slog.v(
   4767                             TAG, "State=" + top.state + "Idle=" + top.idle
   4768                             + " app=" + top.app
   4769                             + " thr=" + (top.app != null ? top.app.thread : null));
   4770                         if (top.state == ActivityState.RESUMED
   4771                                 || top.state == ActivityState.PAUSING) {
   4772                             if (top.idle && top.app != null
   4773                                 && top.app.thread != null) {
   4774                                 topRecord = top;
   4775                                 topThumbnail = top.app.thread;
   4776                             } else {
   4777                                 top.thumbnailNeeded = true;
   4778                             }
   4779                         }
   4780                         if (pending == null) {
   4781                             pending = new PendingThumbnailsRecord(receiver);
   4782                         }
   4783                         pending.pendingRecords.add(top);
   4784                     }
   4785                     list.add(ci);
   4786                     maxNum--;
   4787                     top = null;
   4788                 }
   4789             }
   4790 
   4791             if (pending != null) {
   4792                 mPendingThumbnails.add(pending);
   4793             }
   4794         }
   4795 
   4796         if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
   4797 
   4798         if (topThumbnail != null) {
   4799             if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
   4800             try {
   4801                 topThumbnail.requestThumbnail(topRecord);
   4802             } catch (Exception e) {
   4803                 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
   4804                 sendPendingThumbnail(null, topRecord, null, null, true);
   4805             }
   4806         }
   4807 
   4808         if (pending == null && receiver != null) {
   4809             // In this case all thumbnails were available and the client
   4810             // is being asked to be told when the remaining ones come in...
   4811             // which is unusually, since the top-most currently running
   4812             // activity should never have a canned thumbnail!  Oh well.
   4813             try {
   4814                 receiver.finished();
   4815             } catch (RemoteException ex) {
   4816             }
   4817         }
   4818 
   4819         return list;
   4820     }
   4821 
   4822     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
   4823             int flags) {
   4824         synchronized (this) {
   4825             enforceCallingPermission(android.Manifest.permission.GET_TASKS,
   4826                     "getRecentTasks()");
   4827 
   4828             IPackageManager pm = AppGlobals.getPackageManager();
   4829 
   4830             final int N = mRecentTasks.size();
   4831             ArrayList<ActivityManager.RecentTaskInfo> res
   4832                     = new ArrayList<ActivityManager.RecentTaskInfo>(
   4833                             maxNum < N ? maxNum : N);
   4834             for (int i=0; i<N && maxNum > 0; i++) {
   4835                 TaskRecord tr = mRecentTasks.get(i);
   4836                 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
   4837                         || (tr.intent == null)
   4838                         || ((tr.intent.getFlags()
   4839                                 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
   4840                     ActivityManager.RecentTaskInfo rti
   4841                             = new ActivityManager.RecentTaskInfo();
   4842                     rti.id = tr.numActivities > 0 ? tr.taskId : -1;
   4843                     rti.baseIntent = new Intent(
   4844                             tr.intent != null ? tr.intent : tr.affinityIntent);
   4845                     rti.origActivity = tr.origActivity;
   4846 
   4847                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
   4848                         // Check whether this activity is currently available.
   4849                         try {
   4850                             if (rti.origActivity != null) {
   4851                                 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
   4852                                     continue;
   4853                                 }
   4854                             } else if (rti.baseIntent != null) {
   4855                                 if (pm.queryIntentActivities(rti.baseIntent,
   4856                                         null, 0) == null) {
   4857                                     continue;
   4858                                 }
   4859                             }
   4860                         } catch (RemoteException e) {
   4861                             // Will never happen.
   4862                         }
   4863                     }
   4864 
   4865                     res.add(rti);
   4866                     maxNum--;
   4867                 }
   4868             }
   4869             return res;
   4870         }
   4871     }
   4872 
   4873     private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
   4874         int j;
   4875         TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
   4876         TaskRecord jt = startTask;
   4877 
   4878         // First look backwards
   4879         for (j=startIndex-1; j>=0; j--) {
   4880             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
   4881             if (r.task != jt) {
   4882                 jt = r.task;
   4883                 if (affinity.equals(jt.affinity)) {
   4884                     return j;
   4885                 }
   4886             }
   4887         }
   4888 
   4889         // Now look forwards
   4890         final int N = mMainStack.mHistory.size();
   4891         jt = startTask;
   4892         for (j=startIndex+1; j<N; j++) {
   4893             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
   4894             if (r.task != jt) {
   4895                 if (affinity.equals(jt.affinity)) {
   4896                     return j;
   4897                 }
   4898                 jt = r.task;
   4899             }
   4900         }
   4901 
   4902         // Might it be at the top?
   4903         if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
   4904             return N-1;
   4905         }
   4906 
   4907         return -1;
   4908     }
   4909 
   4910     /**
   4911      * TODO: Add mController hook
   4912      */
   4913     public void moveTaskToFront(int task) {
   4914         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   4915                 "moveTaskToFront()");
   4916 
   4917         synchronized(this) {
   4918             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   4919                     Binder.getCallingUid(), "Task to front")) {
   4920                 return;
   4921             }
   4922             final long origId = Binder.clearCallingIdentity();
   4923             try {
   4924                 int N = mRecentTasks.size();
   4925                 for (int i=0; i<N; i++) {
   4926                     TaskRecord tr = mRecentTasks.get(i);
   4927                     if (tr.taskId == task) {
   4928                         mMainStack.moveTaskToFrontLocked(tr, null);
   4929                         return;
   4930                     }
   4931                 }
   4932                 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
   4933                     ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
   4934                     if (hr.task.taskId == task) {
   4935                         mMainStack.moveTaskToFrontLocked(hr.task, null);
   4936                         return;
   4937                     }
   4938                 }
   4939             } finally {
   4940                 Binder.restoreCallingIdentity(origId);
   4941             }
   4942         }
   4943     }
   4944 
   4945     public void moveTaskToBack(int task) {
   4946         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   4947                 "moveTaskToBack()");
   4948 
   4949         synchronized(this) {
   4950             if (mMainStack.mResumedActivity != null
   4951                     && mMainStack.mResumedActivity.task.taskId == task) {
   4952                 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   4953                         Binder.getCallingUid(), "Task to back")) {
   4954                     return;
   4955                 }
   4956             }
   4957             final long origId = Binder.clearCallingIdentity();
   4958             mMainStack.moveTaskToBackLocked(task, null);
   4959             Binder.restoreCallingIdentity(origId);
   4960         }
   4961     }
   4962 
   4963     /**
   4964      * Moves an activity, and all of the other activities within the same task, to the bottom
   4965      * of the history stack.  The activity's order within the task is unchanged.
   4966      *
   4967      * @param token A reference to the activity we wish to move
   4968      * @param nonRoot If false then this only works if the activity is the root
   4969      *                of a task; if true it will work for any activity in a task.
   4970      * @return Returns true if the move completed, false if not.
   4971      */
   4972     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
   4973         synchronized(this) {
   4974             final long origId = Binder.clearCallingIdentity();
   4975             int taskId = getTaskForActivityLocked(token, !nonRoot);
   4976             if (taskId >= 0) {
   4977                 return mMainStack.moveTaskToBackLocked(taskId, null);
   4978             }
   4979             Binder.restoreCallingIdentity(origId);
   4980         }
   4981         return false;
   4982     }
   4983 
   4984     public void moveTaskBackwards(int task) {
   4985         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   4986                 "moveTaskBackwards()");
   4987 
   4988         synchronized(this) {
   4989             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   4990                     Binder.getCallingUid(), "Task backwards")) {
   4991                 return;
   4992             }
   4993             final long origId = Binder.clearCallingIdentity();
   4994             moveTaskBackwardsLocked(task);
   4995             Binder.restoreCallingIdentity(origId);
   4996         }
   4997     }
   4998 
   4999     private final void moveTaskBackwardsLocked(int task) {
   5000         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
   5001     }
   5002 
   5003     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
   5004         synchronized(this) {
   5005             return getTaskForActivityLocked(token, onlyRoot);
   5006         }
   5007     }
   5008 
   5009     int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
   5010         final int N = mMainStack.mHistory.size();
   5011         TaskRecord lastTask = null;
   5012         for (int i=0; i<N; i++) {
   5013             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   5014             if (r == token) {
   5015                 if (!onlyRoot || lastTask != r.task) {
   5016                     return r.task.taskId;
   5017                 }
   5018                 return -1;
   5019             }
   5020             lastTask = r.task;
   5021         }
   5022 
   5023         return -1;
   5024     }
   5025 
   5026     public void finishOtherInstances(IBinder token, ComponentName className) {
   5027         synchronized(this) {
   5028             final long origId = Binder.clearCallingIdentity();
   5029 
   5030             int N = mMainStack.mHistory.size();
   5031             TaskRecord lastTask = null;
   5032             for (int i=0; i<N; i++) {
   5033                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   5034                 if (r.realActivity.equals(className)
   5035                         && r != token && lastTask != r.task) {
   5036                     if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
   5037                             null, "others")) {
   5038                         i--;
   5039                         N--;
   5040                     }
   5041                 }
   5042                 lastTask = r.task;
   5043             }
   5044 
   5045             Binder.restoreCallingIdentity(origId);
   5046         }
   5047     }
   5048 
   5049     // =========================================================
   5050     // THUMBNAILS
   5051     // =========================================================
   5052 
   5053     public void reportThumbnail(IBinder token,
   5054             Bitmap thumbnail, CharSequence description) {
   5055         //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
   5056         final long origId = Binder.clearCallingIdentity();
   5057         sendPendingThumbnail(null, token, thumbnail, description, true);
   5058         Binder.restoreCallingIdentity(origId);
   5059     }
   5060 
   5061     final void sendPendingThumbnail(ActivityRecord r, IBinder token,
   5062             Bitmap thumbnail, CharSequence description, boolean always) {
   5063         TaskRecord task = null;
   5064         ArrayList receivers = null;
   5065 
   5066         //System.out.println("Send pending thumbnail: " + r);
   5067 
   5068         synchronized(this) {
   5069             if (r == null) {
   5070                 int index = mMainStack.indexOfTokenLocked(token);
   5071                 if (index < 0) {
   5072                     return;
   5073                 }
   5074                 r = (ActivityRecord)mMainStack.mHistory.get(index);
   5075             }
   5076             if (thumbnail == null) {
   5077                 thumbnail = r.thumbnail;
   5078                 description = r.description;
   5079             }
   5080             if (thumbnail == null && !always) {
   5081                 // If there is no thumbnail, and this entry is not actually
   5082                 // going away, then abort for now and pick up the next
   5083                 // thumbnail we get.
   5084                 return;
   5085             }
   5086             task = r.task;
   5087 
   5088             int N = mPendingThumbnails.size();
   5089             int i=0;
   5090             while (i<N) {
   5091                 PendingThumbnailsRecord pr =
   5092                     (PendingThumbnailsRecord)mPendingThumbnails.get(i);
   5093                 //System.out.println("Looking in " + pr.pendingRecords);
   5094                 if (pr.pendingRecords.remove(r)) {
   5095                     if (receivers == null) {
   5096                         receivers = new ArrayList();
   5097                     }
   5098                     receivers.add(pr);
   5099                     if (pr.pendingRecords.size() == 0) {
   5100                         pr.finished = true;
   5101                         mPendingThumbnails.remove(i);
   5102                         N--;
   5103                         continue;
   5104                     }
   5105                 }
   5106                 i++;
   5107             }
   5108         }
   5109 
   5110         if (receivers != null) {
   5111             final int N = receivers.size();
   5112             for (int i=0; i<N; i++) {
   5113                 try {
   5114                     PendingThumbnailsRecord pr =
   5115                         (PendingThumbnailsRecord)receivers.get(i);
   5116                     pr.receiver.newThumbnail(
   5117                         task != null ? task.taskId : -1, thumbnail, description);
   5118                     if (pr.finished) {
   5119                         pr.receiver.finished();
   5120                     }
   5121                 } catch (Exception e) {
   5122                     Slog.w(TAG, "Exception thrown when sending thumbnail", e);
   5123                 }
   5124             }
   5125         }
   5126     }
   5127 
   5128     // =========================================================
   5129     // CONTENT PROVIDERS
   5130     // =========================================================
   5131 
   5132     private final List generateApplicationProvidersLocked(ProcessRecord app) {
   5133         List providers = null;
   5134         try {
   5135             providers = AppGlobals.getPackageManager().
   5136                 queryContentProviders(app.processName, app.info.uid,
   5137                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
   5138         } catch (RemoteException ex) {
   5139         }
   5140         if (providers != null) {
   5141             final int N = providers.size();
   5142             for (int i=0; i<N; i++) {
   5143                 ProviderInfo cpi =
   5144                     (ProviderInfo)providers.get(i);
   5145                 ContentProviderRecord cpr = mProvidersByClass.get(cpi.name);
   5146                 if (cpr == null) {
   5147                     cpr = new ContentProviderRecord(cpi, app.info);
   5148                     mProvidersByClass.put(cpi.name, cpr);
   5149                 }
   5150                 app.pubProviders.put(cpi.name, cpr);
   5151                 app.addPackage(cpi.applicationInfo.packageName);
   5152                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
   5153             }
   5154         }
   5155         return providers;
   5156     }
   5157 
   5158     private final String checkContentProviderPermissionLocked(
   5159             ProviderInfo cpi, ProcessRecord r) {
   5160         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
   5161         final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
   5162         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
   5163                 cpi.exported ? -1 : cpi.applicationInfo.uid)
   5164                 == PackageManager.PERMISSION_GRANTED) {
   5165             return null;
   5166         }
   5167         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
   5168                 cpi.exported ? -1 : cpi.applicationInfo.uid)
   5169                 == PackageManager.PERMISSION_GRANTED) {
   5170             return null;
   5171         }
   5172 
   5173         PathPermission[] pps = cpi.pathPermissions;
   5174         if (pps != null) {
   5175             int i = pps.length;
   5176             while (i > 0) {
   5177                 i--;
   5178                 PathPermission pp = pps[i];
   5179                 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
   5180                         cpi.exported ? -1 : cpi.applicationInfo.uid)
   5181                         == PackageManager.PERMISSION_GRANTED) {
   5182                     return null;
   5183                 }
   5184                 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
   5185                         cpi.exported ? -1 : cpi.applicationInfo.uid)
   5186                         == PackageManager.PERMISSION_GRANTED) {
   5187                     return null;
   5188                 }
   5189             }
   5190         }
   5191 
   5192         HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   5193         if (perms != null) {
   5194             for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
   5195                 if (uri.getKey().getAuthority().equals(cpi.authority)) {
   5196                     return null;
   5197                 }
   5198             }
   5199         }
   5200 
   5201         String msg = "Permission Denial: opening provider " + cpi.name
   5202                 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   5203                 + ", uid=" + callingUid + ") requires "
   5204                 + cpi.readPermission + " or " + cpi.writePermission;
   5205         Slog.w(TAG, msg);
   5206         return msg;
   5207     }
   5208 
   5209     private final ContentProviderHolder getContentProviderImpl(
   5210         IApplicationThread caller, String name) {
   5211         ContentProviderRecord cpr;
   5212         ProviderInfo cpi = null;
   5213 
   5214         synchronized(this) {
   5215             ProcessRecord r = null;
   5216             if (caller != null) {
   5217                 r = getRecordForAppLocked(caller);
   5218                 if (r == null) {
   5219                     throw new SecurityException(
   5220                             "Unable to find app for caller " + caller
   5221                           + " (pid=" + Binder.getCallingPid()
   5222                           + ") when getting content provider " + name);
   5223                 }
   5224             }
   5225 
   5226             // First check if this content provider has been published...
   5227             cpr = mProvidersByName.get(name);
   5228             if (cpr != null) {
   5229                 cpi = cpr.info;
   5230                 String msg;
   5231                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
   5232                     throw new SecurityException(msg);
   5233                 }
   5234 
   5235                 if (r != null && cpr.canRunHere(r)) {
   5236                     // This provider has been published or is in the process
   5237                     // of being published...  but it is also allowed to run
   5238                     // in the caller's process, so don't make a connection
   5239                     // and just let the caller instantiate its own instance.
   5240                     if (cpr.provider != null) {
   5241                         // don't give caller the provider object, it needs
   5242                         // to make its own.
   5243                         cpr = new ContentProviderRecord(cpr);
   5244                     }
   5245                     return cpr;
   5246                 }
   5247 
   5248                 final long origId = Binder.clearCallingIdentity();
   5249 
   5250                 // In this case the provider instance already exists, so we can
   5251                 // return it right away.
   5252                 if (r != null) {
   5253                     if (DEBUG_PROVIDER) Slog.v(TAG,
   5254                             "Adding provider requested by "
   5255                             + r.processName + " from process "
   5256                             + cpr.info.processName);
   5257                     Integer cnt = r.conProviders.get(cpr);
   5258                     if (cnt == null) {
   5259                         r.conProviders.put(cpr, new Integer(1));
   5260                     } else {
   5261                         r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
   5262                     }
   5263                     cpr.clients.add(r);
   5264                     if (cpr.app != null && r.setAdj <= PERCEPTIBLE_APP_ADJ) {
   5265                         // If this is a perceptible app accessing the provider,
   5266                         // make sure to count it as being accessed and thus
   5267                         // back up on the LRU list.  This is good because
   5268                         // content providers are often expensive to start.
   5269                         updateLruProcessLocked(cpr.app, false, true);
   5270                     }
   5271                 } else {
   5272                     cpr.externals++;
   5273                 }
   5274 
   5275                 if (cpr.app != null) {
   5276                     updateOomAdjLocked(cpr.app);
   5277                 }
   5278 
   5279                 Binder.restoreCallingIdentity(origId);
   5280 
   5281             } else {
   5282                 try {
   5283                     cpi = AppGlobals.getPackageManager().
   5284                         resolveContentProvider(name,
   5285                                 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
   5286                 } catch (RemoteException ex) {
   5287                 }
   5288                 if (cpi == null) {
   5289                     return null;
   5290                 }
   5291 
   5292                 String msg;
   5293                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
   5294                     throw new SecurityException(msg);
   5295                 }
   5296 
   5297                 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
   5298                         && !cpi.processName.equals("system")) {
   5299                     // If this content provider does not run in the system
   5300                     // process, and the system is not yet ready to run other
   5301                     // processes, then fail fast instead of hanging.
   5302                     throw new IllegalArgumentException(
   5303                             "Attempt to launch content provider before system ready");
   5304                 }
   5305 
   5306                 cpr = mProvidersByClass.get(cpi.name);
   5307                 final boolean firstClass = cpr == null;
   5308                 if (firstClass) {
   5309                     try {
   5310                         ApplicationInfo ai =
   5311                             AppGlobals.getPackageManager().
   5312                                 getApplicationInfo(
   5313                                         cpi.applicationInfo.packageName,
   5314                                         STOCK_PM_FLAGS);
   5315                         if (ai == null) {
   5316                             Slog.w(TAG, "No package info for content provider "
   5317                                     + cpi.name);
   5318                             return null;
   5319                         }
   5320                         cpr = new ContentProviderRecord(cpi, ai);
   5321                     } catch (RemoteException ex) {
   5322                         // pm is in same process, this will never happen.
   5323                     }
   5324                 }
   5325 
   5326                 if (r != null && cpr.canRunHere(r)) {
   5327                     // If this is a multiprocess provider, then just return its
   5328                     // info and allow the caller to instantiate it.  Only do
   5329                     // this if the provider is the same user as the caller's
   5330                     // process, or can run as root (so can be in any process).
   5331                     return cpr;
   5332                 }
   5333 
   5334                 if (DEBUG_PROVIDER) {
   5335                     RuntimeException e = new RuntimeException("here");
   5336                     Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
   5337                           + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
   5338                 }
   5339 
   5340                 // This is single process, and our app is now connecting to it.
   5341                 // See if we are already in the process of launching this
   5342                 // provider.
   5343                 final int N = mLaunchingProviders.size();
   5344                 int i;
   5345                 for (i=0; i<N; i++) {
   5346                     if (mLaunchingProviders.get(i) == cpr) {
   5347                         break;
   5348                     }
   5349                 }
   5350 
   5351                 // If the provider is not already being launched, then get it
   5352                 // started.
   5353                 if (i >= N) {
   5354                     final long origId = Binder.clearCallingIdentity();
   5355                     ProcessRecord proc = startProcessLocked(cpi.processName,
   5356                             cpr.appInfo, false, 0, "content provider",
   5357                             new ComponentName(cpi.applicationInfo.packageName,
   5358                                     cpi.name), false);
   5359                     if (proc == null) {
   5360                         Slog.w(TAG, "Unable to launch app "
   5361                                 + cpi.applicationInfo.packageName + "/"
   5362                                 + cpi.applicationInfo.uid + " for provider "
   5363                                 + name + ": process is bad");
   5364                         return null;
   5365                     }
   5366                     cpr.launchingApp = proc;
   5367                     mLaunchingProviders.add(cpr);
   5368                     Binder.restoreCallingIdentity(origId);
   5369                 }
   5370 
   5371                 // Make sure the provider is published (the same provider class
   5372                 // may be published under multiple names).
   5373                 if (firstClass) {
   5374                     mProvidersByClass.put(cpi.name, cpr);
   5375                 }
   5376                 mProvidersByName.put(name, cpr);
   5377 
   5378                 if (r != null) {
   5379                     if (DEBUG_PROVIDER) Slog.v(TAG,
   5380                             "Adding provider requested by "
   5381                             + r.processName + " from process "
   5382                             + cpr.info.processName);
   5383                     Integer cnt = r.conProviders.get(cpr);
   5384                     if (cnt == null) {
   5385                         r.conProviders.put(cpr, new Integer(1));
   5386                     } else {
   5387                         r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
   5388                     }
   5389                     cpr.clients.add(r);
   5390                 } else {
   5391                     cpr.externals++;
   5392                 }
   5393             }
   5394         }
   5395 
   5396         // Wait for the provider to be published...
   5397         synchronized (cpr) {
   5398             while (cpr.provider == null) {
   5399                 if (cpr.launchingApp == null) {
   5400                     Slog.w(TAG, "Unable to launch app "
   5401                             + cpi.applicationInfo.packageName + "/"
   5402                             + cpi.applicationInfo.uid + " for provider "
   5403                             + name + ": launching app became null");
   5404                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
   5405                             cpi.applicationInfo.packageName,
   5406                             cpi.applicationInfo.uid, name);
   5407                     return null;
   5408                 }
   5409                 try {
   5410                     cpr.wait();
   5411                 } catch (InterruptedException ex) {
   5412                 }
   5413             }
   5414         }
   5415         return cpr;
   5416     }
   5417 
   5418     public final ContentProviderHolder getContentProvider(
   5419             IApplicationThread caller, String name) {
   5420         if (caller == null) {
   5421             String msg = "null IApplicationThread when getting content provider "
   5422                     + name;
   5423             Slog.w(TAG, msg);
   5424             throw new SecurityException(msg);
   5425         }
   5426 
   5427         return getContentProviderImpl(caller, name);
   5428     }
   5429 
   5430     private ContentProviderHolder getContentProviderExternal(String name) {
   5431         return getContentProviderImpl(null, name);
   5432     }
   5433 
   5434     /**
   5435      * Drop a content provider from a ProcessRecord's bookkeeping
   5436      * @param cpr
   5437      */
   5438     public void removeContentProvider(IApplicationThread caller, String name) {
   5439         synchronized (this) {
   5440             ContentProviderRecord cpr = mProvidersByName.get(name);
   5441             if(cpr == null) {
   5442                 // remove from mProvidersByClass
   5443                 if (DEBUG_PROVIDER) Slog.v(TAG, name +
   5444                         " provider not found in providers list");
   5445                 return;
   5446             }
   5447             final ProcessRecord r = getRecordForAppLocked(caller);
   5448             if (r == null) {
   5449                 throw new SecurityException(
   5450                         "Unable to find app for caller " + caller +
   5451                         " when removing content provider " + name);
   5452             }
   5453             //update content provider record entry info
   5454             ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
   5455             if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
   5456                     + r.info.processName + " from process "
   5457                     + localCpr.appInfo.processName);
   5458             if (localCpr.app == r) {
   5459                 //should not happen. taken care of as a local provider
   5460                 Slog.w(TAG, "removeContentProvider called on local provider: "
   5461                         + cpr.info.name + " in process " + r.processName);
   5462                 return;
   5463             } else {
   5464                 Integer cnt = r.conProviders.get(localCpr);
   5465                 if (cnt == null || cnt.intValue() <= 1) {
   5466                     localCpr.clients.remove(r);
   5467                     r.conProviders.remove(localCpr);
   5468                 } else {
   5469                     r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
   5470                 }
   5471             }
   5472             updateOomAdjLocked();
   5473         }
   5474     }
   5475 
   5476     private void removeContentProviderExternal(String name) {
   5477         synchronized (this) {
   5478             ContentProviderRecord cpr = mProvidersByName.get(name);
   5479             if(cpr == null) {
   5480                 //remove from mProvidersByClass
   5481                 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
   5482                 return;
   5483             }
   5484 
   5485             //update content provider record entry info
   5486             ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
   5487             localCpr.externals--;
   5488             if (localCpr.externals < 0) {
   5489                 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
   5490             }
   5491             updateOomAdjLocked();
   5492         }
   5493     }
   5494 
   5495     public final void publishContentProviders(IApplicationThread caller,
   5496             List<ContentProviderHolder> providers) {
   5497         if (providers == null) {
   5498             return;
   5499         }
   5500 
   5501         synchronized(this) {
   5502             final ProcessRecord r = getRecordForAppLocked(caller);
   5503             if (r == null) {
   5504                 throw new SecurityException(
   5505                         "Unable to find app for caller " + caller
   5506                       + " (pid=" + Binder.getCallingPid()
   5507                       + ") when publishing content providers");
   5508             }
   5509 
   5510             final long origId = Binder.clearCallingIdentity();
   5511 
   5512             final int N = providers.size();
   5513             for (int i=0; i<N; i++) {
   5514                 ContentProviderHolder src = providers.get(i);
   5515                 if (src == null || src.info == null || src.provider == null) {
   5516                     continue;
   5517                 }
   5518                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
   5519                 if (dst != null) {
   5520                     mProvidersByClass.put(dst.info.name, dst);
   5521                     String names[] = dst.info.authority.split(";");
   5522                     for (int j = 0; j < names.length; j++) {
   5523                         mProvidersByName.put(names[j], dst);
   5524                     }
   5525 
   5526                     int NL = mLaunchingProviders.size();
   5527                     int j;
   5528                     for (j=0; j<NL; j++) {
   5529                         if (mLaunchingProviders.get(j) == dst) {
   5530                             mLaunchingProviders.remove(j);
   5531                             j--;
   5532                             NL--;
   5533                         }
   5534                     }
   5535                     synchronized (dst) {
   5536                         dst.provider = src.provider;
   5537                         dst.app = r;
   5538                         dst.notifyAll();
   5539                     }
   5540                     updateOomAdjLocked(r);
   5541                 }
   5542             }
   5543 
   5544             Binder.restoreCallingIdentity(origId);
   5545         }
   5546     }
   5547 
   5548     public static final void installSystemProviders() {
   5549         List providers;
   5550         synchronized (mSelf) {
   5551             ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
   5552             providers = mSelf.generateApplicationProvidersLocked(app);
   5553             if (providers != null) {
   5554                 for (int i=providers.size()-1; i>=0; i--) {
   5555                     ProviderInfo pi = (ProviderInfo)providers.get(i);
   5556                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   5557                         Slog.w(TAG, "Not installing system proc provider " + pi.name
   5558                                 + ": not system .apk");
   5559                         providers.remove(i);
   5560                     }
   5561                 }
   5562             }
   5563         }
   5564         if (providers != null) {
   5565             mSystemThread.installSystemProviders(providers);
   5566         }
   5567     }
   5568 
   5569     /**
   5570      * Allows app to retrieve the MIME type of a URI without having permission
   5571      * to access its content provider.
   5572      *
   5573      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
   5574      *
   5575      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
   5576      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
   5577      */
   5578     public String getProviderMimeType(Uri uri) {
   5579         final String name = uri.getAuthority();
   5580         final long ident = Binder.clearCallingIdentity();
   5581         ContentProviderHolder holder = null;
   5582 
   5583         try {
   5584             holder = getContentProviderExternal(name);
   5585             if (holder != null) {
   5586                 return holder.provider.getType(uri);
   5587             }
   5588         } catch (RemoteException e) {
   5589             Log.w(TAG, "Content provider dead retrieving " + uri, e);
   5590             return null;
   5591         } finally {
   5592             if (holder != null) {
   5593                 removeContentProviderExternal(name);
   5594             }
   5595             Binder.restoreCallingIdentity(ident);
   5596         }
   5597 
   5598         return null;
   5599     }
   5600 
   5601     // =========================================================
   5602     // GLOBAL MANAGEMENT
   5603     // =========================================================
   5604 
   5605     final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
   5606             ApplicationInfo info, String customProcess) {
   5607         String proc = customProcess != null ? customProcess : info.processName;
   5608         BatteryStatsImpl.Uid.Proc ps = null;
   5609         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   5610         synchronized (stats) {
   5611             ps = stats.getProcessStatsLocked(info.uid, proc);
   5612         }
   5613         return new ProcessRecord(ps, thread, info, proc);
   5614     }
   5615 
   5616     final ProcessRecord addAppLocked(ApplicationInfo info) {
   5617         ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
   5618 
   5619         if (app == null) {
   5620             app = newProcessRecordLocked(null, info, null);
   5621             mProcessNames.put(info.processName, info.uid, app);
   5622             updateLruProcessLocked(app, true, true);
   5623         }
   5624 
   5625         if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
   5626                 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
   5627             app.persistent = true;
   5628             app.maxAdj = CORE_SERVER_ADJ;
   5629         }
   5630         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
   5631             mPersistentStartingProcesses.add(app);
   5632             startProcessLocked(app, "added application", app.processName);
   5633         }
   5634 
   5635         return app;
   5636     }
   5637 
   5638     public void unhandledBack() {
   5639         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
   5640                 "unhandledBack()");
   5641 
   5642         synchronized(this) {
   5643             int count = mMainStack.mHistory.size();
   5644             if (DEBUG_SWITCH) Slog.d(
   5645                 TAG, "Performing unhandledBack(): stack size = " + count);
   5646             if (count > 1) {
   5647                 final long origId = Binder.clearCallingIdentity();
   5648                 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
   5649                         count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
   5650                 Binder.restoreCallingIdentity(origId);
   5651             }
   5652         }
   5653     }
   5654 
   5655     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
   5656         String name = uri.getAuthority();
   5657         ContentProviderHolder cph = getContentProviderExternal(name);
   5658         ParcelFileDescriptor pfd = null;
   5659         if (cph != null) {
   5660             // We record the binder invoker's uid in thread-local storage before
   5661             // going to the content provider to open the file.  Later, in the code
   5662             // that handles all permissions checks, we look for this uid and use
   5663             // that rather than the Activity Manager's own uid.  The effect is that
   5664             // we do the check against the caller's permissions even though it looks
   5665             // to the content provider like the Activity Manager itself is making
   5666             // the request.
   5667             sCallerIdentity.set(new Identity(
   5668                     Binder.getCallingPid(), Binder.getCallingUid()));
   5669             try {
   5670                 pfd = cph.provider.openFile(uri, "r");
   5671             } catch (FileNotFoundException e) {
   5672                 // do nothing; pfd will be returned null
   5673             } finally {
   5674                 // Ensure that whatever happens, we clean up the identity state
   5675                 sCallerIdentity.remove();
   5676             }
   5677 
   5678             // We've got the fd now, so we're done with the provider.
   5679             removeContentProviderExternal(name);
   5680         } else {
   5681             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
   5682         }
   5683         return pfd;
   5684     }
   5685 
   5686     public void goingToSleep() {
   5687         synchronized(this) {
   5688             mSleeping = true;
   5689             mWindowManager.setEventDispatching(false);
   5690 
   5691             if (mMainStack.mResumedActivity != null) {
   5692                 mMainStack.pauseIfSleepingLocked();
   5693             } else {
   5694                 Slog.w(TAG, "goingToSleep with no resumed activity!");
   5695             }
   5696 
   5697             // Initialize the wake times of all processes.
   5698             checkExcessivePowerUsageLocked(false);
   5699             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   5700             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   5701             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   5702         }
   5703     }
   5704 
   5705     public boolean shutdown(int timeout) {
   5706         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
   5707                 != PackageManager.PERMISSION_GRANTED) {
   5708             throw new SecurityException("Requires permission "
   5709                     + android.Manifest.permission.SHUTDOWN);
   5710         }
   5711 
   5712         boolean timedout = false;
   5713 
   5714         synchronized(this) {
   5715             mShuttingDown = true;
   5716             mWindowManager.setEventDispatching(false);
   5717 
   5718             if (mMainStack.mResumedActivity != null) {
   5719                 mMainStack.pauseIfSleepingLocked();
   5720                 final long endTime = System.currentTimeMillis() + timeout;
   5721                 while (mMainStack.mResumedActivity != null
   5722                         || mMainStack.mPausingActivity != null) {
   5723                     long delay = endTime - System.currentTimeMillis();
   5724                     if (delay <= 0) {
   5725                         Slog.w(TAG, "Activity manager shutdown timed out");
   5726                         timedout = true;
   5727                         break;
   5728                     }
   5729                     try {
   5730                         this.wait();
   5731                     } catch (InterruptedException e) {
   5732                     }
   5733                 }
   5734             }
   5735         }
   5736 
   5737         mUsageStatsService.shutdown();
   5738         mBatteryStatsService.shutdown();
   5739 
   5740         return timedout;
   5741     }
   5742 
   5743     public void wakingUp() {
   5744         synchronized(this) {
   5745             if (mMainStack.mGoingToSleep.isHeld()) {
   5746                 mMainStack.mGoingToSleep.release();
   5747             }
   5748             mWindowManager.setEventDispatching(true);
   5749             mSleeping = false;
   5750             mMainStack.resumeTopActivityLocked(null);
   5751         }
   5752     }
   5753 
   5754     public void stopAppSwitches() {
   5755         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   5756                 != PackageManager.PERMISSION_GRANTED) {
   5757             throw new SecurityException("Requires permission "
   5758                     + android.Manifest.permission.STOP_APP_SWITCHES);
   5759         }
   5760 
   5761         synchronized(this) {
   5762             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
   5763                     + APP_SWITCH_DELAY_TIME;
   5764             mDidAppSwitch = false;
   5765             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   5766             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   5767             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
   5768         }
   5769     }
   5770 
   5771     public void resumeAppSwitches() {
   5772         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   5773                 != PackageManager.PERMISSION_GRANTED) {
   5774             throw new SecurityException("Requires permission "
   5775                     + android.Manifest.permission.STOP_APP_SWITCHES);
   5776         }
   5777 
   5778         synchronized(this) {
   5779             // Note that we don't execute any pending app switches... we will
   5780             // let those wait until either the timeout, or the next start
   5781             // activity request.
   5782             mAppSwitchesAllowedTime = 0;
   5783         }
   5784     }
   5785 
   5786     boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
   5787             String name) {
   5788         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
   5789             return true;
   5790         }
   5791 
   5792         final int perm = checkComponentPermission(
   5793                 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
   5794                 callingUid, -1);
   5795         if (perm == PackageManager.PERMISSION_GRANTED) {
   5796             return true;
   5797         }
   5798 
   5799         Slog.w(TAG, name + " request from " + callingUid + " stopped");
   5800         return false;
   5801     }
   5802 
   5803     public void setDebugApp(String packageName, boolean waitForDebugger,
   5804             boolean persistent) {
   5805         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
   5806                 "setDebugApp()");
   5807 
   5808         // Note that this is not really thread safe if there are multiple
   5809         // callers into it at the same time, but that's not a situation we
   5810         // care about.
   5811         if (persistent) {
   5812             final ContentResolver resolver = mContext.getContentResolver();
   5813             Settings.System.putString(
   5814                 resolver, Settings.System.DEBUG_APP,
   5815                 packageName);
   5816             Settings.System.putInt(
   5817                 resolver, Settings.System.WAIT_FOR_DEBUGGER,
   5818                 waitForDebugger ? 1 : 0);
   5819         }
   5820 
   5821         synchronized (this) {
   5822             if (!persistent) {
   5823                 mOrigDebugApp = mDebugApp;
   5824                 mOrigWaitForDebugger = mWaitForDebugger;
   5825             }
   5826             mDebugApp = packageName;
   5827             mWaitForDebugger = waitForDebugger;
   5828             mDebugTransient = !persistent;
   5829             if (packageName != null) {
   5830                 final long origId = Binder.clearCallingIdentity();
   5831                 forceStopPackageLocked(packageName, -1, false, false, true);
   5832                 Binder.restoreCallingIdentity(origId);
   5833             }
   5834         }
   5835     }
   5836 
   5837     public void setAlwaysFinish(boolean enabled) {
   5838         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
   5839                 "setAlwaysFinish()");
   5840 
   5841         Settings.System.putInt(
   5842                 mContext.getContentResolver(),
   5843                 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
   5844 
   5845         synchronized (this) {
   5846             mAlwaysFinishActivities = enabled;
   5847         }
   5848     }
   5849 
   5850     public void setActivityController(IActivityController controller) {
   5851         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   5852                 "setActivityController()");
   5853         synchronized (this) {
   5854             mController = controller;
   5855         }
   5856     }
   5857 
   5858     public boolean isUserAMonkey() {
   5859         // For now the fact that there is a controller implies
   5860         // we have a monkey.
   5861         synchronized (this) {
   5862             return mController != null;
   5863         }
   5864     }
   5865 
   5866     public void registerActivityWatcher(IActivityWatcher watcher) {
   5867         synchronized (this) {
   5868             mWatchers.register(watcher);
   5869         }
   5870     }
   5871 
   5872     public void unregisterActivityWatcher(IActivityWatcher watcher) {
   5873         synchronized (this) {
   5874             mWatchers.unregister(watcher);
   5875         }
   5876     }
   5877 
   5878     public final void enterSafeMode() {
   5879         synchronized(this) {
   5880             // It only makes sense to do this before the system is ready
   5881             // and started launching other packages.
   5882             if (!mSystemReady) {
   5883                 try {
   5884                     AppGlobals.getPackageManager().enterSafeMode();
   5885                 } catch (RemoteException e) {
   5886                 }
   5887 
   5888                 View v = LayoutInflater.from(mContext).inflate(
   5889                         com.android.internal.R.layout.safe_mode, null);
   5890                 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
   5891                 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
   5892                 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
   5893                 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
   5894                 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
   5895                 lp.format = v.getBackground().getOpacity();
   5896                 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
   5897                         | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
   5898                 ((WindowManager)mContext.getSystemService(
   5899                         Context.WINDOW_SERVICE)).addView(v, lp);
   5900             }
   5901         }
   5902     }
   5903 
   5904     public void noteWakeupAlarm(IIntentSender sender) {
   5905         if (!(sender instanceof PendingIntentRecord)) {
   5906             return;
   5907         }
   5908         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   5909         synchronized (stats) {
   5910             if (mBatteryStatsService.isOnBattery()) {
   5911                 mBatteryStatsService.enforceCallingPermission();
   5912                 PendingIntentRecord rec = (PendingIntentRecord)sender;
   5913                 int MY_UID = Binder.getCallingUid();
   5914                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
   5915                 BatteryStatsImpl.Uid.Pkg pkg =
   5916                     stats.getPackageStatsLocked(uid, rec.key.packageName);
   5917                 pkg.incWakeupsLocked();
   5918             }
   5919         }
   5920     }
   5921 
   5922     public boolean killPids(int[] pids, String pReason) {
   5923         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   5924             throw new SecurityException("killPids only available to the system");
   5925         }
   5926         String reason = (pReason == null) ? "Unknown" : pReason;
   5927         // XXX Note: don't acquire main activity lock here, because the window
   5928         // manager calls in with its locks held.
   5929 
   5930         boolean killed = false;
   5931         synchronized (mPidsSelfLocked) {
   5932             int[] types = new int[pids.length];
   5933             int worstType = 0;
   5934             for (int i=0; i<pids.length; i++) {
   5935                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   5936                 if (proc != null) {
   5937                     int type = proc.setAdj;
   5938                     types[i] = type;
   5939                     if (type > worstType) {
   5940                         worstType = type;
   5941                     }
   5942                 }
   5943             }
   5944 
   5945             // If the worse oom_adj is somewhere in the hidden proc LRU range,
   5946             // then constrain it so we will kill all hidden procs.
   5947             if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
   5948                 worstType = HIDDEN_APP_MIN_ADJ;
   5949             }
   5950             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
   5951             for (int i=0; i<pids.length; i++) {
   5952                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   5953                 if (proc == null) {
   5954                     continue;
   5955                 }
   5956                 int adj = proc.setAdj;
   5957                 if (adj >= worstType && !proc.killedBackground) {
   5958                     Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
   5959                     EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
   5960                             proc.processName, adj, reason);
   5961                     killed = true;
   5962                     proc.killedBackground = true;
   5963                     Process.killProcessQuiet(pids[i]);
   5964                 }
   5965             }
   5966         }
   5967         return killed;
   5968     }
   5969 
   5970     public final void startRunning(String pkg, String cls, String action,
   5971             String data) {
   5972         synchronized(this) {
   5973             if (mStartRunning) {
   5974                 return;
   5975             }
   5976             mStartRunning = true;
   5977             mTopComponent = pkg != null && cls != null
   5978                     ? new ComponentName(pkg, cls) : null;
   5979             mTopAction = action != null ? action : Intent.ACTION_MAIN;
   5980             mTopData = data;
   5981             if (!mSystemReady) {
   5982                 return;
   5983             }
   5984         }
   5985 
   5986         systemReady(null);
   5987     }
   5988 
   5989     private void retrieveSettings() {
   5990         final ContentResolver resolver = mContext.getContentResolver();
   5991         String debugApp = Settings.System.getString(
   5992             resolver, Settings.System.DEBUG_APP);
   5993         boolean waitForDebugger = Settings.System.getInt(
   5994             resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
   5995         boolean alwaysFinishActivities = Settings.System.getInt(
   5996             resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
   5997 
   5998         Configuration configuration = new Configuration();
   5999         Settings.System.getConfiguration(resolver, configuration);
   6000 
   6001         synchronized (this) {
   6002             mDebugApp = mOrigDebugApp = debugApp;
   6003             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
   6004             mAlwaysFinishActivities = alwaysFinishActivities;
   6005             // This happens before any activities are started, so we can
   6006             // change mConfiguration in-place.
   6007             mConfiguration.updateFrom(configuration);
   6008             mConfigurationSeq = mConfiguration.seq = 1;
   6009             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
   6010         }
   6011     }
   6012 
   6013     public boolean testIsSystemReady() {
   6014         // no need to synchronize(this) just to read & return the value
   6015         return mSystemReady;
   6016     }
   6017 
   6018     private static File getCalledPreBootReceiversFile() {
   6019         File dataDir = Environment.getDataDirectory();
   6020         File systemDir = new File(dataDir, "system");
   6021         File fname = new File(systemDir, "called_pre_boots.dat");
   6022         return fname;
   6023     }
   6024 
   6025     private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
   6026         ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
   6027         File file = getCalledPreBootReceiversFile();
   6028         FileInputStream fis = null;
   6029         try {
   6030             fis = new FileInputStream(file);
   6031             DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
   6032             int vers = dis.readInt();
   6033             String codename = dis.readUTF();
   6034             if (vers == android.os.Build.VERSION.SDK_INT
   6035                     && codename.equals(android.os.Build.VERSION.CODENAME)) {
   6036                 int num = dis.readInt();
   6037                 while (num > 0) {
   6038                     num--;
   6039                     String pkg = dis.readUTF();
   6040                     String cls = dis.readUTF();
   6041                     lastDoneReceivers.add(new ComponentName(pkg, cls));
   6042                 }
   6043             }
   6044         } catch (FileNotFoundException e) {
   6045         } catch (IOException e) {
   6046             Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
   6047         } finally {
   6048             if (fis != null) {
   6049                 try {
   6050                     fis.close();
   6051                 } catch (IOException e) {
   6052                 }
   6053             }
   6054         }
   6055         return lastDoneReceivers;
   6056     }
   6057 
   6058     private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
   6059         File file = getCalledPreBootReceiversFile();
   6060         FileOutputStream fos = null;
   6061         DataOutputStream dos = null;
   6062         try {
   6063             Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
   6064             fos = new FileOutputStream(file);
   6065             dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
   6066             dos.writeInt(android.os.Build.VERSION.SDK_INT);
   6067             dos.writeUTF(android.os.Build.VERSION.CODENAME);
   6068             dos.writeInt(list.size());
   6069             for (int i=0; i<list.size(); i++) {
   6070                 dos.writeUTF(list.get(i).getPackageName());
   6071                 dos.writeUTF(list.get(i).getClassName());
   6072             }
   6073         } catch (IOException e) {
   6074             Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
   6075             file.delete();
   6076         } finally {
   6077             FileUtils.sync(fos);
   6078             if (dos != null) {
   6079                 try {
   6080                     dos.close();
   6081                 } catch (IOException e) {
   6082                     // TODO Auto-generated catch block
   6083                     e.printStackTrace();
   6084                 }
   6085             }
   6086         }
   6087     }
   6088 
   6089     public void systemReady(final Runnable goingCallback) {
   6090         // In the simulator, startRunning will never have been called, which
   6091         // normally sets a few crucial variables. Do it here instead.
   6092         if (!Process.supportsProcesses()) {
   6093             mStartRunning = true;
   6094             mTopAction = Intent.ACTION_MAIN;
   6095         }
   6096 
   6097         synchronized(this) {
   6098             if (mSystemReady) {
   6099                 if (goingCallback != null) goingCallback.run();
   6100                 return;
   6101             }
   6102 
   6103             // Check to see if there are any update receivers to run.
   6104             if (!mDidUpdate) {
   6105                 if (mWaitingUpdate) {
   6106                     return;
   6107                 }
   6108                 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
   6109                 List<ResolveInfo> ris = null;
   6110                 try {
   6111                     ris = AppGlobals.getPackageManager().queryIntentReceivers(
   6112                                 intent, null, 0);
   6113                 } catch (RemoteException e) {
   6114                 }
   6115                 if (ris != null) {
   6116                     for (int i=ris.size()-1; i>=0; i--) {
   6117                         if ((ris.get(i).activityInfo.applicationInfo.flags
   6118                                 &ApplicationInfo.FLAG_SYSTEM) == 0) {
   6119                             ris.remove(i);
   6120                         }
   6121                     }
   6122                     intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
   6123 
   6124                     ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
   6125 
   6126                     final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
   6127                     for (int i=0; i<ris.size(); i++) {
   6128                         ActivityInfo ai = ris.get(i).activityInfo;
   6129                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
   6130                         if (lastDoneReceivers.contains(comp)) {
   6131                             ris.remove(i);
   6132                             i--;
   6133                         }
   6134                     }
   6135 
   6136                     for (int i=0; i<ris.size(); i++) {
   6137                         ActivityInfo ai = ris.get(i).activityInfo;
   6138                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
   6139                         doneReceivers.add(comp);
   6140                         intent.setComponent(comp);
   6141                         IIntentReceiver finisher = null;
   6142                         if (i == ris.size()-1) {
   6143                             finisher = new IIntentReceiver.Stub() {
   6144                                 public void performReceive(Intent intent, int resultCode,
   6145                                         String data, Bundle extras, boolean ordered,
   6146                                         boolean sticky) {
   6147                                     // The raw IIntentReceiver interface is called
   6148                                     // with the AM lock held, so redispatch to
   6149                                     // execute our code without the lock.
   6150                                     mHandler.post(new Runnable() {
   6151                                         public void run() {
   6152                                             synchronized (ActivityManagerService.this) {
   6153                                                 mDidUpdate = true;
   6154                                             }
   6155                                             writeLastDonePreBootReceivers(doneReceivers);
   6156                                             systemReady(goingCallback);
   6157                                         }
   6158                                     });
   6159                                 }
   6160                             };
   6161                         }
   6162                         Slog.i(TAG, "Sending system update to: " + intent.getComponent());
   6163                         broadcastIntentLocked(null, null, intent, null, finisher,
   6164                                 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
   6165                         if (finisher != null) {
   6166                             mWaitingUpdate = true;
   6167                         }
   6168                     }
   6169                 }
   6170                 if (mWaitingUpdate) {
   6171                     return;
   6172                 }
   6173                 mDidUpdate = true;
   6174             }
   6175 
   6176             mSystemReady = true;
   6177             if (!mStartRunning) {
   6178                 return;
   6179             }
   6180         }
   6181 
   6182         ArrayList<ProcessRecord> procsToKill = null;
   6183         synchronized(mPidsSelfLocked) {
   6184             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
   6185                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   6186                 if (!isAllowedWhileBooting(proc.info)){
   6187                     if (procsToKill == null) {
   6188                         procsToKill = new ArrayList<ProcessRecord>();
   6189                     }
   6190                     procsToKill.add(proc);
   6191                 }
   6192             }
   6193         }
   6194 
   6195         synchronized(this) {
   6196             if (procsToKill != null) {
   6197                 for (int i=procsToKill.size()-1; i>=0; i--) {
   6198                     ProcessRecord proc = procsToKill.get(i);
   6199                     Slog.i(TAG, "Removing system update proc: " + proc);
   6200                     removeProcessLocked(proc, true);
   6201                 }
   6202             }
   6203 
   6204             // Now that we have cleaned up any update processes, we
   6205             // are ready to start launching real processes and know that
   6206             // we won't trample on them any more.
   6207             mProcessesReady = true;
   6208         }
   6209 
   6210         Slog.i(TAG, "System now ready");
   6211         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
   6212             SystemClock.uptimeMillis());
   6213 
   6214         synchronized(this) {
   6215             // Make sure we have no pre-ready processes sitting around.
   6216 
   6217             if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
   6218                 ResolveInfo ri = mContext.getPackageManager()
   6219                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
   6220                                 STOCK_PM_FLAGS);
   6221                 CharSequence errorMsg = null;
   6222                 if (ri != null) {
   6223                     ActivityInfo ai = ri.activityInfo;
   6224                     ApplicationInfo app = ai.applicationInfo;
   6225                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   6226                         mTopAction = Intent.ACTION_FACTORY_TEST;
   6227                         mTopData = null;
   6228                         mTopComponent = new ComponentName(app.packageName,
   6229                                 ai.name);
   6230                     } else {
   6231                         errorMsg = mContext.getResources().getText(
   6232                                 com.android.internal.R.string.factorytest_not_system);
   6233                     }
   6234                 } else {
   6235                     errorMsg = mContext.getResources().getText(
   6236                             com.android.internal.R.string.factorytest_no_action);
   6237                 }
   6238                 if (errorMsg != null) {
   6239                     mTopAction = null;
   6240                     mTopData = null;
   6241                     mTopComponent = null;
   6242                     Message msg = Message.obtain();
   6243                     msg.what = SHOW_FACTORY_ERROR_MSG;
   6244                     msg.getData().putCharSequence("msg", errorMsg);
   6245                     mHandler.sendMessage(msg);
   6246                 }
   6247             }
   6248         }
   6249 
   6250         retrieveSettings();
   6251 
   6252         if (goingCallback != null) goingCallback.run();
   6253 
   6254         synchronized (this) {
   6255             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   6256                 try {
   6257                     List apps = AppGlobals.getPackageManager().
   6258                         getPersistentApplications(STOCK_PM_FLAGS);
   6259                     if (apps != null) {
   6260                         int N = apps.size();
   6261                         int i;
   6262                         for (i=0; i<N; i++) {
   6263                             ApplicationInfo info
   6264                                 = (ApplicationInfo)apps.get(i);
   6265                             if (info != null &&
   6266                                     !info.packageName.equals("android")) {
   6267                                 addAppLocked(info);
   6268                             }
   6269                         }
   6270                     }
   6271                 } catch (RemoteException ex) {
   6272                     // pm is in same process, this will never happen.
   6273                 }
   6274             }
   6275 
   6276             // Start up initial activity.
   6277             mBooting = true;
   6278 
   6279             try {
   6280                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
   6281                     Message msg = Message.obtain();
   6282                     msg.what = SHOW_UID_ERROR_MSG;
   6283                     mHandler.sendMessage(msg);
   6284                 }
   6285             } catch (RemoteException e) {
   6286             }
   6287 
   6288             mMainStack.resumeTopActivityLocked(null);
   6289         }
   6290     }
   6291 
   6292     private boolean makeAppCrashingLocked(ProcessRecord app,
   6293             String shortMsg, String longMsg, String stackTrace) {
   6294         app.crashing = true;
   6295         app.crashingReport = generateProcessError(app,
   6296                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
   6297         startAppProblemLocked(app);
   6298         app.stopFreezingAllLocked();
   6299         return handleAppCrashLocked(app);
   6300     }
   6301 
   6302     private void makeAppNotRespondingLocked(ProcessRecord app,
   6303             String activity, String shortMsg, String longMsg) {
   6304         app.notResponding = true;
   6305         app.notRespondingReport = generateProcessError(app,
   6306                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
   6307                 activity, shortMsg, longMsg, null);
   6308         startAppProblemLocked(app);
   6309         app.stopFreezingAllLocked();
   6310     }
   6311 
   6312     /**
   6313      * Generate a process error record, suitable for attachment to a ProcessRecord.
   6314      *
   6315      * @param app The ProcessRecord in which the error occurred.
   6316      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
   6317      *                      ActivityManager.AppErrorStateInfo
   6318      * @param activity The activity associated with the crash, if known.
   6319      * @param shortMsg Short message describing the crash.
   6320      * @param longMsg Long message describing the crash.
   6321      * @param stackTrace Full crash stack trace, may be null.
   6322      *
   6323      * @return Returns a fully-formed AppErrorStateInfo record.
   6324      */
   6325     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
   6326             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
   6327         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
   6328 
   6329         report.condition = condition;
   6330         report.processName = app.processName;
   6331         report.pid = app.pid;
   6332         report.uid = app.info.uid;
   6333         report.tag = activity;
   6334         report.shortMsg = shortMsg;
   6335         report.longMsg = longMsg;
   6336         report.stackTrace = stackTrace;
   6337 
   6338         return report;
   6339     }
   6340 
   6341     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
   6342         synchronized (this) {
   6343             app.crashing = false;
   6344             app.crashingReport = null;
   6345             app.notResponding = false;
   6346             app.notRespondingReport = null;
   6347             if (app.anrDialog == fromDialog) {
   6348                 app.anrDialog = null;
   6349             }
   6350             if (app.waitDialog == fromDialog) {
   6351                 app.waitDialog = null;
   6352             }
   6353             if (app.pid > 0 && app.pid != MY_PID) {
   6354                 handleAppCrashLocked(app);
   6355                 Slog.i(ActivityManagerService.TAG, "Killing "
   6356                         + app.processName + " (pid=" + app.pid + "): user's request");
   6357                 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   6358                         app.processName, app.setAdj, "user's request after error");
   6359                 Process.killProcess(app.pid);
   6360             }
   6361         }
   6362     }
   6363 
   6364     private boolean handleAppCrashLocked(ProcessRecord app) {
   6365         long now = SystemClock.uptimeMillis();
   6366 
   6367         Long crashTime = mProcessCrashTimes.get(app.info.processName,
   6368                 app.info.uid);
   6369         if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
   6370             // This process loses!
   6371             Slog.w(TAG, "Process " + app.info.processName
   6372                     + " has crashed too many times: killing!");
   6373             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
   6374                     app.info.processName, app.info.uid);
   6375             killServicesLocked(app, false);
   6376             for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
   6377                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   6378                 if (r.app == app) {
   6379                     Slog.w(TAG, "  Force finishing activity "
   6380                         + r.intent.getComponent().flattenToShortString());
   6381                     r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
   6382                 }
   6383             }
   6384             if (!app.persistent) {
   6385                 // We don't want to start this process again until the user
   6386                 // explicitly does so...  but for persistent process, we really
   6387                 // need to keep it running.  If a persistent process is actually
   6388                 // repeatedly crashing, then badness for everyone.
   6389                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
   6390                         app.info.processName);
   6391                 mBadProcesses.put(app.info.processName, app.info.uid, now);
   6392                 app.bad = true;
   6393                 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
   6394                 app.removed = true;
   6395                 removeProcessLocked(app, false);
   6396                 return false;
   6397             }
   6398         } else {
   6399             ActivityRecord r = mMainStack.topRunningActivityLocked(null);
   6400             if (r.app == app) {
   6401                 // If the top running activity is from this crashing
   6402                 // process, then terminate it to avoid getting in a loop.
   6403                 Slog.w(TAG, "  Force finishing activity "
   6404                         + r.intent.getComponent().flattenToShortString());
   6405                 int index = mMainStack.indexOfTokenLocked(r);
   6406                 r.stack.finishActivityLocked(r, index,
   6407                         Activity.RESULT_CANCELED, null, "crashed");
   6408                 // Also terminate an activities below it that aren't yet
   6409                 // stopped, to avoid a situation where one will get
   6410                 // re-start our crashing activity once it gets resumed again.
   6411                 index--;
   6412                 if (index >= 0) {
   6413                     r = (ActivityRecord)mMainStack.mHistory.get(index);
   6414                     if (r.state == ActivityState.RESUMED
   6415                             || r.state == ActivityState.PAUSING
   6416                             || r.state == ActivityState.PAUSED) {
   6417                         if (!r.isHomeActivity) {
   6418                             Slog.w(TAG, "  Force finishing activity "
   6419                                     + r.intent.getComponent().flattenToShortString());
   6420                             r.stack.finishActivityLocked(r, index,
   6421                                     Activity.RESULT_CANCELED, null, "crashed");
   6422                         }
   6423                     }
   6424                 }
   6425             }
   6426         }
   6427 
   6428         // Bump up the crash count of any services currently running in the proc.
   6429         if (app.services.size() != 0) {
   6430             // Any services running in the application need to be placed
   6431             // back in the pending list.
   6432             Iterator<ServiceRecord> it = app.services.iterator();
   6433             while (it.hasNext()) {
   6434                 ServiceRecord sr = it.next();
   6435                 sr.crashCount++;
   6436             }
   6437         }
   6438 
   6439         mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
   6440         return true;
   6441     }
   6442 
   6443     void startAppProblemLocked(ProcessRecord app) {
   6444         app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
   6445                 mContext, app.info.packageName, app.info.flags);
   6446         skipCurrentReceiverLocked(app);
   6447     }
   6448 
   6449     void skipCurrentReceiverLocked(ProcessRecord app) {
   6450         boolean reschedule = false;
   6451         BroadcastRecord r = app.curReceiver;
   6452         if (r != null) {
   6453             // The current broadcast is waiting for this app's receiver
   6454             // to be finished.  Looks like that's not going to happen, so
   6455             // let the broadcast continue.
   6456             logBroadcastReceiverDiscardLocked(r);
   6457             finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
   6458                     r.resultExtras, r.resultAbort, true);
   6459             reschedule = true;
   6460         }
   6461         r = mPendingBroadcast;
   6462         if (r != null && r.curApp == app) {
   6463             if (DEBUG_BROADCAST) Slog.v(TAG,
   6464                     "skip & discard pending app " + r);
   6465             logBroadcastReceiverDiscardLocked(r);
   6466             finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
   6467                     r.resultExtras, r.resultAbort, true);
   6468             reschedule = true;
   6469         }
   6470         if (reschedule) {
   6471             scheduleBroadcastsLocked();
   6472         }
   6473     }
   6474 
   6475     /**
   6476      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
   6477      * The application process will exit immediately after this call returns.
   6478      * @param app object of the crashing app, null for the system server
   6479      * @param crashInfo describing the exception
   6480      */
   6481     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
   6482         ProcessRecord r = findAppProcess(app);
   6483 
   6484         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
   6485                 app == null ? "system" : (r == null ? "unknown" : r.processName),
   6486                 r == null ? -1 : r.info.flags,
   6487                 crashInfo.exceptionClassName,
   6488                 crashInfo.exceptionMessage,
   6489                 crashInfo.throwFileName,
   6490                 crashInfo.throwLineNumber);
   6491 
   6492         addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
   6493 
   6494         crashApplication(r, crashInfo);
   6495     }
   6496 
   6497     public void handleApplicationStrictModeViolation(
   6498             IBinder app,
   6499             int violationMask,
   6500             StrictMode.ViolationInfo info) {
   6501         ProcessRecord r = findAppProcess(app);
   6502 
   6503         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
   6504             Integer stackFingerprint = info.crashInfo.stackTrace.hashCode();
   6505             boolean logIt = true;
   6506             synchronized (mAlreadyLoggedViolatedStacks) {
   6507                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
   6508                     logIt = false;
   6509                     // TODO: sub-sample into EventLog for these, with
   6510                     // the info.durationMillis?  Then we'd get
   6511                     // the relative pain numbers, without logging all
   6512                     // the stack traces repeatedly.  We'd want to do
   6513                     // likewise in the client code, which also does
   6514                     // dup suppression, before the Binder call.
   6515                 } else {
   6516                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
   6517                         mAlreadyLoggedViolatedStacks.clear();
   6518                     }
   6519                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
   6520                 }
   6521             }
   6522             if (logIt) {
   6523                 logStrictModeViolationToDropBox(r, info);
   6524             }
   6525         }
   6526 
   6527         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
   6528             AppErrorResult result = new AppErrorResult();
   6529             synchronized (this) {
   6530                 final long origId = Binder.clearCallingIdentity();
   6531 
   6532                 Message msg = Message.obtain();
   6533                 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
   6534                 HashMap<String, Object> data = new HashMap<String, Object>();
   6535                 data.put("result", result);
   6536                 data.put("app", r);
   6537                 data.put("violationMask", violationMask);
   6538                 data.put("info", info);
   6539                 msg.obj = data;
   6540                 mHandler.sendMessage(msg);
   6541 
   6542                 Binder.restoreCallingIdentity(origId);
   6543             }
   6544             int res = result.get();
   6545             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
   6546         }
   6547     }
   6548 
   6549     // Depending on the policy in effect, there could be a bunch of
   6550     // these in quick succession so we try to batch these together to
   6551     // minimize disk writes, number of dropbox entries, and maximize
   6552     // compression, by having more fewer, larger records.
   6553     private void logStrictModeViolationToDropBox(
   6554             ProcessRecord process,
   6555             StrictMode.ViolationInfo info) {
   6556         if (info == null) {
   6557             return;
   6558         }
   6559         final boolean isSystemApp = process == null ||
   6560                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
   6561                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
   6562         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
   6563         final DropBoxManager dbox = (DropBoxManager)
   6564                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   6565 
   6566         // Exit early if the dropbox isn't configured to accept this report type.
   6567         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   6568 
   6569         boolean bufferWasEmpty;
   6570         boolean needsFlush;
   6571         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
   6572         synchronized (sb) {
   6573             bufferWasEmpty = sb.length() == 0;
   6574             appendDropBoxProcessHeaders(process, sb);
   6575             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   6576             sb.append("System-App: ").append(isSystemApp).append("\n");
   6577             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
   6578             if (info.violationNumThisLoop != 0) {
   6579                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
   6580             }
   6581             if (info != null && info.durationMillis != -1) {
   6582                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
   6583             }
   6584             sb.append("\n");
   6585             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
   6586                 sb.append(info.crashInfo.stackTrace);
   6587             }
   6588             sb.append("\n");
   6589 
   6590             // Only buffer up to ~64k.  Various logging bits truncate
   6591             // things at 128k.
   6592             needsFlush = (sb.length() > 64 * 1024);
   6593         }
   6594 
   6595         // Flush immediately if the buffer's grown too large, or this
   6596         // is a non-system app.  Non-system apps are isolated with a
   6597         // different tag & policy and not batched.
   6598         //
   6599         // Batching is useful during internal testing with
   6600         // StrictMode settings turned up high.  Without batching,
   6601         // thousands of separate files could be created on boot.
   6602         if (!isSystemApp || needsFlush) {
   6603             new Thread("Error dump: " + dropboxTag) {
   6604                 @Override
   6605                 public void run() {
   6606                     String report;
   6607                     synchronized (sb) {
   6608                         report = sb.toString();
   6609                         sb.delete(0, sb.length());
   6610                         sb.trimToSize();
   6611                     }
   6612                     if (report.length() != 0) {
   6613                         dbox.addText(dropboxTag, report);
   6614                     }
   6615                 }
   6616             }.start();
   6617             return;
   6618         }
   6619 
   6620         // System app batching:
   6621         if (!bufferWasEmpty) {
   6622             // An existing dropbox-writing thread is outstanding, so
   6623             // we don't need to start it up.  The existing thread will
   6624             // catch the buffer appends we just did.
   6625             return;
   6626         }
   6627 
   6628         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
   6629         // (After this point, we shouldn't access AMS internal data structures.)
   6630         new Thread("Error dump: " + dropboxTag) {
   6631             @Override
   6632             public void run() {
   6633                 // 5 second sleep to let stacks arrive and be batched together
   6634                 try {
   6635                     Thread.sleep(5000);  // 5 seconds
   6636                 } catch (InterruptedException e) {}
   6637 
   6638                 String errorReport;
   6639                 synchronized (mStrictModeBuffer) {
   6640                     errorReport = mStrictModeBuffer.toString();
   6641                     if (errorReport.length() == 0) {
   6642                         return;
   6643                     }
   6644                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
   6645                     mStrictModeBuffer.trimToSize();
   6646                 }
   6647                 dbox.addText(dropboxTag, errorReport);
   6648             }
   6649         }.start();
   6650     }
   6651 
   6652     /**
   6653      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
   6654      * @param app object of the crashing app, null for the system server
   6655      * @param tag reported by the caller
   6656      * @param crashInfo describing the context of the error
   6657      * @return true if the process should exit immediately (WTF is fatal)
   6658      */
   6659     public boolean handleApplicationWtf(IBinder app, String tag,
   6660             ApplicationErrorReport.CrashInfo crashInfo) {
   6661         ProcessRecord r = findAppProcess(app);
   6662 
   6663         EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
   6664                 app == null ? "system" : (r == null ? "unknown" : r.processName),
   6665                 r == null ? -1 : r.info.flags,
   6666                 tag, crashInfo.exceptionMessage);
   6667 
   6668         addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
   6669 
   6670         if (r != null && r.pid != Process.myPid() &&
   6671                 Settings.Secure.getInt(mContext.getContentResolver(),
   6672                         Settings.Secure.WTF_IS_FATAL, 0) != 0) {
   6673             crashApplication(r, crashInfo);
   6674             return true;
   6675         } else {
   6676             return false;
   6677         }
   6678     }
   6679 
   6680     /**
   6681      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
   6682      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
   6683      */
   6684     private ProcessRecord findAppProcess(IBinder app) {
   6685         if (app == null) {
   6686             return null;
   6687         }
   6688 
   6689         synchronized (this) {
   6690             for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   6691                 final int NA = apps.size();
   6692                 for (int ia=0; ia<NA; ia++) {
   6693                     ProcessRecord p = apps.valueAt(ia);
   6694                     if (p.thread != null && p.thread.asBinder() == app) {
   6695                         return p;
   6696                     }
   6697                 }
   6698             }
   6699 
   6700             Slog.w(TAG, "Can't find mystery application: " + app);
   6701             return null;
   6702         }
   6703     }
   6704 
   6705     /**
   6706      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
   6707      * to append various headers to the dropbox log text.
   6708      */
   6709     private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
   6710         // Note: ProcessRecord 'process' is guarded by the service
   6711         // instance.  (notably process.pkgList, which could otherwise change
   6712         // concurrently during execution of this method)
   6713         synchronized (this) {
   6714             if (process == null || process.pid == MY_PID) {
   6715                 sb.append("Process: system_server\n");
   6716             } else {
   6717                 sb.append("Process: ").append(process.processName).append("\n");
   6718             }
   6719             if (process == null) {
   6720                 return;
   6721             }
   6722             int flags = process.info.flags;
   6723             IPackageManager pm = AppGlobals.getPackageManager();
   6724             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
   6725             for (String pkg : process.pkgList) {
   6726                 sb.append("Package: ").append(pkg);
   6727                 try {
   6728                     PackageInfo pi = pm.getPackageInfo(pkg, 0);
   6729                     if (pi != null) {
   6730                         sb.append(" v").append(pi.versionCode);
   6731                         if (pi.versionName != null) {
   6732                             sb.append(" (").append(pi.versionName).append(")");
   6733                         }
   6734                     }
   6735                 } catch (RemoteException e) {
   6736                     Slog.e(TAG, "Error getting package info: " + pkg, e);
   6737                 }
   6738                 sb.append("\n");
   6739             }
   6740         }
   6741     }
   6742 
   6743     private static String processClass(ProcessRecord process) {
   6744         if (process == null || process.pid == MY_PID) {
   6745             return "system_server";
   6746         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   6747             return "system_app";
   6748         } else {
   6749             return "data_app";
   6750         }
   6751     }
   6752 
   6753     /**
   6754      * Write a description of an error (crash, WTF, ANR) to the drop box.
   6755      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
   6756      * @param process which caused the error, null means the system server
   6757      * @param activity which triggered the error, null if unknown
   6758      * @param parent activity related to the error, null if unknown
   6759      * @param subject line related to the error, null if absent
   6760      * @param report in long form describing the error, null if absent
   6761      * @param logFile to include in the report, null if none
   6762      * @param crashInfo giving an application stack trace, null if absent
   6763      */
   6764     public void addErrorToDropBox(String eventType,
   6765             ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
   6766             final String report, final File logFile,
   6767             final ApplicationErrorReport.CrashInfo crashInfo) {
   6768         // NOTE -- this must never acquire the ActivityManagerService lock,
   6769         // otherwise the watchdog may be prevented from resetting the system.
   6770 
   6771         final String dropboxTag = processClass(process) + "_" + eventType;
   6772         final DropBoxManager dbox = (DropBoxManager)
   6773                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   6774 
   6775         // Exit early if the dropbox isn't configured to accept this report type.
   6776         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   6777 
   6778         final StringBuilder sb = new StringBuilder(1024);
   6779         appendDropBoxProcessHeaders(process, sb);
   6780         if (activity != null) {
   6781             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
   6782         }
   6783         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
   6784             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
   6785         }
   6786         if (parent != null && parent != activity) {
   6787             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
   6788         }
   6789         if (subject != null) {
   6790             sb.append("Subject: ").append(subject).append("\n");
   6791         }
   6792         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   6793         sb.append("\n");
   6794 
   6795         // Do the rest in a worker thread to avoid blocking the caller on I/O
   6796         // (After this point, we shouldn't access AMS internal data structures.)
   6797         Thread worker = new Thread("Error dump: " + dropboxTag) {
   6798             @Override
   6799             public void run() {
   6800                 if (report != null) {
   6801                     sb.append(report);
   6802                 }
   6803                 if (logFile != null) {
   6804                     try {
   6805                         sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
   6806                     } catch (IOException e) {
   6807                         Slog.e(TAG, "Error reading " + logFile, e);
   6808                     }
   6809                 }
   6810                 if (crashInfo != null && crashInfo.stackTrace != null) {
   6811                     sb.append(crashInfo.stackTrace);
   6812                 }
   6813 
   6814                 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
   6815                 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
   6816                 if (lines > 0) {
   6817                     sb.append("\n");
   6818 
   6819                     // Merge several logcat streams, and take the last N lines
   6820                     InputStreamReader input = null;
   6821                     try {
   6822                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
   6823                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
   6824                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
   6825 
   6826                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
   6827                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
   6828                         input = new InputStreamReader(logcat.getInputStream());
   6829 
   6830                         int num;
   6831                         char[] buf = new char[8192];
   6832                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
   6833                     } catch (IOException e) {
   6834                         Slog.e(TAG, "Error running logcat", e);
   6835                     } finally {
   6836                         if (input != null) try { input.close(); } catch (IOException e) {}
   6837                     }
   6838                 }
   6839 
   6840                 dbox.addText(dropboxTag, sb.toString());
   6841             }
   6842         };
   6843 
   6844         if (process == null || process.pid == MY_PID) {
   6845             worker.run();  // We may be about to die -- need to run this synchronously
   6846         } else {
   6847             worker.start();
   6848         }
   6849     }
   6850 
   6851     /**
   6852      * Bring up the "unexpected error" dialog box for a crashing app.
   6853      * Deal with edge cases (intercepts from instrumented applications,
   6854      * ActivityController, error intent receivers, that sort of thing).
   6855      * @param r the application crashing
   6856      * @param crashInfo describing the failure
   6857      */
   6858     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
   6859         long timeMillis = System.currentTimeMillis();
   6860         String shortMsg = crashInfo.exceptionClassName;
   6861         String longMsg = crashInfo.exceptionMessage;
   6862         String stackTrace = crashInfo.stackTrace;
   6863         if (shortMsg != null && longMsg != null) {
   6864             longMsg = shortMsg + ": " + longMsg;
   6865         } else if (shortMsg != null) {
   6866             longMsg = shortMsg;
   6867         }
   6868 
   6869         AppErrorResult result = new AppErrorResult();
   6870         synchronized (this) {
   6871             if (mController != null) {
   6872                 try {
   6873                     String name = r != null ? r.processName : null;
   6874                     int pid = r != null ? r.pid : Binder.getCallingPid();
   6875                     if (!mController.appCrashed(name, pid,
   6876                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
   6877                         Slog.w(TAG, "Force-killing crashed app " + name
   6878                                 + " at watcher's request");
   6879                         Process.killProcess(pid);
   6880                         return;
   6881                     }
   6882                 } catch (RemoteException e) {
   6883                     mController = null;
   6884                 }
   6885             }
   6886 
   6887             final long origId = Binder.clearCallingIdentity();
   6888 
   6889             // If this process is running instrumentation, finish it.
   6890             if (r != null && r.instrumentationClass != null) {
   6891                 Slog.w(TAG, "Error in app " + r.processName
   6892                       + " running instrumentation " + r.instrumentationClass + ":");
   6893                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
   6894                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
   6895                 Bundle info = new Bundle();
   6896                 info.putString("shortMsg", shortMsg);
   6897                 info.putString("longMsg", longMsg);
   6898                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
   6899                 Binder.restoreCallingIdentity(origId);
   6900                 return;
   6901             }
   6902 
   6903             // If we can't identify the process or it's already exceeded its crash quota,
   6904             // quit right away without showing a crash dialog.
   6905             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
   6906                 Binder.restoreCallingIdentity(origId);
   6907                 return;
   6908             }
   6909 
   6910             Message msg = Message.obtain();
   6911             msg.what = SHOW_ERROR_MSG;
   6912             HashMap data = new HashMap();
   6913             data.put("result", result);
   6914             data.put("app", r);
   6915             msg.obj = data;
   6916             mHandler.sendMessage(msg);
   6917 
   6918             Binder.restoreCallingIdentity(origId);
   6919         }
   6920 
   6921         int res = result.get();
   6922 
   6923         Intent appErrorIntent = null;
   6924         synchronized (this) {
   6925             if (r != null) {
   6926                 mProcessCrashTimes.put(r.info.processName, r.info.uid,
   6927                         SystemClock.uptimeMillis());
   6928             }
   6929             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
   6930                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
   6931             }
   6932         }
   6933 
   6934         if (appErrorIntent != null) {
   6935             try {
   6936                 mContext.startActivity(appErrorIntent);
   6937             } catch (ActivityNotFoundException e) {
   6938                 Slog.w(TAG, "bug report receiver dissappeared", e);
   6939             }
   6940         }
   6941     }
   6942 
   6943     Intent createAppErrorIntentLocked(ProcessRecord r,
   6944             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   6945         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
   6946         if (report == null) {
   6947             return null;
   6948         }
   6949         Intent result = new Intent(Intent.ACTION_APP_ERROR);
   6950         result.setComponent(r.errorReportReceiver);
   6951         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
   6952         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   6953         return result;
   6954     }
   6955 
   6956     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
   6957             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   6958         if (r.errorReportReceiver == null) {
   6959             return null;
   6960         }
   6961 
   6962         if (!r.crashing && !r.notResponding) {
   6963             return null;
   6964         }
   6965 
   6966         ApplicationErrorReport report = new ApplicationErrorReport();
   6967         report.packageName = r.info.packageName;
   6968         report.installerPackageName = r.errorReportReceiver.getPackageName();
   6969         report.processName = r.processName;
   6970         report.time = timeMillis;
   6971         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   6972 
   6973         if (r.crashing) {
   6974             report.type = ApplicationErrorReport.TYPE_CRASH;
   6975             report.crashInfo = crashInfo;
   6976         } else if (r.notResponding) {
   6977             report.type = ApplicationErrorReport.TYPE_ANR;
   6978             report.anrInfo = new ApplicationErrorReport.AnrInfo();
   6979 
   6980             report.anrInfo.activity = r.notRespondingReport.tag;
   6981             report.anrInfo.cause = r.notRespondingReport.shortMsg;
   6982             report.anrInfo.info = r.notRespondingReport.longMsg;
   6983         }
   6984 
   6985         return report;
   6986     }
   6987 
   6988     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
   6989         // assume our apps are happy - lazy create the list
   6990         List<ActivityManager.ProcessErrorStateInfo> errList = null;
   6991 
   6992         synchronized (this) {
   6993 
   6994             // iterate across all processes
   6995             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   6996                 ProcessRecord app = mLruProcesses.get(i);
   6997                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
   6998                     // This one's in trouble, so we'll generate a report for it
   6999                     // crashes are higher priority (in case there's a crash *and* an anr)
   7000                     ActivityManager.ProcessErrorStateInfo report = null;
   7001                     if (app.crashing) {
   7002                         report = app.crashingReport;
   7003                     } else if (app.notResponding) {
   7004                         report = app.notRespondingReport;
   7005                     }
   7006 
   7007                     if (report != null) {
   7008                         if (errList == null) {
   7009                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
   7010                         }
   7011                         errList.add(report);
   7012                     } else {
   7013                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
   7014                                 " crashing = " + app.crashing +
   7015                                 " notResponding = " + app.notResponding);
   7016                     }
   7017                 }
   7018             }
   7019         }
   7020 
   7021         return errList;
   7022     }
   7023 
   7024     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
   7025         // Lazy instantiation of list
   7026         List<ActivityManager.RunningAppProcessInfo> runList = null;
   7027         synchronized (this) {
   7028             // Iterate across all processes
   7029             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   7030                 ProcessRecord app = mLruProcesses.get(i);
   7031                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
   7032                     // Generate process state info for running application
   7033                     ActivityManager.RunningAppProcessInfo currApp =
   7034                         new ActivityManager.RunningAppProcessInfo(app.processName,
   7035                                 app.pid, app.getPackageList());
   7036                     currApp.uid = app.info.uid;
   7037                     if (mHeavyWeightProcess == app) {
   7038                         currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
   7039                     }
   7040                     if (app.persistent) {
   7041                         currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
   7042                     }
   7043                     int adj = app.curAdj;
   7044                     if (adj >= EMPTY_APP_ADJ) {
   7045                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
   7046                     } else if (adj >= HIDDEN_APP_MIN_ADJ) {
   7047                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   7048                         currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
   7049                     } else if (adj >= HOME_APP_ADJ) {
   7050                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   7051                         currApp.lru = 0;
   7052                     } else if (adj >= SECONDARY_SERVER_ADJ) {
   7053                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   7054                     } else if (adj >= HEAVY_WEIGHT_APP_ADJ) {
   7055                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
   7056                     } else if (adj >= PERCEPTIBLE_APP_ADJ) {
   7057                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
   7058                     } else if (adj >= VISIBLE_APP_ADJ) {
   7059                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
   7060                     } else {
   7061                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
   7062                     }
   7063                     currApp.importanceReasonCode = app.adjTypeCode;
   7064                     if (app.adjSource instanceof ProcessRecord) {
   7065                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
   7066                     } else if (app.adjSource instanceof ActivityRecord) {
   7067                         ActivityRecord r = (ActivityRecord)app.adjSource;
   7068                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
   7069                     }
   7070                     if (app.adjTarget instanceof ComponentName) {
   7071                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
   7072                     }
   7073                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
   7074                     //        + " lru=" + currApp.lru);
   7075                     if (runList == null) {
   7076                         runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
   7077                     }
   7078                     runList.add(currApp);
   7079                 }
   7080             }
   7081         }
   7082         return runList;
   7083     }
   7084 
   7085     public List<ApplicationInfo> getRunningExternalApplications() {
   7086         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
   7087         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
   7088         if (runningApps != null && runningApps.size() > 0) {
   7089             Set<String> extList = new HashSet<String>();
   7090             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
   7091                 if (app.pkgList != null) {
   7092                     for (String pkg : app.pkgList) {
   7093                         extList.add(pkg);
   7094                     }
   7095                 }
   7096             }
   7097             IPackageManager pm = AppGlobals.getPackageManager();
   7098             for (String pkg : extList) {
   7099                 try {
   7100                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
   7101                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
   7102                         retList.add(info);
   7103                     }
   7104                 } catch (RemoteException e) {
   7105                 }
   7106             }
   7107         }
   7108         return retList;
   7109     }
   7110 
   7111     @Override
   7112     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   7113         if (checkCallingPermission(android.Manifest.permission.DUMP)
   7114                 != PackageManager.PERMISSION_GRANTED) {
   7115             pw.println("Permission Denial: can't dump ActivityManager from from pid="
   7116                     + Binder.getCallingPid()
   7117                     + ", uid=" + Binder.getCallingUid()
   7118                     + " without permission "
   7119                     + android.Manifest.permission.DUMP);
   7120             return;
   7121         }
   7122 
   7123         boolean dumpAll = false;
   7124 
   7125         int opti = 0;
   7126         while (opti < args.length) {
   7127             String opt = args[opti];
   7128             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   7129                 break;
   7130             }
   7131             opti++;
   7132             if ("-a".equals(opt)) {
   7133                 dumpAll = true;
   7134             } else if ("-h".equals(opt)) {
   7135                 pw.println("Activity manager dump options:");
   7136                 pw.println("  [-a] [-h] [cmd] ...");
   7137                 pw.println("  cmd may be one of:");
   7138                 pw.println("    a[ctivities]: activity stack state");
   7139                 pw.println("    b[roadcasts]: broadcast state");
   7140                 pw.println("    i[ntents]: pending intent state");
   7141                 pw.println("    p[rocesses]: process state");
   7142                 pw.println("    o[om]: out of memory management");
   7143                 pw.println("    prov[iders]: content provider state");
   7144                 pw.println("    s[ervices]: service state");
   7145                 pw.println("    service [name]: service client-side state");
   7146                 return;
   7147             } else {
   7148                 pw.println("Unknown argument: " + opt + "; use -h for help");
   7149             }
   7150         }
   7151 
   7152         // Is the caller requesting to dump a particular piece of data?
   7153         if (opti < args.length) {
   7154             String cmd = args[opti];
   7155             opti++;
   7156             if ("activities".equals(cmd) || "a".equals(cmd)) {
   7157                 synchronized (this) {
   7158                     dumpActivitiesLocked(fd, pw, args, opti, true, true);
   7159                 }
   7160                 return;
   7161             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
   7162                 synchronized (this) {
   7163                     dumpBroadcastsLocked(fd, pw, args, opti, true);
   7164                 }
   7165                 return;
   7166             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
   7167                 synchronized (this) {
   7168                     dumpPendingIntentsLocked(fd, pw, args, opti, true);
   7169                 }
   7170                 return;
   7171             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
   7172                 synchronized (this) {
   7173                     dumpProcessesLocked(fd, pw, args, opti, true);
   7174                 }
   7175                 return;
   7176             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
   7177                 synchronized (this) {
   7178                     dumpOomLocked(fd, pw, args, opti, true);
   7179                 }
   7180                 return;
   7181             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
   7182                 synchronized (this) {
   7183                     dumpProvidersLocked(fd, pw, args, opti, true);
   7184                 }
   7185                 return;
   7186             } else if ("service".equals(cmd)) {
   7187                 dumpService(fd, pw, args, opti, dumpAll);
   7188                 return;
   7189             } else if ("services".equals(cmd) || "s".equals(cmd)) {
   7190                 synchronized (this) {
   7191                     dumpServicesLocked(fd, pw, args, opti, true);
   7192                 }
   7193                 return;
   7194             }
   7195         }
   7196 
   7197         // No piece of data specified, dump everything.
   7198         synchronized (this) {
   7199             boolean needSep;
   7200             if (dumpAll) {
   7201                 pw.println("Providers in Current Activity Manager State:");
   7202             }
   7203             needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
   7204             if (needSep) {
   7205                 pw.println(" ");
   7206             }
   7207             if (dumpAll) {
   7208                 pw.println("-------------------------------------------------------------------------------");
   7209                 pw.println("Broadcasts in Current Activity Manager State:");
   7210             }
   7211             needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
   7212             if (needSep) {
   7213                 pw.println(" ");
   7214             }
   7215             if (dumpAll) {
   7216                 pw.println("-------------------------------------------------------------------------------");
   7217                 pw.println("Services in Current Activity Manager State:");
   7218             }
   7219             needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll);
   7220             if (needSep) {
   7221                 pw.println(" ");
   7222             }
   7223             if (dumpAll) {
   7224                 pw.println("-------------------------------------------------------------------------------");
   7225                 pw.println("PendingIntents in Current Activity Manager State:");
   7226             }
   7227             needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
   7228             if (needSep) {
   7229                 pw.println(" ");
   7230             }
   7231             if (dumpAll) {
   7232                 pw.println("-------------------------------------------------------------------------------");
   7233                 pw.println("Activities in Current Activity Manager State:");
   7234             }
   7235             needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, !dumpAll);
   7236             if (needSep) {
   7237                 pw.println(" ");
   7238             }
   7239             if (dumpAll) {
   7240                 pw.println("-------------------------------------------------------------------------------");
   7241                 pw.println("Processes in Current Activity Manager State:");
   7242             }
   7243             dumpProcessesLocked(fd, pw, args, opti, dumpAll);
   7244         }
   7245     }
   7246 
   7247     boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   7248             int opti, boolean dumpAll, boolean needHeader) {
   7249         if (needHeader) {
   7250             pw.println("  Activity stack:");
   7251         }
   7252         dumpHistoryList(pw, mMainStack.mHistory, "  ", "Hist", true);
   7253         pw.println(" ");
   7254         pw.println("  Running activities (most recent first):");
   7255         dumpHistoryList(pw, mMainStack.mLRUActivities, "  ", "Run", false);
   7256         if (mMainStack.mWaitingVisibleActivities.size() > 0) {
   7257             pw.println(" ");
   7258             pw.println("  Activities waiting for another to become visible:");
   7259             dumpHistoryList(pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false);
   7260         }
   7261         if (mMainStack.mStoppingActivities.size() > 0) {
   7262             pw.println(" ");
   7263             pw.println("  Activities waiting to stop:");
   7264             dumpHistoryList(pw, mMainStack.mStoppingActivities, "  ", "Stop", false);
   7265         }
   7266         if (mMainStack.mFinishingActivities.size() > 0) {
   7267             pw.println(" ");
   7268             pw.println("  Activities waiting to finish:");
   7269             dumpHistoryList(pw, mMainStack.mFinishingActivities, "  ", "Fin", false);
   7270         }
   7271 
   7272         pw.println(" ");
   7273         pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
   7274         pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
   7275         pw.println("  mFocusedActivity: " + mFocusedActivity);
   7276         pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
   7277 
   7278         if (dumpAll && mRecentTasks.size() > 0) {
   7279             pw.println(" ");
   7280             pw.println("Recent tasks in Current Activity Manager State:");
   7281 
   7282             final int N = mRecentTasks.size();
   7283             for (int i=0; i<N; i++) {
   7284                 TaskRecord tr = mRecentTasks.get(i);
   7285                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
   7286                         pw.println(tr);
   7287                 mRecentTasks.get(i).dump(pw, "    ");
   7288             }
   7289         }
   7290 
   7291         pw.println(" ");
   7292         pw.println("  mCurTask: " + mCurTask);
   7293 
   7294         return true;
   7295     }
   7296 
   7297     boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   7298             int opti, boolean dumpAll) {
   7299         boolean needSep = false;
   7300         int numPers = 0;
   7301 
   7302         if (dumpAll) {
   7303             for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
   7304                 final int NA = procs.size();
   7305                 for (int ia=0; ia<NA; ia++) {
   7306                     if (!needSep) {
   7307                         pw.println("  All known processes:");
   7308                         needSep = true;
   7309                     }
   7310                     ProcessRecord r = procs.valueAt(ia);
   7311                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
   7312                         pw.print(" UID "); pw.print(procs.keyAt(ia));
   7313                         pw.print(" "); pw.println(r);
   7314                     r.dump(pw, "    ");
   7315                     if (r.persistent) {
   7316                         numPers++;
   7317                     }
   7318                 }
   7319             }
   7320         }
   7321 
   7322         if (mLruProcesses.size() > 0) {
   7323             if (needSep) pw.println(" ");
   7324             needSep = true;
   7325             pw.println("  Running processes (most recent first):");
   7326             dumpProcessOomList(pw, this, mLruProcesses, "    ",
   7327                     "Proc", "PERS", false);
   7328             needSep = true;
   7329         }
   7330 
   7331         synchronized (mPidsSelfLocked) {
   7332             if (mPidsSelfLocked.size() > 0) {
   7333                 if (needSep) pw.println(" ");
   7334                 needSep = true;
   7335                 pw.println("  PID mappings:");
   7336                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   7337                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
   7338                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
   7339                 }
   7340             }
   7341         }
   7342 
   7343         if (mForegroundProcesses.size() > 0) {
   7344             if (needSep) pw.println(" ");
   7345             needSep = true;
   7346             pw.println("  Foreground Processes:");
   7347             for (int i=0; i<mForegroundProcesses.size(); i++) {
   7348                 pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
   7349                         pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
   7350             }
   7351         }
   7352 
   7353         if (mPersistentStartingProcesses.size() > 0) {
   7354             if (needSep) pw.println(" ");
   7355             needSep = true;
   7356             pw.println("  Persisent processes that are starting:");
   7357             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
   7358                     "Starting Norm", "Restarting PERS");
   7359         }
   7360 
   7361         if (mStartingProcesses.size() > 0) {
   7362             if (needSep) pw.println(" ");
   7363             needSep = true;
   7364             pw.println("  Processes that are starting:");
   7365             dumpProcessList(pw, this, mStartingProcesses, "    ",
   7366                     "Starting Norm", "Starting PERS");
   7367         }
   7368 
   7369         if (mRemovedProcesses.size() > 0) {
   7370             if (needSep) pw.println(" ");
   7371             needSep = true;
   7372             pw.println("  Processes that are being removed:");
   7373             dumpProcessList(pw, this, mRemovedProcesses, "    ",
   7374                     "Removed Norm", "Removed PERS");
   7375         }
   7376 
   7377         if (mProcessesOnHold.size() > 0) {
   7378             if (needSep) pw.println(" ");
   7379             needSep = true;
   7380             pw.println("  Processes that are on old until the system is ready:");
   7381             dumpProcessList(pw, this, mProcessesOnHold, "    ",
   7382                     "OnHold Norm", "OnHold PERS");
   7383         }
   7384 
   7385         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
   7386 
   7387         if (mProcessCrashTimes.getMap().size() > 0) {
   7388             if (needSep) pw.println(" ");
   7389             needSep = true;
   7390             pw.println("  Time since processes crashed:");
   7391             long now = SystemClock.uptimeMillis();
   7392             for (Map.Entry<String, SparseArray<Long>> procs
   7393                     : mProcessCrashTimes.getMap().entrySet()) {
   7394                 SparseArray<Long> uids = procs.getValue();
   7395                 final int N = uids.size();
   7396                 for (int i=0; i<N; i++) {
   7397                     pw.print("    Process "); pw.print(procs.getKey());
   7398                             pw.print(" uid "); pw.print(uids.keyAt(i));
   7399                             pw.print(": last crashed ");
   7400                             pw.print((now-uids.valueAt(i)));
   7401                             pw.println(" ms ago");
   7402                 }
   7403             }
   7404         }
   7405 
   7406         if (mBadProcesses.getMap().size() > 0) {
   7407             if (needSep) pw.println(" ");
   7408             needSep = true;
   7409             pw.println("  Bad processes:");
   7410             for (Map.Entry<String, SparseArray<Long>> procs
   7411                     : mBadProcesses.getMap().entrySet()) {
   7412                 SparseArray<Long> uids = procs.getValue();
   7413                 final int N = uids.size();
   7414                 for (int i=0; i<N; i++) {
   7415                     pw.print("    Bad process "); pw.print(procs.getKey());
   7416                             pw.print(" uid "); pw.print(uids.keyAt(i));
   7417                             pw.print(": crashed at time ");
   7418                             pw.println(uids.valueAt(i));
   7419                 }
   7420             }
   7421         }
   7422 
   7423         pw.println(" ");
   7424         pw.println("  mHomeProcess: " + mHomeProcess);
   7425         if (mHeavyWeightProcess != null) {
   7426             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   7427         }
   7428         pw.println("  mConfiguration: " + mConfiguration);
   7429         pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
   7430         pw.println("  mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
   7431         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
   7432                 || mOrigWaitForDebugger) {
   7433             pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
   7434                     + " mDebugTransient=" + mDebugTransient
   7435                     + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
   7436         }
   7437         if (mAlwaysFinishActivities || mController != null) {
   7438             pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
   7439                     + " mController=" + mController);
   7440         }
   7441         if (dumpAll) {
   7442             pw.println("  Total persistent processes: " + numPers);
   7443             pw.println("  mStartRunning=" + mStartRunning
   7444                     + " mProcessesReady=" + mProcessesReady
   7445                     + " mSystemReady=" + mSystemReady);
   7446             pw.println("  mBooting=" + mBooting
   7447                     + " mBooted=" + mBooted
   7448                     + " mFactoryTest=" + mFactoryTest);
   7449             pw.print("  mLastPowerCheckRealtime=");
   7450                     TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
   7451                     pw.println("");
   7452             pw.print("  mLastPowerCheckUptime=");
   7453                     TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
   7454                     pw.println("");
   7455             pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
   7456             pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
   7457             pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
   7458         }
   7459 
   7460         return true;
   7461     }
   7462 
   7463     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
   7464             int opti, boolean needSep, boolean dumpAll) {
   7465         if (mProcessesToGc.size() > 0) {
   7466             if (needSep) pw.println(" ");
   7467             needSep = true;
   7468             pw.println("  Processes that are waiting to GC:");
   7469             long now = SystemClock.uptimeMillis();
   7470             for (int i=0; i<mProcessesToGc.size(); i++) {
   7471                 ProcessRecord proc = mProcessesToGc.get(i);
   7472                 pw.print("    Process "); pw.println(proc);
   7473                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
   7474                         pw.print(", last gced=");
   7475                         pw.print(now-proc.lastRequestedGc);
   7476                         pw.print(" ms ago, last lowMem=");
   7477                         pw.print(now-proc.lastLowMemory);
   7478                         pw.println(" ms ago");
   7479 
   7480             }
   7481         }
   7482         return needSep;
   7483     }
   7484 
   7485     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   7486             int opti, boolean dumpAll) {
   7487         boolean needSep = false;
   7488 
   7489         if (mLruProcesses.size() > 0) {
   7490             ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses);
   7491 
   7492             Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() {
   7493                 @Override
   7494                 public int compare(ProcessRecord object1, ProcessRecord object2) {
   7495                     if (object1.setAdj != object2.setAdj) {
   7496                         return object1.setAdj > object2.setAdj ? -1 : 1;
   7497                     }
   7498                     if (object1.setSchedGroup != object2.setSchedGroup) {
   7499                         return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1;
   7500                     }
   7501                     if (object1.keeping != object2.keeping) {
   7502                         return object1.keeping ? -1 : 1;
   7503                     }
   7504                     if (object1.pid != object2.pid) {
   7505                         return object1.pid > object2.pid ? -1 : 1;
   7506                     }
   7507                     return 0;
   7508                 }
   7509             };
   7510 
   7511             Collections.sort(procs, comparator);
   7512 
   7513             if (needSep) pw.println(" ");
   7514             needSep = true;
   7515             pw.println("  Process OOM control:");
   7516             dumpProcessOomList(pw, this, procs, "    ",
   7517                     "Proc", "PERS", true);
   7518             needSep = true;
   7519         }
   7520 
   7521         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
   7522 
   7523         pw.println(" ");
   7524         pw.println("  mHomeProcess: " + mHomeProcess);
   7525         if (mHeavyWeightProcess != null) {
   7526             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   7527         }
   7528 
   7529         return true;
   7530     }
   7531 
   7532     /**
   7533      * There are three ways to call this:
   7534      *  - no service specified: dump all the services
   7535      *  - a flattened component name that matched an existing service was specified as the
   7536      *    first arg: dump that one service
   7537      *  - the first arg isn't the flattened component name of an existing service:
   7538      *    dump all services whose component contains the first arg as a substring
   7539      */
   7540     protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args,
   7541             int opti, boolean dumpAll) {
   7542         String[] newArgs;
   7543         String componentNameString;
   7544         ServiceRecord r;
   7545         if (opti >= args.length) {
   7546             componentNameString = null;
   7547             newArgs = EMPTY_STRING_ARRAY;
   7548             r = null;
   7549         } else {
   7550             componentNameString = args[opti];
   7551             opti++;
   7552             ComponentName componentName = ComponentName.unflattenFromString(componentNameString);
   7553             synchronized (this) {
   7554                 r = componentName != null ? mServices.get(componentName) : null;
   7555             }
   7556             newArgs = new String[args.length - opti];
   7557             if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   7558         }
   7559 
   7560         if (r != null) {
   7561             dumpService(fd, pw, r, newArgs, dumpAll);
   7562         } else {
   7563             ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
   7564             synchronized (this) {
   7565                 for (ServiceRecord r1 : mServices.values()) {
   7566                     if (componentNameString == null
   7567                             || r1.name.flattenToString().contains(componentNameString)) {
   7568                         services.add(r1);
   7569                     }
   7570                 }
   7571             }
   7572             for (int i=0; i<services.size(); i++) {
   7573                 dumpService(fd, pw, services.get(i), newArgs, dumpAll);
   7574             }
   7575         }
   7576     }
   7577 
   7578     /**
   7579      * Invokes IApplicationThread.dumpService() on the thread of the specified service if
   7580      * there is a thread associated with the service.
   7581      */
   7582     private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args,
   7583             boolean dumpAll) {
   7584         pw.println("  Service " + r.name.flattenToString());
   7585         if (dumpAll) {
   7586             synchronized (this) {
   7587                 pw.print("  * "); pw.println(r);
   7588                 r.dump(pw, "    ");
   7589             }
   7590             pw.println("");
   7591         }
   7592         if (r.app != null && r.app.thread != null) {
   7593             try {
   7594                 // flush anything that is already in the PrintWriter since the thread is going
   7595                 // to write to the file descriptor directly
   7596                 pw.flush();
   7597                 r.app.thread.dumpService(fd, r, args);
   7598                 pw.print("\n");
   7599                 pw.flush();
   7600             } catch (RemoteException e) {
   7601                 pw.println("got a RemoteException while dumping the service");
   7602             }
   7603         }
   7604     }
   7605 
   7606     boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   7607             int opti, boolean dumpAll) {
   7608         boolean needSep = false;
   7609 
   7610         if (dumpAll) {
   7611             if (mRegisteredReceivers.size() > 0) {
   7612                 pw.println(" ");
   7613                 pw.println("  Registered Receivers:");
   7614                 Iterator it = mRegisteredReceivers.values().iterator();
   7615                 while (it.hasNext()) {
   7616                     ReceiverList r = (ReceiverList)it.next();
   7617                     pw.print("  * "); pw.println(r);
   7618                     r.dump(pw, "    ");
   7619                 }
   7620             }
   7621 
   7622             pw.println(" ");
   7623             pw.println("Receiver Resolver Table:");
   7624             mReceiverResolver.dump(pw, null, "  ", null, false);
   7625             needSep = true;
   7626         }
   7627 
   7628         if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
   7629                 || mPendingBroadcast != null) {
   7630             if (mParallelBroadcasts.size() > 0) {
   7631                 pw.println(" ");
   7632                 pw.println("  Active broadcasts:");
   7633             }
   7634             for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
   7635                 pw.println("  Broadcast #" + i + ":");
   7636                 mParallelBroadcasts.get(i).dump(pw, "    ");
   7637             }
   7638             if (mOrderedBroadcasts.size() > 0) {
   7639                 pw.println(" ");
   7640                 pw.println("  Active ordered broadcasts:");
   7641             }
   7642             for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
   7643                 pw.println("  Serialized Broadcast #" + i + ":");
   7644                 mOrderedBroadcasts.get(i).dump(pw, "    ");
   7645             }
   7646             pw.println(" ");
   7647             pw.println("  Pending broadcast:");
   7648             if (mPendingBroadcast != null) {
   7649                 mPendingBroadcast.dump(pw, "    ");
   7650             } else {
   7651                 pw.println("    (null)");
   7652             }
   7653             needSep = true;
   7654         }
   7655 
   7656         if (dumpAll) {
   7657             pw.println(" ");
   7658             pw.println("  Historical broadcasts:");
   7659             for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
   7660                 BroadcastRecord r = mBroadcastHistory[i];
   7661                 if (r == null) {
   7662                     break;
   7663                 }
   7664                 pw.println("  Historical Broadcast #" + i + ":");
   7665                 r.dump(pw, "    ");
   7666             }
   7667             needSep = true;
   7668         }
   7669 
   7670         if (mStickyBroadcasts != null) {
   7671             pw.println(" ");
   7672             pw.println("  Sticky broadcasts:");
   7673             StringBuilder sb = new StringBuilder(128);
   7674             for (Map.Entry<String, ArrayList<Intent>> ent
   7675                     : mStickyBroadcasts.entrySet()) {
   7676                 pw.print("  * Sticky action "); pw.print(ent.getKey());
   7677                         pw.println(":");
   7678                 ArrayList<Intent> intents = ent.getValue();
   7679                 final int N = intents.size();
   7680                 for (int i=0; i<N; i++) {
   7681                     sb.setLength(0);
   7682                     sb.append("    Intent: ");
   7683                     intents.get(i).toShortString(sb, true, false);
   7684                     pw.println(sb.toString());
   7685                     Bundle bundle = intents.get(i).getExtras();
   7686                     if (bundle != null) {
   7687                         pw.print("      ");
   7688                         pw.println(bundle.toString());
   7689                     }
   7690                 }
   7691             }
   7692             needSep = true;
   7693         }
   7694 
   7695         if (dumpAll) {
   7696             pw.println(" ");
   7697             pw.println("  mBroadcastsScheduled=" + mBroadcastsScheduled);
   7698             pw.println("  mHandler:");
   7699             mHandler.dump(new PrintWriterPrinter(pw), "    ");
   7700             needSep = true;
   7701         }
   7702 
   7703         return needSep;
   7704     }
   7705 
   7706     boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   7707             int opti, boolean dumpAll) {
   7708         boolean needSep = false;
   7709 
   7710         if (dumpAll) {
   7711             if (mServices.size() > 0) {
   7712                 pw.println("  Active services:");
   7713                 Iterator<ServiceRecord> it = mServices.values().iterator();
   7714                 while (it.hasNext()) {
   7715                     ServiceRecord r = it.next();
   7716                     pw.print("  * "); pw.println(r);
   7717                     r.dump(pw, "    ");
   7718                 }
   7719                 needSep = true;
   7720             }
   7721         }
   7722 
   7723         if (mPendingServices.size() > 0) {
   7724             if (needSep) pw.println(" ");
   7725             pw.println("  Pending services:");
   7726             for (int i=0; i<mPendingServices.size(); i++) {
   7727                 ServiceRecord r = mPendingServices.get(i);
   7728                 pw.print("  * Pending "); pw.println(r);
   7729                 r.dump(pw, "    ");
   7730             }
   7731             needSep = true;
   7732         }
   7733 
   7734         if (mRestartingServices.size() > 0) {
   7735             if (needSep) pw.println(" ");
   7736             pw.println("  Restarting services:");
   7737             for (int i=0; i<mRestartingServices.size(); i++) {
   7738                 ServiceRecord r = mRestartingServices.get(i);
   7739                 pw.print("  * Restarting "); pw.println(r);
   7740                 r.dump(pw, "    ");
   7741             }
   7742             needSep = true;
   7743         }
   7744 
   7745         if (mStoppingServices.size() > 0) {
   7746             if (needSep) pw.println(" ");
   7747             pw.println("  Stopping services:");
   7748             for (int i=0; i<mStoppingServices.size(); i++) {
   7749                 ServiceRecord r = mStoppingServices.get(i);
   7750                 pw.print("  * Stopping "); pw.println(r);
   7751                 r.dump(pw, "    ");
   7752             }
   7753             needSep = true;
   7754         }
   7755 
   7756         if (dumpAll) {
   7757             if (mServiceConnections.size() > 0) {
   7758                 if (needSep) pw.println(" ");
   7759                 pw.println("  Connection bindings to services:");
   7760                 Iterator<ArrayList<ConnectionRecord>> it
   7761                         = mServiceConnections.values().iterator();
   7762                 while (it.hasNext()) {
   7763                     ArrayList<ConnectionRecord> r = it.next();
   7764                     for (int i=0; i<r.size(); i++) {
   7765                         pw.print("  * "); pw.println(r.get(i));
   7766                         r.get(i).dump(pw, "    ");
   7767                     }
   7768                 }
   7769                 needSep = true;
   7770             }
   7771         }
   7772 
   7773         return needSep;
   7774     }
   7775 
   7776     boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   7777             int opti, boolean dumpAll) {
   7778         boolean needSep = false;
   7779 
   7780         if (dumpAll) {
   7781             if (mProvidersByClass.size() > 0) {
   7782                 if (needSep) pw.println(" ");
   7783                 pw.println("  Published content providers (by class):");
   7784                 Iterator<Map.Entry<String, ContentProviderRecord>> it
   7785                         = mProvidersByClass.entrySet().iterator();
   7786                 while (it.hasNext()) {
   7787                     Map.Entry<String, ContentProviderRecord> e = it.next();
   7788                     ContentProviderRecord r = e.getValue();
   7789                     pw.print("  * "); pw.println(r);
   7790                     r.dump(pw, "    ");
   7791                 }
   7792                 needSep = true;
   7793             }
   7794 
   7795             if (mProvidersByName.size() > 0) {
   7796                 pw.println(" ");
   7797                 pw.println("  Authority to provider mappings:");
   7798                 Iterator<Map.Entry<String, ContentProviderRecord>> it
   7799                         = mProvidersByName.entrySet().iterator();
   7800                 while (it.hasNext()) {
   7801                     Map.Entry<String, ContentProviderRecord> e = it.next();
   7802                     ContentProviderRecord r = e.getValue();
   7803                     pw.print("  "); pw.print(e.getKey()); pw.print(": ");
   7804                             pw.println(r);
   7805                 }
   7806                 needSep = true;
   7807             }
   7808         }
   7809 
   7810         if (mLaunchingProviders.size() > 0) {
   7811             if (needSep) pw.println(" ");
   7812             pw.println("  Launching content providers:");
   7813             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
   7814                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
   7815                         pw.println(mLaunchingProviders.get(i));
   7816             }
   7817             needSep = true;
   7818         }
   7819 
   7820         if (mGrantedUriPermissions.size() > 0) {
   7821             pw.println();
   7822             pw.println("Granted Uri Permissions:");
   7823             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
   7824                 int uid = mGrantedUriPermissions.keyAt(i);
   7825                 HashMap<Uri, UriPermission> perms
   7826                         = mGrantedUriPermissions.valueAt(i);
   7827                 pw.print("  * UID "); pw.print(uid);
   7828                         pw.println(" holds:");
   7829                 for (UriPermission perm : perms.values()) {
   7830                     pw.print("    "); pw.println(perm);
   7831                     perm.dump(pw, "      ");
   7832                 }
   7833             }
   7834             needSep = true;
   7835         }
   7836 
   7837         return needSep;
   7838     }
   7839 
   7840     boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   7841             int opti, boolean dumpAll) {
   7842         boolean needSep = false;
   7843 
   7844         if (dumpAll) {
   7845             if (this.mIntentSenderRecords.size() > 0) {
   7846                 Iterator<WeakReference<PendingIntentRecord>> it
   7847                         = mIntentSenderRecords.values().iterator();
   7848                 while (it.hasNext()) {
   7849                     WeakReference<PendingIntentRecord> ref = it.next();
   7850                     PendingIntentRecord rec = ref != null ? ref.get(): null;
   7851                     needSep = true;
   7852                     if (rec != null) {
   7853                         pw.print("  * "); pw.println(rec);
   7854                         rec.dump(pw, "    ");
   7855                     } else {
   7856                         pw.print("  * "); pw.print(ref);
   7857                     }
   7858                 }
   7859             }
   7860         }
   7861 
   7862         return needSep;
   7863     }
   7864 
   7865     private static final void dumpHistoryList(PrintWriter pw, List list,
   7866             String prefix, String label, boolean complete) {
   7867         TaskRecord lastTask = null;
   7868         for (int i=list.size()-1; i>=0; i--) {
   7869             ActivityRecord r = (ActivityRecord)list.get(i);
   7870             final boolean full = complete || !r.inHistory;
   7871             if (lastTask != r.task) {
   7872                 lastTask = r.task;
   7873                 pw.print(prefix);
   7874                 pw.print(full ? "* " : "  ");
   7875                 pw.println(lastTask);
   7876                 if (full) {
   7877                     lastTask.dump(pw, prefix + "  ");
   7878                 }
   7879             }
   7880             pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
   7881             pw.print(" #"); pw.print(i); pw.print(": ");
   7882             pw.println(r);
   7883             if (full) {
   7884                 r.dump(pw, prefix + "      ");
   7885             }
   7886         }
   7887     }
   7888 
   7889     private static String buildOomTag(String prefix, String space, int val, int base) {
   7890         if (val == base) {
   7891             if (space == null) return prefix;
   7892             return prefix + "  ";
   7893         }
   7894         return prefix + "+" + Integer.toString(val-base);
   7895     }
   7896 
   7897     private static final int dumpProcessList(PrintWriter pw,
   7898             ActivityManagerService service, List list,
   7899             String prefix, String normalLabel, String persistentLabel) {
   7900         int numPers = 0;
   7901         final int N = list.size()-1;
   7902         for (int i=N; i>=0; i--) {
   7903             ProcessRecord r = (ProcessRecord)list.get(i);
   7904             pw.println(String.format("%s%s #%2d: %s",
   7905                     prefix, (r.persistent ? persistentLabel : normalLabel),
   7906                     i, r.toString()));
   7907             if (r.persistent) {
   7908                 numPers++;
   7909             }
   7910         }
   7911         return numPers;
   7912     }
   7913 
   7914     private static final void dumpProcessOomList(PrintWriter pw,
   7915             ActivityManagerService service, List<ProcessRecord> list,
   7916             String prefix, String normalLabel, String persistentLabel,
   7917             boolean inclDetails) {
   7918 
   7919         final long curRealtime = SystemClock.elapsedRealtime();
   7920         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
   7921         final long curUptime = SystemClock.uptimeMillis();
   7922         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
   7923 
   7924         final int N = list.size()-1;
   7925         for (int i=N; i>=0; i--) {
   7926             ProcessRecord r = list.get(i);
   7927             String oomAdj;
   7928             if (r.setAdj >= EMPTY_APP_ADJ) {
   7929                 oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ);
   7930             } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
   7931                 oomAdj = buildOomTag("bak", "  ", r.setAdj, HIDDEN_APP_MIN_ADJ);
   7932             } else if (r.setAdj >= HOME_APP_ADJ) {
   7933                 oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ);
   7934             } else if (r.setAdj >= SECONDARY_SERVER_ADJ) {
   7935                 oomAdj = buildOomTag("svc", "  ", r.setAdj, SECONDARY_SERVER_ADJ);
   7936             } else if (r.setAdj >= BACKUP_APP_ADJ) {
   7937                 oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ);
   7938             } else if (r.setAdj >= HEAVY_WEIGHT_APP_ADJ) {
   7939                 oomAdj = buildOomTag("hvy  ", null, r.setAdj, HEAVY_WEIGHT_APP_ADJ);
   7940             } else if (r.setAdj >= PERCEPTIBLE_APP_ADJ) {
   7941                 oomAdj = buildOomTag("prcp ", null, r.setAdj, PERCEPTIBLE_APP_ADJ);
   7942             } else if (r.setAdj >= VISIBLE_APP_ADJ) {
   7943                 oomAdj = buildOomTag("vis  ", null, r.setAdj, VISIBLE_APP_ADJ);
   7944             } else if (r.setAdj >= FOREGROUND_APP_ADJ) {
   7945                 oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ);
   7946             } else if (r.setAdj >= CORE_SERVER_ADJ) {
   7947                 oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ);
   7948             } else if (r.setAdj >= SYSTEM_ADJ) {
   7949                 oomAdj = buildOomTag("sys  ", null, r.setAdj, SYSTEM_ADJ);
   7950             } else {
   7951                 oomAdj = Integer.toString(r.setAdj);
   7952             }
   7953             String schedGroup;
   7954             switch (r.setSchedGroup) {
   7955                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
   7956                     schedGroup = "B";
   7957                     break;
   7958                 case Process.THREAD_GROUP_DEFAULT:
   7959                     schedGroup = "F";
   7960                     break;
   7961                 default:
   7962                     schedGroup = Integer.toString(r.setSchedGroup);
   7963                     break;
   7964             }
   7965             pw.println(String.format("%s%s #%2d: adj=%s/%s %s (%s)",
   7966                     prefix, (r.persistent ? persistentLabel : normalLabel),
   7967                     N-i, oomAdj, schedGroup, r.toShortString(), r.adjType));
   7968             if (r.adjSource != null || r.adjTarget != null) {
   7969                 pw.print(prefix);
   7970                 pw.print("          ");
   7971                 if (r.adjTarget instanceof ComponentName) {
   7972                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
   7973                 } else if (r.adjTarget != null) {
   7974                     pw.print(r.adjTarget.toString());
   7975                 } else {
   7976                     pw.print("{null}");
   7977                 }
   7978                 pw.print("<=");
   7979                 if (r.adjSource instanceof ProcessRecord) {
   7980                     pw.print("Proc{");
   7981                     pw.print(((ProcessRecord)r.adjSource).toShortString());
   7982                     pw.println("}");
   7983                 } else if (r.adjSource != null) {
   7984                     pw.println(r.adjSource.toString());
   7985                 } else {
   7986                     pw.println("{null}");
   7987                 }
   7988             }
   7989             if (inclDetails) {
   7990                 pw.print(prefix);
   7991                 pw.print("    ");
   7992                 pw.print("oom: max="); pw.print(r.maxAdj);
   7993                 pw.print(" hidden="); pw.print(r.hiddenAdj);
   7994                 pw.print(" curRaw="); pw.print(r.curRawAdj);
   7995                 pw.print(" setRaw="); pw.print(r.setRawAdj);
   7996                 pw.print(" cur="); pw.print(r.curAdj);
   7997                 pw.print(" set="); pw.println(r.setAdj);
   7998                 pw.print(prefix);
   7999                 pw.print("    ");
   8000                 pw.print("keeping="); pw.print(r.keeping);
   8001                 pw.print(" hidden="); pw.print(r.hidden);
   8002                 pw.print(" empty="); pw.println(r.empty);
   8003 
   8004                 if (!r.keeping) {
   8005                     if (r.lastWakeTime != 0) {
   8006                         long wtime;
   8007                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
   8008                         synchronized (stats) {
   8009                             wtime = stats.getProcessWakeTime(r.info.uid,
   8010                                     r.pid, curRealtime);
   8011                         }
   8012                         long timeUsed = wtime - r.lastWakeTime;
   8013                         pw.print(prefix);
   8014                         pw.print("    ");
   8015                         pw.print("keep awake over ");
   8016                         TimeUtils.formatDuration(realtimeSince, pw);
   8017                         pw.print(" used ");
   8018                         TimeUtils.formatDuration(timeUsed, pw);
   8019                         pw.print(" (");
   8020                         pw.print((timeUsed*100)/realtimeSince);
   8021                         pw.println("%)");
   8022                     }
   8023                     if (r.lastCpuTime != 0) {
   8024                         long timeUsed = r.curCpuTime - r.lastCpuTime;
   8025                         pw.print(prefix);
   8026                         pw.print("    ");
   8027                         pw.print("run cpu over ");
   8028                         TimeUtils.formatDuration(uptimeSince, pw);
   8029                         pw.print(" used ");
   8030                         TimeUtils.formatDuration(timeUsed, pw);
   8031                         pw.print(" (");
   8032                         pw.print((timeUsed*100)/uptimeSince);
   8033                         pw.println("%)");
   8034                     }
   8035                 }
   8036             }
   8037         }
   8038     }
   8039 
   8040     static final void dumpApplicationMemoryUsage(FileDescriptor fd,
   8041             PrintWriter pw, List list, String prefix, String[] args) {
   8042         final boolean isCheckinRequest = scanArgs(args, "--checkin");
   8043         long uptime = SystemClock.uptimeMillis();
   8044         long realtime = SystemClock.elapsedRealtime();
   8045 
   8046         if (isCheckinRequest) {
   8047             // short checkin version
   8048             pw.println(uptime + "," + realtime);
   8049             pw.flush();
   8050         } else {
   8051             pw.println("Applications Memory Usage (kB):");
   8052             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   8053         }
   8054         for (int i = list.size() - 1 ; i >= 0 ; i--) {
   8055             ProcessRecord r = (ProcessRecord)list.get(i);
   8056             if (r.thread != null) {
   8057                 if (!isCheckinRequest) {
   8058                     pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
   8059                     pw.flush();
   8060                 }
   8061                 try {
   8062                     r.thread.asBinder().dump(fd, args);
   8063                 } catch (RemoteException e) {
   8064                     if (!isCheckinRequest) {
   8065                         pw.println("Got RemoteException!");
   8066                         pw.flush();
   8067                     }
   8068                 }
   8069             }
   8070         }
   8071     }
   8072 
   8073     /**
   8074      * Searches array of arguments for the specified string
   8075      * @param args array of argument strings
   8076      * @param value value to search for
   8077      * @return true if the value is contained in the array
   8078      */
   8079     private static boolean scanArgs(String[] args, String value) {
   8080         if (args != null) {
   8081             for (String arg : args) {
   8082                 if (value.equals(arg)) {
   8083                     return true;
   8084                 }
   8085             }
   8086         }
   8087         return false;
   8088     }
   8089 
   8090     private final void killServicesLocked(ProcessRecord app,
   8091             boolean allowRestart) {
   8092         // Report disconnected services.
   8093         if (false) {
   8094             // XXX we are letting the client link to the service for
   8095             // death notifications.
   8096             if (app.services.size() > 0) {
   8097                 Iterator<ServiceRecord> it = app.services.iterator();
   8098                 while (it.hasNext()) {
   8099                     ServiceRecord r = it.next();
   8100                     if (r.connections.size() > 0) {
   8101                         Iterator<ArrayList<ConnectionRecord>> jt
   8102                                 = r.connections.values().iterator();
   8103                         while (jt.hasNext()) {
   8104                             ArrayList<ConnectionRecord> cl = jt.next();
   8105                             for (int i=0; i<cl.size(); i++) {
   8106                                 ConnectionRecord c = cl.get(i);
   8107                                 if (c.binding.client != app) {
   8108                                     try {
   8109                                         //c.conn.connected(r.className, null);
   8110                                     } catch (Exception e) {
   8111                                         // todo: this should be asynchronous!
   8112                                         Slog.w(TAG, "Exception thrown disconnected servce "
   8113                                               + r.shortName
   8114                                               + " from app " + app.processName, e);
   8115                                     }
   8116                                 }
   8117                             }
   8118                         }
   8119                     }
   8120                 }
   8121             }
   8122         }
   8123 
   8124         // Clean up any connections this application has to other services.
   8125         if (app.connections.size() > 0) {
   8126             Iterator<ConnectionRecord> it = app.connections.iterator();
   8127             while (it.hasNext()) {
   8128                 ConnectionRecord r = it.next();
   8129                 removeConnectionLocked(r, app, null);
   8130             }
   8131         }
   8132         app.connections.clear();
   8133 
   8134         if (app.services.size() != 0) {
   8135             // Any services running in the application need to be placed
   8136             // back in the pending list.
   8137             Iterator<ServiceRecord> it = app.services.iterator();
   8138             while (it.hasNext()) {
   8139                 ServiceRecord sr = it.next();
   8140                 synchronized (sr.stats.getBatteryStats()) {
   8141                     sr.stats.stopLaunchedLocked();
   8142                 }
   8143                 sr.app = null;
   8144                 sr.executeNesting = 0;
   8145                 if (mStoppingServices.remove(sr)) {
   8146                     if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
   8147                 }
   8148 
   8149                 boolean hasClients = sr.bindings.size() > 0;
   8150                 if (hasClients) {
   8151                     Iterator<IntentBindRecord> bindings
   8152                             = sr.bindings.values().iterator();
   8153                     while (bindings.hasNext()) {
   8154                         IntentBindRecord b = bindings.next();
   8155                         if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
   8156                                 + ": shouldUnbind=" + b.hasBound);
   8157                         b.binder = null;
   8158                         b.requested = b.received = b.hasBound = false;
   8159                     }
   8160                 }
   8161 
   8162                 if (sr.crashCount >= 2) {
   8163                     Slog.w(TAG, "Service crashed " + sr.crashCount
   8164                             + " times, stopping: " + sr);
   8165                     EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
   8166                             sr.crashCount, sr.shortName, app.pid);
   8167                     bringDownServiceLocked(sr, true);
   8168                 } else if (!allowRestart) {
   8169                     bringDownServiceLocked(sr, true);
   8170                 } else {
   8171                     boolean canceled = scheduleServiceRestartLocked(sr, true);
   8172 
   8173                     // Should the service remain running?  Note that in the
   8174                     // extreme case of so many attempts to deliver a command
   8175                     // that it failed, that we also will stop it here.
   8176                     if (sr.startRequested && (sr.stopIfKilled || canceled)) {
   8177                         if (sr.pendingStarts.size() == 0) {
   8178                             sr.startRequested = false;
   8179                             if (!hasClients) {
   8180                                 // Whoops, no reason to restart!
   8181                                 bringDownServiceLocked(sr, true);
   8182                             }
   8183                         }
   8184                     }
   8185                 }
   8186             }
   8187 
   8188             if (!allowRestart) {
   8189                 app.services.clear();
   8190             }
   8191         }
   8192 
   8193         // Make sure we have no more records on the stopping list.
   8194         int i = mStoppingServices.size();
   8195         while (i > 0) {
   8196             i--;
   8197             ServiceRecord sr = mStoppingServices.get(i);
   8198             if (sr.app == app) {
   8199                 mStoppingServices.remove(i);
   8200                 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
   8201             }
   8202         }
   8203 
   8204         app.executingServices.clear();
   8205     }
   8206 
   8207     private final void removeDyingProviderLocked(ProcessRecord proc,
   8208             ContentProviderRecord cpr) {
   8209         synchronized (cpr) {
   8210             cpr.launchingApp = null;
   8211             cpr.notifyAll();
   8212         }
   8213 
   8214         mProvidersByClass.remove(cpr.info.name);
   8215         String names[] = cpr.info.authority.split(";");
   8216         for (int j = 0; j < names.length; j++) {
   8217             mProvidersByName.remove(names[j]);
   8218         }
   8219 
   8220         Iterator<ProcessRecord> cit = cpr.clients.iterator();
   8221         while (cit.hasNext()) {
   8222             ProcessRecord capp = cit.next();
   8223             if (!capp.persistent && capp.thread != null
   8224                     && capp.pid != 0
   8225                     && capp.pid != MY_PID) {
   8226                 Slog.i(TAG, "Kill " + capp.processName
   8227                         + " (pid " + capp.pid + "): provider " + cpr.info.name
   8228                         + " in dying process " + proc.processName);
   8229                 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
   8230                         capp.processName, capp.setAdj, "dying provider " + proc.processName);
   8231                 Process.killProcess(capp.pid);
   8232             }
   8233         }
   8234 
   8235         mLaunchingProviders.remove(cpr);
   8236     }
   8237 
   8238     /**
   8239      * Main code for cleaning up a process when it has gone away.  This is
   8240      * called both as a result of the process dying, or directly when stopping
   8241      * a process when running in single process mode.
   8242      */
   8243     private final void cleanUpApplicationRecordLocked(ProcessRecord app,
   8244             boolean restarting, int index) {
   8245         if (index >= 0) {
   8246             mLruProcesses.remove(index);
   8247         }
   8248 
   8249         mProcessesToGc.remove(app);
   8250 
   8251         // Dismiss any open dialogs.
   8252         if (app.crashDialog != null) {
   8253             app.crashDialog.dismiss();
   8254             app.crashDialog = null;
   8255         }
   8256         if (app.anrDialog != null) {
   8257             app.anrDialog.dismiss();
   8258             app.anrDialog = null;
   8259         }
   8260         if (app.waitDialog != null) {
   8261             app.waitDialog.dismiss();
   8262             app.waitDialog = null;
   8263         }
   8264 
   8265         app.crashing = false;
   8266         app.notResponding = false;
   8267 
   8268         app.resetPackageList();
   8269         app.thread = null;
   8270         app.forcingToForeground = null;
   8271         app.foregroundServices = false;
   8272 
   8273         killServicesLocked(app, true);
   8274 
   8275         boolean restart = false;
   8276 
   8277         int NL = mLaunchingProviders.size();
   8278 
   8279         // Remove published content providers.
   8280         if (!app.pubProviders.isEmpty()) {
   8281             Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
   8282             while (it.hasNext()) {
   8283                 ContentProviderRecord cpr = it.next();
   8284                 cpr.provider = null;
   8285                 cpr.app = null;
   8286 
   8287                 // See if someone is waiting for this provider...  in which
   8288                 // case we don't remove it, but just let it restart.
   8289                 int i = 0;
   8290                 if (!app.bad) {
   8291                     for (; i<NL; i++) {
   8292                         if (mLaunchingProviders.get(i) == cpr) {
   8293                             restart = true;
   8294                             break;
   8295                         }
   8296                     }
   8297                 } else {
   8298                     i = NL;
   8299                 }
   8300 
   8301                 if (i >= NL) {
   8302                     removeDyingProviderLocked(app, cpr);
   8303                     NL = mLaunchingProviders.size();
   8304                 }
   8305             }
   8306             app.pubProviders.clear();
   8307         }
   8308 
   8309         // Take care of any launching providers waiting for this process.
   8310         if (checkAppInLaunchingProvidersLocked(app, false)) {
   8311             restart = true;
   8312         }
   8313 
   8314         // Unregister from connected content providers.
   8315         if (!app.conProviders.isEmpty()) {
   8316             Iterator it = app.conProviders.keySet().iterator();
   8317             while (it.hasNext()) {
   8318                 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
   8319                 cpr.clients.remove(app);
   8320             }
   8321             app.conProviders.clear();
   8322         }
   8323 
   8324         // At this point there may be remaining entries in mLaunchingProviders
   8325         // where we were the only one waiting, so they are no longer of use.
   8326         // Look for these and clean up if found.
   8327         // XXX Commented out for now.  Trying to figure out a way to reproduce
   8328         // the actual situation to identify what is actually going on.
   8329         if (false) {
   8330             for (int i=0; i<NL; i++) {
   8331                 ContentProviderRecord cpr = (ContentProviderRecord)
   8332                         mLaunchingProviders.get(i);
   8333                 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
   8334                     synchronized (cpr) {
   8335                         cpr.launchingApp = null;
   8336                         cpr.notifyAll();
   8337                     }
   8338                 }
   8339             }
   8340         }
   8341 
   8342         skipCurrentReceiverLocked(app);
   8343 
   8344         // Unregister any receivers.
   8345         if (app.receivers.size() > 0) {
   8346             Iterator<ReceiverList> it = app.receivers.iterator();
   8347             while (it.hasNext()) {
   8348                 removeReceiverLocked(it.next());
   8349             }
   8350             app.receivers.clear();
   8351         }
   8352 
   8353         // If the app is undergoing backup, tell the backup manager about it
   8354         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
   8355             if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
   8356             try {
   8357                 IBackupManager bm = IBackupManager.Stub.asInterface(
   8358                         ServiceManager.getService(Context.BACKUP_SERVICE));
   8359                 bm.agentDisconnected(app.info.packageName);
   8360             } catch (RemoteException e) {
   8361                 // can't happen; backup manager is local
   8362             }
   8363         }
   8364 
   8365         // If the caller is restarting this app, then leave it in its
   8366         // current lists and let the caller take care of it.
   8367         if (restarting) {
   8368             return;
   8369         }
   8370 
   8371         if (!app.persistent) {
   8372             if (DEBUG_PROCESSES) Slog.v(TAG,
   8373                     "Removing non-persistent process during cleanup: " + app);
   8374             mProcessNames.remove(app.processName, app.info.uid);
   8375             if (mHeavyWeightProcess == app) {
   8376                 mHeavyWeightProcess = null;
   8377                 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
   8378             }
   8379         } else if (!app.removed) {
   8380             // This app is persistent, so we need to keep its record around.
   8381             // If it is not already on the pending app list, add it there
   8382             // and start a new process for it.
   8383             app.thread = null;
   8384             app.forcingToForeground = null;
   8385             app.foregroundServices = false;
   8386             if (mPersistentStartingProcesses.indexOf(app) < 0) {
   8387                 mPersistentStartingProcesses.add(app);
   8388                 restart = true;
   8389             }
   8390         }
   8391         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   8392                 "Clean-up removing on hold: " + app);
   8393         mProcessesOnHold.remove(app);
   8394 
   8395         if (app == mHomeProcess) {
   8396             mHomeProcess = null;
   8397         }
   8398 
   8399         if (restart) {
   8400             // We have components that still need to be running in the
   8401             // process, so re-launch it.
   8402             mProcessNames.put(app.processName, app.info.uid, app);
   8403             startProcessLocked(app, "restart", app.processName);
   8404         } else if (app.pid > 0 && app.pid != MY_PID) {
   8405             // Goodbye!
   8406             synchronized (mPidsSelfLocked) {
   8407                 mPidsSelfLocked.remove(app.pid);
   8408                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   8409             }
   8410             app.setPid(0);
   8411         }
   8412     }
   8413 
   8414     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
   8415         // Look through the content providers we are waiting to have launched,
   8416         // and if any run in this process then either schedule a restart of
   8417         // the process or kill the client waiting for it if this process has
   8418         // gone bad.
   8419         int NL = mLaunchingProviders.size();
   8420         boolean restart = false;
   8421         for (int i=0; i<NL; i++) {
   8422             ContentProviderRecord cpr = mLaunchingProviders.get(i);
   8423             if (cpr.launchingApp == app) {
   8424                 if (!alwaysBad && !app.bad) {
   8425                     restart = true;
   8426                 } else {
   8427                     removeDyingProviderLocked(app, cpr);
   8428                     NL = mLaunchingProviders.size();
   8429                 }
   8430             }
   8431         }
   8432         return restart;
   8433     }
   8434 
   8435     // =========================================================
   8436     // SERVICES
   8437     // =========================================================
   8438 
   8439     ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
   8440         ActivityManager.RunningServiceInfo info =
   8441             new ActivityManager.RunningServiceInfo();
   8442         info.service = r.name;
   8443         if (r.app != null) {
   8444             info.pid = r.app.pid;
   8445         }
   8446         info.uid = r.appInfo.uid;
   8447         info.process = r.processName;
   8448         info.foreground = r.isForeground;
   8449         info.activeSince = r.createTime;
   8450         info.started = r.startRequested;
   8451         info.clientCount = r.connections.size();
   8452         info.crashCount = r.crashCount;
   8453         info.lastActivityTime = r.lastActivity;
   8454         if (r.isForeground) {
   8455             info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
   8456         }
   8457         if (r.startRequested) {
   8458             info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
   8459         }
   8460         if (r.app != null && r.app.pid == MY_PID) {
   8461             info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
   8462         }
   8463         if (r.app != null && r.app.persistent) {
   8464             info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
   8465         }
   8466 
   8467         for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
   8468             for (int i=0; i<connl.size(); i++) {
   8469                 ConnectionRecord conn = connl.get(i);
   8470                 if (conn.clientLabel != 0) {
   8471                     info.clientPackage = conn.binding.client.info.packageName;
   8472                     info.clientLabel = conn.clientLabel;
   8473                     return info;
   8474                 }
   8475             }
   8476         }
   8477         return info;
   8478     }
   8479 
   8480     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
   8481             int flags) {
   8482         synchronized (this) {
   8483             ArrayList<ActivityManager.RunningServiceInfo> res
   8484                     = new ArrayList<ActivityManager.RunningServiceInfo>();
   8485 
   8486             if (mServices.size() > 0) {
   8487                 Iterator<ServiceRecord> it = mServices.values().iterator();
   8488                 while (it.hasNext() && res.size() < maxNum) {
   8489                     res.add(makeRunningServiceInfoLocked(it.next()));
   8490                 }
   8491             }
   8492 
   8493             for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
   8494                 ServiceRecord r = mRestartingServices.get(i);
   8495                 ActivityManager.RunningServiceInfo info =
   8496                         makeRunningServiceInfoLocked(r);
   8497                 info.restarting = r.nextRestartTime;
   8498                 res.add(info);
   8499             }
   8500 
   8501             return res;
   8502         }
   8503     }
   8504 
   8505     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
   8506         synchronized (this) {
   8507             ServiceRecord r = mServices.get(name);
   8508             if (r != null) {
   8509                 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
   8510                     for (int i=0; i<conn.size(); i++) {
   8511                         if (conn.get(i).clientIntent != null) {
   8512                             return conn.get(i).clientIntent;
   8513                         }
   8514                     }
   8515                 }
   8516             }
   8517         }
   8518         return null;
   8519     }
   8520 
   8521     private final ServiceRecord findServiceLocked(ComponentName name,
   8522             IBinder token) {
   8523         ServiceRecord r = mServices.get(name);
   8524         return r == token ? r : null;
   8525     }
   8526 
   8527     private final class ServiceLookupResult {
   8528         final ServiceRecord record;
   8529         final String permission;
   8530 
   8531         ServiceLookupResult(ServiceRecord _record, String _permission) {
   8532             record = _record;
   8533             permission = _permission;
   8534         }
   8535     };
   8536 
   8537     private ServiceLookupResult findServiceLocked(Intent service,
   8538             String resolvedType) {
   8539         ServiceRecord r = null;
   8540         if (service.getComponent() != null) {
   8541             r = mServices.get(service.getComponent());
   8542         }
   8543         if (r == null) {
   8544             Intent.FilterComparison filter = new Intent.FilterComparison(service);
   8545             r = mServicesByIntent.get(filter);
   8546         }
   8547 
   8548         if (r == null) {
   8549             try {
   8550                 ResolveInfo rInfo =
   8551                     AppGlobals.getPackageManager().resolveService(
   8552                             service, resolvedType, 0);
   8553                 ServiceInfo sInfo =
   8554                     rInfo != null ? rInfo.serviceInfo : null;
   8555                 if (sInfo == null) {
   8556                     return null;
   8557                 }
   8558 
   8559                 ComponentName name = new ComponentName(
   8560                         sInfo.applicationInfo.packageName, sInfo.name);
   8561                 r = mServices.get(name);
   8562             } catch (RemoteException ex) {
   8563                 // pm is in same process, this will never happen.
   8564             }
   8565         }
   8566         if (r != null) {
   8567             int callingPid = Binder.getCallingPid();
   8568             int callingUid = Binder.getCallingUid();
   8569             if (checkComponentPermission(r.permission,
   8570                     callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
   8571                     != PackageManager.PERMISSION_GRANTED) {
   8572                 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
   8573                         + " from pid=" + callingPid
   8574                         + ", uid=" + callingUid
   8575                         + " requires " + r.permission);
   8576                 return new ServiceLookupResult(null, r.permission);
   8577             }
   8578             return new ServiceLookupResult(r, null);
   8579         }
   8580         return null;
   8581     }
   8582 
   8583     private class ServiceRestarter implements Runnable {
   8584         private ServiceRecord mService;
   8585 
   8586         void setService(ServiceRecord service) {
   8587             mService = service;
   8588         }
   8589 
   8590         public void run() {
   8591             synchronized(ActivityManagerService.this) {
   8592                 performServiceRestartLocked(mService);
   8593             }
   8594         }
   8595     }
   8596 
   8597     private ServiceLookupResult retrieveServiceLocked(Intent service,
   8598             String resolvedType, int callingPid, int callingUid) {
   8599         ServiceRecord r = null;
   8600         if (service.getComponent() != null) {
   8601             r = mServices.get(service.getComponent());
   8602         }
   8603         Intent.FilterComparison filter = new Intent.FilterComparison(service);
   8604         r = mServicesByIntent.get(filter);
   8605         if (r == null) {
   8606             try {
   8607                 ResolveInfo rInfo =
   8608                     AppGlobals.getPackageManager().resolveService(
   8609                             service, resolvedType, STOCK_PM_FLAGS);
   8610                 ServiceInfo sInfo =
   8611                     rInfo != null ? rInfo.serviceInfo : null;
   8612                 if (sInfo == null) {
   8613                     Slog.w(TAG, "Unable to start service " + service +
   8614                           ": not found");
   8615                     return null;
   8616                 }
   8617 
   8618                 ComponentName name = new ComponentName(
   8619                         sInfo.applicationInfo.packageName, sInfo.name);
   8620                 r = mServices.get(name);
   8621                 if (r == null) {
   8622                     filter = new Intent.FilterComparison(service.cloneFilter());
   8623                     ServiceRestarter res = new ServiceRestarter();
   8624                     BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   8625                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   8626                     synchronized (stats) {
   8627                         ss = stats.getServiceStatsLocked(
   8628                                 sInfo.applicationInfo.uid, sInfo.packageName,
   8629                                 sInfo.name);
   8630                     }
   8631                     r = new ServiceRecord(this, ss, name, filter, sInfo, res);
   8632                     res.setService(r);
   8633                     mServices.put(name, r);
   8634                     mServicesByIntent.put(filter, r);
   8635 
   8636                     // Make sure this component isn't in the pending list.
   8637                     int N = mPendingServices.size();
   8638                     for (int i=0; i<N; i++) {
   8639                         ServiceRecord pr = mPendingServices.get(i);
   8640                         if (pr.name.equals(name)) {
   8641                             mPendingServices.remove(i);
   8642                             i--;
   8643                             N--;
   8644                         }
   8645                     }
   8646                 }
   8647             } catch (RemoteException ex) {
   8648                 // pm is in same process, this will never happen.
   8649             }
   8650         }
   8651         if (r != null) {
   8652             if (checkComponentPermission(r.permission,
   8653                     callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
   8654                     != PackageManager.PERMISSION_GRANTED) {
   8655                 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
   8656                         + " from pid=" + Binder.getCallingPid()
   8657                         + ", uid=" + Binder.getCallingUid()
   8658                         + " requires " + r.permission);
   8659                 return new ServiceLookupResult(null, r.permission);
   8660             }
   8661             return new ServiceLookupResult(r, null);
   8662         }
   8663         return null;
   8664     }
   8665 
   8666     private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
   8667         if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
   8668                 + why + " of " + r + " in app " + r.app);
   8669         else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
   8670                 + why + " of " + r.shortName);
   8671         long now = SystemClock.uptimeMillis();
   8672         if (r.executeNesting == 0 && r.app != null) {
   8673             if (r.app.executingServices.size() == 0) {
   8674                 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   8675                 msg.obj = r.app;
   8676                 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
   8677             }
   8678             r.app.executingServices.add(r);
   8679         }
   8680         r.executeNesting++;
   8681         r.executingStart = now;
   8682     }
   8683 
   8684     private final void sendServiceArgsLocked(ServiceRecord r,
   8685             boolean oomAdjusted) {
   8686         final int N = r.pendingStarts.size();
   8687         if (N == 0) {
   8688             return;
   8689         }
   8690 
   8691         while (r.pendingStarts.size() > 0) {
   8692             try {
   8693                 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
   8694                 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
   8695                         + r + " " + r.intent + " args=" + si.intent);
   8696                 if (si.intent == null) {
   8697                     // If somehow we got a dummy start at the front, then
   8698                     // just drop it here.
   8699                     continue;
   8700                 }
   8701                 si.deliveredTime = SystemClock.uptimeMillis();
   8702                 r.deliveredStarts.add(si);
   8703                 si.deliveryCount++;
   8704                 if (si.targetPermissionUid >= 0) {
   8705                     grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
   8706                             r.packageName, si.intent, si.getUriPermissionsLocked());
   8707                 }
   8708                 bumpServiceExecutingLocked(r, "start");
   8709                 if (!oomAdjusted) {
   8710                     oomAdjusted = true;
   8711                     updateOomAdjLocked(r.app);
   8712                 }
   8713                 int flags = 0;
   8714                 if (si.deliveryCount > 0) {
   8715                     flags |= Service.START_FLAG_RETRY;
   8716                 }
   8717                 if (si.doneExecutingCount > 0) {
   8718                     flags |= Service.START_FLAG_REDELIVERY;
   8719                 }
   8720                 r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent);
   8721             } catch (RemoteException e) {
   8722                 // Remote process gone...  we'll let the normal cleanup take
   8723                 // care of this.
   8724                 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
   8725                 break;
   8726             } catch (Exception e) {
   8727                 Slog.w(TAG, "Unexpected exception", e);
   8728                 break;
   8729             }
   8730         }
   8731     }
   8732 
   8733     private final boolean requestServiceBindingLocked(ServiceRecord r,
   8734             IntentBindRecord i, boolean rebind) {
   8735         if (r.app == null || r.app.thread == null) {
   8736             // If service is not currently running, can't yet bind.
   8737             return false;
   8738         }
   8739         if ((!i.requested || rebind) && i.apps.size() > 0) {
   8740             try {
   8741                 bumpServiceExecutingLocked(r, "bind");
   8742                 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
   8743                 if (!rebind) {
   8744                     i.requested = true;
   8745                 }
   8746                 i.hasBound = true;
   8747                 i.doRebind = false;
   8748             } catch (RemoteException e) {
   8749                 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
   8750                 return false;
   8751             }
   8752         }
   8753         return true;
   8754     }
   8755 
   8756     private final void requestServiceBindingsLocked(ServiceRecord r) {
   8757         Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
   8758         while (bindings.hasNext()) {
   8759             IntentBindRecord i = bindings.next();
   8760             if (!requestServiceBindingLocked(r, i, false)) {
   8761                 break;
   8762             }
   8763         }
   8764     }
   8765 
   8766     private final void realStartServiceLocked(ServiceRecord r,
   8767             ProcessRecord app) throws RemoteException {
   8768         if (app.thread == null) {
   8769             throw new RemoteException();
   8770         }
   8771 
   8772         r.app = app;
   8773         r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
   8774 
   8775         app.services.add(r);
   8776         bumpServiceExecutingLocked(r, "create");
   8777         updateLruProcessLocked(app, true, true);
   8778 
   8779         boolean created = false;
   8780         try {
   8781             mStringBuilder.setLength(0);
   8782             r.intent.getIntent().toShortString(mStringBuilder, false, true);
   8783             EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
   8784                     System.identityHashCode(r), r.shortName,
   8785                     mStringBuilder.toString(), r.app.pid);
   8786             synchronized (r.stats.getBatteryStats()) {
   8787                 r.stats.startLaunchedLocked();
   8788             }
   8789             ensurePackageDexOpt(r.serviceInfo.packageName);
   8790             app.thread.scheduleCreateService(r, r.serviceInfo);
   8791             r.postNotification();
   8792             created = true;
   8793         } finally {
   8794             if (!created) {
   8795                 app.services.remove(r);
   8796                 scheduleServiceRestartLocked(r, false);
   8797             }
   8798         }
   8799 
   8800         requestServiceBindingsLocked(r);
   8801 
   8802         // If the service is in the started state, and there are no
   8803         // pending arguments, then fake up one so its onStartCommand() will
   8804         // be called.
   8805         if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
   8806             r.lastStartId++;
   8807             if (r.lastStartId < 1) {
   8808                 r.lastStartId = 1;
   8809             }
   8810             r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId, null, -1));
   8811         }
   8812 
   8813         sendServiceArgsLocked(r, true);
   8814     }
   8815 
   8816     private final boolean scheduleServiceRestartLocked(ServiceRecord r,
   8817             boolean allowCancel) {
   8818         boolean canceled = false;
   8819 
   8820         final long now = SystemClock.uptimeMillis();
   8821         long minDuration = SERVICE_RESTART_DURATION;
   8822         long resetTime = SERVICE_RESET_RUN_DURATION;
   8823 
   8824         // Any delivered but not yet finished starts should be put back
   8825         // on the pending list.
   8826         final int N = r.deliveredStarts.size();
   8827         if (N > 0) {
   8828             for (int i=N-1; i>=0; i--) {
   8829                 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
   8830                 si.removeUriPermissionsLocked();
   8831                 if (si.intent == null) {
   8832                     // We'll generate this again if needed.
   8833                 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
   8834                         && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
   8835                     r.pendingStarts.add(0, si);
   8836                     long dur = SystemClock.uptimeMillis() - si.deliveredTime;
   8837                     dur *= 2;
   8838                     if (minDuration < dur) minDuration = dur;
   8839                     if (resetTime < dur) resetTime = dur;
   8840                 } else {
   8841                     Slog.w(TAG, "Canceling start item " + si.intent + " in service "
   8842                             + r.name);
   8843                     canceled = true;
   8844                 }
   8845             }
   8846             r.deliveredStarts.clear();
   8847         }
   8848 
   8849         r.totalRestartCount++;
   8850         if (r.restartDelay == 0) {
   8851             r.restartCount++;
   8852             r.restartDelay = minDuration;
   8853         } else {
   8854             // If it has been a "reasonably long time" since the service
   8855             // was started, then reset our restart duration back to
   8856             // the beginning, so we don't infinitely increase the duration
   8857             // on a service that just occasionally gets killed (which is
   8858             // a normal case, due to process being killed to reclaim memory).
   8859             if (now > (r.restartTime+resetTime)) {
   8860                 r.restartCount = 1;
   8861                 r.restartDelay = minDuration;
   8862             } else {
   8863                 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
   8864                 if (r.restartDelay < minDuration) {
   8865                     r.restartDelay = minDuration;
   8866                 }
   8867             }
   8868         }
   8869 
   8870         r.nextRestartTime = now + r.restartDelay;
   8871 
   8872         // Make sure that we don't end up restarting a bunch of services
   8873         // all at the same time.
   8874         boolean repeat;
   8875         do {
   8876             repeat = false;
   8877             for (int i=mRestartingServices.size()-1; i>=0; i--) {
   8878                 ServiceRecord r2 = mRestartingServices.get(i);
   8879                 if (r2 != r && r.nextRestartTime
   8880                         >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
   8881                         && r.nextRestartTime
   8882                         < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
   8883                     r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
   8884                     r.restartDelay = r.nextRestartTime - now;
   8885                     repeat = true;
   8886                     break;
   8887                 }
   8888             }
   8889         } while (repeat);
   8890 
   8891         if (!mRestartingServices.contains(r)) {
   8892             mRestartingServices.add(r);
   8893         }
   8894 
   8895         r.cancelNotification();
   8896 
   8897         mHandler.removeCallbacks(r.restarter);
   8898         mHandler.postAtTime(r.restarter, r.nextRestartTime);
   8899         r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
   8900         Slog.w(TAG, "Scheduling restart of crashed service "
   8901                 + r.shortName + " in " + r.restartDelay + "ms");
   8902         EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
   8903                 r.shortName, r.restartDelay);
   8904 
   8905         return canceled;
   8906     }
   8907 
   8908     final void performServiceRestartLocked(ServiceRecord r) {
   8909         if (!mRestartingServices.contains(r)) {
   8910             return;
   8911         }
   8912         bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
   8913     }
   8914 
   8915     private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
   8916         if (r.restartDelay == 0) {
   8917             return false;
   8918         }
   8919         r.resetRestartCounter();
   8920         mRestartingServices.remove(r);
   8921         mHandler.removeCallbacks(r.restarter);
   8922         return true;
   8923     }
   8924 
   8925     private final boolean bringUpServiceLocked(ServiceRecord r,
   8926             int intentFlags, boolean whileRestarting) {
   8927         //Slog.i(TAG, "Bring up service:");
   8928         //r.dump("  ");
   8929 
   8930         if (r.app != null && r.app.thread != null) {
   8931             sendServiceArgsLocked(r, false);
   8932             return true;
   8933         }
   8934 
   8935         if (!whileRestarting && r.restartDelay > 0) {
   8936             // If waiting for a restart, then do nothing.
   8937             return true;
   8938         }
   8939 
   8940         if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
   8941 
   8942         // We are now bringing the service up, so no longer in the
   8943         // restarting state.
   8944         mRestartingServices.remove(r);
   8945 
   8946         final String appName = r.processName;
   8947         ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
   8948         if (app != null && app.thread != null) {
   8949             try {
   8950                 realStartServiceLocked(r, app);
   8951                 return true;
   8952             } catch (RemoteException e) {
   8953                 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
   8954             }
   8955 
   8956             // If a dead object exception was thrown -- fall through to
   8957             // restart the application.
   8958         }
   8959 
   8960         // Not running -- get it started, and enqueue this service record
   8961         // to be executed when the app comes up.
   8962         if (startProcessLocked(appName, r.appInfo, true, intentFlags,
   8963                 "service", r.name, false) == null) {
   8964             Slog.w(TAG, "Unable to launch app "
   8965                     + r.appInfo.packageName + "/"
   8966                     + r.appInfo.uid + " for service "
   8967                     + r.intent.getIntent() + ": process is bad");
   8968             bringDownServiceLocked(r, true);
   8969             return false;
   8970         }
   8971 
   8972         if (!mPendingServices.contains(r)) {
   8973             mPendingServices.add(r);
   8974         }
   8975 
   8976         return true;
   8977     }
   8978 
   8979     private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
   8980         //Slog.i(TAG, "Bring down service:");
   8981         //r.dump("  ");
   8982 
   8983         // Does it still need to run?
   8984         if (!force && r.startRequested) {
   8985             return;
   8986         }
   8987         if (r.connections.size() > 0) {
   8988             if (!force) {
   8989                 // XXX should probably keep a count of the number of auto-create
   8990                 // connections directly in the service.
   8991                 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
   8992                 while (it.hasNext()) {
   8993                     ArrayList<ConnectionRecord> cr = it.next();
   8994                     for (int i=0; i<cr.size(); i++) {
   8995                         if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
   8996                             return;
   8997                         }
   8998                     }
   8999                 }
   9000             }
   9001 
   9002             // Report to all of the connections that the service is no longer
   9003             // available.
   9004             Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
   9005             while (it.hasNext()) {
   9006                 ArrayList<ConnectionRecord> c = it.next();
   9007                 for (int i=0; i<c.size(); i++) {
   9008                     try {
   9009                         c.get(i).conn.connected(r.name, null);
   9010                     } catch (Exception e) {
   9011                         Slog.w(TAG, "Failure disconnecting service " + r.name +
   9012                               " to connection " + c.get(i).conn.asBinder() +
   9013                               " (in " + c.get(i).binding.client.processName + ")", e);
   9014                     }
   9015                 }
   9016             }
   9017         }
   9018 
   9019         // Tell the service that it has been unbound.
   9020         if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
   9021             Iterator<IntentBindRecord> it = r.bindings.values().iterator();
   9022             while (it.hasNext()) {
   9023                 IntentBindRecord ibr = it.next();
   9024                 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
   9025                         + ": hasBound=" + ibr.hasBound);
   9026                 if (r.app != null && r.app.thread != null && ibr.hasBound) {
   9027                     try {
   9028                         bumpServiceExecutingLocked(r, "bring down unbind");
   9029                         updateOomAdjLocked(r.app);
   9030                         ibr.hasBound = false;
   9031                         r.app.thread.scheduleUnbindService(r,
   9032                                 ibr.intent.getIntent());
   9033                     } catch (Exception e) {
   9034                         Slog.w(TAG, "Exception when unbinding service "
   9035                                 + r.shortName, e);
   9036                         serviceDoneExecutingLocked(r, true);
   9037                     }
   9038                 }
   9039             }
   9040         }
   9041 
   9042         if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
   9043         EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
   9044                 System.identityHashCode(r), r.shortName,
   9045                 (r.app != null) ? r.app.pid : -1);
   9046 
   9047         mServices.remove(r.name);
   9048         mServicesByIntent.remove(r.intent);
   9049         r.totalRestartCount = 0;
   9050         unscheduleServiceRestartLocked(r);
   9051 
   9052         // Also make sure it is not on the pending list.
   9053         int N = mPendingServices.size();
   9054         for (int i=0; i<N; i++) {
   9055             if (mPendingServices.get(i) == r) {
   9056                 mPendingServices.remove(i);
   9057                 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
   9058                 i--;
   9059                 N--;
   9060             }
   9061         }
   9062 
   9063         r.cancelNotification();
   9064         r.isForeground = false;
   9065         r.foregroundId = 0;
   9066         r.foregroundNoti = null;
   9067 
   9068         // Clear start entries.
   9069         r.clearDeliveredStartsLocked();
   9070         r.pendingStarts.clear();
   9071 
   9072         if (r.app != null) {
   9073             synchronized (r.stats.getBatteryStats()) {
   9074                 r.stats.stopLaunchedLocked();
   9075             }
   9076             r.app.services.remove(r);
   9077             if (r.app.thread != null) {
   9078                 try {
   9079                     bumpServiceExecutingLocked(r, "stop");
   9080                     mStoppingServices.add(r);
   9081                     updateOomAdjLocked(r.app);
   9082                     r.app.thread.scheduleStopService(r);
   9083                 } catch (Exception e) {
   9084                     Slog.w(TAG, "Exception when stopping service "
   9085                             + r.shortName, e);
   9086                     serviceDoneExecutingLocked(r, true);
   9087                 }
   9088                 updateServiceForegroundLocked(r.app, false);
   9089             } else {
   9090                 if (DEBUG_SERVICE) Slog.v(
   9091                     TAG, "Removed service that has no process: " + r);
   9092             }
   9093         } else {
   9094             if (DEBUG_SERVICE) Slog.v(
   9095                 TAG, "Removed service that is not running: " + r);
   9096         }
   9097 
   9098         if (r.bindings.size() > 0) {
   9099             r.bindings.clear();
   9100         }
   9101 
   9102         if (r.restarter instanceof ServiceRestarter) {
   9103            ((ServiceRestarter)r.restarter).setService(null);
   9104         }
   9105     }
   9106 
   9107     ComponentName startServiceLocked(IApplicationThread caller,
   9108             Intent service, String resolvedType,
   9109             int callingPid, int callingUid) {
   9110         synchronized(this) {
   9111             if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
   9112                     + " type=" + resolvedType + " args=" + service.getExtras());
   9113 
   9114             if (caller != null) {
   9115                 final ProcessRecord callerApp = getRecordForAppLocked(caller);
   9116                 if (callerApp == null) {
   9117                     throw new SecurityException(
   9118                             "Unable to find app for caller " + caller
   9119                             + " (pid=" + Binder.getCallingPid()
   9120                             + ") when starting service " + service);
   9121                 }
   9122             }
   9123 
   9124             ServiceLookupResult res =
   9125                 retrieveServiceLocked(service, resolvedType,
   9126                         callingPid, callingUid);
   9127             if (res == null) {
   9128                 return null;
   9129             }
   9130             if (res.record == null) {
   9131                 return new ComponentName("!", res.permission != null
   9132                         ? res.permission : "private to package");
   9133             }
   9134             ServiceRecord r = res.record;
   9135             int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
   9136                     callingUid, r.packageName, service);
   9137             if (unscheduleServiceRestartLocked(r)) {
   9138                 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
   9139             }
   9140             r.startRequested = true;
   9141             r.callStart = false;
   9142             r.lastStartId++;
   9143             if (r.lastStartId < 1) {
   9144                 r.lastStartId = 1;
   9145             }
   9146             r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId,
   9147                     service, targetPermissionUid));
   9148             r.lastActivity = SystemClock.uptimeMillis();
   9149             synchronized (r.stats.getBatteryStats()) {
   9150                 r.stats.startRunningLocked();
   9151             }
   9152             if (!bringUpServiceLocked(r, service.getFlags(), false)) {
   9153                 return new ComponentName("!", "Service process is bad");
   9154             }
   9155             return r.name;
   9156         }
   9157     }
   9158 
   9159     public ComponentName startService(IApplicationThread caller, Intent service,
   9160             String resolvedType) {
   9161         // Refuse possible leaked file descriptors
   9162         if (service != null && service.hasFileDescriptors() == true) {
   9163             throw new IllegalArgumentException("File descriptors passed in Intent");
   9164         }
   9165 
   9166         synchronized(this) {
   9167             final int callingPid = Binder.getCallingPid();
   9168             final int callingUid = Binder.getCallingUid();
   9169             final long origId = Binder.clearCallingIdentity();
   9170             ComponentName res = startServiceLocked(caller, service,
   9171                     resolvedType, callingPid, callingUid);
   9172             Binder.restoreCallingIdentity(origId);
   9173             return res;
   9174         }
   9175     }
   9176 
   9177     ComponentName startServiceInPackage(int uid,
   9178             Intent service, String resolvedType) {
   9179         synchronized(this) {
   9180             final long origId = Binder.clearCallingIdentity();
   9181             ComponentName res = startServiceLocked(null, service,
   9182                     resolvedType, -1, uid);
   9183             Binder.restoreCallingIdentity(origId);
   9184             return res;
   9185         }
   9186     }
   9187 
   9188     public int stopService(IApplicationThread caller, Intent service,
   9189             String resolvedType) {
   9190         // Refuse possible leaked file descriptors
   9191         if (service != null && service.hasFileDescriptors() == true) {
   9192             throw new IllegalArgumentException("File descriptors passed in Intent");
   9193         }
   9194 
   9195         synchronized(this) {
   9196             if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
   9197                     + " type=" + resolvedType);
   9198 
   9199             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   9200             if (caller != null && callerApp == null) {
   9201                 throw new SecurityException(
   9202                         "Unable to find app for caller " + caller
   9203                         + " (pid=" + Binder.getCallingPid()
   9204                         + ") when stopping service " + service);
   9205             }
   9206 
   9207             // If this service is active, make sure it is stopped.
   9208             ServiceLookupResult r = findServiceLocked(service, resolvedType);
   9209             if (r != null) {
   9210                 if (r.record != null) {
   9211                     synchronized (r.record.stats.getBatteryStats()) {
   9212                         r.record.stats.stopRunningLocked();
   9213                     }
   9214                     r.record.startRequested = false;
   9215                     r.record.callStart = false;
   9216                     final long origId = Binder.clearCallingIdentity();
   9217                     bringDownServiceLocked(r.record, false);
   9218                     Binder.restoreCallingIdentity(origId);
   9219                     return 1;
   9220                 }
   9221                 return -1;
   9222             }
   9223         }
   9224 
   9225         return 0;
   9226     }
   9227 
   9228     public IBinder peekService(Intent service, String resolvedType) {
   9229         // Refuse possible leaked file descriptors
   9230         if (service != null && service.hasFileDescriptors() == true) {
   9231             throw new IllegalArgumentException("File descriptors passed in Intent");
   9232         }
   9233 
   9234         IBinder ret = null;
   9235 
   9236         synchronized(this) {
   9237             ServiceLookupResult r = findServiceLocked(service, resolvedType);
   9238 
   9239             if (r != null) {
   9240                 // r.record is null if findServiceLocked() failed the caller permission check
   9241                 if (r.record == null) {
   9242                     throw new SecurityException(
   9243                             "Permission Denial: Accessing service "
   9244                             + " from pid=" + Binder.getCallingPid()
   9245                             + ", uid=" + Binder.getCallingUid()
   9246                             + " requires " + r.permission);
   9247                 }
   9248                 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
   9249                 if (ib != null) {
   9250                     ret = ib.binder;
   9251                 }
   9252             }
   9253         }
   9254 
   9255         return ret;
   9256     }
   9257 
   9258     public boolean stopServiceToken(ComponentName className, IBinder token,
   9259             int startId) {
   9260         synchronized(this) {
   9261             if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
   9262                     + " " + token + " startId=" + startId);
   9263             ServiceRecord r = findServiceLocked(className, token);
   9264             if (r != null) {
   9265                 if (startId >= 0) {
   9266                     // Asked to only stop if done with all work.  Note that
   9267                     // to avoid leaks, we will take this as dropping all
   9268                     // start items up to and including this one.
   9269                     ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
   9270                     if (si != null) {
   9271                         while (r.deliveredStarts.size() > 0) {
   9272                             ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
   9273                             cur.removeUriPermissionsLocked();
   9274                             if (cur == si) {
   9275                                 break;
   9276                             }
   9277                         }
   9278                     }
   9279 
   9280                     if (r.lastStartId != startId) {
   9281                         return false;
   9282                     }
   9283 
   9284                     if (r.deliveredStarts.size() > 0) {
   9285                         Slog.w(TAG, "stopServiceToken startId " + startId
   9286                                 + " is last, but have " + r.deliveredStarts.size()
   9287                                 + " remaining args");
   9288                     }
   9289                 }
   9290 
   9291                 synchronized (r.stats.getBatteryStats()) {
   9292                     r.stats.stopRunningLocked();
   9293                     r.startRequested = false;
   9294                     r.callStart = false;
   9295                 }
   9296                 final long origId = Binder.clearCallingIdentity();
   9297                 bringDownServiceLocked(r, false);
   9298                 Binder.restoreCallingIdentity(origId);
   9299                 return true;
   9300             }
   9301         }
   9302         return false;
   9303     }
   9304 
   9305     public void setServiceForeground(ComponentName className, IBinder token,
   9306             int id, Notification notification, boolean removeNotification) {
   9307         final long origId = Binder.clearCallingIdentity();
   9308         try {
   9309         synchronized(this) {
   9310             ServiceRecord r = findServiceLocked(className, token);
   9311             if (r != null) {
   9312                 if (id != 0) {
   9313                     if (notification == null) {
   9314                         throw new IllegalArgumentException("null notification");
   9315                     }
   9316                     if (r.foregroundId != id) {
   9317                         r.cancelNotification();
   9318                         r.foregroundId = id;
   9319                     }
   9320                     notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
   9321                     r.foregroundNoti = notification;
   9322                     r.isForeground = true;
   9323                     r.postNotification();
   9324                     if (r.app != null) {
   9325                         updateServiceForegroundLocked(r.app, true);
   9326                     }
   9327                 } else {
   9328                     if (r.isForeground) {
   9329                         r.isForeground = false;
   9330                         if (r.app != null) {
   9331                             updateLruProcessLocked(r.app, false, true);
   9332                             updateServiceForegroundLocked(r.app, true);
   9333                         }
   9334                     }
   9335                     if (removeNotification) {
   9336                         r.cancelNotification();
   9337                         r.foregroundId = 0;
   9338                         r.foregroundNoti = null;
   9339                     }
   9340                 }
   9341             }
   9342         }
   9343         } finally {
   9344             Binder.restoreCallingIdentity(origId);
   9345         }
   9346     }
   9347 
   9348     public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
   9349         boolean anyForeground = false;
   9350         for (ServiceRecord sr : proc.services) {
   9351             if (sr.isForeground) {
   9352                 anyForeground = true;
   9353                 break;
   9354             }
   9355         }
   9356         if (anyForeground != proc.foregroundServices) {
   9357             proc.foregroundServices = anyForeground;
   9358             if (oomAdj) {
   9359                 updateOomAdjLocked();
   9360             }
   9361         }
   9362     }
   9363 
   9364     public int bindService(IApplicationThread caller, IBinder token,
   9365             Intent service, String resolvedType,
   9366             IServiceConnection connection, int flags) {
   9367         // Refuse possible leaked file descriptors
   9368         if (service != null && service.hasFileDescriptors() == true) {
   9369             throw new IllegalArgumentException("File descriptors passed in Intent");
   9370         }
   9371 
   9372         synchronized(this) {
   9373             if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
   9374                     + " type=" + resolvedType + " conn=" + connection.asBinder()
   9375                     + " flags=0x" + Integer.toHexString(flags));
   9376             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   9377             if (callerApp == null) {
   9378                 throw new SecurityException(
   9379                         "Unable to find app for caller " + caller
   9380                         + " (pid=" + Binder.getCallingPid()
   9381                         + ") when binding service " + service);
   9382             }
   9383 
   9384             ActivityRecord activity = null;
   9385             if (token != null) {
   9386                 int aindex = mMainStack.indexOfTokenLocked(token);
   9387                 if (aindex < 0) {
   9388                     Slog.w(TAG, "Binding with unknown activity: " + token);
   9389                     return 0;
   9390                 }
   9391                 activity = (ActivityRecord)mMainStack.mHistory.get(aindex);
   9392             }
   9393 
   9394             int clientLabel = 0;
   9395             PendingIntent clientIntent = null;
   9396 
   9397             if (callerApp.info.uid == Process.SYSTEM_UID) {
   9398                 // Hacky kind of thing -- allow system stuff to tell us
   9399                 // what they are, so we can report this elsewhere for
   9400                 // others to know why certain services are running.
   9401                 try {
   9402                     clientIntent = (PendingIntent)service.getParcelableExtra(
   9403                             Intent.EXTRA_CLIENT_INTENT);
   9404                 } catch (RuntimeException e) {
   9405                 }
   9406                 if (clientIntent != null) {
   9407                     clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
   9408                     if (clientLabel != 0) {
   9409                         // There are no useful extras in the intent, trash them.
   9410                         // System code calling with this stuff just needs to know
   9411                         // this will happen.
   9412                         service = service.cloneFilter();
   9413                     }
   9414                 }
   9415             }
   9416 
   9417             ServiceLookupResult res =
   9418                 retrieveServiceLocked(service, resolvedType,
   9419                         Binder.getCallingPid(), Binder.getCallingUid());
   9420             if (res == null) {
   9421                 return 0;
   9422             }
   9423             if (res.record == null) {
   9424                 return -1;
   9425             }
   9426             ServiceRecord s = res.record;
   9427 
   9428             final long origId = Binder.clearCallingIdentity();
   9429 
   9430             if (unscheduleServiceRestartLocked(s)) {
   9431                 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
   9432                         + s);
   9433             }
   9434 
   9435             AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
   9436             ConnectionRecord c = new ConnectionRecord(b, activity,
   9437                     connection, flags, clientLabel, clientIntent);
   9438 
   9439             IBinder binder = connection.asBinder();
   9440             ArrayList<ConnectionRecord> clist = s.connections.get(binder);
   9441             if (clist == null) {
   9442                 clist = new ArrayList<ConnectionRecord>();
   9443                 s.connections.put(binder, clist);
   9444             }
   9445             clist.add(c);
   9446             b.connections.add(c);
   9447             if (activity != null) {
   9448                 if (activity.connections == null) {
   9449                     activity.connections = new HashSet<ConnectionRecord>();
   9450                 }
   9451                 activity.connections.add(c);
   9452             }
   9453             b.client.connections.add(c);
   9454             clist = mServiceConnections.get(binder);
   9455             if (clist == null) {
   9456                 clist = new ArrayList<ConnectionRecord>();
   9457                 mServiceConnections.put(binder, clist);
   9458             }
   9459             clist.add(c);
   9460 
   9461             if ((flags&Context.BIND_AUTO_CREATE) != 0) {
   9462                 s.lastActivity = SystemClock.uptimeMillis();
   9463                 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
   9464                     return 0;
   9465                 }
   9466             }
   9467 
   9468             if (s.app != null) {
   9469                 // This could have made the service more important.
   9470                 updateOomAdjLocked(s.app);
   9471             }
   9472 
   9473             if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
   9474                     + ": received=" + b.intent.received
   9475                     + " apps=" + b.intent.apps.size()
   9476                     + " doRebind=" + b.intent.doRebind);
   9477 
   9478             if (s.app != null && b.intent.received) {
   9479                 // Service is already running, so we can immediately
   9480                 // publish the connection.
   9481                 try {
   9482                     c.conn.connected(s.name, b.intent.binder);
   9483                 } catch (Exception e) {
   9484                     Slog.w(TAG, "Failure sending service " + s.shortName
   9485                             + " to connection " + c.conn.asBinder()
   9486                             + " (in " + c.binding.client.processName + ")", e);
   9487                 }
   9488 
   9489                 // If this is the first app connected back to this binding,
   9490                 // and the service had previously asked to be told when
   9491                 // rebound, then do so.
   9492                 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
   9493                     requestServiceBindingLocked(s, b.intent, true);
   9494                 }
   9495             } else if (!b.intent.requested) {
   9496                 requestServiceBindingLocked(s, b.intent, false);
   9497             }
   9498 
   9499             Binder.restoreCallingIdentity(origId);
   9500         }
   9501 
   9502         return 1;
   9503     }
   9504 
   9505     void removeConnectionLocked(
   9506         ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
   9507         IBinder binder = c.conn.asBinder();
   9508         AppBindRecord b = c.binding;
   9509         ServiceRecord s = b.service;
   9510         ArrayList<ConnectionRecord> clist = s.connections.get(binder);
   9511         if (clist != null) {
   9512             clist.remove(c);
   9513             if (clist.size() == 0) {
   9514                 s.connections.remove(binder);
   9515             }
   9516         }
   9517         b.connections.remove(c);
   9518         if (c.activity != null && c.activity != skipAct) {
   9519             if (c.activity.connections != null) {
   9520                 c.activity.connections.remove(c);
   9521             }
   9522         }
   9523         if (b.client != skipApp) {
   9524             b.client.connections.remove(c);
   9525         }
   9526         clist = mServiceConnections.get(binder);
   9527         if (clist != null) {
   9528             clist.remove(c);
   9529             if (clist.size() == 0) {
   9530                 mServiceConnections.remove(binder);
   9531             }
   9532         }
   9533 
   9534         if (b.connections.size() == 0) {
   9535             b.intent.apps.remove(b.client);
   9536         }
   9537 
   9538         if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
   9539                 + ": shouldUnbind=" + b.intent.hasBound);
   9540         if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
   9541                 && b.intent.hasBound) {
   9542             try {
   9543                 bumpServiceExecutingLocked(s, "unbind");
   9544                 updateOomAdjLocked(s.app);
   9545                 b.intent.hasBound = false;
   9546                 // Assume the client doesn't want to know about a rebind;
   9547                 // we will deal with that later if it asks for one.
   9548                 b.intent.doRebind = false;
   9549                 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
   9550             } catch (Exception e) {
   9551                 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
   9552                 serviceDoneExecutingLocked(s, true);
   9553             }
   9554         }
   9555 
   9556         if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
   9557             bringDownServiceLocked(s, false);
   9558         }
   9559     }
   9560 
   9561     public boolean unbindService(IServiceConnection connection) {
   9562         synchronized (this) {
   9563             IBinder binder = connection.asBinder();
   9564             if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
   9565             ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
   9566             if (clist == null) {
   9567                 Slog.w(TAG, "Unbind failed: could not find connection for "
   9568                       + connection.asBinder());
   9569                 return false;
   9570             }
   9571 
   9572             final long origId = Binder.clearCallingIdentity();
   9573 
   9574             while (clist.size() > 0) {
   9575                 ConnectionRecord r = clist.get(0);
   9576                 removeConnectionLocked(r, null, null);
   9577 
   9578                 if (r.binding.service.app != null) {
   9579                     // This could have made the service less important.
   9580                     updateOomAdjLocked(r.binding.service.app);
   9581                 }
   9582             }
   9583 
   9584             Binder.restoreCallingIdentity(origId);
   9585         }
   9586 
   9587         return true;
   9588     }
   9589 
   9590     public void publishService(IBinder token, Intent intent, IBinder service) {
   9591         // Refuse possible leaked file descriptors
   9592         if (intent != null && intent.hasFileDescriptors() == true) {
   9593             throw new IllegalArgumentException("File descriptors passed in Intent");
   9594         }
   9595 
   9596         synchronized(this) {
   9597             if (!(token instanceof ServiceRecord)) {
   9598                 throw new IllegalArgumentException("Invalid service token");
   9599             }
   9600             ServiceRecord r = (ServiceRecord)token;
   9601 
   9602             final long origId = Binder.clearCallingIdentity();
   9603 
   9604             if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
   9605                     + " " + intent + ": " + service);
   9606             if (r != null) {
   9607                 Intent.FilterComparison filter
   9608                         = new Intent.FilterComparison(intent);
   9609                 IntentBindRecord b = r.bindings.get(filter);
   9610                 if (b != null && !b.received) {
   9611                     b.binder = service;
   9612                     b.requested = true;
   9613                     b.received = true;
   9614                     if (r.connections.size() > 0) {
   9615                         Iterator<ArrayList<ConnectionRecord>> it
   9616                                 = r.connections.values().iterator();
   9617                         while (it.hasNext()) {
   9618                             ArrayList<ConnectionRecord> clist = it.next();
   9619                             for (int i=0; i<clist.size(); i++) {
   9620                                 ConnectionRecord c = clist.get(i);
   9621                                 if (!filter.equals(c.binding.intent.intent)) {
   9622                                     if (DEBUG_SERVICE) Slog.v(
   9623                                             TAG, "Not publishing to: " + c);
   9624                                     if (DEBUG_SERVICE) Slog.v(
   9625                                             TAG, "Bound intent: " + c.binding.intent.intent);
   9626                                     if (DEBUG_SERVICE) Slog.v(
   9627                                             TAG, "Published intent: " + intent);
   9628                                     continue;
   9629                                 }
   9630                                 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
   9631                                 try {
   9632                                     c.conn.connected(r.name, service);
   9633                                 } catch (Exception e) {
   9634                                     Slog.w(TAG, "Failure sending service " + r.name +
   9635                                           " to connection " + c.conn.asBinder() +
   9636                                           " (in " + c.binding.client.processName + ")", e);
   9637                                 }
   9638                             }
   9639                         }
   9640                     }
   9641                 }
   9642 
   9643                 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
   9644 
   9645                 Binder.restoreCallingIdentity(origId);
   9646             }
   9647         }
   9648     }
   9649 
   9650     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
   9651         // Refuse possible leaked file descriptors
   9652         if (intent != null && intent.hasFileDescriptors() == true) {
   9653             throw new IllegalArgumentException("File descriptors passed in Intent");
   9654         }
   9655 
   9656         synchronized(this) {
   9657             if (!(token instanceof ServiceRecord)) {
   9658                 throw new IllegalArgumentException("Invalid service token");
   9659             }
   9660             ServiceRecord r = (ServiceRecord)token;
   9661 
   9662             final long origId = Binder.clearCallingIdentity();
   9663 
   9664             if (r != null) {
   9665                 Intent.FilterComparison filter
   9666                         = new Intent.FilterComparison(intent);
   9667                 IntentBindRecord b = r.bindings.get(filter);
   9668                 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
   9669                         + " at " + b + ": apps="
   9670                         + (b != null ? b.apps.size() : 0));
   9671                 if (b != null) {
   9672                     if (b.apps.size() > 0) {
   9673                         // Applications have already bound since the last
   9674                         // unbind, so just rebind right here.
   9675                         requestServiceBindingLocked(r, b, true);
   9676                     } else {
   9677                         // Note to tell the service the next time there is
   9678                         // a new client.
   9679                         b.doRebind = true;
   9680                     }
   9681                 }
   9682 
   9683                 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
   9684 
   9685                 Binder.restoreCallingIdentity(origId);
   9686             }
   9687         }
   9688     }
   9689 
   9690     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
   9691         synchronized(this) {
   9692             if (!(token instanceof ServiceRecord)) {
   9693                 throw new IllegalArgumentException("Invalid service token");
   9694             }
   9695             ServiceRecord r = (ServiceRecord)token;
   9696             boolean inStopping = mStoppingServices.contains(token);
   9697             if (r != null) {
   9698                 if (r != token) {
   9699                     Slog.w(TAG, "Done executing service " + r.name
   9700                           + " with incorrect token: given " + token
   9701                           + ", expected " + r);
   9702                     return;
   9703                 }
   9704 
   9705                 if (type == 1) {
   9706                     // This is a call from a service start...  take care of
   9707                     // book-keeping.
   9708                     r.callStart = true;
   9709                     switch (res) {
   9710                         case Service.START_STICKY_COMPATIBILITY:
   9711                         case Service.START_STICKY: {
   9712                             // We are done with the associated start arguments.
   9713                             r.findDeliveredStart(startId, true);
   9714                             // Don't stop if killed.
   9715                             r.stopIfKilled = false;
   9716                             break;
   9717                         }
   9718                         case Service.START_NOT_STICKY: {
   9719                             // We are done with the associated start arguments.
   9720                             r.findDeliveredStart(startId, true);
   9721                             if (r.lastStartId == startId) {
   9722                                 // There is no more work, and this service
   9723                                 // doesn't want to hang around if killed.
   9724                                 r.stopIfKilled = true;
   9725                             }
   9726                             break;
   9727                         }
   9728                         case Service.START_REDELIVER_INTENT: {
   9729                             // We'll keep this item until they explicitly
   9730                             // call stop for it, but keep track of the fact
   9731                             // that it was delivered.
   9732                             ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
   9733                             if (si != null) {
   9734                                 si.deliveryCount = 0;
   9735                                 si.doneExecutingCount++;
   9736                                 // Don't stop if killed.
   9737                                 r.stopIfKilled = true;
   9738                             }
   9739                             break;
   9740                         }
   9741                         default:
   9742                             throw new IllegalArgumentException(
   9743                                     "Unknown service start result: " + res);
   9744                     }
   9745                     if (res == Service.START_STICKY_COMPATIBILITY) {
   9746                         r.callStart = false;
   9747                     }
   9748                 }
   9749 
   9750                 final long origId = Binder.clearCallingIdentity();
   9751                 serviceDoneExecutingLocked(r, inStopping);
   9752                 Binder.restoreCallingIdentity(origId);
   9753             } else {
   9754                 Slog.w(TAG, "Done executing unknown service from pid "
   9755                         + Binder.getCallingPid());
   9756             }
   9757         }
   9758     }
   9759 
   9760     public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
   9761         if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
   9762                 + ": nesting=" + r.executeNesting
   9763                 + ", inStopping=" + inStopping + ", app=" + r.app);
   9764         else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
   9765         r.executeNesting--;
   9766         if (r.executeNesting <= 0 && r.app != null) {
   9767             if (DEBUG_SERVICE) Slog.v(TAG,
   9768                     "Nesting at 0 of " + r.shortName);
   9769             r.app.executingServices.remove(r);
   9770             if (r.app.executingServices.size() == 0) {
   9771                 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
   9772                         "No more executingServices of " + r.shortName);
   9773                 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
   9774             }
   9775             if (inStopping) {
   9776                 if (DEBUG_SERVICE) Slog.v(TAG,
   9777                         "doneExecuting remove stopping " + r);
   9778                 mStoppingServices.remove(r);
   9779                 r.bindings.clear();
   9780             }
   9781             updateOomAdjLocked(r.app);
   9782         }
   9783     }
   9784 
   9785     void serviceTimeout(ProcessRecord proc) {
   9786         String anrMessage = null;
   9787 
   9788         synchronized(this) {
   9789             if (proc.executingServices.size() == 0 || proc.thread == null) {
   9790                 return;
   9791             }
   9792             long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
   9793             Iterator<ServiceRecord> it = proc.executingServices.iterator();
   9794             ServiceRecord timeout = null;
   9795             long nextTime = 0;
   9796             while (it.hasNext()) {
   9797                 ServiceRecord sr = it.next();
   9798                 if (sr.executingStart < maxTime) {
   9799                     timeout = sr;
   9800                     break;
   9801                 }
   9802                 if (sr.executingStart > nextTime) {
   9803                     nextTime = sr.executingStart;
   9804                 }
   9805             }
   9806             if (timeout != null && mLruProcesses.contains(proc)) {
   9807                 Slog.w(TAG, "Timeout executing service: " + timeout);
   9808                 anrMessage = "Executing service " + timeout.shortName;
   9809             } else {
   9810                 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   9811                 msg.obj = proc;
   9812                 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
   9813             }
   9814         }
   9815 
   9816         if (anrMessage != null) {
   9817             appNotResponding(proc, null, null, anrMessage);
   9818         }
   9819     }
   9820 
   9821     // =========================================================
   9822     // BACKUP AND RESTORE
   9823     // =========================================================
   9824 
   9825     // Cause the target app to be launched if necessary and its backup agent
   9826     // instantiated.  The backup agent will invoke backupAgentCreated() on the
   9827     // activity manager to announce its creation.
   9828     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
   9829         if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
   9830         enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
   9831 
   9832         synchronized(this) {
   9833             // !!! TODO: currently no check here that we're already bound
   9834             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   9835             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   9836             synchronized (stats) {
   9837                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
   9838             }
   9839 
   9840             BackupRecord r = new BackupRecord(ss, app, backupMode);
   9841             ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName);
   9842             // startProcessLocked() returns existing proc's record if it's already running
   9843             ProcessRecord proc = startProcessLocked(app.processName, app,
   9844                     false, 0, "backup", hostingName, false);
   9845             if (proc == null) {
   9846                 Slog.e(TAG, "Unable to start backup agent process " + r);
   9847                 return false;
   9848             }
   9849 
   9850             r.app = proc;
   9851             mBackupTarget = r;
   9852             mBackupAppName = app.packageName;
   9853 
   9854             // Try not to kill the process during backup
   9855             updateOomAdjLocked(proc);
   9856 
   9857             // If the process is already attached, schedule the creation of the backup agent now.
   9858             // If it is not yet live, this will be done when it attaches to the framework.
   9859             if (proc.thread != null) {
   9860                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
   9861                 try {
   9862                     proc.thread.scheduleCreateBackupAgent(app, backupMode);
   9863                 } catch (RemoteException e) {
   9864                     // Will time out on the backup manager side
   9865                 }
   9866             } else {
   9867                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
   9868             }
   9869             // Invariants: at this point, the target app process exists and the application
   9870             // is either already running or in the process of coming up.  mBackupTarget and
   9871             // mBackupAppName describe the app, so that when it binds back to the AM we
   9872             // know that it's scheduled for a backup-agent operation.
   9873         }
   9874 
   9875         return true;
   9876     }
   9877 
   9878     // A backup agent has just come up
   9879     public void backupAgentCreated(String agentPackageName, IBinder agent) {
   9880         if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
   9881                 + " = " + agent);
   9882 
   9883         synchronized(this) {
   9884             if (!agentPackageName.equals(mBackupAppName)) {
   9885                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
   9886                 return;
   9887             }
   9888         }
   9889 
   9890         long oldIdent = Binder.clearCallingIdentity();
   9891         try {
   9892             IBackupManager bm = IBackupManager.Stub.asInterface(
   9893                     ServiceManager.getService(Context.BACKUP_SERVICE));
   9894             bm.agentConnected(agentPackageName, agent);
   9895         } catch (RemoteException e) {
   9896             // can't happen; the backup manager service is local
   9897         } catch (Exception e) {
   9898             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
   9899             e.printStackTrace();
   9900         } finally {
   9901             Binder.restoreCallingIdentity(oldIdent);
   9902         }
   9903     }
   9904 
   9905     // done with this agent
   9906     public void unbindBackupAgent(ApplicationInfo appInfo) {
   9907         if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
   9908         if (appInfo == null) {
   9909             Slog.w(TAG, "unbind backup agent for null app");
   9910             return;
   9911         }
   9912 
   9913         synchronized(this) {
   9914             if (mBackupAppName == null) {
   9915                 Slog.w(TAG, "Unbinding backup agent with no active backup");
   9916                 return;
   9917             }
   9918 
   9919             if (!mBackupAppName.equals(appInfo.packageName)) {
   9920                 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
   9921                 return;
   9922             }
   9923 
   9924             ProcessRecord proc = mBackupTarget.app;
   9925             mBackupTarget = null;
   9926             mBackupAppName = null;
   9927 
   9928             // Not backing this app up any more; reset its OOM adjustment
   9929             updateOomAdjLocked(proc);
   9930 
   9931             // If the app crashed during backup, 'thread' will be null here
   9932             if (proc.thread != null) {
   9933                 try {
   9934                     proc.thread.scheduleDestroyBackupAgent(appInfo);
   9935                 } catch (Exception e) {
   9936                     Slog.e(TAG, "Exception when unbinding backup agent:");
   9937                     e.printStackTrace();
   9938                 }
   9939             }
   9940         }
   9941     }
   9942     // =========================================================
   9943     // BROADCASTS
   9944     // =========================================================
   9945 
   9946     private final List getStickiesLocked(String action, IntentFilter filter,
   9947             List cur) {
   9948         final ContentResolver resolver = mContext.getContentResolver();
   9949         final ArrayList<Intent> list = mStickyBroadcasts.get(action);
   9950         if (list == null) {
   9951             return cur;
   9952         }
   9953         int N = list.size();
   9954         for (int i=0; i<N; i++) {
   9955             Intent intent = list.get(i);
   9956             if (filter.match(resolver, intent, true, TAG) >= 0) {
   9957                 if (cur == null) {
   9958                     cur = new ArrayList<Intent>();
   9959                 }
   9960                 cur.add(intent);
   9961             }
   9962         }
   9963         return cur;
   9964     }
   9965 
   9966     private final void scheduleBroadcastsLocked() {
   9967         if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
   9968                 + mBroadcastsScheduled);
   9969 
   9970         if (mBroadcastsScheduled) {
   9971             return;
   9972         }
   9973         mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
   9974         mBroadcastsScheduled = true;
   9975     }
   9976 
   9977     public Intent registerReceiver(IApplicationThread caller,
   9978             IIntentReceiver receiver, IntentFilter filter, String permission) {
   9979         synchronized(this) {
   9980             ProcessRecord callerApp = null;
   9981             if (caller != null) {
   9982                 callerApp = getRecordForAppLocked(caller);
   9983                 if (callerApp == null) {
   9984                     throw new SecurityException(
   9985                             "Unable to find app for caller " + caller
   9986                             + " (pid=" + Binder.getCallingPid()
   9987                             + ") when registering receiver " + receiver);
   9988                 }
   9989             }
   9990 
   9991             List allSticky = null;
   9992 
   9993             // Look for any matching sticky broadcasts...
   9994             Iterator actions = filter.actionsIterator();
   9995             if (actions != null) {
   9996                 while (actions.hasNext()) {
   9997                     String action = (String)actions.next();
   9998                     allSticky = getStickiesLocked(action, filter, allSticky);
   9999                 }
   10000             } else {
   10001                 allSticky = getStickiesLocked(null, filter, allSticky);
   10002             }
   10003 
   10004             // The first sticky in the list is returned directly back to
   10005             // the client.
   10006             Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
   10007 
   10008             if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
   10009                     + ": " + sticky);
   10010 
   10011             if (receiver == null) {
   10012                 return sticky;
   10013             }
   10014 
   10015             ReceiverList rl
   10016                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   10017             if (rl == null) {
   10018                 rl = new ReceiverList(this, callerApp,
   10019                         Binder.getCallingPid(),
   10020                         Binder.getCallingUid(), receiver);
   10021                 if (rl.app != null) {
   10022                     rl.app.receivers.add(rl);
   10023                 } else {
   10024                     try {
   10025                         receiver.asBinder().linkToDeath(rl, 0);
   10026                     } catch (RemoteException e) {
   10027                         return sticky;
   10028                     }
   10029                     rl.linkedToDeath = true;
   10030                 }
   10031                 mRegisteredReceivers.put(receiver.asBinder(), rl);
   10032             }
   10033             BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
   10034             rl.add(bf);
   10035             if (!bf.debugCheck()) {
   10036                 Slog.w(TAG, "==> For Dynamic broadast");
   10037             }
   10038             mReceiverResolver.addFilter(bf);
   10039 
   10040             // Enqueue broadcasts for all existing stickies that match
   10041             // this filter.
   10042             if (allSticky != null) {
   10043                 ArrayList receivers = new ArrayList();
   10044                 receivers.add(bf);
   10045 
   10046                 int N = allSticky.size();
   10047                 for (int i=0; i<N; i++) {
   10048                     Intent intent = (Intent)allSticky.get(i);
   10049                     BroadcastRecord r = new BroadcastRecord(intent, null,
   10050                             null, -1, -1, null, receivers, null, 0, null, null,
   10051                             false, true, true);
   10052                     if (mParallelBroadcasts.size() == 0) {
   10053                         scheduleBroadcastsLocked();
   10054                     }
   10055                     mParallelBroadcasts.add(r);
   10056                 }
   10057             }
   10058 
   10059             return sticky;
   10060         }
   10061     }
   10062 
   10063     public void unregisterReceiver(IIntentReceiver receiver) {
   10064         if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
   10065 
   10066         boolean doNext = false;
   10067 
   10068         synchronized(this) {
   10069             ReceiverList rl
   10070                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   10071             if (rl != null) {
   10072                 if (rl.curBroadcast != null) {
   10073                     BroadcastRecord r = rl.curBroadcast;
   10074                     doNext = finishReceiverLocked(
   10075                         receiver.asBinder(), r.resultCode, r.resultData,
   10076                         r.resultExtras, r.resultAbort, true);
   10077                 }
   10078 
   10079                 if (rl.app != null) {
   10080                     rl.app.receivers.remove(rl);
   10081                 }
   10082                 removeReceiverLocked(rl);
   10083                 if (rl.linkedToDeath) {
   10084                     rl.linkedToDeath = false;
   10085                     rl.receiver.asBinder().unlinkToDeath(rl, 0);
   10086                 }
   10087             }
   10088         }
   10089 
   10090         if (!doNext) {
   10091             return;
   10092         }
   10093 
   10094         final long origId = Binder.clearCallingIdentity();
   10095         processNextBroadcast(false);
   10096         trimApplications();
   10097         Binder.restoreCallingIdentity(origId);
   10098     }
   10099 
   10100     void removeReceiverLocked(ReceiverList rl) {
   10101         mRegisteredReceivers.remove(rl.receiver.asBinder());
   10102         int N = rl.size();
   10103         for (int i=0; i<N; i++) {
   10104             mReceiverResolver.removeFilter(rl.get(i));
   10105         }
   10106     }
   10107 
   10108     private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
   10109         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   10110             ProcessRecord r = mLruProcesses.get(i);
   10111             if (r.thread != null) {
   10112                 try {
   10113                     r.thread.dispatchPackageBroadcast(cmd, packages);
   10114                 } catch (RemoteException ex) {
   10115                 }
   10116             }
   10117         }
   10118     }
   10119 
   10120     private final int broadcastIntentLocked(ProcessRecord callerApp,
   10121             String callerPackage, Intent intent, String resolvedType,
   10122             IIntentReceiver resultTo, int resultCode, String resultData,
   10123             Bundle map, String requiredPermission,
   10124             boolean ordered, boolean sticky, int callingPid, int callingUid) {
   10125         intent = new Intent(intent);
   10126 
   10127         if (DEBUG_BROADCAST_LIGHT) Slog.v(
   10128             TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
   10129             + " ordered=" + ordered);
   10130         if ((resultTo != null) && !ordered) {
   10131             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
   10132         }
   10133 
   10134         // Handle special intents: if this broadcast is from the package
   10135         // manager about a package being removed, we need to remove all of
   10136         // its activities from the history stack.
   10137         final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals(
   10138                 intent.getAction());
   10139         if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
   10140                 || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
   10141                 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
   10142                 || uidRemoved) {
   10143             if (checkComponentPermission(
   10144                     android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
   10145                     callingPid, callingUid, -1)
   10146                     == PackageManager.PERMISSION_GRANTED) {
   10147                 if (uidRemoved) {
   10148                     final Bundle intentExtras = intent.getExtras();
   10149                     final int uid = intentExtras != null
   10150                             ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
   10151                     if (uid >= 0) {
   10152                         BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
   10153                         synchronized (bs) {
   10154                             bs.removeUidStatsLocked(uid);
   10155                         }
   10156                     }
   10157                 } else {
   10158                     // If resources are unvailble just force stop all
   10159                     // those packages and flush the attribute cache as well.
   10160                     if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
   10161                         String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   10162                         if (list != null && (list.length > 0)) {
   10163                             for (String pkg : list) {
   10164                                 forceStopPackageLocked(pkg, -1, false, true, true);
   10165                             }
   10166                             sendPackageBroadcastLocked(
   10167                                     IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
   10168                         }
   10169                     } else {
   10170                         Uri data = intent.getData();
   10171                         String ssp;
   10172                         if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   10173                             if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
   10174                                 forceStopPackageLocked(ssp,
   10175                                         intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
   10176                             }
   10177                             if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
   10178                                 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
   10179                                         new String[] {ssp});
   10180                             }
   10181                         }
   10182                     }
   10183                 }
   10184             } else {
   10185                 String msg = "Permission Denial: " + intent.getAction()
   10186                         + " broadcast from " + callerPackage + " (pid=" + callingPid
   10187                         + ", uid=" + callingUid + ")"
   10188                         + " requires "
   10189                         + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
   10190                 Slog.w(TAG, msg);
   10191                 throw new SecurityException(msg);
   10192             }
   10193         }
   10194 
   10195         /*
   10196          * If this is the time zone changed action, queue up a message that will reset the timezone
   10197          * of all currently running processes. This message will get queued up before the broadcast
   10198          * happens.
   10199          */
   10200         if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
   10201             mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
   10202         }
   10203 
   10204         /*
   10205          * Prevent non-system code (defined here to be non-persistent
   10206          * processes) from sending protected broadcasts.
   10207          */
   10208         if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
   10209                 || callingUid == Process.SHELL_UID || callingUid == 0) {
   10210             // Always okay.
   10211         } else if (callerApp == null || !callerApp.persistent) {
   10212             try {
   10213                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
   10214                         intent.getAction())) {
   10215                     String msg = "Permission Denial: not allowed to send broadcast "
   10216                             + intent.getAction() + " from pid="
   10217                             + callingPid + ", uid=" + callingUid;
   10218                     Slog.w(TAG, msg);
   10219                     throw new SecurityException(msg);
   10220                 }
   10221             } catch (RemoteException e) {
   10222                 Slog.w(TAG, "Remote exception", e);
   10223                 return BROADCAST_SUCCESS;
   10224             }
   10225         }
   10226 
   10227         // Add to the sticky list if requested.
   10228         if (sticky) {
   10229             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
   10230                     callingPid, callingUid)
   10231                     != PackageManager.PERMISSION_GRANTED) {
   10232                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
   10233                         + callingPid + ", uid=" + callingUid
   10234                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   10235                 Slog.w(TAG, msg);
   10236                 throw new SecurityException(msg);
   10237             }
   10238             if (requiredPermission != null) {
   10239                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
   10240                         + " and enforce permission " + requiredPermission);
   10241                 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
   10242             }
   10243             if (intent.getComponent() != null) {
   10244                 throw new SecurityException(
   10245                         "Sticky broadcasts can't target a specific component");
   10246             }
   10247             ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
   10248             if (list == null) {
   10249                 list = new ArrayList<Intent>();
   10250                 mStickyBroadcasts.put(intent.getAction(), list);
   10251             }
   10252             int N = list.size();
   10253             int i;
   10254             for (i=0; i<N; i++) {
   10255                 if (intent.filterEquals(list.get(i))) {
   10256                     // This sticky already exists, replace it.
   10257                     list.set(i, new Intent(intent));
   10258                     break;
   10259                 }
   10260             }
   10261             if (i >= N) {
   10262                 list.add(new Intent(intent));
   10263             }
   10264         }
   10265 
   10266         // Figure out who all will receive this broadcast.
   10267         List receivers = null;
   10268         List<BroadcastFilter> registeredReceivers = null;
   10269         try {
   10270             if (intent.getComponent() != null) {
   10271                 // Broadcast is going to one specific receiver class...
   10272                 ActivityInfo ai = AppGlobals.getPackageManager().
   10273                     getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
   10274                 if (ai != null) {
   10275                     receivers = new ArrayList();
   10276                     ResolveInfo ri = new ResolveInfo();
   10277                     ri.activityInfo = ai;
   10278                     receivers.add(ri);
   10279                 }
   10280             } else {
   10281                 // Need to resolve the intent to interested receivers...
   10282                 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
   10283                          == 0) {
   10284                     receivers =
   10285                         AppGlobals.getPackageManager().queryIntentReceivers(
   10286                                 intent, resolvedType, STOCK_PM_FLAGS);
   10287                 }
   10288                 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
   10289             }
   10290         } catch (RemoteException ex) {
   10291             // pm is in same process, this will never happen.
   10292         }
   10293 
   10294         final boolean replacePending =
   10295                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
   10296 
   10297         if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
   10298                 + " replacePending=" + replacePending);
   10299 
   10300         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
   10301         if (!ordered && NR > 0) {
   10302             // If we are not serializing this broadcast, then send the
   10303             // registered receivers separately so they don't wait for the
   10304             // components to be launched.
   10305             BroadcastRecord r = new BroadcastRecord(intent, callerApp,
   10306                     callerPackage, callingPid, callingUid, requiredPermission,
   10307                     registeredReceivers, resultTo, resultCode, resultData, map,
   10308                     ordered, sticky, false);
   10309             if (DEBUG_BROADCAST) Slog.v(
   10310                     TAG, "Enqueueing parallel broadcast " + r
   10311                     + ": prev had " + mParallelBroadcasts.size());
   10312             boolean replaced = false;
   10313             if (replacePending) {
   10314                 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
   10315                     if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
   10316                         if (DEBUG_BROADCAST) Slog.v(TAG,
   10317                                 "***** DROPPING PARALLEL: " + intent);
   10318                         mParallelBroadcasts.set(i, r);
   10319                         replaced = true;
   10320                         break;
   10321                     }
   10322                 }
   10323             }
   10324             if (!replaced) {
   10325                 mParallelBroadcasts.add(r);
   10326                 scheduleBroadcastsLocked();
   10327             }
   10328             registeredReceivers = null;
   10329             NR = 0;
   10330         }
   10331 
   10332         // Merge into one list.
   10333         int ir = 0;
   10334         if (receivers != null) {
   10335             // A special case for PACKAGE_ADDED: do not allow the package
   10336             // being added to see this broadcast.  This prevents them from
   10337             // using this as a back door to get run as soon as they are
   10338             // installed.  Maybe in the future we want to have a special install
   10339             // broadcast or such for apps, but we'd like to deliberately make
   10340             // this decision.
   10341             String skipPackages[] = null;
   10342             if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
   10343                     || intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
   10344                     || intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
   10345                 Uri data = intent.getData();
   10346                 if (data != null) {
   10347                     String pkgName = data.getSchemeSpecificPart();
   10348                     if (pkgName != null) {
   10349                         skipPackages = new String[] { pkgName };
   10350                     }
   10351                 }
   10352             } else if (intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
   10353                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   10354             }
   10355             if (skipPackages != null && (skipPackages.length > 0)) {
   10356                 for (String skipPackage : skipPackages) {
   10357                     if (skipPackage != null) {
   10358                         int NT = receivers.size();
   10359                         for (int it=0; it<NT; it++) {
   10360                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
   10361                             if (curt.activityInfo.packageName.equals(skipPackage)) {
   10362                                 receivers.remove(it);
   10363                                 it--;
   10364                                 NT--;
   10365                             }
   10366                         }
   10367                     }
   10368                 }
   10369             }
   10370 
   10371             int NT = receivers != null ? receivers.size() : 0;
   10372             int it = 0;
   10373             ResolveInfo curt = null;
   10374             BroadcastFilter curr = null;
   10375             while (it < NT && ir < NR) {
   10376                 if (curt == null) {
   10377                     curt = (ResolveInfo)receivers.get(it);
   10378                 }
   10379                 if (curr == null) {
   10380                     curr = registeredReceivers.get(ir);
   10381                 }
   10382                 if (curr.getPriority() >= curt.priority) {
   10383                     // Insert this broadcast record into the final list.
   10384                     receivers.add(it, curr);
   10385                     ir++;
   10386                     curr = null;
   10387                     it++;
   10388                     NT++;
   10389                 } else {
   10390                     // Skip to the next ResolveInfo in the final list.
   10391                     it++;
   10392                     curt = null;
   10393                 }
   10394             }
   10395         }
   10396         while (ir < NR) {
   10397             if (receivers == null) {
   10398                 receivers = new ArrayList();
   10399             }
   10400             receivers.add(registeredReceivers.get(ir));
   10401             ir++;
   10402         }
   10403 
   10404         if ((receivers != null && receivers.size() > 0)
   10405                 || resultTo != null) {
   10406             BroadcastRecord r = new BroadcastRecord(intent, callerApp,
   10407                     callerPackage, callingPid, callingUid, requiredPermission,
   10408                     receivers, resultTo, resultCode, resultData, map, ordered,
   10409                     sticky, false);
   10410             if (DEBUG_BROADCAST) Slog.v(
   10411                     TAG, "Enqueueing ordered broadcast " + r
   10412                     + ": prev had " + mOrderedBroadcasts.size());
   10413             if (DEBUG_BROADCAST) {
   10414                 int seq = r.intent.getIntExtra("seq", -1);
   10415                 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
   10416             }
   10417             boolean replaced = false;
   10418             if (replacePending) {
   10419                 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
   10420                     if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
   10421                         if (DEBUG_BROADCAST) Slog.v(TAG,
   10422                                 "***** DROPPING ORDERED: " + intent);
   10423                         mOrderedBroadcasts.set(i, r);
   10424                         replaced = true;
   10425                         break;
   10426                     }
   10427                 }
   10428             }
   10429             if (!replaced) {
   10430                 mOrderedBroadcasts.add(r);
   10431                 scheduleBroadcastsLocked();
   10432             }
   10433         }
   10434 
   10435         return BROADCAST_SUCCESS;
   10436     }
   10437 
   10438     final Intent verifyBroadcastLocked(Intent intent) {
   10439         // Refuse possible leaked file descriptors
   10440         if (intent != null && intent.hasFileDescriptors() == true) {
   10441             throw new IllegalArgumentException("File descriptors passed in Intent");
   10442         }
   10443 
   10444         int flags = intent.getFlags();
   10445 
   10446         if (!mProcessesReady) {
   10447             // if the caller really truly claims to know what they're doing, go
   10448             // ahead and allow the broadcast without launching any receivers
   10449             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
   10450                 intent = new Intent(intent);
   10451                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   10452             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
   10453                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
   10454                         + " before boot completion");
   10455                 throw new IllegalStateException("Cannot broadcast before boot completed");
   10456             }
   10457         }
   10458 
   10459         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   10460             throw new IllegalArgumentException(
   10461                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   10462         }
   10463 
   10464         return intent;
   10465     }
   10466 
   10467     public final int broadcastIntent(IApplicationThread caller,
   10468             Intent intent, String resolvedType, IIntentReceiver resultTo,
   10469             int resultCode, String resultData, Bundle map,
   10470             String requiredPermission, boolean serialized, boolean sticky) {
   10471         synchronized(this) {
   10472             intent = verifyBroadcastLocked(intent);
   10473 
   10474             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   10475             final int callingPid = Binder.getCallingPid();
   10476             final int callingUid = Binder.getCallingUid();
   10477             final long origId = Binder.clearCallingIdentity();
   10478             int res = broadcastIntentLocked(callerApp,
   10479                     callerApp != null ? callerApp.info.packageName : null,
   10480                     intent, resolvedType, resultTo,
   10481                     resultCode, resultData, map, requiredPermission, serialized,
   10482                     sticky, callingPid, callingUid);
   10483             Binder.restoreCallingIdentity(origId);
   10484             return res;
   10485         }
   10486     }
   10487 
   10488     int broadcastIntentInPackage(String packageName, int uid,
   10489             Intent intent, String resolvedType, IIntentReceiver resultTo,
   10490             int resultCode, String resultData, Bundle map,
   10491             String requiredPermission, boolean serialized, boolean sticky) {
   10492         synchronized(this) {
   10493             intent = verifyBroadcastLocked(intent);
   10494 
   10495             final long origId = Binder.clearCallingIdentity();
   10496             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
   10497                     resultTo, resultCode, resultData, map, requiredPermission,
   10498                     serialized, sticky, -1, uid);
   10499             Binder.restoreCallingIdentity(origId);
   10500             return res;
   10501         }
   10502     }
   10503 
   10504     public final void unbroadcastIntent(IApplicationThread caller,
   10505             Intent intent) {
   10506         // Refuse possible leaked file descriptors
   10507         if (intent != null && intent.hasFileDescriptors() == true) {
   10508             throw new IllegalArgumentException("File descriptors passed in Intent");
   10509         }
   10510 
   10511         synchronized(this) {
   10512             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
   10513                     != PackageManager.PERMISSION_GRANTED) {
   10514                 String msg = "Permission Denial: unbroadcastIntent() from pid="
   10515                         + Binder.getCallingPid()
   10516                         + ", uid=" + Binder.getCallingUid()
   10517                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   10518                 Slog.w(TAG, msg);
   10519                 throw new SecurityException(msg);
   10520             }
   10521             ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
   10522             if (list != null) {
   10523                 int N = list.size();
   10524                 int i;
   10525                 for (i=0; i<N; i++) {
   10526                     if (intent.filterEquals(list.get(i))) {
   10527                         list.remove(i);
   10528                         break;
   10529                     }
   10530                 }
   10531             }
   10532         }
   10533     }
   10534 
   10535     private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
   10536             String resultData, Bundle resultExtras, boolean resultAbort,
   10537             boolean explicit) {
   10538         if (mOrderedBroadcasts.size() == 0) {
   10539             if (explicit) {
   10540                 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
   10541             }
   10542             return false;
   10543         }
   10544         BroadcastRecord r = mOrderedBroadcasts.get(0);
   10545         if (r.receiver == null) {
   10546             if (explicit) {
   10547                 Slog.w(TAG, "finishReceiver called but none active");
   10548             }
   10549             return false;
   10550         }
   10551         if (r.receiver != receiver) {
   10552             Slog.w(TAG, "finishReceiver called but active receiver is different");
   10553             return false;
   10554         }
   10555         int state = r.state;
   10556         r.state = r.IDLE;
   10557         if (state == r.IDLE) {
   10558             if (explicit) {
   10559                 Slog.w(TAG, "finishReceiver called but state is IDLE");
   10560             }
   10561         }
   10562         r.receiver = null;
   10563         r.intent.setComponent(null);
   10564         if (r.curApp != null) {
   10565             r.curApp.curReceiver = null;
   10566         }
   10567         if (r.curFilter != null) {
   10568             r.curFilter.receiverList.curBroadcast = null;
   10569         }
   10570         r.curFilter = null;
   10571         r.curApp = null;
   10572         r.curComponent = null;
   10573         r.curReceiver = null;
   10574         mPendingBroadcast = null;
   10575 
   10576         r.resultCode = resultCode;
   10577         r.resultData = resultData;
   10578         r.resultExtras = resultExtras;
   10579         r.resultAbort = resultAbort;
   10580 
   10581         // We will process the next receiver right now if this is finishing
   10582         // an app receiver (which is always asynchronous) or after we have
   10583         // come back from calling a receiver.
   10584         return state == BroadcastRecord.APP_RECEIVE
   10585                 || state == BroadcastRecord.CALL_DONE_RECEIVE;
   10586     }
   10587 
   10588     public void finishReceiver(IBinder who, int resultCode, String resultData,
   10589             Bundle resultExtras, boolean resultAbort) {
   10590         if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
   10591 
   10592         // Refuse possible leaked file descriptors
   10593         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
   10594             throw new IllegalArgumentException("File descriptors passed in Bundle");
   10595         }
   10596 
   10597         boolean doNext;
   10598 
   10599         final long origId = Binder.clearCallingIdentity();
   10600 
   10601         synchronized(this) {
   10602             doNext = finishReceiverLocked(
   10603                 who, resultCode, resultData, resultExtras, resultAbort, true);
   10604         }
   10605 
   10606         if (doNext) {
   10607             processNextBroadcast(false);
   10608         }
   10609         trimApplications();
   10610 
   10611         Binder.restoreCallingIdentity(origId);
   10612     }
   10613 
   10614     private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
   10615         if (r.nextReceiver > 0) {
   10616             Object curReceiver = r.receivers.get(r.nextReceiver-1);
   10617             if (curReceiver instanceof BroadcastFilter) {
   10618                 BroadcastFilter bf = (BroadcastFilter) curReceiver;
   10619                 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
   10620                         System.identityHashCode(r),
   10621                         r.intent.getAction(),
   10622                         r.nextReceiver - 1,
   10623                         System.identityHashCode(bf));
   10624             } else {
   10625                 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
   10626                         System.identityHashCode(r),
   10627                         r.intent.getAction(),
   10628                         r.nextReceiver - 1,
   10629                         ((ResolveInfo)curReceiver).toString());
   10630             }
   10631         } else {
   10632             Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
   10633                     + r);
   10634             EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
   10635                     System.identityHashCode(r),
   10636                     r.intent.getAction(),
   10637                     r.nextReceiver,
   10638                     "NONE");
   10639         }
   10640     }
   10641 
   10642     private final void setBroadcastTimeoutLocked(long timeoutTime) {
   10643         if (! mPendingBroadcastTimeoutMessage) {
   10644             Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
   10645             mHandler.sendMessageAtTime(msg, timeoutTime);
   10646             mPendingBroadcastTimeoutMessage = true;
   10647         }
   10648     }
   10649 
   10650     private final void cancelBroadcastTimeoutLocked() {
   10651         if (mPendingBroadcastTimeoutMessage) {
   10652             mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
   10653             mPendingBroadcastTimeoutMessage = false;
   10654         }
   10655     }
   10656 
   10657     private final void broadcastTimeoutLocked(boolean fromMsg) {
   10658         if (fromMsg) {
   10659             mPendingBroadcastTimeoutMessage = false;
   10660         }
   10661 
   10662         if (mOrderedBroadcasts.size() == 0) {
   10663             return;
   10664         }
   10665 
   10666         long now = SystemClock.uptimeMillis();
   10667         BroadcastRecord r = mOrderedBroadcasts.get(0);
   10668         if (fromMsg) {
   10669             if (mDidDexOpt) {
   10670                 // Delay timeouts until dexopt finishes.
   10671                 mDidDexOpt = false;
   10672                 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
   10673                 setBroadcastTimeoutLocked(timeoutTime);
   10674                 return;
   10675             }
   10676             if (! mProcessesReady) {
   10677                 // Only process broadcast timeouts if the system is ready. That way
   10678                 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
   10679                 // to do heavy lifting for system up.
   10680                 return;
   10681             }
   10682 
   10683             long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
   10684             if (timeoutTime > now) {
   10685                 // We can observe premature timeouts because we do not cancel and reset the
   10686                 // broadcast timeout message after each receiver finishes.  Instead, we set up
   10687                 // an initial timeout then kick it down the road a little further as needed
   10688                 // when it expires.
   10689                 if (DEBUG_BROADCAST) Slog.v(TAG,
   10690                         "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
   10691                         + timeoutTime);
   10692                 setBroadcastTimeoutLocked(timeoutTime);
   10693                 return;
   10694             }
   10695         }
   10696 
   10697         Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
   10698                 + ", started " + (now - r.receiverTime) + "ms ago");
   10699         r.receiverTime = now;
   10700         r.anrCount++;
   10701 
   10702         // Current receiver has passed its expiration date.
   10703         if (r.nextReceiver <= 0) {
   10704             Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
   10705             return;
   10706         }
   10707 
   10708         ProcessRecord app = null;
   10709         String anrMessage = null;
   10710 
   10711         Object curReceiver = r.receivers.get(r.nextReceiver-1);
   10712         Slog.w(TAG, "Receiver during timeout: " + curReceiver);
   10713         logBroadcastReceiverDiscardLocked(r);
   10714         if (curReceiver instanceof BroadcastFilter) {
   10715             BroadcastFilter bf = (BroadcastFilter)curReceiver;
   10716             if (bf.receiverList.pid != 0
   10717                     && bf.receiverList.pid != MY_PID) {
   10718                 synchronized (this.mPidsSelfLocked) {
   10719                     app = this.mPidsSelfLocked.get(
   10720                             bf.receiverList.pid);
   10721                 }
   10722             }
   10723         } else {
   10724             app = r.curApp;
   10725         }
   10726 
   10727         if (app != null) {
   10728             anrMessage = "Broadcast of " + r.intent.toString();
   10729         }
   10730 
   10731         if (mPendingBroadcast == r) {
   10732             mPendingBroadcast = null;
   10733         }
   10734 
   10735         // Move on to the next receiver.
   10736         finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
   10737                 r.resultExtras, r.resultAbort, true);
   10738         scheduleBroadcastsLocked();
   10739 
   10740         if (anrMessage != null) {
   10741             // Post the ANR to the handler since we do not want to process ANRs while
   10742             // potentially holding our lock.
   10743             mHandler.post(new AppNotResponding(app, anrMessage));
   10744         }
   10745     }
   10746 
   10747     private final void processCurBroadcastLocked(BroadcastRecord r,
   10748             ProcessRecord app) throws RemoteException {
   10749         if (DEBUG_BROADCAST)  Slog.v(TAG,
   10750                 "Process cur broadcast " + r + " for app " + app);
   10751         if (app.thread == null) {
   10752             throw new RemoteException();
   10753         }
   10754         r.receiver = app.thread.asBinder();
   10755         r.curApp = app;
   10756         app.curReceiver = r;
   10757         updateLruProcessLocked(app, true, true);
   10758 
   10759         // Tell the application to launch this receiver.
   10760         r.intent.setComponent(r.curComponent);
   10761 
   10762         boolean started = false;
   10763         try {
   10764             if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
   10765                     "Delivering to component " + r.curComponent
   10766                     + ": " + r);
   10767             ensurePackageDexOpt(r.intent.getComponent().getPackageName());
   10768             app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
   10769                     r.resultCode, r.resultData, r.resultExtras, r.ordered);
   10770             if (DEBUG_BROADCAST)  Slog.v(TAG,
   10771                     "Process cur broadcast " + r + " DELIVERED for app " + app);
   10772             started = true;
   10773         } finally {
   10774             if (!started) {
   10775                 if (DEBUG_BROADCAST)  Slog.v(TAG,
   10776                         "Process cur broadcast " + r + ": NOT STARTED!");
   10777                 r.receiver = null;
   10778                 r.curApp = null;
   10779                 app.curReceiver = null;
   10780             }
   10781         }
   10782 
   10783     }
   10784 
   10785     static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
   10786             Intent intent, int resultCode, String data, Bundle extras,
   10787             boolean ordered, boolean sticky) throws RemoteException {
   10788         // Send the intent to the receiver asynchronously using one-way binder calls.
   10789         if (app != null && app.thread != null) {
   10790             // If we have an app thread, do the call through that so it is
   10791             // correctly ordered with other one-way calls.
   10792             app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
   10793                     data, extras, ordered, sticky);
   10794         } else {
   10795             receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
   10796         }
   10797     }
   10798 
   10799     private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
   10800             BroadcastFilter filter, boolean ordered) {
   10801         boolean skip = false;
   10802         if (filter.requiredPermission != null) {
   10803             int perm = checkComponentPermission(filter.requiredPermission,
   10804                     r.callingPid, r.callingUid, -1);
   10805             if (perm != PackageManager.PERMISSION_GRANTED) {
   10806                 Slog.w(TAG, "Permission Denial: broadcasting "
   10807                         + r.intent.toString()
   10808                         + " from " + r.callerPackage + " (pid="
   10809                         + r.callingPid + ", uid=" + r.callingUid + ")"
   10810                         + " requires " + filter.requiredPermission
   10811                         + " due to registered receiver " + filter);
   10812                 skip = true;
   10813             }
   10814         }
   10815         if (r.requiredPermission != null) {
   10816             int perm = checkComponentPermission(r.requiredPermission,
   10817                     filter.receiverList.pid, filter.receiverList.uid, -1);
   10818             if (perm != PackageManager.PERMISSION_GRANTED) {
   10819                 Slog.w(TAG, "Permission Denial: receiving "
   10820                         + r.intent.toString()
   10821                         + " to " + filter.receiverList.app
   10822                         + " (pid=" + filter.receiverList.pid
   10823                         + ", uid=" + filter.receiverList.uid + ")"
   10824                         + " requires " + r.requiredPermission
   10825                         + " due to sender " + r.callerPackage
   10826                         + " (uid " + r.callingUid + ")");
   10827                 skip = true;
   10828             }
   10829         }
   10830 
   10831         if (!skip) {
   10832             // If this is not being sent as an ordered broadcast, then we
   10833             // don't want to touch the fields that keep track of the current
   10834             // state of ordered broadcasts.
   10835             if (ordered) {
   10836                 r.receiver = filter.receiverList.receiver.asBinder();
   10837                 r.curFilter = filter;
   10838                 filter.receiverList.curBroadcast = r;
   10839                 r.state = BroadcastRecord.CALL_IN_RECEIVE;
   10840                 if (filter.receiverList.app != null) {
   10841                     // Bump hosting application to no longer be in background
   10842                     // scheduling class.  Note that we can't do that if there
   10843                     // isn't an app...  but we can only be in that case for
   10844                     // things that directly call the IActivityManager API, which
   10845                     // are already core system stuff so don't matter for this.
   10846                     r.curApp = filter.receiverList.app;
   10847                     filter.receiverList.app.curReceiver = r;
   10848                     updateOomAdjLocked();
   10849                 }
   10850             }
   10851             try {
   10852                 if (DEBUG_BROADCAST_LIGHT) {
   10853                     int seq = r.intent.getIntExtra("seq", -1);
   10854                     Slog.i(TAG, "Delivering to " + filter
   10855                             + " (seq=" + seq + "): " + r);
   10856                 }
   10857                 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
   10858                     new Intent(r.intent), r.resultCode,
   10859                     r.resultData, r.resultExtras, r.ordered, r.initialSticky);
   10860                 if (ordered) {
   10861                     r.state = BroadcastRecord.CALL_DONE_RECEIVE;
   10862                 }
   10863             } catch (RemoteException e) {
   10864                 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
   10865                 if (ordered) {
   10866                     r.receiver = null;
   10867                     r.curFilter = null;
   10868                     filter.receiverList.curBroadcast = null;
   10869                     if (filter.receiverList.app != null) {
   10870                         filter.receiverList.app.curReceiver = null;
   10871                     }
   10872                 }
   10873             }
   10874         }
   10875     }
   10876 
   10877     private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
   10878         if (r.callingUid < 0) {
   10879             // This was from a registerReceiver() call; ignore it.
   10880             return;
   10881         }
   10882         System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
   10883                 MAX_BROADCAST_HISTORY-1);
   10884         r.finishTime = SystemClock.uptimeMillis();
   10885         mBroadcastHistory[0] = r;
   10886     }
   10887 
   10888     private final void processNextBroadcast(boolean fromMsg) {
   10889         synchronized(this) {
   10890             BroadcastRecord r;
   10891 
   10892             if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
   10893                     + mParallelBroadcasts.size() + " broadcasts, "
   10894                     + mOrderedBroadcasts.size() + " ordered broadcasts");
   10895 
   10896             updateCpuStats();
   10897 
   10898             if (fromMsg) {
   10899                 mBroadcastsScheduled = false;
   10900             }
   10901 
   10902             // First, deliver any non-serialized broadcasts right away.
   10903             while (mParallelBroadcasts.size() > 0) {
   10904                 r = mParallelBroadcasts.remove(0);
   10905                 r.dispatchTime = SystemClock.uptimeMillis();
   10906                 final int N = r.receivers.size();
   10907                 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
   10908                         + r);
   10909                 for (int i=0; i<N; i++) {
   10910                     Object target = r.receivers.get(i);
   10911                     if (DEBUG_BROADCAST)  Slog.v(TAG,
   10912                             "Delivering non-ordered to registered "
   10913                             + target + ": " + r);
   10914                     deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
   10915                 }
   10916                 addBroadcastToHistoryLocked(r);
   10917                 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
   10918                         + r);
   10919             }
   10920 
   10921             // Now take care of the next serialized one...
   10922 
   10923             // If we are waiting for a process to come up to handle the next
   10924             // broadcast, then do nothing at this point.  Just in case, we
   10925             // check that the process we're waiting for still exists.
   10926             if (mPendingBroadcast != null) {
   10927                 if (DEBUG_BROADCAST_LIGHT) {
   10928                     Slog.v(TAG, "processNextBroadcast: waiting for "
   10929                             + mPendingBroadcast.curApp);
   10930                 }
   10931 
   10932                 boolean isDead;
   10933                 synchronized (mPidsSelfLocked) {
   10934                     isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
   10935                 }
   10936                 if (!isDead) {
   10937                     // It's still alive, so keep waiting
   10938                     return;
   10939                 } else {
   10940                     Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
   10941                             + " died before responding to broadcast");
   10942                     mPendingBroadcast.state = BroadcastRecord.IDLE;
   10943                     mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
   10944                     mPendingBroadcast = null;
   10945                 }
   10946             }
   10947 
   10948             boolean looped = false;
   10949 
   10950             do {
   10951                 if (mOrderedBroadcasts.size() == 0) {
   10952                     // No more broadcasts pending, so all done!
   10953                     scheduleAppGcsLocked();
   10954                     if (looped) {
   10955                         // If we had finished the last ordered broadcast, then
   10956                         // make sure all processes have correct oom and sched
   10957                         // adjustments.
   10958                         updateOomAdjLocked();
   10959                     }
   10960                     return;
   10961                 }
   10962                 r = mOrderedBroadcasts.get(0);
   10963                 boolean forceReceive = false;
   10964 
   10965                 // Ensure that even if something goes awry with the timeout
   10966                 // detection, we catch "hung" broadcasts here, discard them,
   10967                 // and continue to make progress.
   10968                 //
   10969                 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
   10970                 // receivers don't get executed with timeouts. They're intended for
   10971                 // one time heavy lifting after system upgrades and can take
   10972                 // significant amounts of time.
   10973                 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
   10974                 if (mProcessesReady && r.dispatchTime > 0) {
   10975                     long now = SystemClock.uptimeMillis();
   10976                     if ((numReceivers > 0) &&
   10977                             (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
   10978                         Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
   10979                                 + " now=" + now
   10980                                 + " dispatchTime=" + r.dispatchTime
   10981                                 + " startTime=" + r.receiverTime
   10982                                 + " intent=" + r.intent
   10983                                 + " numReceivers=" + numReceivers
   10984                                 + " nextReceiver=" + r.nextReceiver
   10985                                 + " state=" + r.state);
   10986                         broadcastTimeoutLocked(false); // forcibly finish this broadcast
   10987                         forceReceive = true;
   10988                         r.state = BroadcastRecord.IDLE;
   10989                     }
   10990                 }
   10991 
   10992                 if (r.state != BroadcastRecord.IDLE) {
   10993                     if (DEBUG_BROADCAST) Slog.d(TAG,
   10994                             "processNextBroadcast() called when not idle (state="
   10995                             + r.state + ")");
   10996                     return;
   10997                 }
   10998 
   10999                 if (r.receivers == null || r.nextReceiver >= numReceivers
   11000                         || r.resultAbort || forceReceive) {
   11001                     // No more receivers for this broadcast!  Send the final
   11002                     // result if requested...
   11003                     if (r.resultTo != null) {
   11004                         try {
   11005                             if (DEBUG_BROADCAST) {
   11006                                 int seq = r.intent.getIntExtra("seq", -1);
   11007                                 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
   11008                                         + " seq=" + seq + " app=" + r.callerApp);
   11009                             }
   11010                             performReceiveLocked(r.callerApp, r.resultTo,
   11011                                 new Intent(r.intent), r.resultCode,
   11012                                 r.resultData, r.resultExtras, false, false);
   11013                             // Set this to null so that the reference
   11014                             // (local and remote) isnt kept in the mBroadcastHistory.
   11015                             r.resultTo = null;
   11016                         } catch (RemoteException e) {
   11017                             Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
   11018                         }
   11019                     }
   11020 
   11021                     if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
   11022                     cancelBroadcastTimeoutLocked();
   11023 
   11024                     if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
   11025                             + r);
   11026 
   11027                     // ... and on to the next...
   11028                     addBroadcastToHistoryLocked(r);
   11029                     mOrderedBroadcasts.remove(0);
   11030                     r = null;
   11031                     looped = true;
   11032                     continue;
   11033                 }
   11034             } while (r == null);
   11035 
   11036             // Get the next receiver...
   11037             int recIdx = r.nextReceiver++;
   11038 
   11039             // Keep track of when this receiver started, and make sure there
   11040             // is a timeout message pending to kill it if need be.
   11041             r.receiverTime = SystemClock.uptimeMillis();
   11042             if (recIdx == 0) {
   11043                 r.dispatchTime = r.receiverTime;
   11044 
   11045                 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
   11046                         + r);
   11047             }
   11048             if (! mPendingBroadcastTimeoutMessage) {
   11049                 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
   11050                 if (DEBUG_BROADCAST) Slog.v(TAG,
   11051                         "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
   11052                 setBroadcastTimeoutLocked(timeoutTime);
   11053             }
   11054 
   11055             Object nextReceiver = r.receivers.get(recIdx);
   11056             if (nextReceiver instanceof BroadcastFilter) {
   11057                 // Simple case: this is a registered receiver who gets
   11058                 // a direct call.
   11059                 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
   11060                 if (DEBUG_BROADCAST)  Slog.v(TAG,
   11061                         "Delivering ordered to registered "
   11062                         + filter + ": " + r);
   11063                 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
   11064                 if (r.receiver == null || !r.ordered) {
   11065                     // The receiver has already finished, so schedule to
   11066                     // process the next one.
   11067                     if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
   11068                             + r.ordered + " receiver=" + r.receiver);
   11069                     r.state = BroadcastRecord.IDLE;
   11070                     scheduleBroadcastsLocked();
   11071                 }
   11072                 return;
   11073             }
   11074 
   11075             // Hard case: need to instantiate the receiver, possibly
   11076             // starting its application process to host it.
   11077 
   11078             ResolveInfo info =
   11079                 (ResolveInfo)nextReceiver;
   11080 
   11081             boolean skip = false;
   11082             int perm = checkComponentPermission(info.activityInfo.permission,
   11083                     r.callingPid, r.callingUid,
   11084                     info.activityInfo.exported
   11085                             ? -1 : info.activityInfo.applicationInfo.uid);
   11086             if (perm != PackageManager.PERMISSION_GRANTED) {
   11087                 Slog.w(TAG, "Permission Denial: broadcasting "
   11088                         + r.intent.toString()
   11089                         + " from " + r.callerPackage + " (pid=" + r.callingPid
   11090                         + ", uid=" + r.callingUid + ")"
   11091                         + " requires " + info.activityInfo.permission
   11092                         + " due to receiver " + info.activityInfo.packageName
   11093                         + "/" + info.activityInfo.name);
   11094                 skip = true;
   11095             }
   11096             if (r.callingUid != Process.SYSTEM_UID &&
   11097                 r.requiredPermission != null) {
   11098                 try {
   11099                     perm = AppGlobals.getPackageManager().
   11100                             checkPermission(r.requiredPermission,
   11101                                     info.activityInfo.applicationInfo.packageName);
   11102                 } catch (RemoteException e) {
   11103                     perm = PackageManager.PERMISSION_DENIED;
   11104                 }
   11105                 if (perm != PackageManager.PERMISSION_GRANTED) {
   11106                     Slog.w(TAG, "Permission Denial: receiving "
   11107                             + r.intent + " to "
   11108                             + info.activityInfo.applicationInfo.packageName
   11109                             + " requires " + r.requiredPermission
   11110                             + " due to sender " + r.callerPackage
   11111                             + " (uid " + r.callingUid + ")");
   11112                     skip = true;
   11113                 }
   11114             }
   11115             if (r.curApp != null && r.curApp.crashing) {
   11116                 // If the target process is crashing, just skip it.
   11117                 if (DEBUG_BROADCAST)  Slog.v(TAG,
   11118                         "Skipping deliver ordered " + r + " to " + r.curApp
   11119                         + ": process crashing");
   11120                 skip = true;
   11121             }
   11122 
   11123             if (skip) {
   11124                 if (DEBUG_BROADCAST)  Slog.v(TAG,
   11125                         "Skipping delivery of ordered " + r + " for whatever reason");
   11126                 r.receiver = null;
   11127                 r.curFilter = null;
   11128                 r.state = BroadcastRecord.IDLE;
   11129                 scheduleBroadcastsLocked();
   11130                 return;
   11131             }
   11132 
   11133             r.state = BroadcastRecord.APP_RECEIVE;
   11134             String targetProcess = info.activityInfo.processName;
   11135             r.curComponent = new ComponentName(
   11136                     info.activityInfo.applicationInfo.packageName,
   11137                     info.activityInfo.name);
   11138             r.curReceiver = info.activityInfo;
   11139 
   11140             // Is this receiver's application already running?
   11141             ProcessRecord app = getProcessRecordLocked(targetProcess,
   11142                     info.activityInfo.applicationInfo.uid);
   11143             if (app != null && app.thread != null) {
   11144                 try {
   11145                     processCurBroadcastLocked(r, app);
   11146                     return;
   11147                 } catch (RemoteException e) {
   11148                     Slog.w(TAG, "Exception when sending broadcast to "
   11149                           + r.curComponent, e);
   11150                 }
   11151 
   11152                 // If a dead object exception was thrown -- fall through to
   11153                 // restart the application.
   11154             }
   11155 
   11156             // Not running -- get it started, to be executed when the app comes up.
   11157             if (DEBUG_BROADCAST)  Slog.v(TAG,
   11158                     "Need to start app " + targetProcess + " for broadcast " + r);
   11159             if ((r.curApp=startProcessLocked(targetProcess,
   11160                     info.activityInfo.applicationInfo, true,
   11161                     r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
   11162                     "broadcast", r.curComponent,
   11163                     (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
   11164                             == null) {
   11165                 // Ah, this recipient is unavailable.  Finish it if necessary,
   11166                 // and mark the broadcast record as ready for the next.
   11167                 Slog.w(TAG, "Unable to launch app "
   11168                         + info.activityInfo.applicationInfo.packageName + "/"
   11169                         + info.activityInfo.applicationInfo.uid + " for broadcast "
   11170                         + r.intent + ": process is bad");
   11171                 logBroadcastReceiverDiscardLocked(r);
   11172                 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
   11173                         r.resultExtras, r.resultAbort, true);
   11174                 scheduleBroadcastsLocked();
   11175                 r.state = BroadcastRecord.IDLE;
   11176                 return;
   11177             }
   11178 
   11179             mPendingBroadcast = r;
   11180             mPendingBroadcastRecvIndex = recIdx;
   11181         }
   11182     }
   11183 
   11184     // =========================================================
   11185     // INSTRUMENTATION
   11186     // =========================================================
   11187 
   11188     public boolean startInstrumentation(ComponentName className,
   11189             String profileFile, int flags, Bundle arguments,
   11190             IInstrumentationWatcher watcher) {
   11191         // Refuse possible leaked file descriptors
   11192         if (arguments != null && arguments.hasFileDescriptors()) {
   11193             throw new IllegalArgumentException("File descriptors passed in Bundle");
   11194         }
   11195 
   11196         synchronized(this) {
   11197             InstrumentationInfo ii = null;
   11198             ApplicationInfo ai = null;
   11199             try {
   11200                 ii = mContext.getPackageManager().getInstrumentationInfo(
   11201                     className, STOCK_PM_FLAGS);
   11202                 ai = mContext.getPackageManager().getApplicationInfo(
   11203                     ii.targetPackage, STOCK_PM_FLAGS);
   11204             } catch (PackageManager.NameNotFoundException e) {
   11205             }
   11206             if (ii == null) {
   11207                 reportStartInstrumentationFailure(watcher, className,
   11208                         "Unable to find instrumentation info for: " + className);
   11209                 return false;
   11210             }
   11211             if (ai == null) {
   11212                 reportStartInstrumentationFailure(watcher, className,
   11213                         "Unable to find instrumentation target package: " + ii.targetPackage);
   11214                 return false;
   11215             }
   11216 
   11217             int match = mContext.getPackageManager().checkSignatures(
   11218                     ii.targetPackage, ii.packageName);
   11219             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
   11220                 String msg = "Permission Denial: starting instrumentation "
   11221                         + className + " from pid="
   11222                         + Binder.getCallingPid()
   11223                         + ", uid=" + Binder.getCallingPid()
   11224                         + " not allowed because package " + ii.packageName
   11225                         + " does not have a signature matching the target "
   11226                         + ii.targetPackage;
   11227                 reportStartInstrumentationFailure(watcher, className, msg);
   11228                 throw new SecurityException(msg);
   11229             }
   11230 
   11231             final long origId = Binder.clearCallingIdentity();
   11232             forceStopPackageLocked(ii.targetPackage, -1, true, false, true);
   11233             ProcessRecord app = addAppLocked(ai);
   11234             app.instrumentationClass = className;
   11235             app.instrumentationInfo = ai;
   11236             app.instrumentationProfileFile = profileFile;
   11237             app.instrumentationArguments = arguments;
   11238             app.instrumentationWatcher = watcher;
   11239             app.instrumentationResultClass = className;
   11240             Binder.restoreCallingIdentity(origId);
   11241         }
   11242 
   11243         return true;
   11244     }
   11245 
   11246     /**
   11247      * Report errors that occur while attempting to start Instrumentation.  Always writes the
   11248      * error to the logs, but if somebody is watching, send the report there too.  This enables
   11249      * the "am" command to report errors with more information.
   11250      *
   11251      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
   11252      * @param cn The component name of the instrumentation.
   11253      * @param report The error report.
   11254      */
   11255     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
   11256             ComponentName cn, String report) {
   11257         Slog.w(TAG, report);
   11258         try {
   11259             if (watcher != null) {
   11260                 Bundle results = new Bundle();
   11261                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
   11262                 results.putString("Error", report);
   11263                 watcher.instrumentationStatus(cn, -1, results);
   11264             }
   11265         } catch (RemoteException e) {
   11266             Slog.w(TAG, e);
   11267         }
   11268     }
   11269 
   11270     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
   11271         if (app.instrumentationWatcher != null) {
   11272             try {
   11273                 // NOTE:  IInstrumentationWatcher *must* be oneway here
   11274                 app.instrumentationWatcher.instrumentationFinished(
   11275                     app.instrumentationClass,
   11276                     resultCode,
   11277                     results);
   11278             } catch (RemoteException e) {
   11279             }
   11280         }
   11281         app.instrumentationWatcher = null;
   11282         app.instrumentationClass = null;
   11283         app.instrumentationInfo = null;
   11284         app.instrumentationProfileFile = null;
   11285         app.instrumentationArguments = null;
   11286 
   11287         forceStopPackageLocked(app.processName, -1, false, false, true);
   11288     }
   11289 
   11290     public void finishInstrumentation(IApplicationThread target,
   11291             int resultCode, Bundle results) {
   11292         // Refuse possible leaked file descriptors
   11293         if (results != null && results.hasFileDescriptors()) {
   11294             throw new IllegalArgumentException("File descriptors passed in Intent");
   11295         }
   11296 
   11297         synchronized(this) {
   11298             ProcessRecord app = getRecordForAppLocked(target);
   11299             if (app == null) {
   11300                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
   11301                 return;
   11302             }
   11303             final long origId = Binder.clearCallingIdentity();
   11304             finishInstrumentationLocked(app, resultCode, results);
   11305             Binder.restoreCallingIdentity(origId);
   11306         }
   11307     }
   11308 
   11309     // =========================================================
   11310     // CONFIGURATION
   11311     // =========================================================
   11312 
   11313     public ConfigurationInfo getDeviceConfigurationInfo() {
   11314         ConfigurationInfo config = new ConfigurationInfo();
   11315         synchronized (this) {
   11316             config.reqTouchScreen = mConfiguration.touchscreen;
   11317             config.reqKeyboardType = mConfiguration.keyboard;
   11318             config.reqNavigation = mConfiguration.navigation;
   11319             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
   11320                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
   11321                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
   11322             }
   11323             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
   11324                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
   11325                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
   11326             }
   11327             config.reqGlEsVersion = GL_ES_VERSION;
   11328         }
   11329         return config;
   11330     }
   11331 
   11332     public Configuration getConfiguration() {
   11333         Configuration ci;
   11334         synchronized(this) {
   11335             ci = new Configuration(mConfiguration);
   11336         }
   11337         return ci;
   11338     }
   11339 
   11340     public void updateConfiguration(Configuration values) {
   11341         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   11342                 "updateConfiguration()");
   11343 
   11344         synchronized(this) {
   11345             if (values == null && mWindowManager != null) {
   11346                 // sentinel: fetch the current configuration from the window manager
   11347                 values = mWindowManager.computeNewConfiguration();
   11348             }
   11349 
   11350             final long origId = Binder.clearCallingIdentity();
   11351             updateConfigurationLocked(values, null);
   11352             Binder.restoreCallingIdentity(origId);
   11353         }
   11354     }
   11355 
   11356     /**
   11357      * Do either or both things: (1) change the current configuration, and (2)
   11358      * make sure the given activity is running with the (now) current
   11359      * configuration.  Returns true if the activity has been left running, or
   11360      * false if <var>starting</var> is being destroyed to match the new
   11361      * configuration.
   11362      */
   11363     public boolean updateConfigurationLocked(Configuration values,
   11364             ActivityRecord starting) {
   11365         int changes = 0;
   11366 
   11367         boolean kept = true;
   11368 
   11369         if (values != null) {
   11370             Configuration newConfig = new Configuration(mConfiguration);
   11371             changes = newConfig.updateFrom(values);
   11372             if (changes != 0) {
   11373                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
   11374                     Slog.i(TAG, "Updating configuration to: " + values);
   11375                 }
   11376 
   11377                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
   11378 
   11379                 if (values.locale != null) {
   11380                     saveLocaleLocked(values.locale,
   11381                                      !values.locale.equals(mConfiguration.locale),
   11382                                      values.userSetLocale);
   11383                 }
   11384 
   11385                 mConfigurationSeq++;
   11386                 if (mConfigurationSeq <= 0) {
   11387                     mConfigurationSeq = 1;
   11388                 }
   11389                 newConfig.seq = mConfigurationSeq;
   11390                 mConfiguration = newConfig;
   11391                 Slog.i(TAG, "Config changed: " + newConfig);
   11392 
   11393                 AttributeCache ac = AttributeCache.instance();
   11394                 if (ac != null) {
   11395                     ac.updateConfiguration(mConfiguration);
   11396                 }
   11397 
   11398                 if (Settings.System.hasInterestingConfigurationChanges(changes)) {
   11399                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
   11400                     msg.obj = new Configuration(mConfiguration);
   11401                     mHandler.sendMessage(msg);
   11402                 }
   11403 
   11404                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   11405                     ProcessRecord app = mLruProcesses.get(i);
   11406                     try {
   11407                         if (app.thread != null) {
   11408                             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
   11409                                     + app.processName + " new config " + mConfiguration);
   11410                             app.thread.scheduleConfigurationChanged(mConfiguration);
   11411                         }
   11412                     } catch (Exception e) {
   11413                     }
   11414                 }
   11415                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
   11416                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   11417                         | Intent.FLAG_RECEIVER_REPLACE_PENDING);
   11418                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
   11419                         null, false, false, MY_PID, Process.SYSTEM_UID);
   11420                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
   11421                     broadcastIntentLocked(null, null,
   11422                             new Intent(Intent.ACTION_LOCALE_CHANGED),
   11423                             null, null, 0, null, null,
   11424                             null, false, false, MY_PID, Process.SYSTEM_UID);
   11425                 }
   11426             }
   11427         }
   11428 
   11429         if (changes != 0 && starting == null) {
   11430             // If the configuration changed, and the caller is not already
   11431             // in the process of starting an activity, then find the top
   11432             // activity to check if its configuration needs to change.
   11433             starting = mMainStack.topRunningActivityLocked(null);
   11434         }
   11435 
   11436         if (starting != null) {
   11437             kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
   11438             if (kept) {
   11439                 // If this didn't result in the starting activity being
   11440                 // destroyed, then we need to make sure at this point that all
   11441                 // other activities are made visible.
   11442                 if (DEBUG_SWITCH) Slog.i(TAG, "Config didn't destroy " + starting
   11443                         + ", ensuring others are correct.");
   11444                 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
   11445             }
   11446         }
   11447 
   11448         if (values != null && mWindowManager != null) {
   11449             mWindowManager.setNewConfiguration(mConfiguration);
   11450         }
   11451 
   11452         return kept;
   11453     }
   11454 
   11455     /**
   11456      * Save the locale.  You must be inside a synchronized (this) block.
   11457      */
   11458     private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
   11459         if(isDiff) {
   11460             SystemProperties.set("user.language", l.getLanguage());
   11461             SystemProperties.set("user.region", l.getCountry());
   11462         }
   11463 
   11464         if(isPersist) {
   11465             SystemProperties.set("persist.sys.language", l.getLanguage());
   11466             SystemProperties.set("persist.sys.country", l.getCountry());
   11467             SystemProperties.set("persist.sys.localevar", l.getVariant());
   11468         }
   11469     }
   11470 
   11471     // =========================================================
   11472     // LIFETIME MANAGEMENT
   11473     // =========================================================
   11474 
   11475     private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
   11476             ProcessRecord TOP_APP, boolean recursed) {
   11477         if (mAdjSeq == app.adjSeq) {
   11478             // This adjustment has already been computed.  If we are calling
   11479             // from the top, we may have already computed our adjustment with
   11480             // an earlier hidden adjustment that isn't really for us... if
   11481             // so, use the new hidden adjustment.
   11482             if (!recursed && app.hidden) {
   11483                 app.curAdj = hiddenAdj;
   11484             }
   11485             return app.curAdj;
   11486         }
   11487 
   11488         if (app.thread == null) {
   11489             app.adjSeq = mAdjSeq;
   11490             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   11491             return (app.curAdj=EMPTY_APP_ADJ);
   11492         }
   11493 
   11494         if (app.maxAdj <= FOREGROUND_APP_ADJ) {
   11495             // The max adjustment doesn't allow this app to be anything
   11496             // below foreground, so it is not worth doing work for it.
   11497             app.adjType = "fixed";
   11498             app.adjSeq = mAdjSeq;
   11499             app.curRawAdj = app.maxAdj;
   11500             app.keeping = true;
   11501             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
   11502             return (app.curAdj=app.maxAdj);
   11503        }
   11504 
   11505         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
   11506         app.adjSource = null;
   11507         app.adjTarget = null;
   11508         app.keeping = false;
   11509         app.empty = false;
   11510         app.hidden = false;
   11511 
   11512         // Determine the importance of the process, starting with most
   11513         // important to least, and assign an appropriate OOM adjustment.
   11514         int adj;
   11515         int schedGroup;
   11516         int N;
   11517         if (app == TOP_APP) {
   11518             // The last app on the list is the foreground app.
   11519             adj = FOREGROUND_APP_ADJ;
   11520             schedGroup = Process.THREAD_GROUP_DEFAULT;
   11521             app.adjType = "top-activity";
   11522         } else if (app.instrumentationClass != null) {
   11523             // Don't want to kill running instrumentation.
   11524             adj = FOREGROUND_APP_ADJ;
   11525             schedGroup = Process.THREAD_GROUP_DEFAULT;
   11526             app.adjType = "instrumentation";
   11527         } else if (app.curReceiver != null ||
   11528                 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
   11529             // An app that is currently receiving a broadcast also
   11530             // counts as being in the foreground.
   11531             adj = FOREGROUND_APP_ADJ;
   11532             schedGroup = Process.THREAD_GROUP_DEFAULT;
   11533             app.adjType = "broadcast";
   11534         } else if (app.executingServices.size() > 0) {
   11535             // An app that is currently executing a service callback also
   11536             // counts as being in the foreground.
   11537             adj = FOREGROUND_APP_ADJ;
   11538             schedGroup = Process.THREAD_GROUP_DEFAULT;
   11539             app.adjType = "exec-service";
   11540         } else if (app.foregroundServices) {
   11541             // The user is aware of this app, so make it visible.
   11542             adj = PERCEPTIBLE_APP_ADJ;
   11543             schedGroup = Process.THREAD_GROUP_DEFAULT;
   11544             app.adjType = "foreground-service";
   11545         } else if (app.forcingToForeground != null) {
   11546             // The user is aware of this app, so make it visible.
   11547             adj = PERCEPTIBLE_APP_ADJ;
   11548             schedGroup = Process.THREAD_GROUP_DEFAULT;
   11549             app.adjType = "force-foreground";
   11550             app.adjSource = app.forcingToForeground;
   11551         } else if (app == mHeavyWeightProcess) {
   11552             // We don't want to kill the current heavy-weight process.
   11553             adj = HEAVY_WEIGHT_APP_ADJ;
   11554             schedGroup = Process.THREAD_GROUP_DEFAULT;
   11555             app.adjType = "heavy";
   11556         } else if (app == mHomeProcess) {
   11557             // This process is hosting what we currently consider to be the
   11558             // home app, so we don't want to let it go into the background.
   11559             adj = HOME_APP_ADJ;
   11560             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   11561             app.adjType = "home";
   11562         } else if ((N=app.activities.size()) != 0) {
   11563             // This app is in the background with paused activities.
   11564             app.hidden = true;
   11565             adj = hiddenAdj;
   11566             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   11567             app.adjType = "bg-activities";
   11568             N = app.activities.size();
   11569             for (int j=0; j<N; j++) {
   11570                 if (app.activities.get(j).visible) {
   11571                     // This app has a visible activity!
   11572                     app.hidden = false;
   11573                     adj = VISIBLE_APP_ADJ;
   11574                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   11575                     app.adjType = "visible";
   11576                     break;
   11577                 }
   11578             }
   11579         } else {
   11580             // A very not-needed process.  If this is lower in the lru list,
   11581             // we will push it in to the empty bucket.
   11582             app.hidden = true;
   11583             app.empty = true;
   11584             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   11585             adj = hiddenAdj;
   11586             app.adjType = "bg-empty";
   11587         }
   11588 
   11589         //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
   11590 
   11591         // By default, we use the computed adjustment.  It may be changed if
   11592         // there are applications dependent on our services or providers, but
   11593         // this gives us a baseline and makes sure we don't get into an
   11594         // infinite recursion.
   11595         app.adjSeq = mAdjSeq;
   11596         app.curRawAdj = adj;
   11597 
   11598         if (mBackupTarget != null && app == mBackupTarget.app) {
   11599             // If possible we want to avoid killing apps while they're being backed up
   11600             if (adj > BACKUP_APP_ADJ) {
   11601                 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
   11602                 adj = BACKUP_APP_ADJ;
   11603                 app.adjType = "backup";
   11604                 app.hidden = false;
   11605             }
   11606         }
   11607 
   11608         if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
   11609                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   11610             final long now = SystemClock.uptimeMillis();
   11611             // This process is more important if the top activity is
   11612             // bound to the service.
   11613             Iterator<ServiceRecord> jt = app.services.iterator();
   11614             while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
   11615                 ServiceRecord s = jt.next();
   11616                 if (s.startRequested) {
   11617                     if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
   11618                         // This service has seen some activity within
   11619                         // recent memory, so we will keep its process ahead
   11620                         // of the background processes.
   11621                         if (adj > SECONDARY_SERVER_ADJ) {
   11622                             adj = SECONDARY_SERVER_ADJ;
   11623                             app.adjType = "started-services";
   11624                             app.hidden = false;
   11625                         }
   11626                     }
   11627                     // If we have let the service slide into the background
   11628                     // state, still have some text describing what it is doing
   11629                     // even though the service no longer has an impact.
   11630                     if (adj > SECONDARY_SERVER_ADJ) {
   11631                         app.adjType = "started-bg-services";
   11632                     }
   11633                     // Don't kill this process because it is doing work; it
   11634                     // has said it is doing work.
   11635                     app.keeping = true;
   11636                 }
   11637                 if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
   11638                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   11639                     Iterator<ArrayList<ConnectionRecord>> kt
   11640                             = s.connections.values().iterator();
   11641                     while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
   11642                         ArrayList<ConnectionRecord> clist = kt.next();
   11643                         for (int i=0; i<clist.size() && adj > FOREGROUND_APP_ADJ; i++) {
   11644                             // XXX should compute this based on the max of
   11645                             // all connected clients.
   11646                             ConnectionRecord cr = clist.get(i);
   11647                             if (cr.binding.client == app) {
   11648                                 // Binding to ourself is not interesting.
   11649                                 continue;
   11650                             }
   11651                             if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
   11652                                 ProcessRecord client = cr.binding.client;
   11653                                 int myHiddenAdj = hiddenAdj;
   11654                                 if (myHiddenAdj > client.hiddenAdj) {
   11655                                     if (client.hiddenAdj >= VISIBLE_APP_ADJ) {
   11656                                         myHiddenAdj = client.hiddenAdj;
   11657                                     } else {
   11658                                         myHiddenAdj = VISIBLE_APP_ADJ;
   11659                                     }
   11660                                 }
   11661                                 int clientAdj = computeOomAdjLocked(
   11662                                     client, myHiddenAdj, TOP_APP, true);
   11663                                 if (adj > clientAdj) {
   11664                                     adj = clientAdj >= VISIBLE_APP_ADJ
   11665                                             ? clientAdj : VISIBLE_APP_ADJ;
   11666                                     if (!client.hidden) {
   11667                                         app.hidden = false;
   11668                                     }
   11669                                     if (client.keeping) {
   11670                                         app.keeping = true;
   11671                                     }
   11672                                     app.adjType = "service";
   11673                                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   11674                                             .REASON_SERVICE_IN_USE;
   11675                                     app.adjSource = cr.binding.client;
   11676                                     app.adjTarget = s.name;
   11677                                 }
   11678                                 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   11679                                     if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   11680                                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   11681                                     }
   11682                                 }
   11683                             }
   11684                             ActivityRecord a = cr.activity;
   11685                             //if (a != null) {
   11686                             //    Slog.i(TAG, "Connection to " + a ": state=" + a.state);
   11687                             //}
   11688                             if (a != null && adj > FOREGROUND_APP_ADJ &&
   11689                                     (a.state == ActivityState.RESUMED
   11690                                      || a.state == ActivityState.PAUSING)) {
   11691                                 adj = FOREGROUND_APP_ADJ;
   11692                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   11693                                 app.hidden = false;
   11694                                 app.adjType = "service";
   11695                                 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   11696                                         .REASON_SERVICE_IN_USE;
   11697                                 app.adjSource = a;
   11698                                 app.adjTarget = s.name;
   11699                             }
   11700                         }
   11701                     }
   11702                 }
   11703             }
   11704 
   11705             // Finally, if this process has active services running in it, we
   11706             // would like to avoid killing it unless it would prevent the current
   11707             // application from running.  By default we put the process in
   11708             // with the rest of the background processes; as we scan through
   11709             // its services we may bump it up from there.
   11710             if (adj > hiddenAdj) {
   11711                 adj = hiddenAdj;
   11712                 app.hidden = false;
   11713                 app.adjType = "bg-services";
   11714             }
   11715         }
   11716 
   11717         if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ
   11718                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   11719             Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
   11720             while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ
   11721                     || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   11722                 ContentProviderRecord cpr = jt.next();
   11723                 if (cpr.clients.size() != 0) {
   11724                     Iterator<ProcessRecord> kt = cpr.clients.iterator();
   11725                     while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
   11726                         ProcessRecord client = kt.next();
   11727                         if (client == app) {
   11728                             // Being our own client is not interesting.
   11729                             continue;
   11730                         }
   11731                         int myHiddenAdj = hiddenAdj;
   11732                         if (myHiddenAdj > client.hiddenAdj) {
   11733                             if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
   11734                                 myHiddenAdj = client.hiddenAdj;
   11735                             } else {
   11736                                 myHiddenAdj = FOREGROUND_APP_ADJ;
   11737                             }
   11738                         }
   11739                         int clientAdj = computeOomAdjLocked(
   11740                             client, myHiddenAdj, TOP_APP, true);
   11741                         if (adj > clientAdj) {
   11742                             adj = clientAdj > FOREGROUND_APP_ADJ
   11743                                     ? clientAdj : FOREGROUND_APP_ADJ;
   11744                             if (!client.hidden) {
   11745                                 app.hidden = false;
   11746                             }
   11747                             if (client.keeping) {
   11748                                 app.keeping = true;
   11749                             }
   11750                             app.adjType = "provider";
   11751                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   11752                                     .REASON_PROVIDER_IN_USE;
   11753                             app.adjSource = client;
   11754                             app.adjTarget = cpr.name;
   11755                         }
   11756                         if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   11757                             schedGroup = Process.THREAD_GROUP_DEFAULT;
   11758                         }
   11759                     }
   11760                 }
   11761                 // If the provider has external (non-framework) process
   11762                 // dependencies, ensure that its adjustment is at least
   11763                 // FOREGROUND_APP_ADJ.
   11764                 if (cpr.externals != 0) {
   11765                     if (adj > FOREGROUND_APP_ADJ) {
   11766                         adj = FOREGROUND_APP_ADJ;
   11767                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   11768                         app.hidden = false;
   11769                         app.keeping = true;
   11770                         app.adjType = "provider";
   11771                         app.adjTarget = cpr.name;
   11772                     }
   11773                 }
   11774             }
   11775         }
   11776 
   11777         app.curRawAdj = adj;
   11778 
   11779         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
   11780         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
   11781         if (adj > app.maxAdj) {
   11782             adj = app.maxAdj;
   11783             if (app.maxAdj <= PERCEPTIBLE_APP_ADJ) {
   11784                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   11785             }
   11786         }
   11787         if (adj < HIDDEN_APP_MIN_ADJ) {
   11788             app.keeping = true;
   11789         }
   11790 
   11791         app.curAdj = adj;
   11792         app.curSchedGroup = schedGroup;
   11793 
   11794         return adj;
   11795     }
   11796 
   11797     /**
   11798      * Ask a given process to GC right now.
   11799      */
   11800     final void performAppGcLocked(ProcessRecord app) {
   11801         try {
   11802             app.lastRequestedGc = SystemClock.uptimeMillis();
   11803             if (app.thread != null) {
   11804                 if (app.reportLowMemory) {
   11805                     app.reportLowMemory = false;
   11806                     app.thread.scheduleLowMemory();
   11807                 } else {
   11808                     app.thread.processInBackground();
   11809                 }
   11810             }
   11811         } catch (Exception e) {
   11812             // whatever.
   11813         }
   11814     }
   11815 
   11816     /**
   11817      * Returns true if things are idle enough to perform GCs.
   11818      */
   11819     private final boolean canGcNowLocked() {
   11820         return mParallelBroadcasts.size() == 0
   11821                 && mOrderedBroadcasts.size() == 0
   11822                 && (mSleeping || (mMainStack.mResumedActivity != null &&
   11823                         mMainStack.mResumedActivity.idle));
   11824     }
   11825 
   11826     /**
   11827      * Perform GCs on all processes that are waiting for it, but only
   11828      * if things are idle.
   11829      */
   11830     final void performAppGcsLocked() {
   11831         final int N = mProcessesToGc.size();
   11832         if (N <= 0) {
   11833             return;
   11834         }
   11835         if (canGcNowLocked()) {
   11836             while (mProcessesToGc.size() > 0) {
   11837                 ProcessRecord proc = mProcessesToGc.remove(0);
   11838                 if (proc.curRawAdj > PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
   11839                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
   11840                             <= SystemClock.uptimeMillis()) {
   11841                         // To avoid spamming the system, we will GC processes one
   11842                         // at a time, waiting a few seconds between each.
   11843                         performAppGcLocked(proc);
   11844                         scheduleAppGcsLocked();
   11845                         return;
   11846                     } else {
   11847                         // It hasn't been long enough since we last GCed this
   11848                         // process...  put it in the list to wait for its time.
   11849                         addProcessToGcListLocked(proc);
   11850                         break;
   11851                     }
   11852                 }
   11853             }
   11854 
   11855             scheduleAppGcsLocked();
   11856         }
   11857     }
   11858 
   11859     /**
   11860      * If all looks good, perform GCs on all processes waiting for them.
   11861      */
   11862     final void performAppGcsIfAppropriateLocked() {
   11863         if (canGcNowLocked()) {
   11864             performAppGcsLocked();
   11865             return;
   11866         }
   11867         // Still not idle, wait some more.
   11868         scheduleAppGcsLocked();
   11869     }
   11870 
   11871     /**
   11872      * Schedule the execution of all pending app GCs.
   11873      */
   11874     final void scheduleAppGcsLocked() {
   11875         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
   11876 
   11877         if (mProcessesToGc.size() > 0) {
   11878             // Schedule a GC for the time to the next process.
   11879             ProcessRecord proc = mProcessesToGc.get(0);
   11880             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
   11881 
   11882             long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL;
   11883             long now = SystemClock.uptimeMillis();
   11884             if (when < (now+GC_TIMEOUT)) {
   11885                 when = now + GC_TIMEOUT;
   11886             }
   11887             mHandler.sendMessageAtTime(msg, when);
   11888         }
   11889     }
   11890 
   11891     /**
   11892      * Add a process to the array of processes waiting to be GCed.  Keeps the
   11893      * list in sorted order by the last GC time.  The process can't already be
   11894      * on the list.
   11895      */
   11896     final void addProcessToGcListLocked(ProcessRecord proc) {
   11897         boolean added = false;
   11898         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
   11899             if (mProcessesToGc.get(i).lastRequestedGc <
   11900                     proc.lastRequestedGc) {
   11901                 added = true;
   11902                 mProcessesToGc.add(i+1, proc);
   11903                 break;
   11904             }
   11905         }
   11906         if (!added) {
   11907             mProcessesToGc.add(0, proc);
   11908         }
   11909     }
   11910 
   11911     /**
   11912      * Set up to ask a process to GC itself.  This will either do it
   11913      * immediately, or put it on the list of processes to gc the next
   11914      * time things are idle.
   11915      */
   11916     final void scheduleAppGcLocked(ProcessRecord app) {
   11917         long now = SystemClock.uptimeMillis();
   11918         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
   11919             return;
   11920         }
   11921         if (!mProcessesToGc.contains(app)) {
   11922             addProcessToGcListLocked(app);
   11923             scheduleAppGcsLocked();
   11924         }
   11925     }
   11926 
   11927     final void checkExcessivePowerUsageLocked(boolean doKills) {
   11928         updateCpuStatsNow();
   11929 
   11930         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   11931         boolean doWakeKills = doKills;
   11932         boolean doCpuKills = doKills;
   11933         if (mLastPowerCheckRealtime == 0) {
   11934             doWakeKills = false;
   11935         }
   11936         if (mLastPowerCheckUptime == 0) {
   11937             doCpuKills = false;
   11938         }
   11939         if (stats.isScreenOn()) {
   11940             doWakeKills = false;
   11941         }
   11942         final long curRealtime = SystemClock.elapsedRealtime();
   11943         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
   11944         final long curUptime = SystemClock.uptimeMillis();
   11945         final long uptimeSince = curUptime - mLastPowerCheckUptime;
   11946         mLastPowerCheckRealtime = curRealtime;
   11947         mLastPowerCheckUptime = curUptime;
   11948         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
   11949             doWakeKills = false;
   11950         }
   11951         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
   11952             doCpuKills = false;
   11953         }
   11954         int i = mLruProcesses.size();
   11955         while (i > 0) {
   11956             i--;
   11957             ProcessRecord app = mLruProcesses.get(i);
   11958             if (!app.keeping) {
   11959                 long wtime;
   11960                 synchronized (stats) {
   11961                     wtime = stats.getProcessWakeTime(app.info.uid,
   11962                             app.pid, curRealtime);
   11963                 }
   11964                 long wtimeUsed = wtime - app.lastWakeTime;
   11965                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
   11966                 if (DEBUG_POWER) {
   11967                     StringBuilder sb = new StringBuilder(128);
   11968                     sb.append("Wake for ");
   11969                     app.toShortString(sb);
   11970                     sb.append(": over ");
   11971                     TimeUtils.formatDuration(realtimeSince, sb);
   11972                     sb.append(" used ");
   11973                     TimeUtils.formatDuration(wtimeUsed, sb);
   11974                     sb.append(" (");
   11975                     sb.append((wtimeUsed*100)/realtimeSince);
   11976                     sb.append("%)");
   11977                     Slog.i(TAG, sb.toString());
   11978                     sb.setLength(0);
   11979                     sb.append("CPU for ");
   11980                     app.toShortString(sb);
   11981                     sb.append(": over ");
   11982                     TimeUtils.formatDuration(uptimeSince, sb);
   11983                     sb.append(" used ");
   11984                     TimeUtils.formatDuration(cputimeUsed, sb);
   11985                     sb.append(" (");
   11986                     sb.append((cputimeUsed*100)/uptimeSince);
   11987                     sb.append("%)");
   11988                     Slog.i(TAG, sb.toString());
   11989                 }
   11990                 // If a process has held a wake lock for more
   11991                 // than 50% of the time during this period,
   11992                 // that sounds pad.  Kill!
   11993                 if (doWakeKills && realtimeSince > 0
   11994                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
   11995                     synchronized (stats) {
   11996                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
   11997                                 realtimeSince, wtimeUsed);
   11998                     }
   11999                     Slog.w(TAG, "Excessive wake lock in " + app.processName
   12000                             + " (pid " + app.pid + "): held " + wtimeUsed
   12001                             + " during " + realtimeSince);
   12002                     EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   12003                             app.processName, app.setAdj, "excessive wake lock");
   12004                     Process.killProcessQuiet(app.pid);
   12005                 } else if (doCpuKills && uptimeSince > 0
   12006                         && ((cputimeUsed*100)/uptimeSince) >= 50) {
   12007                     synchronized (stats) {
   12008                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
   12009                                 uptimeSince, cputimeUsed);
   12010                     }
   12011                     Slog.w(TAG, "Excessive CPU in " + app.processName
   12012                             + " (pid " + app.pid + "): used " + cputimeUsed
   12013                             + " during " + uptimeSince);
   12014                     EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   12015                             app.processName, app.setAdj, "excessive cpu");
   12016                     Process.killProcessQuiet(app.pid);
   12017                 } else {
   12018                     app.lastWakeTime = wtime;
   12019                     app.lastCpuTime = app.curCpuTime;
   12020                 }
   12021             }
   12022         }
   12023     }
   12024 
   12025     private final boolean updateOomAdjLocked(
   12026         ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
   12027         app.hiddenAdj = hiddenAdj;
   12028 
   12029         if (app.thread == null) {
   12030             return true;
   12031         }
   12032 
   12033         final boolean wasKeeping = app.keeping;
   12034 
   12035         int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
   12036 
   12037         if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) {
   12038             if (app.curRawAdj != app.setRawAdj) {
   12039                 if (app.curRawAdj > FOREGROUND_APP_ADJ
   12040                         && app.setRawAdj <= FOREGROUND_APP_ADJ) {
   12041                     // If this app is transitioning from foreground to
   12042                     // non-foreground, have it do a gc.
   12043                     scheduleAppGcLocked(app);
   12044                 } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
   12045                         && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
   12046                     // Likewise do a gc when an app is moving in to the
   12047                     // background (such as a service stopping).
   12048                     scheduleAppGcLocked(app);
   12049                 }
   12050 
   12051                 if (wasKeeping && !app.keeping) {
   12052                     // This app is no longer something we want to keep.  Note
   12053                     // its current wake lock time to later know to kill it if
   12054                     // it is not behaving well.
   12055                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   12056                     synchronized (stats) {
   12057                         app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
   12058                                 app.pid, SystemClock.elapsedRealtime());
   12059                     }
   12060                     app.lastCpuTime = app.curCpuTime;
   12061                 }
   12062 
   12063                 app.setRawAdj = app.curRawAdj;
   12064             }
   12065             if (adj != app.setAdj) {
   12066                 if (Process.setOomAdj(app.pid, adj)) {
   12067                     if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
   12068                         TAG, "Set app " + app.processName +
   12069                         " oom adj to " + adj);
   12070                     app.setAdj = adj;
   12071                 } else {
   12072                     return false;
   12073                 }
   12074             }
   12075             if (app.setSchedGroup != app.curSchedGroup) {
   12076                 app.setSchedGroup = app.curSchedGroup;
   12077                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   12078                         "Setting process group of " + app.processName
   12079                         + " to " + app.curSchedGroup);
   12080                 if (true) {
   12081                     long oldId = Binder.clearCallingIdentity();
   12082                     try {
   12083                         Process.setProcessGroup(app.pid, app.curSchedGroup);
   12084                     } catch (Exception e) {
   12085                         Slog.w(TAG, "Failed setting process group of " + app.pid
   12086                                 + " to " + app.curSchedGroup);
   12087                         e.printStackTrace();
   12088                     } finally {
   12089                         Binder.restoreCallingIdentity(oldId);
   12090                     }
   12091                 }
   12092                 if (false) {
   12093                     if (app.thread != null) {
   12094                         try {
   12095                             app.thread.setSchedulingGroup(app.curSchedGroup);
   12096                         } catch (RemoteException e) {
   12097                         }
   12098                     }
   12099                 }
   12100             }
   12101         }
   12102 
   12103         return true;
   12104     }
   12105 
   12106     private final ActivityRecord resumedAppLocked() {
   12107         ActivityRecord resumedActivity = mMainStack.mResumedActivity;
   12108         if (resumedActivity == null || resumedActivity.app == null) {
   12109             resumedActivity = mMainStack.mPausingActivity;
   12110             if (resumedActivity == null || resumedActivity.app == null) {
   12111                 resumedActivity = mMainStack.topRunningActivityLocked(null);
   12112             }
   12113         }
   12114         return resumedActivity;
   12115     }
   12116 
   12117     private final boolean updateOomAdjLocked(ProcessRecord app) {
   12118         final ActivityRecord TOP_ACT = resumedAppLocked();
   12119         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   12120         int curAdj = app.curAdj;
   12121         final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
   12122             && app.curAdj <= HIDDEN_APP_MAX_ADJ;
   12123 
   12124         mAdjSeq++;
   12125 
   12126         final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
   12127         if (res) {
   12128             final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
   12129                 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
   12130             if (nowHidden != wasHidden) {
   12131                 // Changed to/from hidden state, so apps after it in the LRU
   12132                 // list may also be changed.
   12133                 updateOomAdjLocked();
   12134             }
   12135         }
   12136         return res;
   12137     }
   12138 
   12139     final boolean updateOomAdjLocked() {
   12140         boolean didOomAdj = true;
   12141         final ActivityRecord TOP_ACT = resumedAppLocked();
   12142         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   12143 
   12144         if (false) {
   12145             RuntimeException e = new RuntimeException();
   12146             e.fillInStackTrace();
   12147             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
   12148         }
   12149 
   12150         mAdjSeq++;
   12151 
   12152         // Let's determine how many processes we have running vs.
   12153         // how many slots we have for background processes; we may want
   12154         // to put multiple processes in a slot of there are enough of
   12155         // them.
   12156         int numSlots = HIDDEN_APP_MAX_ADJ - HIDDEN_APP_MIN_ADJ + 1;
   12157         int factor = (mLruProcesses.size()-4)/numSlots;
   12158         if (factor < 1) factor = 1;
   12159         int step = 0;
   12160         int numHidden = 0;
   12161 
   12162         // First try updating the OOM adjustment for each of the
   12163         // application processes based on their current state.
   12164         int i = mLruProcesses.size();
   12165         int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
   12166         while (i > 0) {
   12167             i--;
   12168             ProcessRecord app = mLruProcesses.get(i);
   12169             //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
   12170             if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
   12171                 if (curHiddenAdj < EMPTY_APP_ADJ
   12172                     && app.curAdj == curHiddenAdj) {
   12173                     step++;
   12174                     if (step >= factor) {
   12175                         step = 0;
   12176                         curHiddenAdj++;
   12177                     }
   12178                 }
   12179                 if (app.curAdj >= HIDDEN_APP_MIN_ADJ) {
   12180                     if (!app.killedBackground) {
   12181                         numHidden++;
   12182                         if (numHidden > MAX_HIDDEN_APPS) {
   12183                             Slog.i(TAG, "No longer want " + app.processName
   12184                                     + " (pid " + app.pid + "): hidden #" + numHidden);
   12185                             EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   12186                                     app.processName, app.setAdj, "too many background");
   12187                             app.killedBackground = true;
   12188                             Process.killProcessQuiet(app.pid);
   12189                         }
   12190                     }
   12191                 }
   12192             } else {
   12193                 didOomAdj = false;
   12194             }
   12195         }
   12196 
   12197         // If we return false, we will fall back on killing processes to
   12198         // have a fixed limit.  Do this if a limit has been requested; else
   12199         // only return false if one of the adjustments failed.
   12200         return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
   12201     }
   12202 
   12203     final void trimApplications() {
   12204         synchronized (this) {
   12205             int i;
   12206 
   12207             // First remove any unused application processes whose package
   12208             // has been removed.
   12209             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
   12210                 final ProcessRecord app = mRemovedProcesses.get(i);
   12211                 if (app.activities.size() == 0
   12212                         && app.curReceiver == null && app.services.size() == 0) {
   12213                     Slog.i(
   12214                         TAG, "Exiting empty application process "
   12215                         + app.processName + " ("
   12216                         + (app.thread != null ? app.thread.asBinder() : null)
   12217                         + ")\n");
   12218                     if (app.pid > 0 && app.pid != MY_PID) {
   12219                         Process.killProcess(app.pid);
   12220                     } else {
   12221                         try {
   12222                             app.thread.scheduleExit();
   12223                         } catch (Exception e) {
   12224                             // Ignore exceptions.
   12225                         }
   12226                     }
   12227                     cleanUpApplicationRecordLocked(app, false, -1);
   12228                     mRemovedProcesses.remove(i);
   12229 
   12230                     if (app.persistent) {
   12231                         if (app.persistent) {
   12232                             addAppLocked(app.info);
   12233                         }
   12234                     }
   12235                 }
   12236             }
   12237 
   12238             // Now try updating the OOM adjustment for each of the
   12239             // application processes based on their current state.
   12240             // If the setOomAdj() API is not supported, then go with our
   12241             // back-up plan...
   12242             if (!updateOomAdjLocked()) {
   12243 
   12244                 // Count how many processes are running services.
   12245                 int numServiceProcs = 0;
   12246                 for (i=mLruProcesses.size()-1; i>=0; i--) {
   12247                     final ProcessRecord app = mLruProcesses.get(i);
   12248 
   12249                     if (app.persistent || app.services.size() != 0
   12250                             || app.curReceiver != null) {
   12251                         // Don't count processes holding services against our
   12252                         // maximum process count.
   12253                         if (localLOGV) Slog.v(
   12254                             TAG, "Not trimming app " + app + " with services: "
   12255                             + app.services);
   12256                         numServiceProcs++;
   12257                     }
   12258                 }
   12259 
   12260                 int curMaxProcs = mProcessLimit;
   12261                 if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
   12262                 if (mAlwaysFinishActivities) {
   12263                     curMaxProcs = 1;
   12264                 }
   12265                 curMaxProcs += numServiceProcs;
   12266 
   12267                 // Quit as many processes as we can to get down to the desired
   12268                 // process count.  First remove any processes that no longer
   12269                 // have activites running in them.
   12270                 for (   i=0;
   12271                         i<mLruProcesses.size()
   12272                             && mLruProcesses.size() > curMaxProcs;
   12273                         i++) {
   12274                     final ProcessRecord app = mLruProcesses.get(i);
   12275                     // Quit an application only if it is not currently
   12276                     // running any activities.
   12277                     if (!app.persistent && app.activities.size() == 0
   12278                             && app.curReceiver == null && app.services.size() == 0) {
   12279                         Slog.i(
   12280                             TAG, "Exiting empty application process "
   12281                             + app.processName + " ("
   12282                             + (app.thread != null ? app.thread.asBinder() : null)
   12283                             + ")\n");
   12284                         if (app.pid > 0 && app.pid != MY_PID) {
   12285                             Process.killProcess(app.pid);
   12286                         } else {
   12287                             try {
   12288                                 app.thread.scheduleExit();
   12289                             } catch (Exception e) {
   12290                                 // Ignore exceptions.
   12291                             }
   12292                         }
   12293                         // todo: For now we assume the application is not buggy
   12294                         // or evil, and will quit as a result of our request.
   12295                         // Eventually we need to drive this off of the death
   12296                         // notification, and kill the process if it takes too long.
   12297                         cleanUpApplicationRecordLocked(app, false, i);
   12298                         i--;
   12299                     }
   12300                 }
   12301 
   12302                 // If we still have too many processes, now from the least
   12303                 // recently used process we start finishing activities.
   12304                 if (Config.LOGV) Slog.v(
   12305                     TAG, "*** NOW HAVE " + mLruProcesses.size() +
   12306                     " of " + curMaxProcs + " processes");
   12307                 for (   i=0;
   12308                         i<mLruProcesses.size()
   12309                             && mLruProcesses.size() > curMaxProcs;
   12310                         i++) {
   12311                     final ProcessRecord app = mLruProcesses.get(i);
   12312                     // Quit the application only if we have a state saved for
   12313                     // all of its activities.
   12314                     boolean canQuit = !app.persistent && app.curReceiver == null
   12315                         && app.services.size() == 0;
   12316                     int NUMA = app.activities.size();
   12317                     int j;
   12318                     if (Config.LOGV) Slog.v(
   12319                         TAG, "Looking to quit " + app.processName);
   12320                     for (j=0; j<NUMA && canQuit; j++) {
   12321                         ActivityRecord r = app.activities.get(j);
   12322                         if (Config.LOGV) Slog.v(
   12323                             TAG, "  " + r.intent.getComponent().flattenToShortString()
   12324                             + ": frozen=" + r.haveState + ", visible=" + r.visible);
   12325                         canQuit = (r.haveState || !r.stateNotNeeded)
   12326                                 && !r.visible && r.stopped;
   12327                     }
   12328                     if (canQuit) {
   12329                         // Finish all of the activities, and then the app itself.
   12330                         for (j=0; j<NUMA; j++) {
   12331                             ActivityRecord r = app.activities.get(j);
   12332                             if (!r.finishing) {
   12333                                 r.stack.destroyActivityLocked(r, false);
   12334                             }
   12335                             r.resultTo = null;
   12336                         }
   12337                         Slog.i(TAG, "Exiting application process "
   12338                               + app.processName + " ("
   12339                               + (app.thread != null ? app.thread.asBinder() : null)
   12340                               + ")\n");
   12341                         if (app.pid > 0 && app.pid != MY_PID) {
   12342                             Process.killProcess(app.pid);
   12343                         } else {
   12344                             try {
   12345                                 app.thread.scheduleExit();
   12346                             } catch (Exception e) {
   12347                                 // Ignore exceptions.
   12348                             }
   12349                         }
   12350                         // todo: For now we assume the application is not buggy
   12351                         // or evil, and will quit as a result of our request.
   12352                         // Eventually we need to drive this off of the death
   12353                         // notification, and kill the process if it takes too long.
   12354                         cleanUpApplicationRecordLocked(app, false, i);
   12355                         i--;
   12356                         //dump();
   12357                     }
   12358                 }
   12359 
   12360             }
   12361 
   12362             int curMaxActivities = MAX_ACTIVITIES;
   12363             if (mAlwaysFinishActivities) {
   12364                 curMaxActivities = 1;
   12365             }
   12366 
   12367             // Finally, if there are too many activities now running, try to
   12368             // finish as many as we can to get back down to the limit.
   12369             for (   i=0;
   12370                     i<mMainStack.mLRUActivities.size()
   12371                         && mMainStack.mLRUActivities.size() > curMaxActivities;
   12372                     i++) {
   12373                 final ActivityRecord r
   12374                     = (ActivityRecord)mMainStack.mLRUActivities.get(i);
   12375 
   12376                 // We can finish this one if we have its icicle saved and
   12377                 // it is not persistent.
   12378                 if ((r.haveState || !r.stateNotNeeded) && !r.visible
   12379                         && r.stopped && !r.finishing) {
   12380                     final int origSize = mMainStack.mLRUActivities.size();
   12381                     r.stack.destroyActivityLocked(r, true);
   12382 
   12383                     // This will remove it from the LRU list, so keep
   12384                     // our index at the same value.  Note that this check to
   12385                     // see if the size changes is just paranoia -- if
   12386                     // something unexpected happens, we don't want to end up
   12387                     // in an infinite loop.
   12388                     if (origSize > mMainStack.mLRUActivities.size()) {
   12389                         i--;
   12390                     }
   12391                 }
   12392             }
   12393         }
   12394     }
   12395 
   12396     /** This method sends the specified signal to each of the persistent apps */
   12397     public void signalPersistentProcesses(int sig) throws RemoteException {
   12398         if (sig != Process.SIGNAL_USR1) {
   12399             throw new SecurityException("Only SIGNAL_USR1 is allowed");
   12400         }
   12401 
   12402         synchronized (this) {
   12403             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
   12404                     != PackageManager.PERMISSION_GRANTED) {
   12405                 throw new SecurityException("Requires permission "
   12406                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
   12407             }
   12408 
   12409             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   12410                 ProcessRecord r = mLruProcesses.get(i);
   12411                 if (r.thread != null && r.persistent) {
   12412                     Process.sendSignal(r.pid, sig);
   12413                 }
   12414             }
   12415         }
   12416     }
   12417 
   12418     public boolean profileControl(String process, boolean start,
   12419             String path, ParcelFileDescriptor fd) throws RemoteException {
   12420 
   12421         try {
   12422             synchronized (this) {
   12423                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   12424                 // its own permission.
   12425                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   12426                         != PackageManager.PERMISSION_GRANTED) {
   12427                     throw new SecurityException("Requires permission "
   12428                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   12429                 }
   12430 
   12431                 if (start && fd == null) {
   12432                     throw new IllegalArgumentException("null fd");
   12433                 }
   12434 
   12435                 ProcessRecord proc = null;
   12436                 try {
   12437                     int pid = Integer.parseInt(process);
   12438                     synchronized (mPidsSelfLocked) {
   12439                         proc = mPidsSelfLocked.get(pid);
   12440                     }
   12441                 } catch (NumberFormatException e) {
   12442                 }
   12443 
   12444                 if (proc == null) {
   12445                     HashMap<String, SparseArray<ProcessRecord>> all
   12446                             = mProcessNames.getMap();
   12447                     SparseArray<ProcessRecord> procs = all.get(process);
   12448                     if (procs != null && procs.size() > 0) {
   12449                         proc = procs.valueAt(0);
   12450                     }
   12451                 }
   12452 
   12453                 if (proc == null || proc.thread == null) {
   12454                     throw new IllegalArgumentException("Unknown process: " + process);
   12455                 }
   12456 
   12457                 boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
   12458                 if (isSecure) {
   12459                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   12460                         throw new SecurityException("Process not debuggable: " + proc);
   12461                     }
   12462                 }
   12463 
   12464                 proc.thread.profilerControl(start, path, fd);
   12465                 fd = null;
   12466                 return true;
   12467             }
   12468         } catch (RemoteException e) {
   12469             throw new IllegalStateException("Process disappeared");
   12470         } finally {
   12471             if (fd != null) {
   12472                 try {
   12473                     fd.close();
   12474                 } catch (IOException e) {
   12475                 }
   12476             }
   12477         }
   12478     }
   12479 
   12480     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
   12481     public void monitor() {
   12482         synchronized (this) { }
   12483     }
   12484 }
   12485