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 (Settings.Secure.getInt(mContext.getContentResolver(),
   6671                 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
   6672             crashApplication(r, crashInfo);
   6673             return true;
   6674         } else {
   6675             return false;
   6676         }
   6677     }
   6678 
   6679     /**
   6680      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
   6681      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
   6682      */
   6683     private ProcessRecord findAppProcess(IBinder app) {
   6684         if (app == null) {
   6685             return null;
   6686         }
   6687 
   6688         synchronized (this) {
   6689             for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   6690                 final int NA = apps.size();
   6691                 for (int ia=0; ia<NA; ia++) {
   6692                     ProcessRecord p = apps.valueAt(ia);
   6693                     if (p.thread != null && p.thread.asBinder() == app) {
   6694                         return p;
   6695                     }
   6696                 }
   6697             }
   6698 
   6699             Slog.w(TAG, "Can't find mystery application: " + app);
   6700             return null;
   6701         }
   6702     }
   6703 
   6704     /**
   6705      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
   6706      * to append various headers to the dropbox log text.
   6707      */
   6708     private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
   6709         // Note: ProcessRecord 'process' is guarded by the service
   6710         // instance.  (notably process.pkgList, which could otherwise change
   6711         // concurrently during execution of this method)
   6712         synchronized (this) {
   6713             if (process == null || process.pid == MY_PID) {
   6714                 sb.append("Process: system_server\n");
   6715             } else {
   6716                 sb.append("Process: ").append(process.processName).append("\n");
   6717             }
   6718             if (process == null) {
   6719                 return;
   6720             }
   6721             int flags = process.info.flags;
   6722             IPackageManager pm = AppGlobals.getPackageManager();
   6723             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
   6724             for (String pkg : process.pkgList) {
   6725                 sb.append("Package: ").append(pkg);
   6726                 try {
   6727                     PackageInfo pi = pm.getPackageInfo(pkg, 0);
   6728                     if (pi != null) {
   6729                         sb.append(" v").append(pi.versionCode);
   6730                         if (pi.versionName != null) {
   6731                             sb.append(" (").append(pi.versionName).append(")");
   6732                         }
   6733                     }
   6734                 } catch (RemoteException e) {
   6735                     Slog.e(TAG, "Error getting package info: " + pkg, e);
   6736                 }
   6737                 sb.append("\n");
   6738             }
   6739         }
   6740     }
   6741 
   6742     private static String processClass(ProcessRecord process) {
   6743         if (process == null || process.pid == MY_PID) {
   6744             return "system_server";
   6745         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   6746             return "system_app";
   6747         } else {
   6748             return "data_app";
   6749         }
   6750     }
   6751 
   6752     /**
   6753      * Write a description of an error (crash, WTF, ANR) to the drop box.
   6754      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
   6755      * @param process which caused the error, null means the system server
   6756      * @param activity which triggered the error, null if unknown
   6757      * @param parent activity related to the error, null if unknown
   6758      * @param subject line related to the error, null if absent
   6759      * @param report in long form describing the error, null if absent
   6760      * @param logFile to include in the report, null if none
   6761      * @param crashInfo giving an application stack trace, null if absent
   6762      */
   6763     public void addErrorToDropBox(String eventType,
   6764             ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
   6765             final String report, final File logFile,
   6766             final ApplicationErrorReport.CrashInfo crashInfo) {
   6767         // NOTE -- this must never acquire the ActivityManagerService lock,
   6768         // otherwise the watchdog may be prevented from resetting the system.
   6769 
   6770         final String dropboxTag = processClass(process) + "_" + eventType;
   6771         final DropBoxManager dbox = (DropBoxManager)
   6772                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   6773 
   6774         // Exit early if the dropbox isn't configured to accept this report type.
   6775         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   6776 
   6777         final StringBuilder sb = new StringBuilder(1024);
   6778         appendDropBoxProcessHeaders(process, sb);
   6779         if (activity != null) {
   6780             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
   6781         }
   6782         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
   6783             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
   6784         }
   6785         if (parent != null && parent != activity) {
   6786             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
   6787         }
   6788         if (subject != null) {
   6789             sb.append("Subject: ").append(subject).append("\n");
   6790         }
   6791         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   6792         sb.append("\n");
   6793 
   6794         // Do the rest in a worker thread to avoid blocking the caller on I/O
   6795         // (After this point, we shouldn't access AMS internal data structures.)
   6796         Thread worker = new Thread("Error dump: " + dropboxTag) {
   6797             @Override
   6798             public void run() {
   6799                 if (report != null) {
   6800                     sb.append(report);
   6801                 }
   6802                 if (logFile != null) {
   6803                     try {
   6804                         sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
   6805                     } catch (IOException e) {
   6806                         Slog.e(TAG, "Error reading " + logFile, e);
   6807                     }
   6808                 }
   6809                 if (crashInfo != null && crashInfo.stackTrace != null) {
   6810                     sb.append(crashInfo.stackTrace);
   6811                 }
   6812 
   6813                 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
   6814                 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
   6815                 if (lines > 0) {
   6816                     sb.append("\n");
   6817 
   6818                     // Merge several logcat streams, and take the last N lines
   6819                     InputStreamReader input = null;
   6820                     try {
   6821                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
   6822                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
   6823                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
   6824 
   6825                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
   6826                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
   6827                         input = new InputStreamReader(logcat.getInputStream());
   6828 
   6829                         int num;
   6830                         char[] buf = new char[8192];
   6831                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
   6832                     } catch (IOException e) {
   6833                         Slog.e(TAG, "Error running logcat", e);
   6834                     } finally {
   6835                         if (input != null) try { input.close(); } catch (IOException e) {}
   6836                     }
   6837                 }
   6838 
   6839                 dbox.addText(dropboxTag, sb.toString());
   6840             }
   6841         };
   6842 
   6843         if (process == null || process.pid == MY_PID) {
   6844             worker.run();  // We may be about to die -- need to run this synchronously
   6845         } else {
   6846             worker.start();
   6847         }
   6848     }
   6849 
   6850     /**
   6851      * Bring up the "unexpected error" dialog box for a crashing app.
   6852      * Deal with edge cases (intercepts from instrumented applications,
   6853      * ActivityController, error intent receivers, that sort of thing).
   6854      * @param r the application crashing
   6855      * @param crashInfo describing the failure
   6856      */
   6857     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
   6858         long timeMillis = System.currentTimeMillis();
   6859         String shortMsg = crashInfo.exceptionClassName;
   6860         String longMsg = crashInfo.exceptionMessage;
   6861         String stackTrace = crashInfo.stackTrace;
   6862         if (shortMsg != null && longMsg != null) {
   6863             longMsg = shortMsg + ": " + longMsg;
   6864         } else if (shortMsg != null) {
   6865             longMsg = shortMsg;
   6866         }
   6867 
   6868         AppErrorResult result = new AppErrorResult();
   6869         synchronized (this) {
   6870             if (mController != null) {
   6871                 try {
   6872                     String name = r != null ? r.processName : null;
   6873                     int pid = r != null ? r.pid : Binder.getCallingPid();
   6874                     if (!mController.appCrashed(name, pid,
   6875                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
   6876                         Slog.w(TAG, "Force-killing crashed app " + name
   6877                                 + " at watcher's request");
   6878                         Process.killProcess(pid);
   6879                         return;
   6880                     }
   6881                 } catch (RemoteException e) {
   6882                     mController = null;
   6883                 }
   6884             }
   6885 
   6886             final long origId = Binder.clearCallingIdentity();
   6887 
   6888             // If this process is running instrumentation, finish it.
   6889             if (r != null && r.instrumentationClass != null) {
   6890                 Slog.w(TAG, "Error in app " + r.processName
   6891                       + " running instrumentation " + r.instrumentationClass + ":");
   6892                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
   6893                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
   6894                 Bundle info = new Bundle();
   6895                 info.putString("shortMsg", shortMsg);
   6896                 info.putString("longMsg", longMsg);
   6897                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
   6898                 Binder.restoreCallingIdentity(origId);
   6899                 return;
   6900             }
   6901 
   6902             // If we can't identify the process or it's already exceeded its crash quota,
   6903             // quit right away without showing a crash dialog.
   6904             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
   6905                 Binder.restoreCallingIdentity(origId);
   6906                 return;
   6907             }
   6908 
   6909             Message msg = Message.obtain();
   6910             msg.what = SHOW_ERROR_MSG;
   6911             HashMap data = new HashMap();
   6912             data.put("result", result);
   6913             data.put("app", r);
   6914             msg.obj = data;
   6915             mHandler.sendMessage(msg);
   6916 
   6917             Binder.restoreCallingIdentity(origId);
   6918         }
   6919 
   6920         int res = result.get();
   6921 
   6922         Intent appErrorIntent = null;
   6923         synchronized (this) {
   6924             if (r != null) {
   6925                 mProcessCrashTimes.put(r.info.processName, r.info.uid,
   6926                         SystemClock.uptimeMillis());
   6927             }
   6928             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
   6929                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
   6930             }
   6931         }
   6932 
   6933         if (appErrorIntent != null) {
   6934             try {
   6935                 mContext.startActivity(appErrorIntent);
   6936             } catch (ActivityNotFoundException e) {
   6937                 Slog.w(TAG, "bug report receiver dissappeared", e);
   6938             }
   6939         }
   6940     }
   6941 
   6942     Intent createAppErrorIntentLocked(ProcessRecord r,
   6943             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   6944         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
   6945         if (report == null) {
   6946             return null;
   6947         }
   6948         Intent result = new Intent(Intent.ACTION_APP_ERROR);
   6949         result.setComponent(r.errorReportReceiver);
   6950         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
   6951         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   6952         return result;
   6953     }
   6954 
   6955     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
   6956             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   6957         if (r.errorReportReceiver == null) {
   6958             return null;
   6959         }
   6960 
   6961         if (!r.crashing && !r.notResponding) {
   6962             return null;
   6963         }
   6964 
   6965         ApplicationErrorReport report = new ApplicationErrorReport();
   6966         report.packageName = r.info.packageName;
   6967         report.installerPackageName = r.errorReportReceiver.getPackageName();
   6968         report.processName = r.processName;
   6969         report.time = timeMillis;
   6970         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   6971 
   6972         if (r.crashing) {
   6973             report.type = ApplicationErrorReport.TYPE_CRASH;
   6974             report.crashInfo = crashInfo;
   6975         } else if (r.notResponding) {
   6976             report.type = ApplicationErrorReport.TYPE_ANR;
   6977             report.anrInfo = new ApplicationErrorReport.AnrInfo();
   6978 
   6979             report.anrInfo.activity = r.notRespondingReport.tag;
   6980             report.anrInfo.cause = r.notRespondingReport.shortMsg;
   6981             report.anrInfo.info = r.notRespondingReport.longMsg;
   6982         }
   6983 
   6984         return report;
   6985     }
   6986 
   6987     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
   6988         // assume our apps are happy - lazy create the list
   6989         List<ActivityManager.ProcessErrorStateInfo> errList = null;
   6990 
   6991         synchronized (this) {
   6992 
   6993             // iterate across all processes
   6994             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   6995                 ProcessRecord app = mLruProcesses.get(i);
   6996                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
   6997                     // This one's in trouble, so we'll generate a report for it
   6998                     // crashes are higher priority (in case there's a crash *and* an anr)
   6999                     ActivityManager.ProcessErrorStateInfo report = null;
   7000                     if (app.crashing) {
   7001                         report = app.crashingReport;
   7002                     } else if (app.notResponding) {
   7003                         report = app.notRespondingReport;
   7004                     }
   7005 
   7006                     if (report != null) {
   7007                         if (errList == null) {
   7008                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
   7009                         }
   7010                         errList.add(report);
   7011                     } else {
   7012                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
   7013                                 " crashing = " + app.crashing +
   7014                                 " notResponding = " + app.notResponding);
   7015                     }
   7016                 }
   7017             }
   7018         }
   7019 
   7020         return errList;
   7021     }
   7022 
   7023     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
   7024         // Lazy instantiation of list
   7025         List<ActivityManager.RunningAppProcessInfo> runList = null;
   7026         synchronized (this) {
   7027             // Iterate across all processes
   7028             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   7029                 ProcessRecord app = mLruProcesses.get(i);
   7030                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
   7031                     // Generate process state info for running application
   7032                     ActivityManager.RunningAppProcessInfo currApp =
   7033                         new ActivityManager.RunningAppProcessInfo(app.processName,
   7034                                 app.pid, app.getPackageList());
   7035                     currApp.uid = app.info.uid;
   7036                     if (mHeavyWeightProcess == app) {
   7037                         currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
   7038                     }
   7039                     if (app.persistent) {
   7040                         currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
   7041                     }
   7042                     int adj = app.curAdj;
   7043                     if (adj >= EMPTY_APP_ADJ) {
   7044                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
   7045                     } else if (adj >= HIDDEN_APP_MIN_ADJ) {
   7046                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   7047                         currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
   7048                     } else if (adj >= HOME_APP_ADJ) {
   7049                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   7050                         currApp.lru = 0;
   7051                     } else if (adj >= SECONDARY_SERVER_ADJ) {
   7052                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   7053                     } else if (adj >= HEAVY_WEIGHT_APP_ADJ) {
   7054                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
   7055                     } else if (adj >= PERCEPTIBLE_APP_ADJ) {
   7056                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
   7057                     } else if (adj >= VISIBLE_APP_ADJ) {
   7058                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
   7059                     } else {
   7060                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
   7061                     }
   7062                     currApp.importanceReasonCode = app.adjTypeCode;
   7063                     if (app.adjSource instanceof ProcessRecord) {
   7064                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
   7065                     } else if (app.adjSource instanceof ActivityRecord) {
   7066                         ActivityRecord r = (ActivityRecord)app.adjSource;
   7067                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
   7068                     }
   7069                     if (app.adjTarget instanceof ComponentName) {
   7070                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
   7071                     }
   7072                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
   7073                     //        + " lru=" + currApp.lru);
   7074                     if (runList == null) {
   7075                         runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
   7076                     }
   7077                     runList.add(currApp);
   7078                 }
   7079             }
   7080         }
   7081         return runList;
   7082     }
   7083 
   7084     public List<ApplicationInfo> getRunningExternalApplications() {
   7085         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
   7086         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
   7087         if (runningApps != null && runningApps.size() > 0) {
   7088             Set<String> extList = new HashSet<String>();
   7089             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
   7090                 if (app.pkgList != null) {
   7091                     for (String pkg : app.pkgList) {
   7092                         extList.add(pkg);
   7093                     }
   7094                 }
   7095             }
   7096             IPackageManager pm = AppGlobals.getPackageManager();
   7097             for (String pkg : extList) {
   7098                 try {
   7099                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
   7100                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
   7101                         retList.add(info);
   7102                     }
   7103                 } catch (RemoteException e) {
   7104                 }
   7105             }
   7106         }
   7107         return retList;
   7108     }
   7109 
   7110     @Override
   7111     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   7112         if (checkCallingPermission(android.Manifest.permission.DUMP)
   7113                 != PackageManager.PERMISSION_GRANTED) {
   7114             pw.println("Permission Denial: can't dump ActivityManager from from pid="
   7115                     + Binder.getCallingPid()
   7116                     + ", uid=" + Binder.getCallingUid()
   7117                     + " without permission "
   7118                     + android.Manifest.permission.DUMP);
   7119             return;
   7120         }
   7121 
   7122         boolean dumpAll = false;
   7123 
   7124         int opti = 0;
   7125         while (opti < args.length) {
   7126             String opt = args[opti];
   7127             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   7128                 break;
   7129             }
   7130             opti++;
   7131             if ("-a".equals(opt)) {
   7132                 dumpAll = true;
   7133             } else if ("-h".equals(opt)) {
   7134                 pw.println("Activity manager dump options:");
   7135                 pw.println("  [-a] [-h] [cmd] ...");
   7136                 pw.println("  cmd may be one of:");
   7137                 pw.println("    a[ctivities]: activity stack state");
   7138                 pw.println("    b[roadcasts]: broadcast state");
   7139                 pw.println("    i[ntents]: pending intent state");
   7140                 pw.println("    p[rocesses]: process state");
   7141                 pw.println("    o[om]: out of memory management");
   7142                 pw.println("    prov[iders]: content provider state");
   7143                 pw.println("    s[ervices]: service state");
   7144                 pw.println("    service [name]: service client-side state");
   7145                 return;
   7146             } else {
   7147                 pw.println("Unknown argument: " + opt + "; use -h for help");
   7148             }
   7149         }
   7150 
   7151         // Is the caller requesting to dump a particular piece of data?
   7152         if (opti < args.length) {
   7153             String cmd = args[opti];
   7154             opti++;
   7155             if ("activities".equals(cmd) || "a".equals(cmd)) {
   7156                 synchronized (this) {
   7157                     dumpActivitiesLocked(fd, pw, args, opti, true, true);
   7158                 }
   7159                 return;
   7160             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
   7161                 synchronized (this) {
   7162                     dumpBroadcastsLocked(fd, pw, args, opti, true);
   7163                 }
   7164                 return;
   7165             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
   7166                 synchronized (this) {
   7167                     dumpPendingIntentsLocked(fd, pw, args, opti, true);
   7168                 }
   7169                 return;
   7170             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
   7171                 synchronized (this) {
   7172                     dumpProcessesLocked(fd, pw, args, opti, true);
   7173                 }
   7174                 return;
   7175             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
   7176                 synchronized (this) {
   7177                     dumpOomLocked(fd, pw, args, opti, true);
   7178                 }
   7179                 return;
   7180             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
   7181                 synchronized (this) {
   7182                     dumpProvidersLocked(fd, pw, args, opti, true);
   7183                 }
   7184                 return;
   7185             } else if ("service".equals(cmd)) {
   7186                 dumpService(fd, pw, args, opti, dumpAll);
   7187                 return;
   7188             } else if ("services".equals(cmd) || "s".equals(cmd)) {
   7189                 synchronized (this) {
   7190                     dumpServicesLocked(fd, pw, args, opti, true);
   7191                 }
   7192                 return;
   7193             }
   7194         }
   7195 
   7196         // No piece of data specified, dump everything.
   7197         synchronized (this) {
   7198             boolean needSep;
   7199             if (dumpAll) {
   7200                 pw.println("Providers in Current Activity Manager State:");
   7201             }
   7202             needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
   7203             if (needSep) {
   7204                 pw.println(" ");
   7205             }
   7206             if (dumpAll) {
   7207                 pw.println("-------------------------------------------------------------------------------");
   7208                 pw.println("Broadcasts in Current Activity Manager State:");
   7209             }
   7210             needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
   7211             if (needSep) {
   7212                 pw.println(" ");
   7213             }
   7214             if (dumpAll) {
   7215                 pw.println("-------------------------------------------------------------------------------");
   7216                 pw.println("Services in Current Activity Manager State:");
   7217             }
   7218             needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll);
   7219             if (needSep) {
   7220                 pw.println(" ");
   7221             }
   7222             if (dumpAll) {
   7223                 pw.println("-------------------------------------------------------------------------------");
   7224                 pw.println("PendingIntents in Current Activity Manager State:");
   7225             }
   7226             needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
   7227             if (needSep) {
   7228                 pw.println(" ");
   7229             }
   7230             if (dumpAll) {
   7231                 pw.println("-------------------------------------------------------------------------------");
   7232                 pw.println("Activities in Current Activity Manager State:");
   7233             }
   7234             needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, !dumpAll);
   7235             if (needSep) {
   7236                 pw.println(" ");
   7237             }
   7238             if (dumpAll) {
   7239                 pw.println("-------------------------------------------------------------------------------");
   7240                 pw.println("Processes in Current Activity Manager State:");
   7241             }
   7242             dumpProcessesLocked(fd, pw, args, opti, dumpAll);
   7243         }
   7244     }
   7245 
   7246     boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   7247             int opti, boolean dumpAll, boolean needHeader) {
   7248         if (needHeader) {
   7249             pw.println("  Activity stack:");
   7250         }
   7251         dumpHistoryList(pw, mMainStack.mHistory, "  ", "Hist", true);
   7252         pw.println(" ");
   7253         pw.println("  Running activities (most recent first):");
   7254         dumpHistoryList(pw, mMainStack.mLRUActivities, "  ", "Run", false);
   7255         if (mMainStack.mWaitingVisibleActivities.size() > 0) {
   7256             pw.println(" ");
   7257             pw.println("  Activities waiting for another to become visible:");
   7258             dumpHistoryList(pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false);
   7259         }
   7260         if (mMainStack.mStoppingActivities.size() > 0) {
   7261             pw.println(" ");
   7262             pw.println("  Activities waiting to stop:");
   7263             dumpHistoryList(pw, mMainStack.mStoppingActivities, "  ", "Stop", false);
   7264         }
   7265         if (mMainStack.mFinishingActivities.size() > 0) {
   7266             pw.println(" ");
   7267             pw.println("  Activities waiting to finish:");
   7268             dumpHistoryList(pw, mMainStack.mFinishingActivities, "  ", "Fin", false);
   7269         }
   7270 
   7271         pw.println(" ");
   7272         pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
   7273         pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
   7274         pw.println("  mFocusedActivity: " + mFocusedActivity);
   7275         pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
   7276 
   7277         if (dumpAll && mRecentTasks.size() > 0) {
   7278             pw.println(" ");
   7279             pw.println("Recent tasks in Current Activity Manager State:");
   7280 
   7281             final int N = mRecentTasks.size();
   7282             for (int i=0; i<N; i++) {
   7283                 TaskRecord tr = mRecentTasks.get(i);
   7284                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
   7285                         pw.println(tr);
   7286                 mRecentTasks.get(i).dump(pw, "    ");
   7287             }
   7288         }
   7289 
   7290         pw.println(" ");
   7291         pw.println("  mCurTask: " + mCurTask);
   7292 
   7293         return true;
   7294     }
   7295 
   7296     boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   7297             int opti, boolean dumpAll) {
   7298         boolean needSep = false;
   7299         int numPers = 0;
   7300 
   7301         if (dumpAll) {
   7302             for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
   7303                 final int NA = procs.size();
   7304                 for (int ia=0; ia<NA; ia++) {
   7305                     if (!needSep) {
   7306                         pw.println("  All known processes:");
   7307                         needSep = true;
   7308                     }
   7309                     ProcessRecord r = procs.valueAt(ia);
   7310                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
   7311                         pw.print(" UID "); pw.print(procs.keyAt(ia));
   7312                         pw.print(" "); pw.println(r);
   7313                     r.dump(pw, "    ");
   7314                     if (r.persistent) {
   7315                         numPers++;
   7316                     }
   7317                 }
   7318             }
   7319         }
   7320 
   7321         if (mLruProcesses.size() > 0) {
   7322             if (needSep) pw.println(" ");
   7323             needSep = true;
   7324             pw.println("  Running processes (most recent first):");
   7325             dumpProcessOomList(pw, this, mLruProcesses, "    ",
   7326                     "Proc", "PERS", false);
   7327             needSep = true;
   7328         }
   7329 
   7330         synchronized (mPidsSelfLocked) {
   7331             if (mPidsSelfLocked.size() > 0) {
   7332                 if (needSep) pw.println(" ");
   7333                 needSep = true;
   7334                 pw.println("  PID mappings:");
   7335                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   7336                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
   7337                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
   7338                 }
   7339             }
   7340         }
   7341 
   7342         if (mForegroundProcesses.size() > 0) {
   7343             if (needSep) pw.println(" ");
   7344             needSep = true;
   7345             pw.println("  Foreground Processes:");
   7346             for (int i=0; i<mForegroundProcesses.size(); i++) {
   7347                 pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
   7348                         pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
   7349             }
   7350         }
   7351 
   7352         if (mPersistentStartingProcesses.size() > 0) {
   7353             if (needSep) pw.println(" ");
   7354             needSep = true;
   7355             pw.println("  Persisent processes that are starting:");
   7356             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
   7357                     "Starting Norm", "Restarting PERS");
   7358         }
   7359 
   7360         if (mStartingProcesses.size() > 0) {
   7361             if (needSep) pw.println(" ");
   7362             needSep = true;
   7363             pw.println("  Processes that are starting:");
   7364             dumpProcessList(pw, this, mStartingProcesses, "    ",
   7365                     "Starting Norm", "Starting PERS");
   7366         }
   7367 
   7368         if (mRemovedProcesses.size() > 0) {
   7369             if (needSep) pw.println(" ");
   7370             needSep = true;
   7371             pw.println("  Processes that are being removed:");
   7372             dumpProcessList(pw, this, mRemovedProcesses, "    ",
   7373                     "Removed Norm", "Removed PERS");
   7374         }
   7375 
   7376         if (mProcessesOnHold.size() > 0) {
   7377             if (needSep) pw.println(" ");
   7378             needSep = true;
   7379             pw.println("  Processes that are on old until the system is ready:");
   7380             dumpProcessList(pw, this, mProcessesOnHold, "    ",
   7381                     "OnHold Norm", "OnHold PERS");
   7382         }
   7383 
   7384         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
   7385 
   7386         if (mProcessCrashTimes.getMap().size() > 0) {
   7387             if (needSep) pw.println(" ");
   7388             needSep = true;
   7389             pw.println("  Time since processes crashed:");
   7390             long now = SystemClock.uptimeMillis();
   7391             for (Map.Entry<String, SparseArray<Long>> procs
   7392                     : mProcessCrashTimes.getMap().entrySet()) {
   7393                 SparseArray<Long> uids = procs.getValue();
   7394                 final int N = uids.size();
   7395                 for (int i=0; i<N; i++) {
   7396                     pw.print("    Process "); pw.print(procs.getKey());
   7397                             pw.print(" uid "); pw.print(uids.keyAt(i));
   7398                             pw.print(": last crashed ");
   7399                             pw.print((now-uids.valueAt(i)));
   7400                             pw.println(" ms ago");
   7401                 }
   7402             }
   7403         }
   7404 
   7405         if (mBadProcesses.getMap().size() > 0) {
   7406             if (needSep) pw.println(" ");
   7407             needSep = true;
   7408             pw.println("  Bad processes:");
   7409             for (Map.Entry<String, SparseArray<Long>> procs
   7410                     : mBadProcesses.getMap().entrySet()) {
   7411                 SparseArray<Long> uids = procs.getValue();
   7412                 final int N = uids.size();
   7413                 for (int i=0; i<N; i++) {
   7414                     pw.print("    Bad process "); pw.print(procs.getKey());
   7415                             pw.print(" uid "); pw.print(uids.keyAt(i));
   7416                             pw.print(": crashed at time ");
   7417                             pw.println(uids.valueAt(i));
   7418                 }
   7419             }
   7420         }
   7421 
   7422         pw.println(" ");
   7423         pw.println("  mHomeProcess: " + mHomeProcess);
   7424         if (mHeavyWeightProcess != null) {
   7425             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   7426         }
   7427         pw.println("  mConfiguration: " + mConfiguration);
   7428         pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
   7429         pw.println("  mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
   7430         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
   7431                 || mOrigWaitForDebugger) {
   7432             pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
   7433                     + " mDebugTransient=" + mDebugTransient
   7434                     + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
   7435         }
   7436         if (mAlwaysFinishActivities || mController != null) {
   7437             pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
   7438                     + " mController=" + mController);
   7439         }
   7440         if (dumpAll) {
   7441             pw.println("  Total persistent processes: " + numPers);
   7442             pw.println("  mStartRunning=" + mStartRunning
   7443                     + " mProcessesReady=" + mProcessesReady
   7444                     + " mSystemReady=" + mSystemReady);
   7445             pw.println("  mBooting=" + mBooting
   7446                     + " mBooted=" + mBooted
   7447                     + " mFactoryTest=" + mFactoryTest);
   7448             pw.print("  mLastPowerCheckRealtime=");
   7449                     TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
   7450                     pw.println("");
   7451             pw.print("  mLastPowerCheckUptime=");
   7452                     TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
   7453                     pw.println("");
   7454             pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
   7455             pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
   7456             pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
   7457         }
   7458 
   7459         return true;
   7460     }
   7461 
   7462     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
   7463             int opti, boolean needSep, boolean dumpAll) {
   7464         if (mProcessesToGc.size() > 0) {
   7465             if (needSep) pw.println(" ");
   7466             needSep = true;
   7467             pw.println("  Processes that are waiting to GC:");
   7468             long now = SystemClock.uptimeMillis();
   7469             for (int i=0; i<mProcessesToGc.size(); i++) {
   7470                 ProcessRecord proc = mProcessesToGc.get(i);
   7471                 pw.print("    Process "); pw.println(proc);
   7472                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
   7473                         pw.print(", last gced=");
   7474                         pw.print(now-proc.lastRequestedGc);
   7475                         pw.print(" ms ago, last lowMem=");
   7476                         pw.print(now-proc.lastLowMemory);
   7477                         pw.println(" ms ago");
   7478 
   7479             }
   7480         }
   7481         return needSep;
   7482     }
   7483 
   7484     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   7485             int opti, boolean dumpAll) {
   7486         boolean needSep = false;
   7487 
   7488         if (mLruProcesses.size() > 0) {
   7489             ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses);
   7490 
   7491             Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() {
   7492                 @Override
   7493                 public int compare(ProcessRecord object1, ProcessRecord object2) {
   7494                     if (object1.setAdj != object2.setAdj) {
   7495                         return object1.setAdj > object2.setAdj ? -1 : 1;
   7496                     }
   7497                     if (object1.setSchedGroup != object2.setSchedGroup) {
   7498                         return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1;
   7499                     }
   7500                     if (object1.keeping != object2.keeping) {
   7501                         return object1.keeping ? -1 : 1;
   7502                     }
   7503                     if (object1.pid != object2.pid) {
   7504                         return object1.pid > object2.pid ? -1 : 1;
   7505                     }
   7506                     return 0;
   7507                 }
   7508             };
   7509 
   7510             Collections.sort(procs, comparator);
   7511 
   7512             if (needSep) pw.println(" ");
   7513             needSep = true;
   7514             pw.println("  Process OOM control:");
   7515             dumpProcessOomList(pw, this, procs, "    ",
   7516                     "Proc", "PERS", true);
   7517             needSep = true;
   7518         }
   7519 
   7520         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
   7521 
   7522         pw.println(" ");
   7523         pw.println("  mHomeProcess: " + mHomeProcess);
   7524         if (mHeavyWeightProcess != null) {
   7525             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   7526         }
   7527 
   7528         return true;
   7529     }
   7530 
   7531     /**
   7532      * There are three ways to call this:
   7533      *  - no service specified: dump all the services
   7534      *  - a flattened component name that matched an existing service was specified as the
   7535      *    first arg: dump that one service
   7536      *  - the first arg isn't the flattened component name of an existing service:
   7537      *    dump all services whose component contains the first arg as a substring
   7538      */
   7539     protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args,
   7540             int opti, boolean dumpAll) {
   7541         String[] newArgs;
   7542         String componentNameString;
   7543         ServiceRecord r;
   7544         if (opti >= args.length) {
   7545             componentNameString = null;
   7546             newArgs = EMPTY_STRING_ARRAY;
   7547             r = null;
   7548         } else {
   7549             componentNameString = args[opti];
   7550             opti++;
   7551             ComponentName componentName = ComponentName.unflattenFromString(componentNameString);
   7552             synchronized (this) {
   7553                 r = componentName != null ? mServices.get(componentName) : null;
   7554             }
   7555             newArgs = new String[args.length - opti];
   7556             if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   7557         }
   7558 
   7559         if (r != null) {
   7560             dumpService(fd, pw, r, newArgs, dumpAll);
   7561         } else {
   7562             ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
   7563             synchronized (this) {
   7564                 for (ServiceRecord r1 : mServices.values()) {
   7565                     if (componentNameString == null
   7566                             || r1.name.flattenToString().contains(componentNameString)) {
   7567                         services.add(r1);
   7568                     }
   7569                 }
   7570             }
   7571             for (int i=0; i<services.size(); i++) {
   7572                 dumpService(fd, pw, services.get(i), newArgs, dumpAll);
   7573             }
   7574         }
   7575     }
   7576 
   7577     /**
   7578      * Invokes IApplicationThread.dumpService() on the thread of the specified service if
   7579      * there is a thread associated with the service.
   7580      */
   7581     private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args,
   7582             boolean dumpAll) {
   7583         pw.println("  Service " + r.name.flattenToString());
   7584         if (dumpAll) {
   7585             synchronized (this) {
   7586                 pw.print("  * "); pw.println(r);
   7587                 r.dump(pw, "    ");
   7588             }
   7589             pw.println("");
   7590         }
   7591         if (r.app != null && r.app.thread != null) {
   7592             try {
   7593                 // flush anything that is already in the PrintWriter since the thread is going
   7594                 // to write to the file descriptor directly
   7595                 pw.flush();
   7596                 r.app.thread.dumpService(fd, r, args);
   7597                 pw.print("\n");
   7598                 pw.flush();
   7599             } catch (RemoteException e) {
   7600                 pw.println("got a RemoteException while dumping the service");
   7601             }
   7602         }
   7603     }
   7604 
   7605     boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   7606             int opti, boolean dumpAll) {
   7607         boolean needSep = false;
   7608 
   7609         if (dumpAll) {
   7610             if (mRegisteredReceivers.size() > 0) {
   7611                 pw.println(" ");
   7612                 pw.println("  Registered Receivers:");
   7613                 Iterator it = mRegisteredReceivers.values().iterator();
   7614                 while (it.hasNext()) {
   7615                     ReceiverList r = (ReceiverList)it.next();
   7616                     pw.print("  * "); pw.println(r);
   7617                     r.dump(pw, "    ");
   7618                 }
   7619             }
   7620 
   7621             pw.println(" ");
   7622             pw.println("Receiver Resolver Table:");
   7623             mReceiverResolver.dump(pw, null, "  ", null, false);
   7624             needSep = true;
   7625         }
   7626 
   7627         if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
   7628                 || mPendingBroadcast != null) {
   7629             if (mParallelBroadcasts.size() > 0) {
   7630                 pw.println(" ");
   7631                 pw.println("  Active broadcasts:");
   7632             }
   7633             for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
   7634                 pw.println("  Broadcast #" + i + ":");
   7635                 mParallelBroadcasts.get(i).dump(pw, "    ");
   7636             }
   7637             if (mOrderedBroadcasts.size() > 0) {
   7638                 pw.println(" ");
   7639                 pw.println("  Active ordered broadcasts:");
   7640             }
   7641             for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
   7642                 pw.println("  Serialized Broadcast #" + i + ":");
   7643                 mOrderedBroadcasts.get(i).dump(pw, "    ");
   7644             }
   7645             pw.println(" ");
   7646             pw.println("  Pending broadcast:");
   7647             if (mPendingBroadcast != null) {
   7648                 mPendingBroadcast.dump(pw, "    ");
   7649             } else {
   7650                 pw.println("    (null)");
   7651             }
   7652             needSep = true;
   7653         }
   7654 
   7655         if (dumpAll) {
   7656             pw.println(" ");
   7657             pw.println("  Historical broadcasts:");
   7658             for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
   7659                 BroadcastRecord r = mBroadcastHistory[i];
   7660                 if (r == null) {
   7661                     break;
   7662                 }
   7663                 pw.println("  Historical Broadcast #" + i + ":");
   7664                 r.dump(pw, "    ");
   7665             }
   7666             needSep = true;
   7667         }
   7668 
   7669         if (mStickyBroadcasts != null) {
   7670             pw.println(" ");
   7671             pw.println("  Sticky broadcasts:");
   7672             StringBuilder sb = new StringBuilder(128);
   7673             for (Map.Entry<String, ArrayList<Intent>> ent
   7674                     : mStickyBroadcasts.entrySet()) {
   7675                 pw.print("  * Sticky action "); pw.print(ent.getKey());
   7676                         pw.println(":");
   7677                 ArrayList<Intent> intents = ent.getValue();
   7678                 final int N = intents.size();
   7679                 for (int i=0; i<N; i++) {
   7680                     sb.setLength(0);
   7681                     sb.append("    Intent: ");
   7682                     intents.get(i).toShortString(sb, true, false);
   7683                     pw.println(sb.toString());
   7684                     Bundle bundle = intents.get(i).getExtras();
   7685                     if (bundle != null) {
   7686                         pw.print("      ");
   7687                         pw.println(bundle.toString());
   7688                     }
   7689                 }
   7690             }
   7691             needSep = true;
   7692         }
   7693 
   7694         if (dumpAll) {
   7695             pw.println(" ");
   7696             pw.println("  mBroadcastsScheduled=" + mBroadcastsScheduled);
   7697             pw.println("  mHandler:");
   7698             mHandler.dump(new PrintWriterPrinter(pw), "    ");
   7699             needSep = true;
   7700         }
   7701 
   7702         return needSep;
   7703     }
   7704 
   7705     boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   7706             int opti, boolean dumpAll) {
   7707         boolean needSep = false;
   7708 
   7709         if (dumpAll) {
   7710             if (mServices.size() > 0) {
   7711                 pw.println("  Active services:");
   7712                 Iterator<ServiceRecord> it = mServices.values().iterator();
   7713                 while (it.hasNext()) {
   7714                     ServiceRecord r = it.next();
   7715                     pw.print("  * "); pw.println(r);
   7716                     r.dump(pw, "    ");
   7717                 }
   7718                 needSep = true;
   7719             }
   7720         }
   7721 
   7722         if (mPendingServices.size() > 0) {
   7723             if (needSep) pw.println(" ");
   7724             pw.println("  Pending services:");
   7725             for (int i=0; i<mPendingServices.size(); i++) {
   7726                 ServiceRecord r = mPendingServices.get(i);
   7727                 pw.print("  * Pending "); pw.println(r);
   7728                 r.dump(pw, "    ");
   7729             }
   7730             needSep = true;
   7731         }
   7732 
   7733         if (mRestartingServices.size() > 0) {
   7734             if (needSep) pw.println(" ");
   7735             pw.println("  Restarting services:");
   7736             for (int i=0; i<mRestartingServices.size(); i++) {
   7737                 ServiceRecord r = mRestartingServices.get(i);
   7738                 pw.print("  * Restarting "); pw.println(r);
   7739                 r.dump(pw, "    ");
   7740             }
   7741             needSep = true;
   7742         }
   7743 
   7744         if (mStoppingServices.size() > 0) {
   7745             if (needSep) pw.println(" ");
   7746             pw.println("  Stopping services:");
   7747             for (int i=0; i<mStoppingServices.size(); i++) {
   7748                 ServiceRecord r = mStoppingServices.get(i);
   7749                 pw.print("  * Stopping "); pw.println(r);
   7750                 r.dump(pw, "    ");
   7751             }
   7752             needSep = true;
   7753         }
   7754 
   7755         if (dumpAll) {
   7756             if (mServiceConnections.size() > 0) {
   7757                 if (needSep) pw.println(" ");
   7758                 pw.println("  Connection bindings to services:");
   7759                 Iterator<ArrayList<ConnectionRecord>> it
   7760                         = mServiceConnections.values().iterator();
   7761                 while (it.hasNext()) {
   7762                     ArrayList<ConnectionRecord> r = it.next();
   7763                     for (int i=0; i<r.size(); i++) {
   7764                         pw.print("  * "); pw.println(r.get(i));
   7765                         r.get(i).dump(pw, "    ");
   7766                     }
   7767                 }
   7768                 needSep = true;
   7769             }
   7770         }
   7771 
   7772         return needSep;
   7773     }
   7774 
   7775     boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   7776             int opti, boolean dumpAll) {
   7777         boolean needSep = false;
   7778 
   7779         if (dumpAll) {
   7780             if (mProvidersByClass.size() > 0) {
   7781                 if (needSep) pw.println(" ");
   7782                 pw.println("  Published content providers (by class):");
   7783                 Iterator<Map.Entry<String, ContentProviderRecord>> it
   7784                         = mProvidersByClass.entrySet().iterator();
   7785                 while (it.hasNext()) {
   7786                     Map.Entry<String, ContentProviderRecord> e = it.next();
   7787                     ContentProviderRecord r = e.getValue();
   7788                     pw.print("  * "); pw.println(r);
   7789                     r.dump(pw, "    ");
   7790                 }
   7791                 needSep = true;
   7792             }
   7793 
   7794             if (mProvidersByName.size() > 0) {
   7795                 pw.println(" ");
   7796                 pw.println("  Authority to provider mappings:");
   7797                 Iterator<Map.Entry<String, ContentProviderRecord>> it
   7798                         = mProvidersByName.entrySet().iterator();
   7799                 while (it.hasNext()) {
   7800                     Map.Entry<String, ContentProviderRecord> e = it.next();
   7801                     ContentProviderRecord r = e.getValue();
   7802                     pw.print("  "); pw.print(e.getKey()); pw.print(": ");
   7803                             pw.println(r);
   7804                 }
   7805                 needSep = true;
   7806             }
   7807         }
   7808 
   7809         if (mLaunchingProviders.size() > 0) {
   7810             if (needSep) pw.println(" ");
   7811             pw.println("  Launching content providers:");
   7812             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
   7813                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
   7814                         pw.println(mLaunchingProviders.get(i));
   7815             }
   7816             needSep = true;
   7817         }
   7818 
   7819         if (mGrantedUriPermissions.size() > 0) {
   7820             pw.println();
   7821             pw.println("Granted Uri Permissions:");
   7822             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
   7823                 int uid = mGrantedUriPermissions.keyAt(i);
   7824                 HashMap<Uri, UriPermission> perms
   7825                         = mGrantedUriPermissions.valueAt(i);
   7826                 pw.print("  * UID "); pw.print(uid);
   7827                         pw.println(" holds:");
   7828                 for (UriPermission perm : perms.values()) {
   7829                     pw.print("    "); pw.println(perm);
   7830                     perm.dump(pw, "      ");
   7831                 }
   7832             }
   7833             needSep = true;
   7834         }
   7835 
   7836         return needSep;
   7837     }
   7838 
   7839     boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   7840             int opti, boolean dumpAll) {
   7841         boolean needSep = false;
   7842 
   7843         if (dumpAll) {
   7844             if (this.mIntentSenderRecords.size() > 0) {
   7845                 Iterator<WeakReference<PendingIntentRecord>> it
   7846                         = mIntentSenderRecords.values().iterator();
   7847                 while (it.hasNext()) {
   7848                     WeakReference<PendingIntentRecord> ref = it.next();
   7849                     PendingIntentRecord rec = ref != null ? ref.get(): null;
   7850                     needSep = true;
   7851                     if (rec != null) {
   7852                         pw.print("  * "); pw.println(rec);
   7853                         rec.dump(pw, "    ");
   7854                     } else {
   7855                         pw.print("  * "); pw.print(ref);
   7856                     }
   7857                 }
   7858             }
   7859         }
   7860 
   7861         return needSep;
   7862     }
   7863 
   7864     private static final void dumpHistoryList(PrintWriter pw, List list,
   7865             String prefix, String label, boolean complete) {
   7866         TaskRecord lastTask = null;
   7867         for (int i=list.size()-1; i>=0; i--) {
   7868             ActivityRecord r = (ActivityRecord)list.get(i);
   7869             final boolean full = complete || !r.inHistory;
   7870             if (lastTask != r.task) {
   7871                 lastTask = r.task;
   7872                 pw.print(prefix);
   7873                 pw.print(full ? "* " : "  ");
   7874                 pw.println(lastTask);
   7875                 if (full) {
   7876                     lastTask.dump(pw, prefix + "  ");
   7877                 }
   7878             }
   7879             pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
   7880             pw.print(" #"); pw.print(i); pw.print(": ");
   7881             pw.println(r);
   7882             if (full) {
   7883                 r.dump(pw, prefix + "      ");
   7884             }
   7885         }
   7886     }
   7887 
   7888     private static String buildOomTag(String prefix, String space, int val, int base) {
   7889         if (val == base) {
   7890             if (space == null) return prefix;
   7891             return prefix + "  ";
   7892         }
   7893         return prefix + "+" + Integer.toString(val-base);
   7894     }
   7895 
   7896     private static final int dumpProcessList(PrintWriter pw,
   7897             ActivityManagerService service, List list,
   7898             String prefix, String normalLabel, String persistentLabel) {
   7899         int numPers = 0;
   7900         final int N = list.size()-1;
   7901         for (int i=N; i>=0; i--) {
   7902             ProcessRecord r = (ProcessRecord)list.get(i);
   7903             pw.println(String.format("%s%s #%2d: %s",
   7904                     prefix, (r.persistent ? persistentLabel : normalLabel),
   7905                     i, r.toString()));
   7906             if (r.persistent) {
   7907                 numPers++;
   7908             }
   7909         }
   7910         return numPers;
   7911     }
   7912 
   7913     private static final void dumpProcessOomList(PrintWriter pw,
   7914             ActivityManagerService service, List<ProcessRecord> list,
   7915             String prefix, String normalLabel, String persistentLabel,
   7916             boolean inclDetails) {
   7917 
   7918         final long curRealtime = SystemClock.elapsedRealtime();
   7919         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
   7920         final long curUptime = SystemClock.uptimeMillis();
   7921         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
   7922 
   7923         final int N = list.size()-1;
   7924         for (int i=N; i>=0; i--) {
   7925             ProcessRecord r = list.get(i);
   7926             String oomAdj;
   7927             if (r.setAdj >= EMPTY_APP_ADJ) {
   7928                 oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ);
   7929             } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
   7930                 oomAdj = buildOomTag("bak", "  ", r.setAdj, HIDDEN_APP_MIN_ADJ);
   7931             } else if (r.setAdj >= HOME_APP_ADJ) {
   7932                 oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ);
   7933             } else if (r.setAdj >= SECONDARY_SERVER_ADJ) {
   7934                 oomAdj = buildOomTag("svc", "  ", r.setAdj, SECONDARY_SERVER_ADJ);
   7935             } else if (r.setAdj >= BACKUP_APP_ADJ) {
   7936                 oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ);
   7937             } else if (r.setAdj >= HEAVY_WEIGHT_APP_ADJ) {
   7938                 oomAdj = buildOomTag("hvy  ", null, r.setAdj, HEAVY_WEIGHT_APP_ADJ);
   7939             } else if (r.setAdj >= PERCEPTIBLE_APP_ADJ) {
   7940                 oomAdj = buildOomTag("prcp ", null, r.setAdj, PERCEPTIBLE_APP_ADJ);
   7941             } else if (r.setAdj >= VISIBLE_APP_ADJ) {
   7942                 oomAdj = buildOomTag("vis  ", null, r.setAdj, VISIBLE_APP_ADJ);
   7943             } else if (r.setAdj >= FOREGROUND_APP_ADJ) {
   7944                 oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ);
   7945             } else if (r.setAdj >= CORE_SERVER_ADJ) {
   7946                 oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ);
   7947             } else if (r.setAdj >= SYSTEM_ADJ) {
   7948                 oomAdj = buildOomTag("sys  ", null, r.setAdj, SYSTEM_ADJ);
   7949             } else {
   7950                 oomAdj = Integer.toString(r.setAdj);
   7951             }
   7952             String schedGroup;
   7953             switch (r.setSchedGroup) {
   7954                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
   7955                     schedGroup = "B";
   7956                     break;
   7957                 case Process.THREAD_GROUP_DEFAULT:
   7958                     schedGroup = "F";
   7959                     break;
   7960                 default:
   7961                     schedGroup = Integer.toString(r.setSchedGroup);
   7962                     break;
   7963             }
   7964             pw.println(String.format("%s%s #%2d: adj=%s/%s %s (%s)",
   7965                     prefix, (r.persistent ? persistentLabel : normalLabel),
   7966                     N-i, oomAdj, schedGroup, r.toShortString(), r.adjType));
   7967             if (r.adjSource != null || r.adjTarget != null) {
   7968                 pw.print(prefix);
   7969                 pw.print("          ");
   7970                 if (r.adjTarget instanceof ComponentName) {
   7971                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
   7972                 } else if (r.adjTarget != null) {
   7973                     pw.print(r.adjTarget.toString());
   7974                 } else {
   7975                     pw.print("{null}");
   7976                 }
   7977                 pw.print("<=");
   7978                 if (r.adjSource instanceof ProcessRecord) {
   7979                     pw.print("Proc{");
   7980                     pw.print(((ProcessRecord)r.adjSource).toShortString());
   7981                     pw.println("}");
   7982                 } else if (r.adjSource != null) {
   7983                     pw.println(r.adjSource.toString());
   7984                 } else {
   7985                     pw.println("{null}");
   7986                 }
   7987             }
   7988             if (inclDetails) {
   7989                 pw.print(prefix);
   7990                 pw.print("    ");
   7991                 pw.print("oom: max="); pw.print(r.maxAdj);
   7992                 pw.print(" hidden="); pw.print(r.hiddenAdj);
   7993                 pw.print(" curRaw="); pw.print(r.curRawAdj);
   7994                 pw.print(" setRaw="); pw.print(r.setRawAdj);
   7995                 pw.print(" cur="); pw.print(r.curAdj);
   7996                 pw.print(" set="); pw.println(r.setAdj);
   7997                 pw.print(prefix);
   7998                 pw.print("    ");
   7999                 pw.print("keeping="); pw.print(r.keeping);
   8000                 pw.print(" hidden="); pw.print(r.hidden);
   8001                 pw.print(" empty="); pw.println(r.empty);
   8002 
   8003                 if (!r.keeping) {
   8004                     if (r.lastWakeTime != 0) {
   8005                         long wtime;
   8006                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
   8007                         synchronized (stats) {
   8008                             wtime = stats.getProcessWakeTime(r.info.uid,
   8009                                     r.pid, curRealtime);
   8010                         }
   8011                         long timeUsed = wtime - r.lastWakeTime;
   8012                         pw.print(prefix);
   8013                         pw.print("    ");
   8014                         pw.print("keep awake over ");
   8015                         TimeUtils.formatDuration(realtimeSince, pw);
   8016                         pw.print(" used ");
   8017                         TimeUtils.formatDuration(timeUsed, pw);
   8018                         pw.print(" (");
   8019                         pw.print((timeUsed*100)/realtimeSince);
   8020                         pw.println("%)");
   8021                     }
   8022                     if (r.lastCpuTime != 0) {
   8023                         long timeUsed = r.curCpuTime - r.lastCpuTime;
   8024                         pw.print(prefix);
   8025                         pw.print("    ");
   8026                         pw.print("run cpu over ");
   8027                         TimeUtils.formatDuration(uptimeSince, pw);
   8028                         pw.print(" used ");
   8029                         TimeUtils.formatDuration(timeUsed, pw);
   8030                         pw.print(" (");
   8031                         pw.print((timeUsed*100)/uptimeSince);
   8032                         pw.println("%)");
   8033                     }
   8034                 }
   8035             }
   8036         }
   8037     }
   8038 
   8039     static final void dumpApplicationMemoryUsage(FileDescriptor fd,
   8040             PrintWriter pw, List list, String prefix, String[] args) {
   8041         final boolean isCheckinRequest = scanArgs(args, "--checkin");
   8042         long uptime = SystemClock.uptimeMillis();
   8043         long realtime = SystemClock.elapsedRealtime();
   8044 
   8045         if (isCheckinRequest) {
   8046             // short checkin version
   8047             pw.println(uptime + "," + realtime);
   8048             pw.flush();
   8049         } else {
   8050             pw.println("Applications Memory Usage (kB):");
   8051             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   8052         }
   8053         for (int i = list.size() - 1 ; i >= 0 ; i--) {
   8054             ProcessRecord r = (ProcessRecord)list.get(i);
   8055             if (r.thread != null) {
   8056                 if (!isCheckinRequest) {
   8057                     pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
   8058                     pw.flush();
   8059                 }
   8060                 try {
   8061                     r.thread.asBinder().dump(fd, args);
   8062                 } catch (RemoteException e) {
   8063                     if (!isCheckinRequest) {
   8064                         pw.println("Got RemoteException!");
   8065                         pw.flush();
   8066                     }
   8067                 }
   8068             }
   8069         }
   8070     }
   8071 
   8072     /**
   8073      * Searches array of arguments for the specified string
   8074      * @param args array of argument strings
   8075      * @param value value to search for
   8076      * @return true if the value is contained in the array
   8077      */
   8078     private static boolean scanArgs(String[] args, String value) {
   8079         if (args != null) {
   8080             for (String arg : args) {
   8081                 if (value.equals(arg)) {
   8082                     return true;
   8083                 }
   8084             }
   8085         }
   8086         return false;
   8087     }
   8088 
   8089     private final void killServicesLocked(ProcessRecord app,
   8090             boolean allowRestart) {
   8091         // Report disconnected services.
   8092         if (false) {
   8093             // XXX we are letting the client link to the service for
   8094             // death notifications.
   8095             if (app.services.size() > 0) {
   8096                 Iterator<ServiceRecord> it = app.services.iterator();
   8097                 while (it.hasNext()) {
   8098                     ServiceRecord r = it.next();
   8099                     if (r.connections.size() > 0) {
   8100                         Iterator<ArrayList<ConnectionRecord>> jt
   8101                                 = r.connections.values().iterator();
   8102                         while (jt.hasNext()) {
   8103                             ArrayList<ConnectionRecord> cl = jt.next();
   8104                             for (int i=0; i<cl.size(); i++) {
   8105                                 ConnectionRecord c = cl.get(i);
   8106                                 if (c.binding.client != app) {
   8107                                     try {
   8108                                         //c.conn.connected(r.className, null);
   8109                                     } catch (Exception e) {
   8110                                         // todo: this should be asynchronous!
   8111                                         Slog.w(TAG, "Exception thrown disconnected servce "
   8112                                               + r.shortName
   8113                                               + " from app " + app.processName, e);
   8114                                     }
   8115                                 }
   8116                             }
   8117                         }
   8118                     }
   8119                 }
   8120             }
   8121         }
   8122 
   8123         // Clean up any connections this application has to other services.
   8124         if (app.connections.size() > 0) {
   8125             Iterator<ConnectionRecord> it = app.connections.iterator();
   8126             while (it.hasNext()) {
   8127                 ConnectionRecord r = it.next();
   8128                 removeConnectionLocked(r, app, null);
   8129             }
   8130         }
   8131         app.connections.clear();
   8132 
   8133         if (app.services.size() != 0) {
   8134             // Any services running in the application need to be placed
   8135             // back in the pending list.
   8136             Iterator<ServiceRecord> it = app.services.iterator();
   8137             while (it.hasNext()) {
   8138                 ServiceRecord sr = it.next();
   8139                 synchronized (sr.stats.getBatteryStats()) {
   8140                     sr.stats.stopLaunchedLocked();
   8141                 }
   8142                 sr.app = null;
   8143                 sr.executeNesting = 0;
   8144                 if (mStoppingServices.remove(sr)) {
   8145                     if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
   8146                 }
   8147 
   8148                 boolean hasClients = sr.bindings.size() > 0;
   8149                 if (hasClients) {
   8150                     Iterator<IntentBindRecord> bindings
   8151                             = sr.bindings.values().iterator();
   8152                     while (bindings.hasNext()) {
   8153                         IntentBindRecord b = bindings.next();
   8154                         if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
   8155                                 + ": shouldUnbind=" + b.hasBound);
   8156                         b.binder = null;
   8157                         b.requested = b.received = b.hasBound = false;
   8158                     }
   8159                 }
   8160 
   8161                 if (sr.crashCount >= 2) {
   8162                     Slog.w(TAG, "Service crashed " + sr.crashCount
   8163                             + " times, stopping: " + sr);
   8164                     EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
   8165                             sr.crashCount, sr.shortName, app.pid);
   8166                     bringDownServiceLocked(sr, true);
   8167                 } else if (!allowRestart) {
   8168                     bringDownServiceLocked(sr, true);
   8169                 } else {
   8170                     boolean canceled = scheduleServiceRestartLocked(sr, true);
   8171 
   8172                     // Should the service remain running?  Note that in the
   8173                     // extreme case of so many attempts to deliver a command
   8174                     // that it failed, that we also will stop it here.
   8175                     if (sr.startRequested && (sr.stopIfKilled || canceled)) {
   8176                         if (sr.pendingStarts.size() == 0) {
   8177                             sr.startRequested = false;
   8178                             if (!hasClients) {
   8179                                 // Whoops, no reason to restart!
   8180                                 bringDownServiceLocked(sr, true);
   8181                             }
   8182                         }
   8183                     }
   8184                 }
   8185             }
   8186 
   8187             if (!allowRestart) {
   8188                 app.services.clear();
   8189             }
   8190         }
   8191 
   8192         // Make sure we have no more records on the stopping list.
   8193         int i = mStoppingServices.size();
   8194         while (i > 0) {
   8195             i--;
   8196             ServiceRecord sr = mStoppingServices.get(i);
   8197             if (sr.app == app) {
   8198                 mStoppingServices.remove(i);
   8199                 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
   8200             }
   8201         }
   8202 
   8203         app.executingServices.clear();
   8204     }
   8205 
   8206     private final void removeDyingProviderLocked(ProcessRecord proc,
   8207             ContentProviderRecord cpr) {
   8208         synchronized (cpr) {
   8209             cpr.launchingApp = null;
   8210             cpr.notifyAll();
   8211         }
   8212 
   8213         mProvidersByClass.remove(cpr.info.name);
   8214         String names[] = cpr.info.authority.split(";");
   8215         for (int j = 0; j < names.length; j++) {
   8216             mProvidersByName.remove(names[j]);
   8217         }
   8218 
   8219         Iterator<ProcessRecord> cit = cpr.clients.iterator();
   8220         while (cit.hasNext()) {
   8221             ProcessRecord capp = cit.next();
   8222             if (!capp.persistent && capp.thread != null
   8223                     && capp.pid != 0
   8224                     && capp.pid != MY_PID) {
   8225                 Slog.i(TAG, "Kill " + capp.processName
   8226                         + " (pid " + capp.pid + "): provider " + cpr.info.name
   8227                         + " in dying process " + proc.processName);
   8228                 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
   8229                         capp.processName, capp.setAdj, "dying provider " + proc.processName);
   8230                 Process.killProcess(capp.pid);
   8231             }
   8232         }
   8233 
   8234         mLaunchingProviders.remove(cpr);
   8235     }
   8236 
   8237     /**
   8238      * Main code for cleaning up a process when it has gone away.  This is
   8239      * called both as a result of the process dying, or directly when stopping
   8240      * a process when running in single process mode.
   8241      */
   8242     private final void cleanUpApplicationRecordLocked(ProcessRecord app,
   8243             boolean restarting, int index) {
   8244         if (index >= 0) {
   8245             mLruProcesses.remove(index);
   8246         }
   8247 
   8248         mProcessesToGc.remove(app);
   8249 
   8250         // Dismiss any open dialogs.
   8251         if (app.crashDialog != null) {
   8252             app.crashDialog.dismiss();
   8253             app.crashDialog = null;
   8254         }
   8255         if (app.anrDialog != null) {
   8256             app.anrDialog.dismiss();
   8257             app.anrDialog = null;
   8258         }
   8259         if (app.waitDialog != null) {
   8260             app.waitDialog.dismiss();
   8261             app.waitDialog = null;
   8262         }
   8263 
   8264         app.crashing = false;
   8265         app.notResponding = false;
   8266 
   8267         app.resetPackageList();
   8268         app.thread = null;
   8269         app.forcingToForeground = null;
   8270         app.foregroundServices = false;
   8271 
   8272         killServicesLocked(app, true);
   8273 
   8274         boolean restart = false;
   8275 
   8276         int NL = mLaunchingProviders.size();
   8277 
   8278         // Remove published content providers.
   8279         if (!app.pubProviders.isEmpty()) {
   8280             Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
   8281             while (it.hasNext()) {
   8282                 ContentProviderRecord cpr = it.next();
   8283                 cpr.provider = null;
   8284                 cpr.app = null;
   8285 
   8286                 // See if someone is waiting for this provider...  in which
   8287                 // case we don't remove it, but just let it restart.
   8288                 int i = 0;
   8289                 if (!app.bad) {
   8290                     for (; i<NL; i++) {
   8291                         if (mLaunchingProviders.get(i) == cpr) {
   8292                             restart = true;
   8293                             break;
   8294                         }
   8295                     }
   8296                 } else {
   8297                     i = NL;
   8298                 }
   8299 
   8300                 if (i >= NL) {
   8301                     removeDyingProviderLocked(app, cpr);
   8302                     NL = mLaunchingProviders.size();
   8303                 }
   8304             }
   8305             app.pubProviders.clear();
   8306         }
   8307 
   8308         // Take care of any launching providers waiting for this process.
   8309         if (checkAppInLaunchingProvidersLocked(app, false)) {
   8310             restart = true;
   8311         }
   8312 
   8313         // Unregister from connected content providers.
   8314         if (!app.conProviders.isEmpty()) {
   8315             Iterator it = app.conProviders.keySet().iterator();
   8316             while (it.hasNext()) {
   8317                 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
   8318                 cpr.clients.remove(app);
   8319             }
   8320             app.conProviders.clear();
   8321         }
   8322 
   8323         // At this point there may be remaining entries in mLaunchingProviders
   8324         // where we were the only one waiting, so they are no longer of use.
   8325         // Look for these and clean up if found.
   8326         // XXX Commented out for now.  Trying to figure out a way to reproduce
   8327         // the actual situation to identify what is actually going on.
   8328         if (false) {
   8329             for (int i=0; i<NL; i++) {
   8330                 ContentProviderRecord cpr = (ContentProviderRecord)
   8331                         mLaunchingProviders.get(i);
   8332                 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
   8333                     synchronized (cpr) {
   8334                         cpr.launchingApp = null;
   8335                         cpr.notifyAll();
   8336                     }
   8337                 }
   8338             }
   8339         }
   8340 
   8341         skipCurrentReceiverLocked(app);
   8342 
   8343         // Unregister any receivers.
   8344         if (app.receivers.size() > 0) {
   8345             Iterator<ReceiverList> it = app.receivers.iterator();
   8346             while (it.hasNext()) {
   8347                 removeReceiverLocked(it.next());
   8348             }
   8349             app.receivers.clear();
   8350         }
   8351 
   8352         // If the app is undergoing backup, tell the backup manager about it
   8353         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
   8354             if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
   8355             try {
   8356                 IBackupManager bm = IBackupManager.Stub.asInterface(
   8357                         ServiceManager.getService(Context.BACKUP_SERVICE));
   8358                 bm.agentDisconnected(app.info.packageName);
   8359             } catch (RemoteException e) {
   8360                 // can't happen; backup manager is local
   8361             }
   8362         }
   8363 
   8364         // If the caller is restarting this app, then leave it in its
   8365         // current lists and let the caller take care of it.
   8366         if (restarting) {
   8367             return;
   8368         }
   8369 
   8370         if (!app.persistent) {
   8371             if (DEBUG_PROCESSES) Slog.v(TAG,
   8372                     "Removing non-persistent process during cleanup: " + app);
   8373             mProcessNames.remove(app.processName, app.info.uid);
   8374             if (mHeavyWeightProcess == app) {
   8375                 mHeavyWeightProcess = null;
   8376                 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
   8377             }
   8378         } else if (!app.removed) {
   8379             // This app is persistent, so we need to keep its record around.
   8380             // If it is not already on the pending app list, add it there
   8381             // and start a new process for it.
   8382             app.thread = null;
   8383             app.forcingToForeground = null;
   8384             app.foregroundServices = false;
   8385             if (mPersistentStartingProcesses.indexOf(app) < 0) {
   8386                 mPersistentStartingProcesses.add(app);
   8387                 restart = true;
   8388             }
   8389         }
   8390         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   8391                 "Clean-up removing on hold: " + app);
   8392         mProcessesOnHold.remove(app);
   8393 
   8394         if (app == mHomeProcess) {
   8395             mHomeProcess = null;
   8396         }
   8397 
   8398         if (restart) {
   8399             // We have components that still need to be running in the
   8400             // process, so re-launch it.
   8401             mProcessNames.put(app.processName, app.info.uid, app);
   8402             startProcessLocked(app, "restart", app.processName);
   8403         } else if (app.pid > 0 && app.pid != MY_PID) {
   8404             // Goodbye!
   8405             synchronized (mPidsSelfLocked) {
   8406                 mPidsSelfLocked.remove(app.pid);
   8407                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   8408             }
   8409             app.setPid(0);
   8410         }
   8411     }
   8412 
   8413     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
   8414         // Look through the content providers we are waiting to have launched,
   8415         // and if any run in this process then either schedule a restart of
   8416         // the process or kill the client waiting for it if this process has
   8417         // gone bad.
   8418         int NL = mLaunchingProviders.size();
   8419         boolean restart = false;
   8420         for (int i=0; i<NL; i++) {
   8421             ContentProviderRecord cpr = mLaunchingProviders.get(i);
   8422             if (cpr.launchingApp == app) {
   8423                 if (!alwaysBad && !app.bad) {
   8424                     restart = true;
   8425                 } else {
   8426                     removeDyingProviderLocked(app, cpr);
   8427                     NL = mLaunchingProviders.size();
   8428                 }
   8429             }
   8430         }
   8431         return restart;
   8432     }
   8433 
   8434     // =========================================================
   8435     // SERVICES
   8436     // =========================================================
   8437 
   8438     ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
   8439         ActivityManager.RunningServiceInfo info =
   8440             new ActivityManager.RunningServiceInfo();
   8441         info.service = r.name;
   8442         if (r.app != null) {
   8443             info.pid = r.app.pid;
   8444         }
   8445         info.uid = r.appInfo.uid;
   8446         info.process = r.processName;
   8447         info.foreground = r.isForeground;
   8448         info.activeSince = r.createTime;
   8449         info.started = r.startRequested;
   8450         info.clientCount = r.connections.size();
   8451         info.crashCount = r.crashCount;
   8452         info.lastActivityTime = r.lastActivity;
   8453         if (r.isForeground) {
   8454             info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
   8455         }
   8456         if (r.startRequested) {
   8457             info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
   8458         }
   8459         if (r.app != null && r.app.pid == MY_PID) {
   8460             info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
   8461         }
   8462         if (r.app != null && r.app.persistent) {
   8463             info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
   8464         }
   8465 
   8466         for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
   8467             for (int i=0; i<connl.size(); i++) {
   8468                 ConnectionRecord conn = connl.get(i);
   8469                 if (conn.clientLabel != 0) {
   8470                     info.clientPackage = conn.binding.client.info.packageName;
   8471                     info.clientLabel = conn.clientLabel;
   8472                     return info;
   8473                 }
   8474             }
   8475         }
   8476         return info;
   8477     }
   8478 
   8479     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
   8480             int flags) {
   8481         synchronized (this) {
   8482             ArrayList<ActivityManager.RunningServiceInfo> res
   8483                     = new ArrayList<ActivityManager.RunningServiceInfo>();
   8484 
   8485             if (mServices.size() > 0) {
   8486                 Iterator<ServiceRecord> it = mServices.values().iterator();
   8487                 while (it.hasNext() && res.size() < maxNum) {
   8488                     res.add(makeRunningServiceInfoLocked(it.next()));
   8489                 }
   8490             }
   8491 
   8492             for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
   8493                 ServiceRecord r = mRestartingServices.get(i);
   8494                 ActivityManager.RunningServiceInfo info =
   8495                         makeRunningServiceInfoLocked(r);
   8496                 info.restarting = r.nextRestartTime;
   8497                 res.add(info);
   8498             }
   8499 
   8500             return res;
   8501         }
   8502     }
   8503 
   8504     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
   8505         synchronized (this) {
   8506             ServiceRecord r = mServices.get(name);
   8507             if (r != null) {
   8508                 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
   8509                     for (int i=0; i<conn.size(); i++) {
   8510                         if (conn.get(i).clientIntent != null) {
   8511                             return conn.get(i).clientIntent;
   8512                         }
   8513                     }
   8514                 }
   8515             }
   8516         }
   8517         return null;
   8518     }
   8519 
   8520     private final ServiceRecord findServiceLocked(ComponentName name,
   8521             IBinder token) {
   8522         ServiceRecord r = mServices.get(name);
   8523         return r == token ? r : null;
   8524     }
   8525 
   8526     private final class ServiceLookupResult {
   8527         final ServiceRecord record;
   8528         final String permission;
   8529 
   8530         ServiceLookupResult(ServiceRecord _record, String _permission) {
   8531             record = _record;
   8532             permission = _permission;
   8533         }
   8534     };
   8535 
   8536     private ServiceLookupResult findServiceLocked(Intent service,
   8537             String resolvedType) {
   8538         ServiceRecord r = null;
   8539         if (service.getComponent() != null) {
   8540             r = mServices.get(service.getComponent());
   8541         }
   8542         if (r == null) {
   8543             Intent.FilterComparison filter = new Intent.FilterComparison(service);
   8544             r = mServicesByIntent.get(filter);
   8545         }
   8546 
   8547         if (r == null) {
   8548             try {
   8549                 ResolveInfo rInfo =
   8550                     AppGlobals.getPackageManager().resolveService(
   8551                             service, resolvedType, 0);
   8552                 ServiceInfo sInfo =
   8553                     rInfo != null ? rInfo.serviceInfo : null;
   8554                 if (sInfo == null) {
   8555                     return null;
   8556                 }
   8557 
   8558                 ComponentName name = new ComponentName(
   8559                         sInfo.applicationInfo.packageName, sInfo.name);
   8560                 r = mServices.get(name);
   8561             } catch (RemoteException ex) {
   8562                 // pm is in same process, this will never happen.
   8563             }
   8564         }
   8565         if (r != null) {
   8566             int callingPid = Binder.getCallingPid();
   8567             int callingUid = Binder.getCallingUid();
   8568             if (checkComponentPermission(r.permission,
   8569                     callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
   8570                     != PackageManager.PERMISSION_GRANTED) {
   8571                 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
   8572                         + " from pid=" + callingPid
   8573                         + ", uid=" + callingUid
   8574                         + " requires " + r.permission);
   8575                 return new ServiceLookupResult(null, r.permission);
   8576             }
   8577             return new ServiceLookupResult(r, null);
   8578         }
   8579         return null;
   8580     }
   8581 
   8582     private class ServiceRestarter implements Runnable {
   8583         private ServiceRecord mService;
   8584 
   8585         void setService(ServiceRecord service) {
   8586             mService = service;
   8587         }
   8588 
   8589         public void run() {
   8590             synchronized(ActivityManagerService.this) {
   8591                 performServiceRestartLocked(mService);
   8592             }
   8593         }
   8594     }
   8595 
   8596     private ServiceLookupResult retrieveServiceLocked(Intent service,
   8597             String resolvedType, int callingPid, int callingUid) {
   8598         ServiceRecord r = null;
   8599         if (service.getComponent() != null) {
   8600             r = mServices.get(service.getComponent());
   8601         }
   8602         Intent.FilterComparison filter = new Intent.FilterComparison(service);
   8603         r = mServicesByIntent.get(filter);
   8604         if (r == null) {
   8605             try {
   8606                 ResolveInfo rInfo =
   8607                     AppGlobals.getPackageManager().resolveService(
   8608                             service, resolvedType, STOCK_PM_FLAGS);
   8609                 ServiceInfo sInfo =
   8610                     rInfo != null ? rInfo.serviceInfo : null;
   8611                 if (sInfo == null) {
   8612                     Slog.w(TAG, "Unable to start service " + service +
   8613                           ": not found");
   8614                     return null;
   8615                 }
   8616 
   8617                 ComponentName name = new ComponentName(
   8618                         sInfo.applicationInfo.packageName, sInfo.name);
   8619                 r = mServices.get(name);
   8620                 if (r == null) {
   8621                     filter = new Intent.FilterComparison(service.cloneFilter());
   8622                     ServiceRestarter res = new ServiceRestarter();
   8623                     BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   8624                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   8625                     synchronized (stats) {
   8626                         ss = stats.getServiceStatsLocked(
   8627                                 sInfo.applicationInfo.uid, sInfo.packageName,
   8628                                 sInfo.name);
   8629                     }
   8630                     r = new ServiceRecord(this, ss, name, filter, sInfo, res);
   8631                     res.setService(r);
   8632                     mServices.put(name, r);
   8633                     mServicesByIntent.put(filter, r);
   8634 
   8635                     // Make sure this component isn't in the pending list.
   8636                     int N = mPendingServices.size();
   8637                     for (int i=0; i<N; i++) {
   8638                         ServiceRecord pr = mPendingServices.get(i);
   8639                         if (pr.name.equals(name)) {
   8640                             mPendingServices.remove(i);
   8641                             i--;
   8642                             N--;
   8643                         }
   8644                     }
   8645                 }
   8646             } catch (RemoteException ex) {
   8647                 // pm is in same process, this will never happen.
   8648             }
   8649         }
   8650         if (r != null) {
   8651             if (checkComponentPermission(r.permission,
   8652                     callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
   8653                     != PackageManager.PERMISSION_GRANTED) {
   8654                 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
   8655                         + " from pid=" + Binder.getCallingPid()
   8656                         + ", uid=" + Binder.getCallingUid()
   8657                         + " requires " + r.permission);
   8658                 return new ServiceLookupResult(null, r.permission);
   8659             }
   8660             return new ServiceLookupResult(r, null);
   8661         }
   8662         return null;
   8663     }
   8664 
   8665     private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
   8666         if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
   8667                 + why + " of " + r + " in app " + r.app);
   8668         else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
   8669                 + why + " of " + r.shortName);
   8670         long now = SystemClock.uptimeMillis();
   8671         if (r.executeNesting == 0 && r.app != null) {
   8672             if (r.app.executingServices.size() == 0) {
   8673                 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   8674                 msg.obj = r.app;
   8675                 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
   8676             }
   8677             r.app.executingServices.add(r);
   8678         }
   8679         r.executeNesting++;
   8680         r.executingStart = now;
   8681     }
   8682 
   8683     private final void sendServiceArgsLocked(ServiceRecord r,
   8684             boolean oomAdjusted) {
   8685         final int N = r.pendingStarts.size();
   8686         if (N == 0) {
   8687             return;
   8688         }
   8689 
   8690         while (r.pendingStarts.size() > 0) {
   8691             try {
   8692                 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
   8693                 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
   8694                         + r + " " + r.intent + " args=" + si.intent);
   8695                 if (si.intent == null) {
   8696                     // If somehow we got a dummy start at the front, then
   8697                     // just drop it here.
   8698                     continue;
   8699                 }
   8700                 si.deliveredTime = SystemClock.uptimeMillis();
   8701                 r.deliveredStarts.add(si);
   8702                 si.deliveryCount++;
   8703                 if (si.targetPermissionUid >= 0) {
   8704                     grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
   8705                             r.packageName, si.intent, si.getUriPermissionsLocked());
   8706                 }
   8707                 bumpServiceExecutingLocked(r, "start");
   8708                 if (!oomAdjusted) {
   8709                     oomAdjusted = true;
   8710                     updateOomAdjLocked(r.app);
   8711                 }
   8712                 int flags = 0;
   8713                 if (si.deliveryCount > 0) {
   8714                     flags |= Service.START_FLAG_RETRY;
   8715                 }
   8716                 if (si.doneExecutingCount > 0) {
   8717                     flags |= Service.START_FLAG_REDELIVERY;
   8718                 }
   8719                 r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent);
   8720             } catch (RemoteException e) {
   8721                 // Remote process gone...  we'll let the normal cleanup take
   8722                 // care of this.
   8723                 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
   8724                 break;
   8725             } catch (Exception e) {
   8726                 Slog.w(TAG, "Unexpected exception", e);
   8727                 break;
   8728             }
   8729         }
   8730     }
   8731 
   8732     private final boolean requestServiceBindingLocked(ServiceRecord r,
   8733             IntentBindRecord i, boolean rebind) {
   8734         if (r.app == null || r.app.thread == null) {
   8735             // If service is not currently running, can't yet bind.
   8736             return false;
   8737         }
   8738         if ((!i.requested || rebind) && i.apps.size() > 0) {
   8739             try {
   8740                 bumpServiceExecutingLocked(r, "bind");
   8741                 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
   8742                 if (!rebind) {
   8743                     i.requested = true;
   8744                 }
   8745                 i.hasBound = true;
   8746                 i.doRebind = false;
   8747             } catch (RemoteException e) {
   8748                 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
   8749                 return false;
   8750             }
   8751         }
   8752         return true;
   8753     }
   8754 
   8755     private final void requestServiceBindingsLocked(ServiceRecord r) {
   8756         Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
   8757         while (bindings.hasNext()) {
   8758             IntentBindRecord i = bindings.next();
   8759             if (!requestServiceBindingLocked(r, i, false)) {
   8760                 break;
   8761             }
   8762         }
   8763     }
   8764 
   8765     private final void realStartServiceLocked(ServiceRecord r,
   8766             ProcessRecord app) throws RemoteException {
   8767         if (app.thread == null) {
   8768             throw new RemoteException();
   8769         }
   8770 
   8771         r.app = app;
   8772         r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
   8773 
   8774         app.services.add(r);
   8775         bumpServiceExecutingLocked(r, "create");
   8776         updateLruProcessLocked(app, true, true);
   8777 
   8778         boolean created = false;
   8779         try {
   8780             mStringBuilder.setLength(0);
   8781             r.intent.getIntent().toShortString(mStringBuilder, false, true);
   8782             EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
   8783                     System.identityHashCode(r), r.shortName,
   8784                     mStringBuilder.toString(), r.app.pid);
   8785             synchronized (r.stats.getBatteryStats()) {
   8786                 r.stats.startLaunchedLocked();
   8787             }
   8788             ensurePackageDexOpt(r.serviceInfo.packageName);
   8789             app.thread.scheduleCreateService(r, r.serviceInfo);
   8790             r.postNotification();
   8791             created = true;
   8792         } finally {
   8793             if (!created) {
   8794                 app.services.remove(r);
   8795                 scheduleServiceRestartLocked(r, false);
   8796             }
   8797         }
   8798 
   8799         requestServiceBindingsLocked(r);
   8800 
   8801         // If the service is in the started state, and there are no
   8802         // pending arguments, then fake up one so its onStartCommand() will
   8803         // be called.
   8804         if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
   8805             r.lastStartId++;
   8806             if (r.lastStartId < 1) {
   8807                 r.lastStartId = 1;
   8808             }
   8809             r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId, null, -1));
   8810         }
   8811 
   8812         sendServiceArgsLocked(r, true);
   8813     }
   8814 
   8815     private final boolean scheduleServiceRestartLocked(ServiceRecord r,
   8816             boolean allowCancel) {
   8817         boolean canceled = false;
   8818 
   8819         final long now = SystemClock.uptimeMillis();
   8820         long minDuration = SERVICE_RESTART_DURATION;
   8821         long resetTime = SERVICE_RESET_RUN_DURATION;
   8822 
   8823         // Any delivered but not yet finished starts should be put back
   8824         // on the pending list.
   8825         final int N = r.deliveredStarts.size();
   8826         if (N > 0) {
   8827             for (int i=N-1; i>=0; i--) {
   8828                 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
   8829                 si.removeUriPermissionsLocked();
   8830                 if (si.intent == null) {
   8831                     // We'll generate this again if needed.
   8832                 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
   8833                         && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
   8834                     r.pendingStarts.add(0, si);
   8835                     long dur = SystemClock.uptimeMillis() - si.deliveredTime;
   8836                     dur *= 2;
   8837                     if (minDuration < dur) minDuration = dur;
   8838                     if (resetTime < dur) resetTime = dur;
   8839                 } else {
   8840                     Slog.w(TAG, "Canceling start item " + si.intent + " in service "
   8841                             + r.name);
   8842                     canceled = true;
   8843                 }
   8844             }
   8845             r.deliveredStarts.clear();
   8846         }
   8847 
   8848         r.totalRestartCount++;
   8849         if (r.restartDelay == 0) {
   8850             r.restartCount++;
   8851             r.restartDelay = minDuration;
   8852         } else {
   8853             // If it has been a "reasonably long time" since the service
   8854             // was started, then reset our restart duration back to
   8855             // the beginning, so we don't infinitely increase the duration
   8856             // on a service that just occasionally gets killed (which is
   8857             // a normal case, due to process being killed to reclaim memory).
   8858             if (now > (r.restartTime+resetTime)) {
   8859                 r.restartCount = 1;
   8860                 r.restartDelay = minDuration;
   8861             } else {
   8862                 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
   8863                 if (r.restartDelay < minDuration) {
   8864                     r.restartDelay = minDuration;
   8865                 }
   8866             }
   8867         }
   8868 
   8869         r.nextRestartTime = now + r.restartDelay;
   8870 
   8871         // Make sure that we don't end up restarting a bunch of services
   8872         // all at the same time.
   8873         boolean repeat;
   8874         do {
   8875             repeat = false;
   8876             for (int i=mRestartingServices.size()-1; i>=0; i--) {
   8877                 ServiceRecord r2 = mRestartingServices.get(i);
   8878                 if (r2 != r && r.nextRestartTime
   8879                         >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
   8880                         && r.nextRestartTime
   8881                         < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
   8882                     r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
   8883                     r.restartDelay = r.nextRestartTime - now;
   8884                     repeat = true;
   8885                     break;
   8886                 }
   8887             }
   8888         } while (repeat);
   8889 
   8890         if (!mRestartingServices.contains(r)) {
   8891             mRestartingServices.add(r);
   8892         }
   8893 
   8894         r.cancelNotification();
   8895 
   8896         mHandler.removeCallbacks(r.restarter);
   8897         mHandler.postAtTime(r.restarter, r.nextRestartTime);
   8898         r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
   8899         Slog.w(TAG, "Scheduling restart of crashed service "
   8900                 + r.shortName + " in " + r.restartDelay + "ms");
   8901         EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
   8902                 r.shortName, r.restartDelay);
   8903 
   8904         return canceled;
   8905     }
   8906 
   8907     final void performServiceRestartLocked(ServiceRecord r) {
   8908         if (!mRestartingServices.contains(r)) {
   8909             return;
   8910         }
   8911         bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
   8912     }
   8913 
   8914     private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
   8915         if (r.restartDelay == 0) {
   8916             return false;
   8917         }
   8918         r.resetRestartCounter();
   8919         mRestartingServices.remove(r);
   8920         mHandler.removeCallbacks(r.restarter);
   8921         return true;
   8922     }
   8923 
   8924     private final boolean bringUpServiceLocked(ServiceRecord r,
   8925             int intentFlags, boolean whileRestarting) {
   8926         //Slog.i(TAG, "Bring up service:");
   8927         //r.dump("  ");
   8928 
   8929         if (r.app != null && r.app.thread != null) {
   8930             sendServiceArgsLocked(r, false);
   8931             return true;
   8932         }
   8933 
   8934         if (!whileRestarting && r.restartDelay > 0) {
   8935             // If waiting for a restart, then do nothing.
   8936             return true;
   8937         }
   8938 
   8939         if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
   8940 
   8941         // We are now bringing the service up, so no longer in the
   8942         // restarting state.
   8943         mRestartingServices.remove(r);
   8944 
   8945         final String appName = r.processName;
   8946         ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
   8947         if (app != null && app.thread != null) {
   8948             try {
   8949                 realStartServiceLocked(r, app);
   8950                 return true;
   8951             } catch (RemoteException e) {
   8952                 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
   8953             }
   8954 
   8955             // If a dead object exception was thrown -- fall through to
   8956             // restart the application.
   8957         }
   8958 
   8959         // Not running -- get it started, and enqueue this service record
   8960         // to be executed when the app comes up.
   8961         if (startProcessLocked(appName, r.appInfo, true, intentFlags,
   8962                 "service", r.name, false) == null) {
   8963             Slog.w(TAG, "Unable to launch app "
   8964                     + r.appInfo.packageName + "/"
   8965                     + r.appInfo.uid + " for service "
   8966                     + r.intent.getIntent() + ": process is bad");
   8967             bringDownServiceLocked(r, true);
   8968             return false;
   8969         }
   8970 
   8971         if (!mPendingServices.contains(r)) {
   8972             mPendingServices.add(r);
   8973         }
   8974 
   8975         return true;
   8976     }
   8977 
   8978     private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
   8979         //Slog.i(TAG, "Bring down service:");
   8980         //r.dump("  ");
   8981 
   8982         // Does it still need to run?
   8983         if (!force && r.startRequested) {
   8984             return;
   8985         }
   8986         if (r.connections.size() > 0) {
   8987             if (!force) {
   8988                 // XXX should probably keep a count of the number of auto-create
   8989                 // connections directly in the service.
   8990                 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
   8991                 while (it.hasNext()) {
   8992                     ArrayList<ConnectionRecord> cr = it.next();
   8993                     for (int i=0; i<cr.size(); i++) {
   8994                         if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
   8995                             return;
   8996                         }
   8997                     }
   8998                 }
   8999             }
   9000 
   9001             // Report to all of the connections that the service is no longer
   9002             // available.
   9003             Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
   9004             while (it.hasNext()) {
   9005                 ArrayList<ConnectionRecord> c = it.next();
   9006                 for (int i=0; i<c.size(); i++) {
   9007                     try {
   9008                         c.get(i).conn.connected(r.name, null);
   9009                     } catch (Exception e) {
   9010                         Slog.w(TAG, "Failure disconnecting service " + r.name +
   9011                               " to connection " + c.get(i).conn.asBinder() +
   9012                               " (in " + c.get(i).binding.client.processName + ")", e);
   9013                     }
   9014                 }
   9015             }
   9016         }
   9017 
   9018         // Tell the service that it has been unbound.
   9019         if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
   9020             Iterator<IntentBindRecord> it = r.bindings.values().iterator();
   9021             while (it.hasNext()) {
   9022                 IntentBindRecord ibr = it.next();
   9023                 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
   9024                         + ": hasBound=" + ibr.hasBound);
   9025                 if (r.app != null && r.app.thread != null && ibr.hasBound) {
   9026                     try {
   9027                         bumpServiceExecutingLocked(r, "bring down unbind");
   9028                         updateOomAdjLocked(r.app);
   9029                         ibr.hasBound = false;
   9030                         r.app.thread.scheduleUnbindService(r,
   9031                                 ibr.intent.getIntent());
   9032                     } catch (Exception e) {
   9033                         Slog.w(TAG, "Exception when unbinding service "
   9034                                 + r.shortName, e);
   9035                         serviceDoneExecutingLocked(r, true);
   9036                     }
   9037                 }
   9038             }
   9039         }
   9040 
   9041         if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
   9042         EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
   9043                 System.identityHashCode(r), r.shortName,
   9044                 (r.app != null) ? r.app.pid : -1);
   9045 
   9046         mServices.remove(r.name);
   9047         mServicesByIntent.remove(r.intent);
   9048         r.totalRestartCount = 0;
   9049         unscheduleServiceRestartLocked(r);
   9050 
   9051         // Also make sure it is not on the pending list.
   9052         int N = mPendingServices.size();
   9053         for (int i=0; i<N; i++) {
   9054             if (mPendingServices.get(i) == r) {
   9055                 mPendingServices.remove(i);
   9056                 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
   9057                 i--;
   9058                 N--;
   9059             }
   9060         }
   9061 
   9062         r.cancelNotification();
   9063         r.isForeground = false;
   9064         r.foregroundId = 0;
   9065         r.foregroundNoti = null;
   9066 
   9067         // Clear start entries.
   9068         r.clearDeliveredStartsLocked();
   9069         r.pendingStarts.clear();
   9070 
   9071         if (r.app != null) {
   9072             synchronized (r.stats.getBatteryStats()) {
   9073                 r.stats.stopLaunchedLocked();
   9074             }
   9075             r.app.services.remove(r);
   9076             if (r.app.thread != null) {
   9077                 try {
   9078                     bumpServiceExecutingLocked(r, "stop");
   9079                     mStoppingServices.add(r);
   9080                     updateOomAdjLocked(r.app);
   9081                     r.app.thread.scheduleStopService(r);
   9082                 } catch (Exception e) {
   9083                     Slog.w(TAG, "Exception when stopping service "
   9084                             + r.shortName, e);
   9085                     serviceDoneExecutingLocked(r, true);
   9086                 }
   9087                 updateServiceForegroundLocked(r.app, false);
   9088             } else {
   9089                 if (DEBUG_SERVICE) Slog.v(
   9090                     TAG, "Removed service that has no process: " + r);
   9091             }
   9092         } else {
   9093             if (DEBUG_SERVICE) Slog.v(
   9094                 TAG, "Removed service that is not running: " + r);
   9095         }
   9096     }
   9097 
   9098     ComponentName startServiceLocked(IApplicationThread caller,
   9099             Intent service, String resolvedType,
   9100             int callingPid, int callingUid) {
   9101         synchronized(this) {
   9102             if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
   9103                     + " type=" + resolvedType + " args=" + service.getExtras());
   9104 
   9105             if (caller != null) {
   9106                 final ProcessRecord callerApp = getRecordForAppLocked(caller);
   9107                 if (callerApp == null) {
   9108                     throw new SecurityException(
   9109                             "Unable to find app for caller " + caller
   9110                             + " (pid=" + Binder.getCallingPid()
   9111                             + ") when starting service " + service);
   9112                 }
   9113             }
   9114 
   9115             ServiceLookupResult res =
   9116                 retrieveServiceLocked(service, resolvedType,
   9117                         callingPid, callingUid);
   9118             if (res == null) {
   9119                 return null;
   9120             }
   9121             if (res.record == null) {
   9122                 return new ComponentName("!", res.permission != null
   9123                         ? res.permission : "private to package");
   9124             }
   9125             ServiceRecord r = res.record;
   9126             int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
   9127                     callingUid, r.packageName, service);
   9128             if (unscheduleServiceRestartLocked(r)) {
   9129                 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
   9130             }
   9131             r.startRequested = true;
   9132             r.callStart = false;
   9133             r.lastStartId++;
   9134             if (r.lastStartId < 1) {
   9135                 r.lastStartId = 1;
   9136             }
   9137             r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId,
   9138                     service, targetPermissionUid));
   9139             r.lastActivity = SystemClock.uptimeMillis();
   9140             synchronized (r.stats.getBatteryStats()) {
   9141                 r.stats.startRunningLocked();
   9142             }
   9143             if (!bringUpServiceLocked(r, service.getFlags(), false)) {
   9144                 return new ComponentName("!", "Service process is bad");
   9145             }
   9146             return r.name;
   9147         }
   9148     }
   9149 
   9150     public ComponentName startService(IApplicationThread caller, Intent service,
   9151             String resolvedType) {
   9152         // Refuse possible leaked file descriptors
   9153         if (service != null && service.hasFileDescriptors() == true) {
   9154             throw new IllegalArgumentException("File descriptors passed in Intent");
   9155         }
   9156 
   9157         synchronized(this) {
   9158             final int callingPid = Binder.getCallingPid();
   9159             final int callingUid = Binder.getCallingUid();
   9160             final long origId = Binder.clearCallingIdentity();
   9161             ComponentName res = startServiceLocked(caller, service,
   9162                     resolvedType, callingPid, callingUid);
   9163             Binder.restoreCallingIdentity(origId);
   9164             return res;
   9165         }
   9166     }
   9167 
   9168     ComponentName startServiceInPackage(int uid,
   9169             Intent service, String resolvedType) {
   9170         synchronized(this) {
   9171             final long origId = Binder.clearCallingIdentity();
   9172             ComponentName res = startServiceLocked(null, service,
   9173                     resolvedType, -1, uid);
   9174             Binder.restoreCallingIdentity(origId);
   9175             return res;
   9176         }
   9177     }
   9178 
   9179     public int stopService(IApplicationThread caller, Intent service,
   9180             String resolvedType) {
   9181         // Refuse possible leaked file descriptors
   9182         if (service != null && service.hasFileDescriptors() == true) {
   9183             throw new IllegalArgumentException("File descriptors passed in Intent");
   9184         }
   9185 
   9186         synchronized(this) {
   9187             if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
   9188                     + " type=" + resolvedType);
   9189 
   9190             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   9191             if (caller != null && callerApp == null) {
   9192                 throw new SecurityException(
   9193                         "Unable to find app for caller " + caller
   9194                         + " (pid=" + Binder.getCallingPid()
   9195                         + ") when stopping service " + service);
   9196             }
   9197 
   9198             // If this service is active, make sure it is stopped.
   9199             ServiceLookupResult r = findServiceLocked(service, resolvedType);
   9200             if (r != null) {
   9201                 if (r.record != null) {
   9202                     synchronized (r.record.stats.getBatteryStats()) {
   9203                         r.record.stats.stopRunningLocked();
   9204                     }
   9205                     r.record.startRequested = false;
   9206                     r.record.callStart = false;
   9207                     final long origId = Binder.clearCallingIdentity();
   9208                     bringDownServiceLocked(r.record, false);
   9209                     Binder.restoreCallingIdentity(origId);
   9210                     return 1;
   9211                 }
   9212                 return -1;
   9213             }
   9214         }
   9215 
   9216         return 0;
   9217     }
   9218 
   9219     public IBinder peekService(Intent service, String resolvedType) {
   9220         // Refuse possible leaked file descriptors
   9221         if (service != null && service.hasFileDescriptors() == true) {
   9222             throw new IllegalArgumentException("File descriptors passed in Intent");
   9223         }
   9224 
   9225         IBinder ret = null;
   9226 
   9227         synchronized(this) {
   9228             ServiceLookupResult r = findServiceLocked(service, resolvedType);
   9229 
   9230             if (r != null) {
   9231                 // r.record is null if findServiceLocked() failed the caller permission check
   9232                 if (r.record == null) {
   9233                     throw new SecurityException(
   9234                             "Permission Denial: Accessing service " + r.record.name
   9235                             + " from pid=" + Binder.getCallingPid()
   9236                             + ", uid=" + Binder.getCallingUid()
   9237                             + " requires " + r.permission);
   9238                 }
   9239                 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
   9240                 if (ib != null) {
   9241                     ret = ib.binder;
   9242                 }
   9243             }
   9244         }
   9245 
   9246         return ret;
   9247     }
   9248 
   9249     public boolean stopServiceToken(ComponentName className, IBinder token,
   9250             int startId) {
   9251         synchronized(this) {
   9252             if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
   9253                     + " " + token + " startId=" + startId);
   9254             ServiceRecord r = findServiceLocked(className, token);
   9255             if (r != null) {
   9256                 if (startId >= 0) {
   9257                     // Asked to only stop if done with all work.  Note that
   9258                     // to avoid leaks, we will take this as dropping all
   9259                     // start items up to and including this one.
   9260                     ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
   9261                     if (si != null) {
   9262                         while (r.deliveredStarts.size() > 0) {
   9263                             ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
   9264                             cur.removeUriPermissionsLocked();
   9265                             if (cur == si) {
   9266                                 break;
   9267                             }
   9268                         }
   9269                     }
   9270 
   9271                     if (r.lastStartId != startId) {
   9272                         return false;
   9273                     }
   9274 
   9275                     if (r.deliveredStarts.size() > 0) {
   9276                         Slog.w(TAG, "stopServiceToken startId " + startId
   9277                                 + " is last, but have " + r.deliveredStarts.size()
   9278                                 + " remaining args");
   9279                     }
   9280                 }
   9281 
   9282                 synchronized (r.stats.getBatteryStats()) {
   9283                     r.stats.stopRunningLocked();
   9284                     r.startRequested = false;
   9285                     r.callStart = false;
   9286                 }
   9287                 final long origId = Binder.clearCallingIdentity();
   9288                 bringDownServiceLocked(r, false);
   9289                 Binder.restoreCallingIdentity(origId);
   9290                 return true;
   9291             }
   9292         }
   9293         return false;
   9294     }
   9295 
   9296     public void setServiceForeground(ComponentName className, IBinder token,
   9297             int id, Notification notification, boolean removeNotification) {
   9298         final long origId = Binder.clearCallingIdentity();
   9299         try {
   9300         synchronized(this) {
   9301             ServiceRecord r = findServiceLocked(className, token);
   9302             if (r != null) {
   9303                 if (id != 0) {
   9304                     if (notification == null) {
   9305                         throw new IllegalArgumentException("null notification");
   9306                     }
   9307                     if (r.foregroundId != id) {
   9308                         r.cancelNotification();
   9309                         r.foregroundId = id;
   9310                     }
   9311                     notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
   9312                     r.foregroundNoti = notification;
   9313                     r.isForeground = true;
   9314                     r.postNotification();
   9315                     if (r.app != null) {
   9316                         updateServiceForegroundLocked(r.app, true);
   9317                     }
   9318                 } else {
   9319                     if (r.isForeground) {
   9320                         r.isForeground = false;
   9321                         if (r.app != null) {
   9322                             updateLruProcessLocked(r.app, false, true);
   9323                             updateServiceForegroundLocked(r.app, true);
   9324                         }
   9325                     }
   9326                     if (removeNotification) {
   9327                         r.cancelNotification();
   9328                         r.foregroundId = 0;
   9329                         r.foregroundNoti = null;
   9330                     }
   9331                 }
   9332             }
   9333         }
   9334         } finally {
   9335             Binder.restoreCallingIdentity(origId);
   9336         }
   9337     }
   9338 
   9339     public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
   9340         boolean anyForeground = false;
   9341         for (ServiceRecord sr : proc.services) {
   9342             if (sr.isForeground) {
   9343                 anyForeground = true;
   9344                 break;
   9345             }
   9346         }
   9347         if (anyForeground != proc.foregroundServices) {
   9348             proc.foregroundServices = anyForeground;
   9349             if (oomAdj) {
   9350                 updateOomAdjLocked();
   9351             }
   9352         }
   9353     }
   9354 
   9355     public int bindService(IApplicationThread caller, IBinder token,
   9356             Intent service, String resolvedType,
   9357             IServiceConnection connection, int flags) {
   9358         // Refuse possible leaked file descriptors
   9359         if (service != null && service.hasFileDescriptors() == true) {
   9360             throw new IllegalArgumentException("File descriptors passed in Intent");
   9361         }
   9362 
   9363         synchronized(this) {
   9364             if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
   9365                     + " type=" + resolvedType + " conn=" + connection.asBinder()
   9366                     + " flags=0x" + Integer.toHexString(flags));
   9367             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   9368             if (callerApp == null) {
   9369                 throw new SecurityException(
   9370                         "Unable to find app for caller " + caller
   9371                         + " (pid=" + Binder.getCallingPid()
   9372                         + ") when binding service " + service);
   9373             }
   9374 
   9375             ActivityRecord activity = null;
   9376             if (token != null) {
   9377                 int aindex = mMainStack.indexOfTokenLocked(token);
   9378                 if (aindex < 0) {
   9379                     Slog.w(TAG, "Binding with unknown activity: " + token);
   9380                     return 0;
   9381                 }
   9382                 activity = (ActivityRecord)mMainStack.mHistory.get(aindex);
   9383             }
   9384 
   9385             int clientLabel = 0;
   9386             PendingIntent clientIntent = null;
   9387 
   9388             if (callerApp.info.uid == Process.SYSTEM_UID) {
   9389                 // Hacky kind of thing -- allow system stuff to tell us
   9390                 // what they are, so we can report this elsewhere for
   9391                 // others to know why certain services are running.
   9392                 try {
   9393                     clientIntent = (PendingIntent)service.getParcelableExtra(
   9394                             Intent.EXTRA_CLIENT_INTENT);
   9395                 } catch (RuntimeException e) {
   9396                 }
   9397                 if (clientIntent != null) {
   9398                     clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
   9399                     if (clientLabel != 0) {
   9400                         // There are no useful extras in the intent, trash them.
   9401                         // System code calling with this stuff just needs to know
   9402                         // this will happen.
   9403                         service = service.cloneFilter();
   9404                     }
   9405                 }
   9406             }
   9407 
   9408             ServiceLookupResult res =
   9409                 retrieveServiceLocked(service, resolvedType,
   9410                         Binder.getCallingPid(), Binder.getCallingUid());
   9411             if (res == null) {
   9412                 return 0;
   9413             }
   9414             if (res.record == null) {
   9415                 return -1;
   9416             }
   9417             ServiceRecord s = res.record;
   9418 
   9419             final long origId = Binder.clearCallingIdentity();
   9420 
   9421             if (unscheduleServiceRestartLocked(s)) {
   9422                 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
   9423                         + s);
   9424             }
   9425 
   9426             AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
   9427             ConnectionRecord c = new ConnectionRecord(b, activity,
   9428                     connection, flags, clientLabel, clientIntent);
   9429 
   9430             IBinder binder = connection.asBinder();
   9431             ArrayList<ConnectionRecord> clist = s.connections.get(binder);
   9432             if (clist == null) {
   9433                 clist = new ArrayList<ConnectionRecord>();
   9434                 s.connections.put(binder, clist);
   9435             }
   9436             clist.add(c);
   9437             b.connections.add(c);
   9438             if (activity != null) {
   9439                 if (activity.connections == null) {
   9440                     activity.connections = new HashSet<ConnectionRecord>();
   9441                 }
   9442                 activity.connections.add(c);
   9443             }
   9444             b.client.connections.add(c);
   9445             clist = mServiceConnections.get(binder);
   9446             if (clist == null) {
   9447                 clist = new ArrayList<ConnectionRecord>();
   9448                 mServiceConnections.put(binder, clist);
   9449             }
   9450             clist.add(c);
   9451 
   9452             if ((flags&Context.BIND_AUTO_CREATE) != 0) {
   9453                 s.lastActivity = SystemClock.uptimeMillis();
   9454                 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
   9455                     return 0;
   9456                 }
   9457             }
   9458 
   9459             if (s.app != null) {
   9460                 // This could have made the service more important.
   9461                 updateOomAdjLocked(s.app);
   9462             }
   9463 
   9464             if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
   9465                     + ": received=" + b.intent.received
   9466                     + " apps=" + b.intent.apps.size()
   9467                     + " doRebind=" + b.intent.doRebind);
   9468 
   9469             if (s.app != null && b.intent.received) {
   9470                 // Service is already running, so we can immediately
   9471                 // publish the connection.
   9472                 try {
   9473                     c.conn.connected(s.name, b.intent.binder);
   9474                 } catch (Exception e) {
   9475                     Slog.w(TAG, "Failure sending service " + s.shortName
   9476                             + " to connection " + c.conn.asBinder()
   9477                             + " (in " + c.binding.client.processName + ")", e);
   9478                 }
   9479 
   9480                 // If this is the first app connected back to this binding,
   9481                 // and the service had previously asked to be told when
   9482                 // rebound, then do so.
   9483                 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
   9484                     requestServiceBindingLocked(s, b.intent, true);
   9485                 }
   9486             } else if (!b.intent.requested) {
   9487                 requestServiceBindingLocked(s, b.intent, false);
   9488             }
   9489 
   9490             Binder.restoreCallingIdentity(origId);
   9491         }
   9492 
   9493         return 1;
   9494     }
   9495 
   9496     void removeConnectionLocked(
   9497         ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
   9498         IBinder binder = c.conn.asBinder();
   9499         AppBindRecord b = c.binding;
   9500         ServiceRecord s = b.service;
   9501         ArrayList<ConnectionRecord> clist = s.connections.get(binder);
   9502         if (clist != null) {
   9503             clist.remove(c);
   9504             if (clist.size() == 0) {
   9505                 s.connections.remove(binder);
   9506             }
   9507         }
   9508         b.connections.remove(c);
   9509         if (c.activity != null && c.activity != skipAct) {
   9510             if (c.activity.connections != null) {
   9511                 c.activity.connections.remove(c);
   9512             }
   9513         }
   9514         if (b.client != skipApp) {
   9515             b.client.connections.remove(c);
   9516         }
   9517         clist = mServiceConnections.get(binder);
   9518         if (clist != null) {
   9519             clist.remove(c);
   9520             if (clist.size() == 0) {
   9521                 mServiceConnections.remove(binder);
   9522             }
   9523         }
   9524 
   9525         if (b.connections.size() == 0) {
   9526             b.intent.apps.remove(b.client);
   9527         }
   9528 
   9529         if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
   9530                 + ": shouldUnbind=" + b.intent.hasBound);
   9531         if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
   9532                 && b.intent.hasBound) {
   9533             try {
   9534                 bumpServiceExecutingLocked(s, "unbind");
   9535                 updateOomAdjLocked(s.app);
   9536                 b.intent.hasBound = false;
   9537                 // Assume the client doesn't want to know about a rebind;
   9538                 // we will deal with that later if it asks for one.
   9539                 b.intent.doRebind = false;
   9540                 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
   9541             } catch (Exception e) {
   9542                 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
   9543                 serviceDoneExecutingLocked(s, true);
   9544             }
   9545         }
   9546 
   9547         if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
   9548             bringDownServiceLocked(s, false);
   9549         }
   9550     }
   9551 
   9552     public boolean unbindService(IServiceConnection connection) {
   9553         synchronized (this) {
   9554             IBinder binder = connection.asBinder();
   9555             if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
   9556             ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
   9557             if (clist == null) {
   9558                 Slog.w(TAG, "Unbind failed: could not find connection for "
   9559                       + connection.asBinder());
   9560                 return false;
   9561             }
   9562 
   9563             final long origId = Binder.clearCallingIdentity();
   9564 
   9565             while (clist.size() > 0) {
   9566                 ConnectionRecord r = clist.get(0);
   9567                 removeConnectionLocked(r, null, null);
   9568 
   9569                 if (r.binding.service.app != null) {
   9570                     // This could have made the service less important.
   9571                     updateOomAdjLocked(r.binding.service.app);
   9572                 }
   9573             }
   9574 
   9575             Binder.restoreCallingIdentity(origId);
   9576         }
   9577 
   9578         return true;
   9579     }
   9580 
   9581     public void publishService(IBinder token, Intent intent, IBinder service) {
   9582         // Refuse possible leaked file descriptors
   9583         if (intent != null && intent.hasFileDescriptors() == true) {
   9584             throw new IllegalArgumentException("File descriptors passed in Intent");
   9585         }
   9586 
   9587         synchronized(this) {
   9588             if (!(token instanceof ServiceRecord)) {
   9589                 throw new IllegalArgumentException("Invalid service token");
   9590             }
   9591             ServiceRecord r = (ServiceRecord)token;
   9592 
   9593             final long origId = Binder.clearCallingIdentity();
   9594 
   9595             if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
   9596                     + " " + intent + ": " + service);
   9597             if (r != null) {
   9598                 Intent.FilterComparison filter
   9599                         = new Intent.FilterComparison(intent);
   9600                 IntentBindRecord b = r.bindings.get(filter);
   9601                 if (b != null && !b.received) {
   9602                     b.binder = service;
   9603                     b.requested = true;
   9604                     b.received = true;
   9605                     if (r.connections.size() > 0) {
   9606                         Iterator<ArrayList<ConnectionRecord>> it
   9607                                 = r.connections.values().iterator();
   9608                         while (it.hasNext()) {
   9609                             ArrayList<ConnectionRecord> clist = it.next();
   9610                             for (int i=0; i<clist.size(); i++) {
   9611                                 ConnectionRecord c = clist.get(i);
   9612                                 if (!filter.equals(c.binding.intent.intent)) {
   9613                                     if (DEBUG_SERVICE) Slog.v(
   9614                                             TAG, "Not publishing to: " + c);
   9615                                     if (DEBUG_SERVICE) Slog.v(
   9616                                             TAG, "Bound intent: " + c.binding.intent.intent);
   9617                                     if (DEBUG_SERVICE) Slog.v(
   9618                                             TAG, "Published intent: " + intent);
   9619                                     continue;
   9620                                 }
   9621                                 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
   9622                                 try {
   9623                                     c.conn.connected(r.name, service);
   9624                                 } catch (Exception e) {
   9625                                     Slog.w(TAG, "Failure sending service " + r.name +
   9626                                           " to connection " + c.conn.asBinder() +
   9627                                           " (in " + c.binding.client.processName + ")", e);
   9628                                 }
   9629                             }
   9630                         }
   9631                     }
   9632                 }
   9633 
   9634                 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
   9635 
   9636                 Binder.restoreCallingIdentity(origId);
   9637             }
   9638         }
   9639     }
   9640 
   9641     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
   9642         // Refuse possible leaked file descriptors
   9643         if (intent != null && intent.hasFileDescriptors() == true) {
   9644             throw new IllegalArgumentException("File descriptors passed in Intent");
   9645         }
   9646 
   9647         synchronized(this) {
   9648             if (!(token instanceof ServiceRecord)) {
   9649                 throw new IllegalArgumentException("Invalid service token");
   9650             }
   9651             ServiceRecord r = (ServiceRecord)token;
   9652 
   9653             final long origId = Binder.clearCallingIdentity();
   9654 
   9655             if (r != null) {
   9656                 Intent.FilterComparison filter
   9657                         = new Intent.FilterComparison(intent);
   9658                 IntentBindRecord b = r.bindings.get(filter);
   9659                 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
   9660                         + " at " + b + ": apps="
   9661                         + (b != null ? b.apps.size() : 0));
   9662                 if (b != null) {
   9663                     if (b.apps.size() > 0) {
   9664                         // Applications have already bound since the last
   9665                         // unbind, so just rebind right here.
   9666                         requestServiceBindingLocked(r, b, true);
   9667                     } else {
   9668                         // Note to tell the service the next time there is
   9669                         // a new client.
   9670                         b.doRebind = true;
   9671                     }
   9672                 }
   9673 
   9674                 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
   9675 
   9676                 Binder.restoreCallingIdentity(origId);
   9677             }
   9678         }
   9679     }
   9680 
   9681     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
   9682         synchronized(this) {
   9683             if (!(token instanceof ServiceRecord)) {
   9684                 throw new IllegalArgumentException("Invalid service token");
   9685             }
   9686             ServiceRecord r = (ServiceRecord)token;
   9687             boolean inStopping = mStoppingServices.contains(token);
   9688             if (r != null) {
   9689                 if (r != token) {
   9690                     Slog.w(TAG, "Done executing service " + r.name
   9691                           + " with incorrect token: given " + token
   9692                           + ", expected " + r);
   9693                     return;
   9694                 }
   9695 
   9696                 if (type == 1) {
   9697                     // This is a call from a service start...  take care of
   9698                     // book-keeping.
   9699                     r.callStart = true;
   9700                     switch (res) {
   9701                         case Service.START_STICKY_COMPATIBILITY:
   9702                         case Service.START_STICKY: {
   9703                             // We are done with the associated start arguments.
   9704                             r.findDeliveredStart(startId, true);
   9705                             // Don't stop if killed.
   9706                             r.stopIfKilled = false;
   9707                             break;
   9708                         }
   9709                         case Service.START_NOT_STICKY: {
   9710                             // We are done with the associated start arguments.
   9711                             r.findDeliveredStart(startId, true);
   9712                             if (r.lastStartId == startId) {
   9713                                 // There is no more work, and this service
   9714                                 // doesn't want to hang around if killed.
   9715                                 r.stopIfKilled = true;
   9716                             }
   9717                             break;
   9718                         }
   9719                         case Service.START_REDELIVER_INTENT: {
   9720                             // We'll keep this item until they explicitly
   9721                             // call stop for it, but keep track of the fact
   9722                             // that it was delivered.
   9723                             ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
   9724                             if (si != null) {
   9725                                 si.deliveryCount = 0;
   9726                                 si.doneExecutingCount++;
   9727                                 // Don't stop if killed.
   9728                                 r.stopIfKilled = true;
   9729                             }
   9730                             break;
   9731                         }
   9732                         default:
   9733                             throw new IllegalArgumentException(
   9734                                     "Unknown service start result: " + res);
   9735                     }
   9736                     if (res == Service.START_STICKY_COMPATIBILITY) {
   9737                         r.callStart = false;
   9738                     }
   9739                 }
   9740 
   9741                 final long origId = Binder.clearCallingIdentity();
   9742                 serviceDoneExecutingLocked(r, inStopping);
   9743                 Binder.restoreCallingIdentity(origId);
   9744             } else {
   9745                 Slog.w(TAG, "Done executing unknown service from pid "
   9746                         + Binder.getCallingPid());
   9747             }
   9748         }
   9749     }
   9750 
   9751     public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
   9752         if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
   9753                 + ": nesting=" + r.executeNesting
   9754                 + ", inStopping=" + inStopping + ", app=" + r.app);
   9755         else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
   9756         r.executeNesting--;
   9757         if (r.executeNesting <= 0 && r.app != null) {
   9758             if (DEBUG_SERVICE) Slog.v(TAG,
   9759                     "Nesting at 0 of " + r.shortName);
   9760             r.app.executingServices.remove(r);
   9761             if (r.app.executingServices.size() == 0) {
   9762                 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
   9763                         "No more executingServices of " + r.shortName);
   9764                 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
   9765             }
   9766             if (inStopping) {
   9767                 if (DEBUG_SERVICE) Slog.v(TAG,
   9768                         "doneExecuting remove stopping " + r);
   9769                 mStoppingServices.remove(r);
   9770             }
   9771             updateOomAdjLocked(r.app);
   9772         }
   9773     }
   9774 
   9775     void serviceTimeout(ProcessRecord proc) {
   9776         String anrMessage = null;
   9777 
   9778         synchronized(this) {
   9779             if (proc.executingServices.size() == 0 || proc.thread == null) {
   9780                 return;
   9781             }
   9782             long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
   9783             Iterator<ServiceRecord> it = proc.executingServices.iterator();
   9784             ServiceRecord timeout = null;
   9785             long nextTime = 0;
   9786             while (it.hasNext()) {
   9787                 ServiceRecord sr = it.next();
   9788                 if (sr.executingStart < maxTime) {
   9789                     timeout = sr;
   9790                     break;
   9791                 }
   9792                 if (sr.executingStart > nextTime) {
   9793                     nextTime = sr.executingStart;
   9794                 }
   9795             }
   9796             if (timeout != null && mLruProcesses.contains(proc)) {
   9797                 Slog.w(TAG, "Timeout executing service: " + timeout);
   9798                 anrMessage = "Executing service " + timeout.shortName;
   9799             } else {
   9800                 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   9801                 msg.obj = proc;
   9802                 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
   9803             }
   9804         }
   9805 
   9806         if (anrMessage != null) {
   9807             appNotResponding(proc, null, null, anrMessage);
   9808         }
   9809     }
   9810 
   9811     // =========================================================
   9812     // BACKUP AND RESTORE
   9813     // =========================================================
   9814 
   9815     // Cause the target app to be launched if necessary and its backup agent
   9816     // instantiated.  The backup agent will invoke backupAgentCreated() on the
   9817     // activity manager to announce its creation.
   9818     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
   9819         if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
   9820         enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
   9821 
   9822         synchronized(this) {
   9823             // !!! TODO: currently no check here that we're already bound
   9824             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   9825             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   9826             synchronized (stats) {
   9827                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
   9828             }
   9829 
   9830             BackupRecord r = new BackupRecord(ss, app, backupMode);
   9831             ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName);
   9832             // startProcessLocked() returns existing proc's record if it's already running
   9833             ProcessRecord proc = startProcessLocked(app.processName, app,
   9834                     false, 0, "backup", hostingName, false);
   9835             if (proc == null) {
   9836                 Slog.e(TAG, "Unable to start backup agent process " + r);
   9837                 return false;
   9838             }
   9839 
   9840             r.app = proc;
   9841             mBackupTarget = r;
   9842             mBackupAppName = app.packageName;
   9843 
   9844             // Try not to kill the process during backup
   9845             updateOomAdjLocked(proc);
   9846 
   9847             // If the process is already attached, schedule the creation of the backup agent now.
   9848             // If it is not yet live, this will be done when it attaches to the framework.
   9849             if (proc.thread != null) {
   9850                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
   9851                 try {
   9852                     proc.thread.scheduleCreateBackupAgent(app, backupMode);
   9853                 } catch (RemoteException e) {
   9854                     // Will time out on the backup manager side
   9855                 }
   9856             } else {
   9857                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
   9858             }
   9859             // Invariants: at this point, the target app process exists and the application
   9860             // is either already running or in the process of coming up.  mBackupTarget and
   9861             // mBackupAppName describe the app, so that when it binds back to the AM we
   9862             // know that it's scheduled for a backup-agent operation.
   9863         }
   9864 
   9865         return true;
   9866     }
   9867 
   9868     // A backup agent has just come up
   9869     public void backupAgentCreated(String agentPackageName, IBinder agent) {
   9870         if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
   9871                 + " = " + agent);
   9872 
   9873         synchronized(this) {
   9874             if (!agentPackageName.equals(mBackupAppName)) {
   9875                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
   9876                 return;
   9877             }
   9878         }
   9879 
   9880         long oldIdent = Binder.clearCallingIdentity();
   9881         try {
   9882             IBackupManager bm = IBackupManager.Stub.asInterface(
   9883                     ServiceManager.getService(Context.BACKUP_SERVICE));
   9884             bm.agentConnected(agentPackageName, agent);
   9885         } catch (RemoteException e) {
   9886             // can't happen; the backup manager service is local
   9887         } catch (Exception e) {
   9888             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
   9889             e.printStackTrace();
   9890         } finally {
   9891             Binder.restoreCallingIdentity(oldIdent);
   9892         }
   9893     }
   9894 
   9895     // done with this agent
   9896     public void unbindBackupAgent(ApplicationInfo appInfo) {
   9897         if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
   9898         if (appInfo == null) {
   9899             Slog.w(TAG, "unbind backup agent for null app");
   9900             return;
   9901         }
   9902 
   9903         synchronized(this) {
   9904             if (mBackupAppName == null) {
   9905                 Slog.w(TAG, "Unbinding backup agent with no active backup");
   9906                 return;
   9907             }
   9908 
   9909             if (!mBackupAppName.equals(appInfo.packageName)) {
   9910                 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
   9911                 return;
   9912             }
   9913 
   9914             ProcessRecord proc = mBackupTarget.app;
   9915             mBackupTarget = null;
   9916             mBackupAppName = null;
   9917 
   9918             // Not backing this app up any more; reset its OOM adjustment
   9919             updateOomAdjLocked(proc);
   9920 
   9921             // If the app crashed during backup, 'thread' will be null here
   9922             if (proc.thread != null) {
   9923                 try {
   9924                     proc.thread.scheduleDestroyBackupAgent(appInfo);
   9925                 } catch (Exception e) {
   9926                     Slog.e(TAG, "Exception when unbinding backup agent:");
   9927                     e.printStackTrace();
   9928                 }
   9929             }
   9930         }
   9931     }
   9932     // =========================================================
   9933     // BROADCASTS
   9934     // =========================================================
   9935 
   9936     private final List getStickiesLocked(String action, IntentFilter filter,
   9937             List cur) {
   9938         final ContentResolver resolver = mContext.getContentResolver();
   9939         final ArrayList<Intent> list = mStickyBroadcasts.get(action);
   9940         if (list == null) {
   9941             return cur;
   9942         }
   9943         int N = list.size();
   9944         for (int i=0; i<N; i++) {
   9945             Intent intent = list.get(i);
   9946             if (filter.match(resolver, intent, true, TAG) >= 0) {
   9947                 if (cur == null) {
   9948                     cur = new ArrayList<Intent>();
   9949                 }
   9950                 cur.add(intent);
   9951             }
   9952         }
   9953         return cur;
   9954     }
   9955 
   9956     private final void scheduleBroadcastsLocked() {
   9957         if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
   9958                 + mBroadcastsScheduled);
   9959 
   9960         if (mBroadcastsScheduled) {
   9961             return;
   9962         }
   9963         mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
   9964         mBroadcastsScheduled = true;
   9965     }
   9966 
   9967     public Intent registerReceiver(IApplicationThread caller,
   9968             IIntentReceiver receiver, IntentFilter filter, String permission) {
   9969         synchronized(this) {
   9970             ProcessRecord callerApp = null;
   9971             if (caller != null) {
   9972                 callerApp = getRecordForAppLocked(caller);
   9973                 if (callerApp == null) {
   9974                     throw new SecurityException(
   9975                             "Unable to find app for caller " + caller
   9976                             + " (pid=" + Binder.getCallingPid()
   9977                             + ") when registering receiver " + receiver);
   9978                 }
   9979             }
   9980 
   9981             List allSticky = null;
   9982 
   9983             // Look for any matching sticky broadcasts...
   9984             Iterator actions = filter.actionsIterator();
   9985             if (actions != null) {
   9986                 while (actions.hasNext()) {
   9987                     String action = (String)actions.next();
   9988                     allSticky = getStickiesLocked(action, filter, allSticky);
   9989                 }
   9990             } else {
   9991                 allSticky = getStickiesLocked(null, filter, allSticky);
   9992             }
   9993 
   9994             // The first sticky in the list is returned directly back to
   9995             // the client.
   9996             Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
   9997 
   9998             if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
   9999                     + ": " + sticky);
   10000 
   10001             if (receiver == null) {
   10002                 return sticky;
   10003             }
   10004 
   10005             ReceiverList rl
   10006                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   10007             if (rl == null) {
   10008                 rl = new ReceiverList(this, callerApp,
   10009                         Binder.getCallingPid(),
   10010                         Binder.getCallingUid(), receiver);
   10011                 if (rl.app != null) {
   10012                     rl.app.receivers.add(rl);
   10013                 } else {
   10014                     try {
   10015                         receiver.asBinder().linkToDeath(rl, 0);
   10016                     } catch (RemoteException e) {
   10017                         return sticky;
   10018                     }
   10019                     rl.linkedToDeath = true;
   10020                 }
   10021                 mRegisteredReceivers.put(receiver.asBinder(), rl);
   10022             }
   10023             BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
   10024             rl.add(bf);
   10025             if (!bf.debugCheck()) {
   10026                 Slog.w(TAG, "==> For Dynamic broadast");
   10027             }
   10028             mReceiverResolver.addFilter(bf);
   10029 
   10030             // Enqueue broadcasts for all existing stickies that match
   10031             // this filter.
   10032             if (allSticky != null) {
   10033                 ArrayList receivers = new ArrayList();
   10034                 receivers.add(bf);
   10035 
   10036                 int N = allSticky.size();
   10037                 for (int i=0; i<N; i++) {
   10038                     Intent intent = (Intent)allSticky.get(i);
   10039                     BroadcastRecord r = new BroadcastRecord(intent, null,
   10040                             null, -1, -1, null, receivers, null, 0, null, null,
   10041                             false, true, true);
   10042                     if (mParallelBroadcasts.size() == 0) {
   10043                         scheduleBroadcastsLocked();
   10044                     }
   10045                     mParallelBroadcasts.add(r);
   10046                 }
   10047             }
   10048 
   10049             return sticky;
   10050         }
   10051     }
   10052 
   10053     public void unregisterReceiver(IIntentReceiver receiver) {
   10054         if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
   10055 
   10056         boolean doNext = false;
   10057 
   10058         synchronized(this) {
   10059             ReceiverList rl
   10060                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   10061             if (rl != null) {
   10062                 if (rl.curBroadcast != null) {
   10063                     BroadcastRecord r = rl.curBroadcast;
   10064                     doNext = finishReceiverLocked(
   10065                         receiver.asBinder(), r.resultCode, r.resultData,
   10066                         r.resultExtras, r.resultAbort, true);
   10067                 }
   10068 
   10069                 if (rl.app != null) {
   10070                     rl.app.receivers.remove(rl);
   10071                 }
   10072                 removeReceiverLocked(rl);
   10073                 if (rl.linkedToDeath) {
   10074                     rl.linkedToDeath = false;
   10075                     rl.receiver.asBinder().unlinkToDeath(rl, 0);
   10076                 }
   10077             }
   10078         }
   10079 
   10080         if (!doNext) {
   10081             return;
   10082         }
   10083 
   10084         final long origId = Binder.clearCallingIdentity();
   10085         processNextBroadcast(false);
   10086         trimApplications();
   10087         Binder.restoreCallingIdentity(origId);
   10088     }
   10089 
   10090     void removeReceiverLocked(ReceiverList rl) {
   10091         mRegisteredReceivers.remove(rl.receiver.asBinder());
   10092         int N = rl.size();
   10093         for (int i=0; i<N; i++) {
   10094             mReceiverResolver.removeFilter(rl.get(i));
   10095         }
   10096     }
   10097 
   10098     private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
   10099         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   10100             ProcessRecord r = mLruProcesses.get(i);
   10101             if (r.thread != null) {
   10102                 try {
   10103                     r.thread.dispatchPackageBroadcast(cmd, packages);
   10104                 } catch (RemoteException ex) {
   10105                 }
   10106             }
   10107         }
   10108     }
   10109 
   10110     private final int broadcastIntentLocked(ProcessRecord callerApp,
   10111             String callerPackage, Intent intent, String resolvedType,
   10112             IIntentReceiver resultTo, int resultCode, String resultData,
   10113             Bundle map, String requiredPermission,
   10114             boolean ordered, boolean sticky, int callingPid, int callingUid) {
   10115         intent = new Intent(intent);
   10116 
   10117         if (DEBUG_BROADCAST_LIGHT) Slog.v(
   10118             TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
   10119             + " ordered=" + ordered);
   10120         if ((resultTo != null) && !ordered) {
   10121             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
   10122         }
   10123 
   10124         // Handle special intents: if this broadcast is from the package
   10125         // manager about a package being removed, we need to remove all of
   10126         // its activities from the history stack.
   10127         final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals(
   10128                 intent.getAction());
   10129         if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
   10130                 || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
   10131                 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
   10132                 || uidRemoved) {
   10133             if (checkComponentPermission(
   10134                     android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
   10135                     callingPid, callingUid, -1)
   10136                     == PackageManager.PERMISSION_GRANTED) {
   10137                 if (uidRemoved) {
   10138                     final Bundle intentExtras = intent.getExtras();
   10139                     final int uid = intentExtras != null
   10140                             ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
   10141                     if (uid >= 0) {
   10142                         BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
   10143                         synchronized (bs) {
   10144                             bs.removeUidStatsLocked(uid);
   10145                         }
   10146                     }
   10147                 } else {
   10148                     // If resources are unvailble just force stop all
   10149                     // those packages and flush the attribute cache as well.
   10150                     if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
   10151                         String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   10152                         if (list != null && (list.length > 0)) {
   10153                             for (String pkg : list) {
   10154                                 forceStopPackageLocked(pkg, -1, false, true, true);
   10155                             }
   10156                             sendPackageBroadcastLocked(
   10157                                     IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
   10158                         }
   10159                     } else {
   10160                         Uri data = intent.getData();
   10161                         String ssp;
   10162                         if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   10163                             if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
   10164                                 forceStopPackageLocked(ssp,
   10165                                         intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
   10166                             }
   10167                             if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
   10168                                 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
   10169                                         new String[] {ssp});
   10170                             }
   10171                         }
   10172                     }
   10173                 }
   10174             } else {
   10175                 String msg = "Permission Denial: " + intent.getAction()
   10176                         + " broadcast from " + callerPackage + " (pid=" + callingPid
   10177                         + ", uid=" + callingUid + ")"
   10178                         + " requires "
   10179                         + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
   10180                 Slog.w(TAG, msg);
   10181                 throw new SecurityException(msg);
   10182             }
   10183         }
   10184 
   10185         /*
   10186          * If this is the time zone changed action, queue up a message that will reset the timezone
   10187          * of all currently running processes. This message will get queued up before the broadcast
   10188          * happens.
   10189          */
   10190         if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
   10191             mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
   10192         }
   10193 
   10194         /*
   10195          * Prevent non-system code (defined here to be non-persistent
   10196          * processes) from sending protected broadcasts.
   10197          */
   10198         if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
   10199                 || callingUid == Process.SHELL_UID || callingUid == 0) {
   10200             // Always okay.
   10201         } else if (callerApp == null || !callerApp.persistent) {
   10202             try {
   10203                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
   10204                         intent.getAction())) {
   10205                     String msg = "Permission Denial: not allowed to send broadcast "
   10206                             + intent.getAction() + " from pid="
   10207                             + callingPid + ", uid=" + callingUid;
   10208                     Slog.w(TAG, msg);
   10209                     throw new SecurityException(msg);
   10210                 }
   10211             } catch (RemoteException e) {
   10212                 Slog.w(TAG, "Remote exception", e);
   10213                 return BROADCAST_SUCCESS;
   10214             }
   10215         }
   10216 
   10217         // Add to the sticky list if requested.
   10218         if (sticky) {
   10219             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
   10220                     callingPid, callingUid)
   10221                     != PackageManager.PERMISSION_GRANTED) {
   10222                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
   10223                         + callingPid + ", uid=" + callingUid
   10224                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   10225                 Slog.w(TAG, msg);
   10226                 throw new SecurityException(msg);
   10227             }
   10228             if (requiredPermission != null) {
   10229                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
   10230                         + " and enforce permission " + requiredPermission);
   10231                 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
   10232             }
   10233             if (intent.getComponent() != null) {
   10234                 throw new SecurityException(
   10235                         "Sticky broadcasts can't target a specific component");
   10236             }
   10237             ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
   10238             if (list == null) {
   10239                 list = new ArrayList<Intent>();
   10240                 mStickyBroadcasts.put(intent.getAction(), list);
   10241             }
   10242             int N = list.size();
   10243             int i;
   10244             for (i=0; i<N; i++) {
   10245                 if (intent.filterEquals(list.get(i))) {
   10246                     // This sticky already exists, replace it.
   10247                     list.set(i, new Intent(intent));
   10248                     break;
   10249                 }
   10250             }
   10251             if (i >= N) {
   10252                 list.add(new Intent(intent));
   10253             }
   10254         }
   10255 
   10256         // Figure out who all will receive this broadcast.
   10257         List receivers = null;
   10258         List<BroadcastFilter> registeredReceivers = null;
   10259         try {
   10260             if (intent.getComponent() != null) {
   10261                 // Broadcast is going to one specific receiver class...
   10262                 ActivityInfo ai = AppGlobals.getPackageManager().
   10263                     getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
   10264                 if (ai != null) {
   10265                     receivers = new ArrayList();
   10266                     ResolveInfo ri = new ResolveInfo();
   10267                     ri.activityInfo = ai;
   10268                     receivers.add(ri);
   10269                 }
   10270             } else {
   10271                 // Need to resolve the intent to interested receivers...
   10272                 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
   10273                          == 0) {
   10274                     receivers =
   10275                         AppGlobals.getPackageManager().queryIntentReceivers(
   10276                                 intent, resolvedType, STOCK_PM_FLAGS);
   10277                 }
   10278                 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
   10279             }
   10280         } catch (RemoteException ex) {
   10281             // pm is in same process, this will never happen.
   10282         }
   10283 
   10284         final boolean replacePending =
   10285                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
   10286 
   10287         if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
   10288                 + " replacePending=" + replacePending);
   10289 
   10290         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
   10291         if (!ordered && NR > 0) {
   10292             // If we are not serializing this broadcast, then send the
   10293             // registered receivers separately so they don't wait for the
   10294             // components to be launched.
   10295             BroadcastRecord r = new BroadcastRecord(intent, callerApp,
   10296                     callerPackage, callingPid, callingUid, requiredPermission,
   10297                     registeredReceivers, resultTo, resultCode, resultData, map,
   10298                     ordered, sticky, false);
   10299             if (DEBUG_BROADCAST) Slog.v(
   10300                     TAG, "Enqueueing parallel broadcast " + r
   10301                     + ": prev had " + mParallelBroadcasts.size());
   10302             boolean replaced = false;
   10303             if (replacePending) {
   10304                 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
   10305                     if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
   10306                         if (DEBUG_BROADCAST) Slog.v(TAG,
   10307                                 "***** DROPPING PARALLEL: " + intent);
   10308                         mParallelBroadcasts.set(i, r);
   10309                         replaced = true;
   10310                         break;
   10311                     }
   10312                 }
   10313             }
   10314             if (!replaced) {
   10315                 mParallelBroadcasts.add(r);
   10316                 scheduleBroadcastsLocked();
   10317             }
   10318             registeredReceivers = null;
   10319             NR = 0;
   10320         }
   10321 
   10322         // Merge into one list.
   10323         int ir = 0;
   10324         if (receivers != null) {
   10325             // A special case for PACKAGE_ADDED: do not allow the package
   10326             // being added to see this broadcast.  This prevents them from
   10327             // using this as a back door to get run as soon as they are
   10328             // installed.  Maybe in the future we want to have a special install
   10329             // broadcast or such for apps, but we'd like to deliberately make
   10330             // this decision.
   10331             String skipPackages[] = null;
   10332             if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
   10333                     || intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
   10334                     || intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
   10335                 Uri data = intent.getData();
   10336                 if (data != null) {
   10337                     String pkgName = data.getSchemeSpecificPart();
   10338                     if (pkgName != null) {
   10339                         skipPackages = new String[] { pkgName };
   10340                     }
   10341                 }
   10342             } else if (intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
   10343                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   10344             }
   10345             if (skipPackages != null && (skipPackages.length > 0)) {
   10346                 for (String skipPackage : skipPackages) {
   10347                     if (skipPackage != null) {
   10348                         int NT = receivers.size();
   10349                         for (int it=0; it<NT; it++) {
   10350                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
   10351                             if (curt.activityInfo.packageName.equals(skipPackage)) {
   10352                                 receivers.remove(it);
   10353                                 it--;
   10354                                 NT--;
   10355                             }
   10356                         }
   10357                     }
   10358                 }
   10359             }
   10360 
   10361             int NT = receivers != null ? receivers.size() : 0;
   10362             int it = 0;
   10363             ResolveInfo curt = null;
   10364             BroadcastFilter curr = null;
   10365             while (it < NT && ir < NR) {
   10366                 if (curt == null) {
   10367                     curt = (ResolveInfo)receivers.get(it);
   10368                 }
   10369                 if (curr == null) {
   10370                     curr = registeredReceivers.get(ir);
   10371                 }
   10372                 if (curr.getPriority() >= curt.priority) {
   10373                     // Insert this broadcast record into the final list.
   10374                     receivers.add(it, curr);
   10375                     ir++;
   10376                     curr = null;
   10377                     it++;
   10378                     NT++;
   10379                 } else {
   10380                     // Skip to the next ResolveInfo in the final list.
   10381                     it++;
   10382                     curt = null;
   10383                 }
   10384             }
   10385         }
   10386         while (ir < NR) {
   10387             if (receivers == null) {
   10388                 receivers = new ArrayList();
   10389             }
   10390             receivers.add(registeredReceivers.get(ir));
   10391             ir++;
   10392         }
   10393 
   10394         if ((receivers != null && receivers.size() > 0)
   10395                 || resultTo != null) {
   10396             BroadcastRecord r = new BroadcastRecord(intent, callerApp,
   10397                     callerPackage, callingPid, callingUid, requiredPermission,
   10398                     receivers, resultTo, resultCode, resultData, map, ordered,
   10399                     sticky, false);
   10400             if (DEBUG_BROADCAST) Slog.v(
   10401                     TAG, "Enqueueing ordered broadcast " + r
   10402                     + ": prev had " + mOrderedBroadcasts.size());
   10403             if (DEBUG_BROADCAST) {
   10404                 int seq = r.intent.getIntExtra("seq", -1);
   10405                 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
   10406             }
   10407             boolean replaced = false;
   10408             if (replacePending) {
   10409                 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
   10410                     if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
   10411                         if (DEBUG_BROADCAST) Slog.v(TAG,
   10412                                 "***** DROPPING ORDERED: " + intent);
   10413                         mOrderedBroadcasts.set(i, r);
   10414                         replaced = true;
   10415                         break;
   10416                     }
   10417                 }
   10418             }
   10419             if (!replaced) {
   10420                 mOrderedBroadcasts.add(r);
   10421                 scheduleBroadcastsLocked();
   10422             }
   10423         }
   10424 
   10425         return BROADCAST_SUCCESS;
   10426     }
   10427 
   10428     final Intent verifyBroadcastLocked(Intent intent) {
   10429         // Refuse possible leaked file descriptors
   10430         if (intent != null && intent.hasFileDescriptors() == true) {
   10431             throw new IllegalArgumentException("File descriptors passed in Intent");
   10432         }
   10433 
   10434         int flags = intent.getFlags();
   10435 
   10436         if (!mProcessesReady) {
   10437             // if the caller really truly claims to know what they're doing, go
   10438             // ahead and allow the broadcast without launching any receivers
   10439             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
   10440                 intent = new Intent(intent);
   10441                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   10442             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
   10443                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
   10444                         + " before boot completion");
   10445                 throw new IllegalStateException("Cannot broadcast before boot completed");
   10446             }
   10447         }
   10448 
   10449         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   10450             throw new IllegalArgumentException(
   10451                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   10452         }
   10453 
   10454         return intent;
   10455     }
   10456 
   10457     public final int broadcastIntent(IApplicationThread caller,
   10458             Intent intent, String resolvedType, IIntentReceiver resultTo,
   10459             int resultCode, String resultData, Bundle map,
   10460             String requiredPermission, boolean serialized, boolean sticky) {
   10461         synchronized(this) {
   10462             intent = verifyBroadcastLocked(intent);
   10463 
   10464             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   10465             final int callingPid = Binder.getCallingPid();
   10466             final int callingUid = Binder.getCallingUid();
   10467             final long origId = Binder.clearCallingIdentity();
   10468             int res = broadcastIntentLocked(callerApp,
   10469                     callerApp != null ? callerApp.info.packageName : null,
   10470                     intent, resolvedType, resultTo,
   10471                     resultCode, resultData, map, requiredPermission, serialized,
   10472                     sticky, callingPid, callingUid);
   10473             Binder.restoreCallingIdentity(origId);
   10474             return res;
   10475         }
   10476     }
   10477 
   10478     int broadcastIntentInPackage(String packageName, int uid,
   10479             Intent intent, String resolvedType, IIntentReceiver resultTo,
   10480             int resultCode, String resultData, Bundle map,
   10481             String requiredPermission, boolean serialized, boolean sticky) {
   10482         synchronized(this) {
   10483             intent = verifyBroadcastLocked(intent);
   10484 
   10485             final long origId = Binder.clearCallingIdentity();
   10486             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
   10487                     resultTo, resultCode, resultData, map, requiredPermission,
   10488                     serialized, sticky, -1, uid);
   10489             Binder.restoreCallingIdentity(origId);
   10490             return res;
   10491         }
   10492     }
   10493 
   10494     public final void unbroadcastIntent(IApplicationThread caller,
   10495             Intent intent) {
   10496         // Refuse possible leaked file descriptors
   10497         if (intent != null && intent.hasFileDescriptors() == true) {
   10498             throw new IllegalArgumentException("File descriptors passed in Intent");
   10499         }
   10500 
   10501         synchronized(this) {
   10502             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
   10503                     != PackageManager.PERMISSION_GRANTED) {
   10504                 String msg = "Permission Denial: unbroadcastIntent() from pid="
   10505                         + Binder.getCallingPid()
   10506                         + ", uid=" + Binder.getCallingUid()
   10507                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   10508                 Slog.w(TAG, msg);
   10509                 throw new SecurityException(msg);
   10510             }
   10511             ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
   10512             if (list != null) {
   10513                 int N = list.size();
   10514                 int i;
   10515                 for (i=0; i<N; i++) {
   10516                     if (intent.filterEquals(list.get(i))) {
   10517                         list.remove(i);
   10518                         break;
   10519                     }
   10520                 }
   10521             }
   10522         }
   10523     }
   10524 
   10525     private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
   10526             String resultData, Bundle resultExtras, boolean resultAbort,
   10527             boolean explicit) {
   10528         if (mOrderedBroadcasts.size() == 0) {
   10529             if (explicit) {
   10530                 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
   10531             }
   10532             return false;
   10533         }
   10534         BroadcastRecord r = mOrderedBroadcasts.get(0);
   10535         if (r.receiver == null) {
   10536             if (explicit) {
   10537                 Slog.w(TAG, "finishReceiver called but none active");
   10538             }
   10539             return false;
   10540         }
   10541         if (r.receiver != receiver) {
   10542             Slog.w(TAG, "finishReceiver called but active receiver is different");
   10543             return false;
   10544         }
   10545         int state = r.state;
   10546         r.state = r.IDLE;
   10547         if (state == r.IDLE) {
   10548             if (explicit) {
   10549                 Slog.w(TAG, "finishReceiver called but state is IDLE");
   10550             }
   10551         }
   10552         r.receiver = null;
   10553         r.intent.setComponent(null);
   10554         if (r.curApp != null) {
   10555             r.curApp.curReceiver = null;
   10556         }
   10557         if (r.curFilter != null) {
   10558             r.curFilter.receiverList.curBroadcast = null;
   10559         }
   10560         r.curFilter = null;
   10561         r.curApp = null;
   10562         r.curComponent = null;
   10563         r.curReceiver = null;
   10564         mPendingBroadcast = null;
   10565 
   10566         r.resultCode = resultCode;
   10567         r.resultData = resultData;
   10568         r.resultExtras = resultExtras;
   10569         r.resultAbort = resultAbort;
   10570 
   10571         // We will process the next receiver right now if this is finishing
   10572         // an app receiver (which is always asynchronous) or after we have
   10573         // come back from calling a receiver.
   10574         return state == BroadcastRecord.APP_RECEIVE
   10575                 || state == BroadcastRecord.CALL_DONE_RECEIVE;
   10576     }
   10577 
   10578     public void finishReceiver(IBinder who, int resultCode, String resultData,
   10579             Bundle resultExtras, boolean resultAbort) {
   10580         if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
   10581 
   10582         // Refuse possible leaked file descriptors
   10583         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
   10584             throw new IllegalArgumentException("File descriptors passed in Bundle");
   10585         }
   10586 
   10587         boolean doNext;
   10588 
   10589         final long origId = Binder.clearCallingIdentity();
   10590 
   10591         synchronized(this) {
   10592             doNext = finishReceiverLocked(
   10593                 who, resultCode, resultData, resultExtras, resultAbort, true);
   10594         }
   10595 
   10596         if (doNext) {
   10597             processNextBroadcast(false);
   10598         }
   10599         trimApplications();
   10600 
   10601         Binder.restoreCallingIdentity(origId);
   10602     }
   10603 
   10604     private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
   10605         if (r.nextReceiver > 0) {
   10606             Object curReceiver = r.receivers.get(r.nextReceiver-1);
   10607             if (curReceiver instanceof BroadcastFilter) {
   10608                 BroadcastFilter bf = (BroadcastFilter) curReceiver;
   10609                 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
   10610                         System.identityHashCode(r),
   10611                         r.intent.getAction(),
   10612                         r.nextReceiver - 1,
   10613                         System.identityHashCode(bf));
   10614             } else {
   10615                 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
   10616                         System.identityHashCode(r),
   10617                         r.intent.getAction(),
   10618                         r.nextReceiver - 1,
   10619                         ((ResolveInfo)curReceiver).toString());
   10620             }
   10621         } else {
   10622             Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
   10623                     + r);
   10624             EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
   10625                     System.identityHashCode(r),
   10626                     r.intent.getAction(),
   10627                     r.nextReceiver,
   10628                     "NONE");
   10629         }
   10630     }
   10631 
   10632     private final void setBroadcastTimeoutLocked(long timeoutTime) {
   10633         if (! mPendingBroadcastTimeoutMessage) {
   10634             Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
   10635             mHandler.sendMessageAtTime(msg, timeoutTime);
   10636             mPendingBroadcastTimeoutMessage = true;
   10637         }
   10638     }
   10639 
   10640     private final void cancelBroadcastTimeoutLocked() {
   10641         if (mPendingBroadcastTimeoutMessage) {
   10642             mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
   10643             mPendingBroadcastTimeoutMessage = false;
   10644         }
   10645     }
   10646 
   10647     private final void broadcastTimeoutLocked(boolean fromMsg) {
   10648         if (fromMsg) {
   10649             mPendingBroadcastTimeoutMessage = false;
   10650         }
   10651 
   10652         if (mOrderedBroadcasts.size() == 0) {
   10653             return;
   10654         }
   10655 
   10656         long now = SystemClock.uptimeMillis();
   10657         BroadcastRecord r = mOrderedBroadcasts.get(0);
   10658         if (fromMsg) {
   10659             if (mDidDexOpt) {
   10660                 // Delay timeouts until dexopt finishes.
   10661                 mDidDexOpt = false;
   10662                 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
   10663                 setBroadcastTimeoutLocked(timeoutTime);
   10664                 return;
   10665             }
   10666             if (! mProcessesReady) {
   10667                 // Only process broadcast timeouts if the system is ready. That way
   10668                 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
   10669                 // to do heavy lifting for system up.
   10670                 return;
   10671             }
   10672 
   10673             long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
   10674             if (timeoutTime > now) {
   10675                 // We can observe premature timeouts because we do not cancel and reset the
   10676                 // broadcast timeout message after each receiver finishes.  Instead, we set up
   10677                 // an initial timeout then kick it down the road a little further as needed
   10678                 // when it expires.
   10679                 if (DEBUG_BROADCAST) Slog.v(TAG,
   10680                         "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
   10681                         + timeoutTime);
   10682                 setBroadcastTimeoutLocked(timeoutTime);
   10683                 return;
   10684             }
   10685         }
   10686 
   10687         Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
   10688                 + ", started " + (now - r.receiverTime) + "ms ago");
   10689         r.receiverTime = now;
   10690         r.anrCount++;
   10691 
   10692         // Current receiver has passed its expiration date.
   10693         if (r.nextReceiver <= 0) {
   10694             Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
   10695             return;
   10696         }
   10697 
   10698         ProcessRecord app = null;
   10699         String anrMessage = null;
   10700 
   10701         Object curReceiver = r.receivers.get(r.nextReceiver-1);
   10702         Slog.w(TAG, "Receiver during timeout: " + curReceiver);
   10703         logBroadcastReceiverDiscardLocked(r);
   10704         if (curReceiver instanceof BroadcastFilter) {
   10705             BroadcastFilter bf = (BroadcastFilter)curReceiver;
   10706             if (bf.receiverList.pid != 0
   10707                     && bf.receiverList.pid != MY_PID) {
   10708                 synchronized (this.mPidsSelfLocked) {
   10709                     app = this.mPidsSelfLocked.get(
   10710                             bf.receiverList.pid);
   10711                 }
   10712             }
   10713         } else {
   10714             app = r.curApp;
   10715         }
   10716 
   10717         if (app != null) {
   10718             anrMessage = "Broadcast of " + r.intent.toString();
   10719         }
   10720 
   10721         if (mPendingBroadcast == r) {
   10722             mPendingBroadcast = null;
   10723         }
   10724 
   10725         // Move on to the next receiver.
   10726         finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
   10727                 r.resultExtras, r.resultAbort, true);
   10728         scheduleBroadcastsLocked();
   10729 
   10730         if (anrMessage != null) {
   10731             // Post the ANR to the handler since we do not want to process ANRs while
   10732             // potentially holding our lock.
   10733             mHandler.post(new AppNotResponding(app, anrMessage));
   10734         }
   10735     }
   10736 
   10737     private final void processCurBroadcastLocked(BroadcastRecord r,
   10738             ProcessRecord app) throws RemoteException {
   10739         if (DEBUG_BROADCAST)  Slog.v(TAG,
   10740                 "Process cur broadcast " + r + " for app " + app);
   10741         if (app.thread == null) {
   10742             throw new RemoteException();
   10743         }
   10744         r.receiver = app.thread.asBinder();
   10745         r.curApp = app;
   10746         app.curReceiver = r;
   10747         updateLruProcessLocked(app, true, true);
   10748 
   10749         // Tell the application to launch this receiver.
   10750         r.intent.setComponent(r.curComponent);
   10751 
   10752         boolean started = false;
   10753         try {
   10754             if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
   10755                     "Delivering to component " + r.curComponent
   10756                     + ": " + r);
   10757             ensurePackageDexOpt(r.intent.getComponent().getPackageName());
   10758             app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
   10759                     r.resultCode, r.resultData, r.resultExtras, r.ordered);
   10760             if (DEBUG_BROADCAST)  Slog.v(TAG,
   10761                     "Process cur broadcast " + r + " DELIVERED for app " + app);
   10762             started = true;
   10763         } finally {
   10764             if (!started) {
   10765                 if (DEBUG_BROADCAST)  Slog.v(TAG,
   10766                         "Process cur broadcast " + r + ": NOT STARTED!");
   10767                 r.receiver = null;
   10768                 r.curApp = null;
   10769                 app.curReceiver = null;
   10770             }
   10771         }
   10772 
   10773     }
   10774 
   10775     static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
   10776             Intent intent, int resultCode, String data, Bundle extras,
   10777             boolean ordered, boolean sticky) throws RemoteException {
   10778         // Send the intent to the receiver asynchronously using one-way binder calls.
   10779         if (app != null && app.thread != null) {
   10780             // If we have an app thread, do the call through that so it is
   10781             // correctly ordered with other one-way calls.
   10782             app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
   10783                     data, extras, ordered, sticky);
   10784         } else {
   10785             receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
   10786         }
   10787     }
   10788 
   10789     private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
   10790             BroadcastFilter filter, boolean ordered) {
   10791         boolean skip = false;
   10792         if (filter.requiredPermission != null) {
   10793             int perm = checkComponentPermission(filter.requiredPermission,
   10794                     r.callingPid, r.callingUid, -1);
   10795             if (perm != PackageManager.PERMISSION_GRANTED) {
   10796                 Slog.w(TAG, "Permission Denial: broadcasting "
   10797                         + r.intent.toString()
   10798                         + " from " + r.callerPackage + " (pid="
   10799                         + r.callingPid + ", uid=" + r.callingUid + ")"
   10800                         + " requires " + filter.requiredPermission
   10801                         + " due to registered receiver " + filter);
   10802                 skip = true;
   10803             }
   10804         }
   10805         if (r.requiredPermission != null) {
   10806             int perm = checkComponentPermission(r.requiredPermission,
   10807                     filter.receiverList.pid, filter.receiverList.uid, -1);
   10808             if (perm != PackageManager.PERMISSION_GRANTED) {
   10809                 Slog.w(TAG, "Permission Denial: receiving "
   10810                         + r.intent.toString()
   10811                         + " to " + filter.receiverList.app
   10812                         + " (pid=" + filter.receiverList.pid
   10813                         + ", uid=" + filter.receiverList.uid + ")"
   10814                         + " requires " + r.requiredPermission
   10815                         + " due to sender " + r.callerPackage
   10816                         + " (uid " + r.callingUid + ")");
   10817                 skip = true;
   10818             }
   10819         }
   10820 
   10821         if (!skip) {
   10822             // If this is not being sent as an ordered broadcast, then we
   10823             // don't want to touch the fields that keep track of the current
   10824             // state of ordered broadcasts.
   10825             if (ordered) {
   10826                 r.receiver = filter.receiverList.receiver.asBinder();
   10827                 r.curFilter = filter;
   10828                 filter.receiverList.curBroadcast = r;
   10829                 r.state = BroadcastRecord.CALL_IN_RECEIVE;
   10830                 if (filter.receiverList.app != null) {
   10831                     // Bump hosting application to no longer be in background
   10832                     // scheduling class.  Note that we can't do that if there
   10833                     // isn't an app...  but we can only be in that case for
   10834                     // things that directly call the IActivityManager API, which
   10835                     // are already core system stuff so don't matter for this.
   10836                     r.curApp = filter.receiverList.app;
   10837                     filter.receiverList.app.curReceiver = r;
   10838                     updateOomAdjLocked();
   10839                 }
   10840             }
   10841             try {
   10842                 if (DEBUG_BROADCAST_LIGHT) {
   10843                     int seq = r.intent.getIntExtra("seq", -1);
   10844                     Slog.i(TAG, "Delivering to " + filter
   10845                             + " (seq=" + seq + "): " + r);
   10846                 }
   10847                 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
   10848                     new Intent(r.intent), r.resultCode,
   10849                     r.resultData, r.resultExtras, r.ordered, r.initialSticky);
   10850                 if (ordered) {
   10851                     r.state = BroadcastRecord.CALL_DONE_RECEIVE;
   10852                 }
   10853             } catch (RemoteException e) {
   10854                 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
   10855                 if (ordered) {
   10856                     r.receiver = null;
   10857                     r.curFilter = null;
   10858                     filter.receiverList.curBroadcast = null;
   10859                     if (filter.receiverList.app != null) {
   10860                         filter.receiverList.app.curReceiver = null;
   10861                     }
   10862                 }
   10863             }
   10864         }
   10865     }
   10866 
   10867     private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
   10868         if (r.callingUid < 0) {
   10869             // This was from a registerReceiver() call; ignore it.
   10870             return;
   10871         }
   10872         System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
   10873                 MAX_BROADCAST_HISTORY-1);
   10874         r.finishTime = SystemClock.uptimeMillis();
   10875         mBroadcastHistory[0] = r;
   10876     }
   10877 
   10878     private final void processNextBroadcast(boolean fromMsg) {
   10879         synchronized(this) {
   10880             BroadcastRecord r;
   10881 
   10882             if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
   10883                     + mParallelBroadcasts.size() + " broadcasts, "
   10884                     + mOrderedBroadcasts.size() + " ordered broadcasts");
   10885 
   10886             updateCpuStats();
   10887 
   10888             if (fromMsg) {
   10889                 mBroadcastsScheduled = false;
   10890             }
   10891 
   10892             // First, deliver any non-serialized broadcasts right away.
   10893             while (mParallelBroadcasts.size() > 0) {
   10894                 r = mParallelBroadcasts.remove(0);
   10895                 r.dispatchTime = SystemClock.uptimeMillis();
   10896                 final int N = r.receivers.size();
   10897                 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
   10898                         + r);
   10899                 for (int i=0; i<N; i++) {
   10900                     Object target = r.receivers.get(i);
   10901                     if (DEBUG_BROADCAST)  Slog.v(TAG,
   10902                             "Delivering non-ordered to registered "
   10903                             + target + ": " + r);
   10904                     deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
   10905                 }
   10906                 addBroadcastToHistoryLocked(r);
   10907                 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
   10908                         + r);
   10909             }
   10910 
   10911             // Now take care of the next serialized one...
   10912 
   10913             // If we are waiting for a process to come up to handle the next
   10914             // broadcast, then do nothing at this point.  Just in case, we
   10915             // check that the process we're waiting for still exists.
   10916             if (mPendingBroadcast != null) {
   10917                 if (DEBUG_BROADCAST_LIGHT) {
   10918                     Slog.v(TAG, "processNextBroadcast: waiting for "
   10919                             + mPendingBroadcast.curApp);
   10920                 }
   10921 
   10922                 boolean isDead;
   10923                 synchronized (mPidsSelfLocked) {
   10924                     isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
   10925                 }
   10926                 if (!isDead) {
   10927                     // It's still alive, so keep waiting
   10928                     return;
   10929                 } else {
   10930                     Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
   10931                             + " died before responding to broadcast");
   10932                     mPendingBroadcast.state = BroadcastRecord.IDLE;
   10933                     mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
   10934                     mPendingBroadcast = null;
   10935                 }
   10936             }
   10937 
   10938             boolean looped = false;
   10939 
   10940             do {
   10941                 if (mOrderedBroadcasts.size() == 0) {
   10942                     // No more broadcasts pending, so all done!
   10943                     scheduleAppGcsLocked();
   10944                     if (looped) {
   10945                         // If we had finished the last ordered broadcast, then
   10946                         // make sure all processes have correct oom and sched
   10947                         // adjustments.
   10948                         updateOomAdjLocked();
   10949                     }
   10950                     return;
   10951                 }
   10952                 r = mOrderedBroadcasts.get(0);
   10953                 boolean forceReceive = false;
   10954 
   10955                 // Ensure that even if something goes awry with the timeout
   10956                 // detection, we catch "hung" broadcasts here, discard them,
   10957                 // and continue to make progress.
   10958                 //
   10959                 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
   10960                 // receivers don't get executed with timeouts. They're intended for
   10961                 // one time heavy lifting after system upgrades and can take
   10962                 // significant amounts of time.
   10963                 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
   10964                 if (mProcessesReady && r.dispatchTime > 0) {
   10965                     long now = SystemClock.uptimeMillis();
   10966                     if ((numReceivers > 0) &&
   10967                             (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
   10968                         Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
   10969                                 + " now=" + now
   10970                                 + " dispatchTime=" + r.dispatchTime
   10971                                 + " startTime=" + r.receiverTime
   10972                                 + " intent=" + r.intent
   10973                                 + " numReceivers=" + numReceivers
   10974                                 + " nextReceiver=" + r.nextReceiver
   10975                                 + " state=" + r.state);
   10976                         broadcastTimeoutLocked(false); // forcibly finish this broadcast
   10977                         forceReceive = true;
   10978                         r.state = BroadcastRecord.IDLE;
   10979                     }
   10980                 }
   10981 
   10982                 if (r.state != BroadcastRecord.IDLE) {
   10983                     if (DEBUG_BROADCAST) Slog.d(TAG,
   10984                             "processNextBroadcast() called when not idle (state="
   10985                             + r.state + ")");
   10986                     return;
   10987                 }
   10988 
   10989                 if (r.receivers == null || r.nextReceiver >= numReceivers
   10990                         || r.resultAbort || forceReceive) {
   10991                     // No more receivers for this broadcast!  Send the final
   10992                     // result if requested...
   10993                     if (r.resultTo != null) {
   10994                         try {
   10995                             if (DEBUG_BROADCAST) {
   10996                                 int seq = r.intent.getIntExtra("seq", -1);
   10997                                 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
   10998                                         + " seq=" + seq + " app=" + r.callerApp);
   10999                             }
   11000                             performReceiveLocked(r.callerApp, r.resultTo,
   11001                                 new Intent(r.intent), r.resultCode,
   11002                                 r.resultData, r.resultExtras, false, false);
   11003                         } catch (RemoteException e) {
   11004                             Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
   11005                         }
   11006                     }
   11007 
   11008                     if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
   11009                     cancelBroadcastTimeoutLocked();
   11010 
   11011                     if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
   11012                             + r);
   11013 
   11014                     // ... and on to the next...
   11015                     addBroadcastToHistoryLocked(r);
   11016                     mOrderedBroadcasts.remove(0);
   11017                     r = null;
   11018                     looped = true;
   11019                     continue;
   11020                 }
   11021             } while (r == null);
   11022 
   11023             // Get the next receiver...
   11024             int recIdx = r.nextReceiver++;
   11025 
   11026             // Keep track of when this receiver started, and make sure there
   11027             // is a timeout message pending to kill it if need be.
   11028             r.receiverTime = SystemClock.uptimeMillis();
   11029             if (recIdx == 0) {
   11030                 r.dispatchTime = r.receiverTime;
   11031 
   11032                 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
   11033                         + r);
   11034             }
   11035             if (! mPendingBroadcastTimeoutMessage) {
   11036                 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
   11037                 if (DEBUG_BROADCAST) Slog.v(TAG,
   11038                         "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
   11039                 setBroadcastTimeoutLocked(timeoutTime);
   11040             }
   11041 
   11042             Object nextReceiver = r.receivers.get(recIdx);
   11043             if (nextReceiver instanceof BroadcastFilter) {
   11044                 // Simple case: this is a registered receiver who gets
   11045                 // a direct call.
   11046                 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
   11047                 if (DEBUG_BROADCAST)  Slog.v(TAG,
   11048                         "Delivering ordered to registered "
   11049                         + filter + ": " + r);
   11050                 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
   11051                 if (r.receiver == null || !r.ordered) {
   11052                     // The receiver has already finished, so schedule to
   11053                     // process the next one.
   11054                     if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
   11055                             + r.ordered + " receiver=" + r.receiver);
   11056                     r.state = BroadcastRecord.IDLE;
   11057                     scheduleBroadcastsLocked();
   11058                 }
   11059                 return;
   11060             }
   11061 
   11062             // Hard case: need to instantiate the receiver, possibly
   11063             // starting its application process to host it.
   11064 
   11065             ResolveInfo info =
   11066                 (ResolveInfo)nextReceiver;
   11067 
   11068             boolean skip = false;
   11069             int perm = checkComponentPermission(info.activityInfo.permission,
   11070                     r.callingPid, r.callingUid,
   11071                     info.activityInfo.exported
   11072                             ? -1 : info.activityInfo.applicationInfo.uid);
   11073             if (perm != PackageManager.PERMISSION_GRANTED) {
   11074                 Slog.w(TAG, "Permission Denial: broadcasting "
   11075                         + r.intent.toString()
   11076                         + " from " + r.callerPackage + " (pid=" + r.callingPid
   11077                         + ", uid=" + r.callingUid + ")"
   11078                         + " requires " + info.activityInfo.permission
   11079                         + " due to receiver " + info.activityInfo.packageName
   11080                         + "/" + info.activityInfo.name);
   11081                 skip = true;
   11082             }
   11083             if (r.callingUid != Process.SYSTEM_UID &&
   11084                 r.requiredPermission != null) {
   11085                 try {
   11086                     perm = AppGlobals.getPackageManager().
   11087                             checkPermission(r.requiredPermission,
   11088                                     info.activityInfo.applicationInfo.packageName);
   11089                 } catch (RemoteException e) {
   11090                     perm = PackageManager.PERMISSION_DENIED;
   11091                 }
   11092                 if (perm != PackageManager.PERMISSION_GRANTED) {
   11093                     Slog.w(TAG, "Permission Denial: receiving "
   11094                             + r.intent + " to "
   11095                             + info.activityInfo.applicationInfo.packageName
   11096                             + " requires " + r.requiredPermission
   11097                             + " due to sender " + r.callerPackage
   11098                             + " (uid " + r.callingUid + ")");
   11099                     skip = true;
   11100                 }
   11101             }
   11102             if (r.curApp != null && r.curApp.crashing) {
   11103                 // If the target process is crashing, just skip it.
   11104                 if (DEBUG_BROADCAST)  Slog.v(TAG,
   11105                         "Skipping deliver ordered " + r + " to " + r.curApp
   11106                         + ": process crashing");
   11107                 skip = true;
   11108             }
   11109 
   11110             if (skip) {
   11111                 if (DEBUG_BROADCAST)  Slog.v(TAG,
   11112                         "Skipping delivery of ordered " + r + " for whatever reason");
   11113                 r.receiver = null;
   11114                 r.curFilter = null;
   11115                 r.state = BroadcastRecord.IDLE;
   11116                 scheduleBroadcastsLocked();
   11117                 return;
   11118             }
   11119 
   11120             r.state = BroadcastRecord.APP_RECEIVE;
   11121             String targetProcess = info.activityInfo.processName;
   11122             r.curComponent = new ComponentName(
   11123                     info.activityInfo.applicationInfo.packageName,
   11124                     info.activityInfo.name);
   11125             r.curReceiver = info.activityInfo;
   11126 
   11127             // Is this receiver's application already running?
   11128             ProcessRecord app = getProcessRecordLocked(targetProcess,
   11129                     info.activityInfo.applicationInfo.uid);
   11130             if (app != null && app.thread != null) {
   11131                 try {
   11132                     processCurBroadcastLocked(r, app);
   11133                     return;
   11134                 } catch (RemoteException e) {
   11135                     Slog.w(TAG, "Exception when sending broadcast to "
   11136                           + r.curComponent, e);
   11137                 }
   11138 
   11139                 // If a dead object exception was thrown -- fall through to
   11140                 // restart the application.
   11141             }
   11142 
   11143             // Not running -- get it started, to be executed when the app comes up.
   11144             if (DEBUG_BROADCAST)  Slog.v(TAG,
   11145                     "Need to start app " + targetProcess + " for broadcast " + r);
   11146             if ((r.curApp=startProcessLocked(targetProcess,
   11147                     info.activityInfo.applicationInfo, true,
   11148                     r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
   11149                     "broadcast", r.curComponent,
   11150                     (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
   11151                             == null) {
   11152                 // Ah, this recipient is unavailable.  Finish it if necessary,
   11153                 // and mark the broadcast record as ready for the next.
   11154                 Slog.w(TAG, "Unable to launch app "
   11155                         + info.activityInfo.applicationInfo.packageName + "/"
   11156                         + info.activityInfo.applicationInfo.uid + " for broadcast "
   11157                         + r.intent + ": process is bad");
   11158                 logBroadcastReceiverDiscardLocked(r);
   11159                 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
   11160                         r.resultExtras, r.resultAbort, true);
   11161                 scheduleBroadcastsLocked();
   11162                 r.state = BroadcastRecord.IDLE;
   11163                 return;
   11164             }
   11165 
   11166             mPendingBroadcast = r;
   11167             mPendingBroadcastRecvIndex = recIdx;
   11168         }
   11169     }
   11170 
   11171     // =========================================================
   11172     // INSTRUMENTATION
   11173     // =========================================================
   11174 
   11175     public boolean startInstrumentation(ComponentName className,
   11176             String profileFile, int flags, Bundle arguments,
   11177             IInstrumentationWatcher watcher) {
   11178         // Refuse possible leaked file descriptors
   11179         if (arguments != null && arguments.hasFileDescriptors()) {
   11180             throw new IllegalArgumentException("File descriptors passed in Bundle");
   11181         }
   11182 
   11183         synchronized(this) {
   11184             InstrumentationInfo ii = null;
   11185             ApplicationInfo ai = null;
   11186             try {
   11187                 ii = mContext.getPackageManager().getInstrumentationInfo(
   11188                     className, STOCK_PM_FLAGS);
   11189                 ai = mContext.getPackageManager().getApplicationInfo(
   11190                     ii.targetPackage, STOCK_PM_FLAGS);
   11191             } catch (PackageManager.NameNotFoundException e) {
   11192             }
   11193             if (ii == null) {
   11194                 reportStartInstrumentationFailure(watcher, className,
   11195                         "Unable to find instrumentation info for: " + className);
   11196                 return false;
   11197             }
   11198             if (ai == null) {
   11199                 reportStartInstrumentationFailure(watcher, className,
   11200                         "Unable to find instrumentation target package: " + ii.targetPackage);
   11201                 return false;
   11202             }
   11203 
   11204             int match = mContext.getPackageManager().checkSignatures(
   11205                     ii.targetPackage, ii.packageName);
   11206             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
   11207                 String msg = "Permission Denial: starting instrumentation "
   11208                         + className + " from pid="
   11209                         + Binder.getCallingPid()
   11210                         + ", uid=" + Binder.getCallingPid()
   11211                         + " not allowed because package " + ii.packageName
   11212                         + " does not have a signature matching the target "
   11213                         + ii.targetPackage;
   11214                 reportStartInstrumentationFailure(watcher, className, msg);
   11215                 throw new SecurityException(msg);
   11216             }
   11217 
   11218             final long origId = Binder.clearCallingIdentity();
   11219             forceStopPackageLocked(ii.targetPackage, -1, true, false, true);
   11220             ProcessRecord app = addAppLocked(ai);
   11221             app.instrumentationClass = className;
   11222             app.instrumentationInfo = ai;
   11223             app.instrumentationProfileFile = profileFile;
   11224             app.instrumentationArguments = arguments;
   11225             app.instrumentationWatcher = watcher;
   11226             app.instrumentationResultClass = className;
   11227             Binder.restoreCallingIdentity(origId);
   11228         }
   11229 
   11230         return true;
   11231     }
   11232 
   11233     /**
   11234      * Report errors that occur while attempting to start Instrumentation.  Always writes the
   11235      * error to the logs, but if somebody is watching, send the report there too.  This enables
   11236      * the "am" command to report errors with more information.
   11237      *
   11238      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
   11239      * @param cn The component name of the instrumentation.
   11240      * @param report The error report.
   11241      */
   11242     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
   11243             ComponentName cn, String report) {
   11244         Slog.w(TAG, report);
   11245         try {
   11246             if (watcher != null) {
   11247                 Bundle results = new Bundle();
   11248                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
   11249                 results.putString("Error", report);
   11250                 watcher.instrumentationStatus(cn, -1, results);
   11251             }
   11252         } catch (RemoteException e) {
   11253             Slog.w(TAG, e);
   11254         }
   11255     }
   11256 
   11257     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
   11258         if (app.instrumentationWatcher != null) {
   11259             try {
   11260                 // NOTE:  IInstrumentationWatcher *must* be oneway here
   11261                 app.instrumentationWatcher.instrumentationFinished(
   11262                     app.instrumentationClass,
   11263                     resultCode,
   11264                     results);
   11265             } catch (RemoteException e) {
   11266             }
   11267         }
   11268         app.instrumentationWatcher = null;
   11269         app.instrumentationClass = null;
   11270         app.instrumentationInfo = null;
   11271         app.instrumentationProfileFile = null;
   11272         app.instrumentationArguments = null;
   11273 
   11274         forceStopPackageLocked(app.processName, -1, false, false, true);
   11275     }
   11276 
   11277     public void finishInstrumentation(IApplicationThread target,
   11278             int resultCode, Bundle results) {
   11279         // Refuse possible leaked file descriptors
   11280         if (results != null && results.hasFileDescriptors()) {
   11281             throw new IllegalArgumentException("File descriptors passed in Intent");
   11282         }
   11283 
   11284         synchronized(this) {
   11285             ProcessRecord app = getRecordForAppLocked(target);
   11286             if (app == null) {
   11287                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
   11288                 return;
   11289             }
   11290             final long origId = Binder.clearCallingIdentity();
   11291             finishInstrumentationLocked(app, resultCode, results);
   11292             Binder.restoreCallingIdentity(origId);
   11293         }
   11294     }
   11295 
   11296     // =========================================================
   11297     // CONFIGURATION
   11298     // =========================================================
   11299 
   11300     public ConfigurationInfo getDeviceConfigurationInfo() {
   11301         ConfigurationInfo config = new ConfigurationInfo();
   11302         synchronized (this) {
   11303             config.reqTouchScreen = mConfiguration.touchscreen;
   11304             config.reqKeyboardType = mConfiguration.keyboard;
   11305             config.reqNavigation = mConfiguration.navigation;
   11306             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
   11307                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
   11308                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
   11309             }
   11310             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
   11311                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
   11312                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
   11313             }
   11314             config.reqGlEsVersion = GL_ES_VERSION;
   11315         }
   11316         return config;
   11317     }
   11318 
   11319     public Configuration getConfiguration() {
   11320         Configuration ci;
   11321         synchronized(this) {
   11322             ci = new Configuration(mConfiguration);
   11323         }
   11324         return ci;
   11325     }
   11326 
   11327     public void updateConfiguration(Configuration values) {
   11328         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   11329                 "updateConfiguration()");
   11330 
   11331         synchronized(this) {
   11332             if (values == null && mWindowManager != null) {
   11333                 // sentinel: fetch the current configuration from the window manager
   11334                 values = mWindowManager.computeNewConfiguration();
   11335             }
   11336 
   11337             final long origId = Binder.clearCallingIdentity();
   11338             updateConfigurationLocked(values, null);
   11339             Binder.restoreCallingIdentity(origId);
   11340         }
   11341     }
   11342 
   11343     /**
   11344      * Do either or both things: (1) change the current configuration, and (2)
   11345      * make sure the given activity is running with the (now) current
   11346      * configuration.  Returns true if the activity has been left running, or
   11347      * false if <var>starting</var> is being destroyed to match the new
   11348      * configuration.
   11349      */
   11350     public boolean updateConfigurationLocked(Configuration values,
   11351             ActivityRecord starting) {
   11352         int changes = 0;
   11353 
   11354         boolean kept = true;
   11355 
   11356         if (values != null) {
   11357             Configuration newConfig = new Configuration(mConfiguration);
   11358             changes = newConfig.updateFrom(values);
   11359             if (changes != 0) {
   11360                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
   11361                     Slog.i(TAG, "Updating configuration to: " + values);
   11362                 }
   11363 
   11364                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
   11365 
   11366                 if (values.locale != null) {
   11367                     saveLocaleLocked(values.locale,
   11368                                      !values.locale.equals(mConfiguration.locale),
   11369                                      values.userSetLocale);
   11370                 }
   11371 
   11372                 mConfigurationSeq++;
   11373                 if (mConfigurationSeq <= 0) {
   11374                     mConfigurationSeq = 1;
   11375                 }
   11376                 newConfig.seq = mConfigurationSeq;
   11377                 mConfiguration = newConfig;
   11378                 Slog.i(TAG, "Config changed: " + newConfig);
   11379 
   11380                 AttributeCache ac = AttributeCache.instance();
   11381                 if (ac != null) {
   11382                     ac.updateConfiguration(mConfiguration);
   11383                 }
   11384 
   11385                 if (Settings.System.hasInterestingConfigurationChanges(changes)) {
   11386                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
   11387                     msg.obj = new Configuration(mConfiguration);
   11388                     mHandler.sendMessage(msg);
   11389                 }
   11390 
   11391                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   11392                     ProcessRecord app = mLruProcesses.get(i);
   11393                     try {
   11394                         if (app.thread != null) {
   11395                             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
   11396                                     + app.processName + " new config " + mConfiguration);
   11397                             app.thread.scheduleConfigurationChanged(mConfiguration);
   11398                         }
   11399                     } catch (Exception e) {
   11400                     }
   11401                 }
   11402                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
   11403                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   11404                         | Intent.FLAG_RECEIVER_REPLACE_PENDING);
   11405                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
   11406                         null, false, false, MY_PID, Process.SYSTEM_UID);
   11407                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
   11408                     broadcastIntentLocked(null, null,
   11409                             new Intent(Intent.ACTION_LOCALE_CHANGED),
   11410                             null, null, 0, null, null,
   11411                             null, false, false, MY_PID, Process.SYSTEM_UID);
   11412                 }
   11413             }
   11414         }
   11415 
   11416         if (changes != 0 && starting == null) {
   11417             // If the configuration changed, and the caller is not already
   11418             // in the process of starting an activity, then find the top
   11419             // activity to check if its configuration needs to change.
   11420             starting = mMainStack.topRunningActivityLocked(null);
   11421         }
   11422 
   11423         if (starting != null) {
   11424             kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
   11425             if (kept) {
   11426                 // If this didn't result in the starting activity being
   11427                 // destroyed, then we need to make sure at this point that all
   11428                 // other activities are made visible.
   11429                 if (DEBUG_SWITCH) Slog.i(TAG, "Config didn't destroy " + starting
   11430                         + ", ensuring others are correct.");
   11431                 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
   11432             }
   11433         }
   11434 
   11435         if (values != null && mWindowManager != null) {
   11436             mWindowManager.setNewConfiguration(mConfiguration);
   11437         }
   11438 
   11439         return kept;
   11440     }
   11441 
   11442     /**
   11443      * Save the locale.  You must be inside a synchronized (this) block.
   11444      */
   11445     private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
   11446         if(isDiff) {
   11447             SystemProperties.set("user.language", l.getLanguage());
   11448             SystemProperties.set("user.region", l.getCountry());
   11449         }
   11450 
   11451         if(isPersist) {
   11452             SystemProperties.set("persist.sys.language", l.getLanguage());
   11453             SystemProperties.set("persist.sys.country", l.getCountry());
   11454             SystemProperties.set("persist.sys.localevar", l.getVariant());
   11455         }
   11456     }
   11457 
   11458     // =========================================================
   11459     // LIFETIME MANAGEMENT
   11460     // =========================================================
   11461 
   11462     private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
   11463             ProcessRecord TOP_APP, boolean recursed) {
   11464         if (mAdjSeq == app.adjSeq) {
   11465             // This adjustment has already been computed.  If we are calling
   11466             // from the top, we may have already computed our adjustment with
   11467             // an earlier hidden adjustment that isn't really for us... if
   11468             // so, use the new hidden adjustment.
   11469             if (!recursed && app.hidden) {
   11470                 app.curAdj = hiddenAdj;
   11471             }
   11472             return app.curAdj;
   11473         }
   11474 
   11475         if (app.thread == null) {
   11476             app.adjSeq = mAdjSeq;
   11477             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   11478             return (app.curAdj=EMPTY_APP_ADJ);
   11479         }
   11480 
   11481         if (app.maxAdj <= FOREGROUND_APP_ADJ) {
   11482             // The max adjustment doesn't allow this app to be anything
   11483             // below foreground, so it is not worth doing work for it.
   11484             app.adjType = "fixed";
   11485             app.adjSeq = mAdjSeq;
   11486             app.curRawAdj = app.maxAdj;
   11487             app.keeping = true;
   11488             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
   11489             return (app.curAdj=app.maxAdj);
   11490        }
   11491 
   11492         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
   11493         app.adjSource = null;
   11494         app.adjTarget = null;
   11495         app.keeping = false;
   11496         app.empty = false;
   11497         app.hidden = false;
   11498 
   11499         // Determine the importance of the process, starting with most
   11500         // important to least, and assign an appropriate OOM adjustment.
   11501         int adj;
   11502         int schedGroup;
   11503         int N;
   11504         if (app == TOP_APP) {
   11505             // The last app on the list is the foreground app.
   11506             adj = FOREGROUND_APP_ADJ;
   11507             schedGroup = Process.THREAD_GROUP_DEFAULT;
   11508             app.adjType = "top-activity";
   11509         } else if (app.instrumentationClass != null) {
   11510             // Don't want to kill running instrumentation.
   11511             adj = FOREGROUND_APP_ADJ;
   11512             schedGroup = Process.THREAD_GROUP_DEFAULT;
   11513             app.adjType = "instrumentation";
   11514         } else if (app.curReceiver != null ||
   11515                 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
   11516             // An app that is currently receiving a broadcast also
   11517             // counts as being in the foreground.
   11518             adj = FOREGROUND_APP_ADJ;
   11519             schedGroup = Process.THREAD_GROUP_DEFAULT;
   11520             app.adjType = "broadcast";
   11521         } else if (app.executingServices.size() > 0) {
   11522             // An app that is currently executing a service callback also
   11523             // counts as being in the foreground.
   11524             adj = FOREGROUND_APP_ADJ;
   11525             schedGroup = Process.THREAD_GROUP_DEFAULT;
   11526             app.adjType = "exec-service";
   11527         } else if (app.foregroundServices) {
   11528             // The user is aware of this app, so make it visible.
   11529             adj = PERCEPTIBLE_APP_ADJ;
   11530             schedGroup = Process.THREAD_GROUP_DEFAULT;
   11531             app.adjType = "foreground-service";
   11532         } else if (app.forcingToForeground != null) {
   11533             // The user is aware of this app, so make it visible.
   11534             adj = PERCEPTIBLE_APP_ADJ;
   11535             schedGroup = Process.THREAD_GROUP_DEFAULT;
   11536             app.adjType = "force-foreground";
   11537             app.adjSource = app.forcingToForeground;
   11538         } else if (app == mHeavyWeightProcess) {
   11539             // We don't want to kill the current heavy-weight process.
   11540             adj = HEAVY_WEIGHT_APP_ADJ;
   11541             schedGroup = Process.THREAD_GROUP_DEFAULT;
   11542             app.adjType = "heavy";
   11543         } else if (app == mHomeProcess) {
   11544             // This process is hosting what we currently consider to be the
   11545             // home app, so we don't want to let it go into the background.
   11546             adj = HOME_APP_ADJ;
   11547             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   11548             app.adjType = "home";
   11549         } else if ((N=app.activities.size()) != 0) {
   11550             // This app is in the background with paused activities.
   11551             app.hidden = true;
   11552             adj = hiddenAdj;
   11553             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   11554             app.adjType = "bg-activities";
   11555             N = app.activities.size();
   11556             for (int j=0; j<N; j++) {
   11557                 if (app.activities.get(j).visible) {
   11558                     // This app has a visible activity!
   11559                     app.hidden = false;
   11560                     adj = VISIBLE_APP_ADJ;
   11561                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   11562                     app.adjType = "visible";
   11563                     break;
   11564                 }
   11565             }
   11566         } else {
   11567             // A very not-needed process.  If this is lower in the lru list,
   11568             // we will push it in to the empty bucket.
   11569             app.hidden = true;
   11570             app.empty = true;
   11571             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   11572             adj = hiddenAdj;
   11573             app.adjType = "bg-empty";
   11574         }
   11575 
   11576         //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
   11577 
   11578         // By default, we use the computed adjustment.  It may be changed if
   11579         // there are applications dependent on our services or providers, but
   11580         // this gives us a baseline and makes sure we don't get into an
   11581         // infinite recursion.
   11582         app.adjSeq = mAdjSeq;
   11583         app.curRawAdj = adj;
   11584 
   11585         if (mBackupTarget != null && app == mBackupTarget.app) {
   11586             // If possible we want to avoid killing apps while they're being backed up
   11587             if (adj > BACKUP_APP_ADJ) {
   11588                 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
   11589                 adj = BACKUP_APP_ADJ;
   11590                 app.adjType = "backup";
   11591                 app.hidden = false;
   11592             }
   11593         }
   11594 
   11595         if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
   11596                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   11597             final long now = SystemClock.uptimeMillis();
   11598             // This process is more important if the top activity is
   11599             // bound to the service.
   11600             Iterator<ServiceRecord> jt = app.services.iterator();
   11601             while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
   11602                 ServiceRecord s = jt.next();
   11603                 if (s.startRequested) {
   11604                     if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
   11605                         // This service has seen some activity within
   11606                         // recent memory, so we will keep its process ahead
   11607                         // of the background processes.
   11608                         if (adj > SECONDARY_SERVER_ADJ) {
   11609                             adj = SECONDARY_SERVER_ADJ;
   11610                             app.adjType = "started-services";
   11611                             app.hidden = false;
   11612                         }
   11613                     }
   11614                     // If we have let the service slide into the background
   11615                     // state, still have some text describing what it is doing
   11616                     // even though the service no longer has an impact.
   11617                     if (adj > SECONDARY_SERVER_ADJ) {
   11618                         app.adjType = "started-bg-services";
   11619                     }
   11620                     // Don't kill this process because it is doing work; it
   11621                     // has said it is doing work.
   11622                     app.keeping = true;
   11623                 }
   11624                 if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
   11625                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   11626                     Iterator<ArrayList<ConnectionRecord>> kt
   11627                             = s.connections.values().iterator();
   11628                     while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
   11629                         ArrayList<ConnectionRecord> clist = kt.next();
   11630                         for (int i=0; i<clist.size() && adj > FOREGROUND_APP_ADJ; i++) {
   11631                             // XXX should compute this based on the max of
   11632                             // all connected clients.
   11633                             ConnectionRecord cr = clist.get(i);
   11634                             if (cr.binding.client == app) {
   11635                                 // Binding to ourself is not interesting.
   11636                                 continue;
   11637                             }
   11638                             if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
   11639                                 ProcessRecord client = cr.binding.client;
   11640                                 int myHiddenAdj = hiddenAdj;
   11641                                 if (myHiddenAdj > client.hiddenAdj) {
   11642                                     if (client.hiddenAdj >= VISIBLE_APP_ADJ) {
   11643                                         myHiddenAdj = client.hiddenAdj;
   11644                                     } else {
   11645                                         myHiddenAdj = VISIBLE_APP_ADJ;
   11646                                     }
   11647                                 }
   11648                                 int clientAdj = computeOomAdjLocked(
   11649                                     client, myHiddenAdj, TOP_APP, true);
   11650                                 if (adj > clientAdj) {
   11651                                     adj = clientAdj >= VISIBLE_APP_ADJ
   11652                                             ? clientAdj : VISIBLE_APP_ADJ;
   11653                                     if (!client.hidden) {
   11654                                         app.hidden = false;
   11655                                     }
   11656                                     if (client.keeping) {
   11657                                         app.keeping = true;
   11658                                     }
   11659                                     app.adjType = "service";
   11660                                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   11661                                             .REASON_SERVICE_IN_USE;
   11662                                     app.adjSource = cr.binding.client;
   11663                                     app.adjTarget = s.name;
   11664                                 }
   11665                                 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   11666                                     if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   11667                                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   11668                                     }
   11669                                 }
   11670                             }
   11671                             ActivityRecord a = cr.activity;
   11672                             //if (a != null) {
   11673                             //    Slog.i(TAG, "Connection to " + a ": state=" + a.state);
   11674                             //}
   11675                             if (a != null && adj > FOREGROUND_APP_ADJ &&
   11676                                     (a.state == ActivityState.RESUMED
   11677                                      || a.state == ActivityState.PAUSING)) {
   11678                                 adj = FOREGROUND_APP_ADJ;
   11679                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   11680                                 app.hidden = false;
   11681                                 app.adjType = "service";
   11682                                 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   11683                                         .REASON_SERVICE_IN_USE;
   11684                                 app.adjSource = a;
   11685                                 app.adjTarget = s.name;
   11686                             }
   11687                         }
   11688                     }
   11689                 }
   11690             }
   11691 
   11692             // Finally, if this process has active services running in it, we
   11693             // would like to avoid killing it unless it would prevent the current
   11694             // application from running.  By default we put the process in
   11695             // with the rest of the background processes; as we scan through
   11696             // its services we may bump it up from there.
   11697             if (adj > hiddenAdj) {
   11698                 adj = hiddenAdj;
   11699                 app.hidden = false;
   11700                 app.adjType = "bg-services";
   11701             }
   11702         }
   11703 
   11704         if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ
   11705                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   11706             Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
   11707             while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ
   11708                     || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   11709                 ContentProviderRecord cpr = jt.next();
   11710                 if (cpr.clients.size() != 0) {
   11711                     Iterator<ProcessRecord> kt = cpr.clients.iterator();
   11712                     while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
   11713                         ProcessRecord client = kt.next();
   11714                         if (client == app) {
   11715                             // Being our own client is not interesting.
   11716                             continue;
   11717                         }
   11718                         int myHiddenAdj = hiddenAdj;
   11719                         if (myHiddenAdj > client.hiddenAdj) {
   11720                             if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
   11721                                 myHiddenAdj = client.hiddenAdj;
   11722                             } else {
   11723                                 myHiddenAdj = FOREGROUND_APP_ADJ;
   11724                             }
   11725                         }
   11726                         int clientAdj = computeOomAdjLocked(
   11727                             client, myHiddenAdj, TOP_APP, true);
   11728                         if (adj > clientAdj) {
   11729                             adj = clientAdj > FOREGROUND_APP_ADJ
   11730                                     ? clientAdj : FOREGROUND_APP_ADJ;
   11731                             if (!client.hidden) {
   11732                                 app.hidden = false;
   11733                             }
   11734                             if (client.keeping) {
   11735                                 app.keeping = true;
   11736                             }
   11737                             app.adjType = "provider";
   11738                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   11739                                     .REASON_PROVIDER_IN_USE;
   11740                             app.adjSource = client;
   11741                             app.adjTarget = cpr.name;
   11742                         }
   11743                         if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   11744                             schedGroup = Process.THREAD_GROUP_DEFAULT;
   11745                         }
   11746                     }
   11747                 }
   11748                 // If the provider has external (non-framework) process
   11749                 // dependencies, ensure that its adjustment is at least
   11750                 // FOREGROUND_APP_ADJ.
   11751                 if (cpr.externals != 0) {
   11752                     if (adj > FOREGROUND_APP_ADJ) {
   11753                         adj = FOREGROUND_APP_ADJ;
   11754                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   11755                         app.hidden = false;
   11756                         app.keeping = true;
   11757                         app.adjType = "provider";
   11758                         app.adjTarget = cpr.name;
   11759                     }
   11760                 }
   11761             }
   11762         }
   11763 
   11764         app.curRawAdj = adj;
   11765 
   11766         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
   11767         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
   11768         if (adj > app.maxAdj) {
   11769             adj = app.maxAdj;
   11770             if (app.maxAdj <= PERCEPTIBLE_APP_ADJ) {
   11771                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   11772             }
   11773         }
   11774         if (adj < HIDDEN_APP_MIN_ADJ) {
   11775             app.keeping = true;
   11776         }
   11777 
   11778         app.curAdj = adj;
   11779         app.curSchedGroup = schedGroup;
   11780 
   11781         return adj;
   11782     }
   11783 
   11784     /**
   11785      * Ask a given process to GC right now.
   11786      */
   11787     final void performAppGcLocked(ProcessRecord app) {
   11788         try {
   11789             app.lastRequestedGc = SystemClock.uptimeMillis();
   11790             if (app.thread != null) {
   11791                 if (app.reportLowMemory) {
   11792                     app.reportLowMemory = false;
   11793                     app.thread.scheduleLowMemory();
   11794                 } else {
   11795                     app.thread.processInBackground();
   11796                 }
   11797             }
   11798         } catch (Exception e) {
   11799             // whatever.
   11800         }
   11801     }
   11802 
   11803     /**
   11804      * Returns true if things are idle enough to perform GCs.
   11805      */
   11806     private final boolean canGcNowLocked() {
   11807         return mParallelBroadcasts.size() == 0
   11808                 && mOrderedBroadcasts.size() == 0
   11809                 && (mSleeping || (mMainStack.mResumedActivity != null &&
   11810                         mMainStack.mResumedActivity.idle));
   11811     }
   11812 
   11813     /**
   11814      * Perform GCs on all processes that are waiting for it, but only
   11815      * if things are idle.
   11816      */
   11817     final void performAppGcsLocked() {
   11818         final int N = mProcessesToGc.size();
   11819         if (N <= 0) {
   11820             return;
   11821         }
   11822         if (canGcNowLocked()) {
   11823             while (mProcessesToGc.size() > 0) {
   11824                 ProcessRecord proc = mProcessesToGc.remove(0);
   11825                 if (proc.curRawAdj > PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
   11826                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
   11827                             <= SystemClock.uptimeMillis()) {
   11828                         // To avoid spamming the system, we will GC processes one
   11829                         // at a time, waiting a few seconds between each.
   11830                         performAppGcLocked(proc);
   11831                         scheduleAppGcsLocked();
   11832                         return;
   11833                     } else {
   11834                         // It hasn't been long enough since we last GCed this
   11835                         // process...  put it in the list to wait for its time.
   11836                         addProcessToGcListLocked(proc);
   11837                         break;
   11838                     }
   11839                 }
   11840             }
   11841 
   11842             scheduleAppGcsLocked();
   11843         }
   11844     }
   11845 
   11846     /**
   11847      * If all looks good, perform GCs on all processes waiting for them.
   11848      */
   11849     final void performAppGcsIfAppropriateLocked() {
   11850         if (canGcNowLocked()) {
   11851             performAppGcsLocked();
   11852             return;
   11853         }
   11854         // Still not idle, wait some more.
   11855         scheduleAppGcsLocked();
   11856     }
   11857 
   11858     /**
   11859      * Schedule the execution of all pending app GCs.
   11860      */
   11861     final void scheduleAppGcsLocked() {
   11862         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
   11863 
   11864         if (mProcessesToGc.size() > 0) {
   11865             // Schedule a GC for the time to the next process.
   11866             ProcessRecord proc = mProcessesToGc.get(0);
   11867             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
   11868 
   11869             long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL;
   11870             long now = SystemClock.uptimeMillis();
   11871             if (when < (now+GC_TIMEOUT)) {
   11872                 when = now + GC_TIMEOUT;
   11873             }
   11874             mHandler.sendMessageAtTime(msg, when);
   11875         }
   11876     }
   11877 
   11878     /**
   11879      * Add a process to the array of processes waiting to be GCed.  Keeps the
   11880      * list in sorted order by the last GC time.  The process can't already be
   11881      * on the list.
   11882      */
   11883     final void addProcessToGcListLocked(ProcessRecord proc) {
   11884         boolean added = false;
   11885         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
   11886             if (mProcessesToGc.get(i).lastRequestedGc <
   11887                     proc.lastRequestedGc) {
   11888                 added = true;
   11889                 mProcessesToGc.add(i+1, proc);
   11890                 break;
   11891             }
   11892         }
   11893         if (!added) {
   11894             mProcessesToGc.add(0, proc);
   11895         }
   11896     }
   11897 
   11898     /**
   11899      * Set up to ask a process to GC itself.  This will either do it
   11900      * immediately, or put it on the list of processes to gc the next
   11901      * time things are idle.
   11902      */
   11903     final void scheduleAppGcLocked(ProcessRecord app) {
   11904         long now = SystemClock.uptimeMillis();
   11905         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
   11906             return;
   11907         }
   11908         if (!mProcessesToGc.contains(app)) {
   11909             addProcessToGcListLocked(app);
   11910             scheduleAppGcsLocked();
   11911         }
   11912     }
   11913 
   11914     final void checkExcessivePowerUsageLocked(boolean doKills) {
   11915         updateCpuStatsNow();
   11916 
   11917         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   11918         boolean doWakeKills = doKills;
   11919         boolean doCpuKills = doKills;
   11920         if (mLastPowerCheckRealtime == 0) {
   11921             doWakeKills = false;
   11922         }
   11923         if (mLastPowerCheckUptime == 0) {
   11924             doCpuKills = false;
   11925         }
   11926         if (stats.isScreenOn()) {
   11927             doWakeKills = false;
   11928         }
   11929         final long curRealtime = SystemClock.elapsedRealtime();
   11930         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
   11931         final long curUptime = SystemClock.uptimeMillis();
   11932         final long uptimeSince = curUptime - mLastPowerCheckUptime;
   11933         mLastPowerCheckRealtime = curRealtime;
   11934         mLastPowerCheckUptime = curUptime;
   11935         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
   11936             doWakeKills = false;
   11937         }
   11938         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
   11939             doCpuKills = false;
   11940         }
   11941         int i = mLruProcesses.size();
   11942         while (i > 0) {
   11943             i--;
   11944             ProcessRecord app = mLruProcesses.get(i);
   11945             if (!app.keeping) {
   11946                 long wtime;
   11947                 synchronized (stats) {
   11948                     wtime = stats.getProcessWakeTime(app.info.uid,
   11949                             app.pid, curRealtime);
   11950                 }
   11951                 long wtimeUsed = wtime - app.lastWakeTime;
   11952                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
   11953                 if (DEBUG_POWER) {
   11954                     StringBuilder sb = new StringBuilder(128);
   11955                     sb.append("Wake for ");
   11956                     app.toShortString(sb);
   11957                     sb.append(": over ");
   11958                     TimeUtils.formatDuration(realtimeSince, sb);
   11959                     sb.append(" used ");
   11960                     TimeUtils.formatDuration(wtimeUsed, sb);
   11961                     sb.append(" (");
   11962                     sb.append((wtimeUsed*100)/realtimeSince);
   11963                     sb.append("%)");
   11964                     Slog.i(TAG, sb.toString());
   11965                     sb.setLength(0);
   11966                     sb.append("CPU for ");
   11967                     app.toShortString(sb);
   11968                     sb.append(": over ");
   11969                     TimeUtils.formatDuration(uptimeSince, sb);
   11970                     sb.append(" used ");
   11971                     TimeUtils.formatDuration(cputimeUsed, sb);
   11972                     sb.append(" (");
   11973                     sb.append((cputimeUsed*100)/uptimeSince);
   11974                     sb.append("%)");
   11975                     Slog.i(TAG, sb.toString());
   11976                 }
   11977                 // If a process has held a wake lock for more
   11978                 // than 50% of the time during this period,
   11979                 // that sounds pad.  Kill!
   11980                 if (doWakeKills && realtimeSince > 0
   11981                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
   11982                     synchronized (stats) {
   11983                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
   11984                                 realtimeSince, wtimeUsed);
   11985                     }
   11986                     Slog.w(TAG, "Excessive wake lock in " + app.processName
   11987                             + " (pid " + app.pid + "): held " + wtimeUsed
   11988                             + " during " + realtimeSince);
   11989                     EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   11990                             app.processName, app.setAdj, "excessive wake lock");
   11991                     Process.killProcessQuiet(app.pid);
   11992                 } else if (doCpuKills && uptimeSince > 0
   11993                         && ((cputimeUsed*100)/uptimeSince) >= 50) {
   11994                     synchronized (stats) {
   11995                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
   11996                                 uptimeSince, cputimeUsed);
   11997                     }
   11998                     Slog.w(TAG, "Excessive CPU in " + app.processName
   11999                             + " (pid " + app.pid + "): used " + cputimeUsed
   12000                             + " during " + uptimeSince);
   12001                     EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   12002                             app.processName, app.setAdj, "excessive cpu");
   12003                     Process.killProcessQuiet(app.pid);
   12004                 } else {
   12005                     app.lastWakeTime = wtime;
   12006                     app.lastCpuTime = app.curCpuTime;
   12007                 }
   12008             }
   12009         }
   12010     }
   12011 
   12012     private final boolean updateOomAdjLocked(
   12013         ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
   12014         app.hiddenAdj = hiddenAdj;
   12015 
   12016         if (app.thread == null) {
   12017             return true;
   12018         }
   12019 
   12020         final boolean wasKeeping = app.keeping;
   12021 
   12022         int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
   12023 
   12024         if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) {
   12025             if (app.curRawAdj != app.setRawAdj) {
   12026                 if (app.curRawAdj > FOREGROUND_APP_ADJ
   12027                         && app.setRawAdj <= FOREGROUND_APP_ADJ) {
   12028                     // If this app is transitioning from foreground to
   12029                     // non-foreground, have it do a gc.
   12030                     scheduleAppGcLocked(app);
   12031                 } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
   12032                         && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
   12033                     // Likewise do a gc when an app is moving in to the
   12034                     // background (such as a service stopping).
   12035                     scheduleAppGcLocked(app);
   12036                 }
   12037 
   12038                 if (wasKeeping && !app.keeping) {
   12039                     // This app is no longer something we want to keep.  Note
   12040                     // its current wake lock time to later know to kill it if
   12041                     // it is not behaving well.
   12042                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   12043                     synchronized (stats) {
   12044                         app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
   12045                                 app.pid, SystemClock.elapsedRealtime());
   12046                     }
   12047                     app.lastCpuTime = app.curCpuTime;
   12048                 }
   12049 
   12050                 app.setRawAdj = app.curRawAdj;
   12051             }
   12052             if (adj != app.setAdj) {
   12053                 if (Process.setOomAdj(app.pid, adj)) {
   12054                     if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
   12055                         TAG, "Set app " + app.processName +
   12056                         " oom adj to " + adj);
   12057                     app.setAdj = adj;
   12058                 } else {
   12059                     return false;
   12060                 }
   12061             }
   12062             if (app.setSchedGroup != app.curSchedGroup) {
   12063                 app.setSchedGroup = app.curSchedGroup;
   12064                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   12065                         "Setting process group of " + app.processName
   12066                         + " to " + app.curSchedGroup);
   12067                 if (true) {
   12068                     long oldId = Binder.clearCallingIdentity();
   12069                     try {
   12070                         Process.setProcessGroup(app.pid, app.curSchedGroup);
   12071                     } catch (Exception e) {
   12072                         Slog.w(TAG, "Failed setting process group of " + app.pid
   12073                                 + " to " + app.curSchedGroup);
   12074                         e.printStackTrace();
   12075                     } finally {
   12076                         Binder.restoreCallingIdentity(oldId);
   12077                     }
   12078                 }
   12079                 if (false) {
   12080                     if (app.thread != null) {
   12081                         try {
   12082                             app.thread.setSchedulingGroup(app.curSchedGroup);
   12083                         } catch (RemoteException e) {
   12084                         }
   12085                     }
   12086                 }
   12087             }
   12088         }
   12089 
   12090         return true;
   12091     }
   12092 
   12093     private final ActivityRecord resumedAppLocked() {
   12094         ActivityRecord resumedActivity = mMainStack.mResumedActivity;
   12095         if (resumedActivity == null || resumedActivity.app == null) {
   12096             resumedActivity = mMainStack.mPausingActivity;
   12097             if (resumedActivity == null || resumedActivity.app == null) {
   12098                 resumedActivity = mMainStack.topRunningActivityLocked(null);
   12099             }
   12100         }
   12101         return resumedActivity;
   12102     }
   12103 
   12104     private final boolean updateOomAdjLocked(ProcessRecord app) {
   12105         final ActivityRecord TOP_ACT = resumedAppLocked();
   12106         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   12107         int curAdj = app.curAdj;
   12108         final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
   12109             && app.curAdj <= HIDDEN_APP_MAX_ADJ;
   12110 
   12111         mAdjSeq++;
   12112 
   12113         final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
   12114         if (res) {
   12115             final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
   12116                 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
   12117             if (nowHidden != wasHidden) {
   12118                 // Changed to/from hidden state, so apps after it in the LRU
   12119                 // list may also be changed.
   12120                 updateOomAdjLocked();
   12121             }
   12122         }
   12123         return res;
   12124     }
   12125 
   12126     final boolean updateOomAdjLocked() {
   12127         boolean didOomAdj = true;
   12128         final ActivityRecord TOP_ACT = resumedAppLocked();
   12129         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   12130 
   12131         if (false) {
   12132             RuntimeException e = new RuntimeException();
   12133             e.fillInStackTrace();
   12134             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
   12135         }
   12136 
   12137         mAdjSeq++;
   12138 
   12139         // Let's determine how many processes we have running vs.
   12140         // how many slots we have for background processes; we may want
   12141         // to put multiple processes in a slot of there are enough of
   12142         // them.
   12143         int numSlots = HIDDEN_APP_MAX_ADJ - HIDDEN_APP_MIN_ADJ + 1;
   12144         int factor = (mLruProcesses.size()-4)/numSlots;
   12145         if (factor < 1) factor = 1;
   12146         int step = 0;
   12147         int numHidden = 0;
   12148 
   12149         // First try updating the OOM adjustment for each of the
   12150         // application processes based on their current state.
   12151         int i = mLruProcesses.size();
   12152         int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
   12153         while (i > 0) {
   12154             i--;
   12155             ProcessRecord app = mLruProcesses.get(i);
   12156             //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
   12157             if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
   12158                 if (curHiddenAdj < EMPTY_APP_ADJ
   12159                     && app.curAdj == curHiddenAdj) {
   12160                     step++;
   12161                     if (step >= factor) {
   12162                         step = 0;
   12163                         curHiddenAdj++;
   12164                     }
   12165                 }
   12166                 if (app.curAdj >= HIDDEN_APP_MIN_ADJ) {
   12167                     if (!app.killedBackground) {
   12168                         numHidden++;
   12169                         if (numHidden > MAX_HIDDEN_APPS) {
   12170                             Slog.i(TAG, "No longer want " + app.processName
   12171                                     + " (pid " + app.pid + "): hidden #" + numHidden);
   12172                             EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   12173                                     app.processName, app.setAdj, "too many background");
   12174                             app.killedBackground = true;
   12175                             Process.killProcessQuiet(app.pid);
   12176                         }
   12177                     }
   12178                 }
   12179             } else {
   12180                 didOomAdj = false;
   12181             }
   12182         }
   12183 
   12184         // If we return false, we will fall back on killing processes to
   12185         // have a fixed limit.  Do this if a limit has been requested; else
   12186         // only return false if one of the adjustments failed.
   12187         return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
   12188     }
   12189 
   12190     final void trimApplications() {
   12191         synchronized (this) {
   12192             int i;
   12193 
   12194             // First remove any unused application processes whose package
   12195             // has been removed.
   12196             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
   12197                 final ProcessRecord app = mRemovedProcesses.get(i);
   12198                 if (app.activities.size() == 0
   12199                         && app.curReceiver == null && app.services.size() == 0) {
   12200                     Slog.i(
   12201                         TAG, "Exiting empty application process "
   12202                         + app.processName + " ("
   12203                         + (app.thread != null ? app.thread.asBinder() : null)
   12204                         + ")\n");
   12205                     if (app.pid > 0 && app.pid != MY_PID) {
   12206                         Process.killProcess(app.pid);
   12207                     } else {
   12208                         try {
   12209                             app.thread.scheduleExit();
   12210                         } catch (Exception e) {
   12211                             // Ignore exceptions.
   12212                         }
   12213                     }
   12214                     cleanUpApplicationRecordLocked(app, false, -1);
   12215                     mRemovedProcesses.remove(i);
   12216 
   12217                     if (app.persistent) {
   12218                         if (app.persistent) {
   12219                             addAppLocked(app.info);
   12220                         }
   12221                     }
   12222                 }
   12223             }
   12224 
   12225             // Now try updating the OOM adjustment for each of the
   12226             // application processes based on their current state.
   12227             // If the setOomAdj() API is not supported, then go with our
   12228             // back-up plan...
   12229             if (!updateOomAdjLocked()) {
   12230 
   12231                 // Count how many processes are running services.
   12232                 int numServiceProcs = 0;
   12233                 for (i=mLruProcesses.size()-1; i>=0; i--) {
   12234                     final ProcessRecord app = mLruProcesses.get(i);
   12235 
   12236                     if (app.persistent || app.services.size() != 0
   12237                             || app.curReceiver != null) {
   12238                         // Don't count processes holding services against our
   12239                         // maximum process count.
   12240                         if (localLOGV) Slog.v(
   12241                             TAG, "Not trimming app " + app + " with services: "
   12242                             + app.services);
   12243                         numServiceProcs++;
   12244                     }
   12245                 }
   12246 
   12247                 int curMaxProcs = mProcessLimit;
   12248                 if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
   12249                 if (mAlwaysFinishActivities) {
   12250                     curMaxProcs = 1;
   12251                 }
   12252                 curMaxProcs += numServiceProcs;
   12253 
   12254                 // Quit as many processes as we can to get down to the desired
   12255                 // process count.  First remove any processes that no longer
   12256                 // have activites running in them.
   12257                 for (   i=0;
   12258                         i<mLruProcesses.size()
   12259                             && mLruProcesses.size() > curMaxProcs;
   12260                         i++) {
   12261                     final ProcessRecord app = mLruProcesses.get(i);
   12262                     // Quit an application only if it is not currently
   12263                     // running any activities.
   12264                     if (!app.persistent && app.activities.size() == 0
   12265                             && app.curReceiver == null && app.services.size() == 0) {
   12266                         Slog.i(
   12267                             TAG, "Exiting empty application process "
   12268                             + app.processName + " ("
   12269                             + (app.thread != null ? app.thread.asBinder() : null)
   12270                             + ")\n");
   12271                         if (app.pid > 0 && app.pid != MY_PID) {
   12272                             Process.killProcess(app.pid);
   12273                         } else {
   12274                             try {
   12275                                 app.thread.scheduleExit();
   12276                             } catch (Exception e) {
   12277                                 // Ignore exceptions.
   12278                             }
   12279                         }
   12280                         // todo: For now we assume the application is not buggy
   12281                         // or evil, and will quit as a result of our request.
   12282                         // Eventually we need to drive this off of the death
   12283                         // notification, and kill the process if it takes too long.
   12284                         cleanUpApplicationRecordLocked(app, false, i);
   12285                         i--;
   12286                     }
   12287                 }
   12288 
   12289                 // If we still have too many processes, now from the least
   12290                 // recently used process we start finishing activities.
   12291                 if (Config.LOGV) Slog.v(
   12292                     TAG, "*** NOW HAVE " + mLruProcesses.size() +
   12293                     " of " + curMaxProcs + " processes");
   12294                 for (   i=0;
   12295                         i<mLruProcesses.size()
   12296                             && mLruProcesses.size() > curMaxProcs;
   12297                         i++) {
   12298                     final ProcessRecord app = mLruProcesses.get(i);
   12299                     // Quit the application only if we have a state saved for
   12300                     // all of its activities.
   12301                     boolean canQuit = !app.persistent && app.curReceiver == null
   12302                         && app.services.size() == 0;
   12303                     int NUMA = app.activities.size();
   12304                     int j;
   12305                     if (Config.LOGV) Slog.v(
   12306                         TAG, "Looking to quit " + app.processName);
   12307                     for (j=0; j<NUMA && canQuit; j++) {
   12308                         ActivityRecord r = app.activities.get(j);
   12309                         if (Config.LOGV) Slog.v(
   12310                             TAG, "  " + r.intent.getComponent().flattenToShortString()
   12311                             + ": frozen=" + r.haveState + ", visible=" + r.visible);
   12312                         canQuit = (r.haveState || !r.stateNotNeeded)
   12313                                 && !r.visible && r.stopped;
   12314                     }
   12315                     if (canQuit) {
   12316                         // Finish all of the activities, and then the app itself.
   12317                         for (j=0; j<NUMA; j++) {
   12318                             ActivityRecord r = app.activities.get(j);
   12319                             if (!r.finishing) {
   12320                                 r.stack.destroyActivityLocked(r, false);
   12321                             }
   12322                             r.resultTo = null;
   12323                         }
   12324                         Slog.i(TAG, "Exiting application process "
   12325                               + app.processName + " ("
   12326                               + (app.thread != null ? app.thread.asBinder() : null)
   12327                               + ")\n");
   12328                         if (app.pid > 0 && app.pid != MY_PID) {
   12329                             Process.killProcess(app.pid);
   12330                         } else {
   12331                             try {
   12332                                 app.thread.scheduleExit();
   12333                             } catch (Exception e) {
   12334                                 // Ignore exceptions.
   12335                             }
   12336                         }
   12337                         // todo: For now we assume the application is not buggy
   12338                         // or evil, and will quit as a result of our request.
   12339                         // Eventually we need to drive this off of the death
   12340                         // notification, and kill the process if it takes too long.
   12341                         cleanUpApplicationRecordLocked(app, false, i);
   12342                         i--;
   12343                         //dump();
   12344                     }
   12345                 }
   12346 
   12347             }
   12348 
   12349             int curMaxActivities = MAX_ACTIVITIES;
   12350             if (mAlwaysFinishActivities) {
   12351                 curMaxActivities = 1;
   12352             }
   12353 
   12354             // Finally, if there are too many activities now running, try to
   12355             // finish as many as we can to get back down to the limit.
   12356             for (   i=0;
   12357                     i<mMainStack.mLRUActivities.size()
   12358                         && mMainStack.mLRUActivities.size() > curMaxActivities;
   12359                     i++) {
   12360                 final ActivityRecord r
   12361                     = (ActivityRecord)mMainStack.mLRUActivities.get(i);
   12362 
   12363                 // We can finish this one if we have its icicle saved and
   12364                 // it is not persistent.
   12365                 if ((r.haveState || !r.stateNotNeeded) && !r.visible
   12366                         && r.stopped && !r.finishing) {
   12367                     final int origSize = mMainStack.mLRUActivities.size();
   12368                     r.stack.destroyActivityLocked(r, true);
   12369 
   12370                     // This will remove it from the LRU list, so keep
   12371                     // our index at the same value.  Note that this check to
   12372                     // see if the size changes is just paranoia -- if
   12373                     // something unexpected happens, we don't want to end up
   12374                     // in an infinite loop.
   12375                     if (origSize > mMainStack.mLRUActivities.size()) {
   12376                         i--;
   12377                     }
   12378                 }
   12379             }
   12380         }
   12381     }
   12382 
   12383     /** This method sends the specified signal to each of the persistent apps */
   12384     public void signalPersistentProcesses(int sig) throws RemoteException {
   12385         if (sig != Process.SIGNAL_USR1) {
   12386             throw new SecurityException("Only SIGNAL_USR1 is allowed");
   12387         }
   12388 
   12389         synchronized (this) {
   12390             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
   12391                     != PackageManager.PERMISSION_GRANTED) {
   12392                 throw new SecurityException("Requires permission "
   12393                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
   12394             }
   12395 
   12396             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   12397                 ProcessRecord r = mLruProcesses.get(i);
   12398                 if (r.thread != null && r.persistent) {
   12399                     Process.sendSignal(r.pid, sig);
   12400                 }
   12401             }
   12402         }
   12403     }
   12404 
   12405     public boolean profileControl(String process, boolean start,
   12406             String path, ParcelFileDescriptor fd) throws RemoteException {
   12407 
   12408         try {
   12409             synchronized (this) {
   12410                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   12411                 // its own permission.
   12412                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   12413                         != PackageManager.PERMISSION_GRANTED) {
   12414                     throw new SecurityException("Requires permission "
   12415                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   12416                 }
   12417 
   12418                 if (start && fd == null) {
   12419                     throw new IllegalArgumentException("null fd");
   12420                 }
   12421 
   12422                 ProcessRecord proc = null;
   12423                 try {
   12424                     int pid = Integer.parseInt(process);
   12425                     synchronized (mPidsSelfLocked) {
   12426                         proc = mPidsSelfLocked.get(pid);
   12427                     }
   12428                 } catch (NumberFormatException e) {
   12429                 }
   12430 
   12431                 if (proc == null) {
   12432                     HashMap<String, SparseArray<ProcessRecord>> all
   12433                             = mProcessNames.getMap();
   12434                     SparseArray<ProcessRecord> procs = all.get(process);
   12435                     if (procs != null && procs.size() > 0) {
   12436                         proc = procs.valueAt(0);
   12437                     }
   12438                 }
   12439 
   12440                 if (proc == null || proc.thread == null) {
   12441                     throw new IllegalArgumentException("Unknown process: " + process);
   12442                 }
   12443 
   12444                 boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
   12445                 if (isSecure) {
   12446                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   12447                         throw new SecurityException("Process not debuggable: " + proc);
   12448                     }
   12449                 }
   12450 
   12451                 proc.thread.profilerControl(start, path, fd);
   12452                 fd = null;
   12453                 return true;
   12454             }
   12455         } catch (RemoteException e) {
   12456             throw new IllegalStateException("Process disappeared");
   12457         } finally {
   12458             if (fd != null) {
   12459                 try {
   12460                     fd.close();
   12461                 } catch (IOException e) {
   12462                 }
   12463             }
   12464         }
   12465     }
   12466 
   12467     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
   12468     public void monitor() {
   12469         synchronized (this) { }
   12470     }
   12471 }
   12472