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.os.BatteryStatsImpl;
     20 import com.android.server.AttributeCache;
     21 import com.android.server.IntentResolver;
     22 import com.android.server.ProcessMap;
     23 import com.android.server.ProcessStats;
     24 import com.android.server.SystemServer;
     25 import com.android.server.Watchdog;
     26 import com.android.server.WindowManagerService;
     27 
     28 import dalvik.system.Zygote;
     29 
     30 import android.app.Activity;
     31 import android.app.ActivityManager;
     32 import android.app.ActivityManagerNative;
     33 import android.app.ActivityThread;
     34 import android.app.AlertDialog;
     35 import android.app.ApplicationErrorReport;
     36 import android.app.Dialog;
     37 import android.app.IActivityController;
     38 import android.app.IActivityManager;
     39 import android.app.IActivityWatcher;
     40 import android.app.IApplicationThread;
     41 import android.app.IInstrumentationWatcher;
     42 import android.app.IServiceConnection;
     43 import android.app.IThumbnailReceiver;
     44 import android.app.Instrumentation;
     45 import android.app.Notification;
     46 import android.app.PendingIntent;
     47 import android.app.ResultInfo;
     48 import android.app.Service;
     49 import android.app.backup.IBackupManager;
     50 import android.content.ActivityNotFoundException;
     51 import android.content.BroadcastReceiver;
     52 import android.content.ComponentName;
     53 import android.content.ContentResolver;
     54 import android.content.Context;
     55 import android.content.Intent;
     56 import android.content.IntentFilter;
     57 import android.content.IIntentReceiver;
     58 import android.content.IIntentSender;
     59 import android.content.IntentSender;
     60 import android.content.pm.ActivityInfo;
     61 import android.content.pm.ApplicationInfo;
     62 import android.content.pm.ConfigurationInfo;
     63 import android.content.pm.IPackageDataObserver;
     64 import android.content.pm.IPackageManager;
     65 import android.content.pm.InstrumentationInfo;
     66 import android.content.pm.PackageInfo;
     67 import android.content.pm.PackageManager;
     68 import android.content.pm.PathPermission;
     69 import android.content.pm.ProviderInfo;
     70 import android.content.pm.ResolveInfo;
     71 import android.content.pm.ServiceInfo;
     72 import android.content.res.Configuration;
     73 import android.graphics.Bitmap;
     74 import android.net.Uri;
     75 import android.os.Binder;
     76 import android.os.Build;
     77 import android.os.Bundle;
     78 import android.os.Debug;
     79 import android.os.DropBoxManager;
     80 import android.os.Environment;
     81 import android.os.FileObserver;
     82 import android.os.FileUtils;
     83 import android.os.Handler;
     84 import android.os.IBinder;
     85 import android.os.IPermissionController;
     86 import android.os.Looper;
     87 import android.os.Message;
     88 import android.os.Parcel;
     89 import android.os.ParcelFileDescriptor;
     90 import android.os.PowerManager;
     91 import android.os.Process;
     92 import android.os.RemoteCallbackList;
     93 import android.os.RemoteException;
     94 import android.os.ServiceManager;
     95 import android.os.SystemClock;
     96 import android.os.SystemProperties;
     97 import android.provider.Settings;
     98 import android.util.Config;
     99 import android.util.EventLog;
    100 import android.util.Slog;
    101 import android.util.Log;
    102 import android.util.PrintWriterPrinter;
    103 import android.util.SparseArray;
    104 import android.view.Gravity;
    105 import android.view.LayoutInflater;
    106 import android.view.View;
    107 import android.view.WindowManager;
    108 import android.view.WindowManagerPolicy;
    109 
    110 import java.io.File;
    111 import java.io.FileDescriptor;
    112 import java.io.FileNotFoundException;
    113 import java.io.IOException;
    114 import java.io.InputStreamReader;
    115 import java.io.PrintWriter;
    116 import java.lang.IllegalStateException;
    117 import java.lang.ref.WeakReference;
    118 import java.util.ArrayList;
    119 import java.util.HashMap;
    120 import java.util.HashSet;
    121 import java.util.Iterator;
    122 import java.util.List;
    123 import java.util.Locale;
    124 import java.util.Map;
    125 import java.util.Set;
    126 import java.util.concurrent.atomic.AtomicBoolean;
    127 import java.util.concurrent.atomic.AtomicLong;
    128 
    129 public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor {
    130     static final String TAG = "ActivityManager";
    131     static final boolean DEBUG = false;
    132     static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
    133     static final boolean DEBUG_SWITCH = localLOGV || false;
    134     static final boolean DEBUG_TASKS = localLOGV || false;
    135     static final boolean DEBUG_PAUSE = localLOGV || false;
    136     static final boolean DEBUG_OOM_ADJ = localLOGV || false;
    137     static final boolean DEBUG_TRANSITION = localLOGV || false;
    138     static final boolean DEBUG_BROADCAST = localLOGV || false;
    139     static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
    140     static final boolean DEBUG_SERVICE = localLOGV || false;
    141     static final boolean DEBUG_VISBILITY = localLOGV || false;
    142     static final boolean DEBUG_PROCESSES = localLOGV || false;
    143     static final boolean DEBUG_PROVIDER = localLOGV || false;
    144     static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
    145     static final boolean DEBUG_USER_LEAVING = localLOGV || false;
    146     static final boolean DEBUG_RESULTS = localLOGV || false;
    147     static final boolean DEBUG_BACKUP = localLOGV || false;
    148     static final boolean DEBUG_CONFIGURATION = localLOGV || false;
    149     static final boolean VALIDATE_TOKENS = false;
    150     static final boolean SHOW_ACTIVITY_START_TIME = true;
    151 
    152     // Control over CPU and battery monitoring.
    153     static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
    154     static final boolean MONITOR_CPU_USAGE = true;
    155     static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
    156     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
    157     static final boolean MONITOR_THREAD_CPU_USAGE = false;
    158 
    159     // The flags that are set for all calls we make to the package manager.
    160     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
    161 
    162     private static final String SYSTEM_SECURE = "ro.secure";
    163 
    164     // This is the maximum number of application processes we would like
    165     // to have running.  Due to the asynchronous nature of things, we can
    166     // temporarily go beyond this limit.
    167     static final int MAX_PROCESSES = 2;
    168 
    169     // Set to false to leave processes running indefinitely, relying on
    170     // the kernel killing them as resources are required.
    171     static final boolean ENFORCE_PROCESS_LIMIT = false;
    172 
    173     // This is the maximum number of activities that we would like to have
    174     // running at a given time.
    175     static final int MAX_ACTIVITIES = 20;
    176 
    177     // Maximum number of recent tasks that we can remember.
    178     static final int MAX_RECENT_TASKS = 20;
    179 
    180     // Amount of time after a call to stopAppSwitches() during which we will
    181     // prevent further untrusted switches from happening.
    182     static final long APP_SWITCH_DELAY_TIME = 5*1000;
    183 
    184     // How long until we reset a task when the user returns to it.  Currently
    185     // 30 minutes.
    186     static final long ACTIVITY_INACTIVE_RESET_TIME = 1000*60*30;
    187 
    188     // Set to true to disable the icon that is shown while a new activity
    189     // is being started.
    190     static final boolean SHOW_APP_STARTING_ICON = true;
    191 
    192     // How long we wait until giving up on the last activity to pause.  This
    193     // is short because it directly impacts the responsiveness of starting the
    194     // next activity.
    195     static final int PAUSE_TIMEOUT = 500;
    196 
    197     /**
    198      * How long we can hold the launch wake lock before giving up.
    199      */
    200     static final int LAUNCH_TIMEOUT = 10*1000;
    201 
    202     // How long we wait for a launched process to attach to the activity manager
    203     // before we decide it's never going to come up for real.
    204     static final int PROC_START_TIMEOUT = 10*1000;
    205 
    206     // How long we wait until giving up on the last activity telling us it
    207     // is idle.
    208     static final int IDLE_TIMEOUT = 10*1000;
    209 
    210     // How long to wait after going idle before forcing apps to GC.
    211     static final int GC_TIMEOUT = 5*1000;
    212 
    213     // The minimum amount of time between successive GC requests for a process.
    214     static final int GC_MIN_INTERVAL = 60*1000;
    215 
    216     // How long we wait until giving up on an activity telling us it has
    217     // finished destroying itself.
    218     static final int DESTROY_TIMEOUT = 10*1000;
    219 
    220     // How long we allow a receiver to run before giving up on it.
    221     static final int BROADCAST_TIMEOUT = 10*1000;
    222 
    223     // How long we wait for a service to finish executing.
    224     static final int SERVICE_TIMEOUT = 20*1000;
    225 
    226     // How long a service needs to be running until restarting its process
    227     // is no longer considered to be a relaunch of the service.
    228     static final int SERVICE_RESTART_DURATION = 5*1000;
    229 
    230     // How long a service needs to be running until it will start back at
    231     // SERVICE_RESTART_DURATION after being killed.
    232     static final int SERVICE_RESET_RUN_DURATION = 60*1000;
    233 
    234     // Multiplying factor to increase restart duration time by, for each time
    235     // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
    236     static final int SERVICE_RESTART_DURATION_FACTOR = 4;
    237 
    238     // The minimum amount of time between restarting services that we allow.
    239     // That is, when multiple services are restarting, we won't allow each
    240     // to restart less than this amount of time from the last one.
    241     static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
    242 
    243     // Maximum amount of time for there to be no activity on a service before
    244     // we consider it non-essential and allow its process to go on the
    245     // LRU background list.
    246     static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
    247 
    248     // How long we wait until we timeout on key dispatching.
    249     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
    250 
    251     // The minimum time we allow between crashes, for us to consider this
    252     // application to be bad and stop and its services and reject broadcasts.
    253     static final int MIN_CRASH_INTERVAL = 60*1000;
    254 
    255     // How long we wait until we timeout on key dispatching during instrumentation.
    256     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
    257 
    258     // OOM adjustments for processes in various states:
    259 
    260     // This is a process without anything currently running in it.  Definitely
    261     // the first to go! Value set in system/rootdir/init.rc on startup.
    262     // This value is initalized in the constructor, careful when refering to
    263     // this static variable externally.
    264     static final int EMPTY_APP_ADJ;
    265 
    266     // This is a process only hosting activities that are not visible,
    267     // so it can be killed without any disruption. Value set in
    268     // system/rootdir/init.rc on startup.
    269     static final int HIDDEN_APP_MAX_ADJ;
    270     static int HIDDEN_APP_MIN_ADJ;
    271 
    272     // This is a process holding the home application -- we want to try
    273     // avoiding killing it, even if it would normally be in the background,
    274     // because the user interacts with it so much.
    275     static final int HOME_APP_ADJ;
    276 
    277     // This is a process currently hosting a backup operation.  Killing it
    278     // is not entirely fatal but is generally a bad idea.
    279     static final int BACKUP_APP_ADJ;
    280 
    281     // This is a process holding a secondary server -- killing it will not
    282     // have much of an impact as far as the user is concerned. Value set in
    283     // system/rootdir/init.rc on startup.
    284     static final int SECONDARY_SERVER_ADJ;
    285 
    286     // This is a process only hosting activities that are visible to the
    287     // user, so we'd prefer they don't disappear. Value set in
    288     // system/rootdir/init.rc on startup.
    289     static final int VISIBLE_APP_ADJ;
    290 
    291     // This is the process running the current foreground app.  We'd really
    292     // rather not kill it! Value set in system/rootdir/init.rc on startup.
    293     static final int FOREGROUND_APP_ADJ;
    294 
    295     // This is a process running a core server, such as telephony.  Definitely
    296     // don't want to kill it, but doing so is not completely fatal.
    297     static final int CORE_SERVER_ADJ = -12;
    298 
    299     // The system process runs at the default adjustment.
    300     static final int SYSTEM_ADJ = -16;
    301 
    302     // Memory pages are 4K.
    303     static final int PAGE_SIZE = 4*1024;
    304 
    305     // Corresponding memory levels for above adjustments.
    306     static final int EMPTY_APP_MEM;
    307     static final int HIDDEN_APP_MEM;
    308     static final int HOME_APP_MEM;
    309     static final int BACKUP_APP_MEM;
    310     static final int SECONDARY_SERVER_MEM;
    311     static final int VISIBLE_APP_MEM;
    312     static final int FOREGROUND_APP_MEM;
    313 
    314     // The minimum number of hidden apps we want to be able to keep around,
    315     // without empty apps being able to push them out of memory.
    316     static final int MIN_HIDDEN_APPS = 2;
    317 
    318     // The maximum number of hidden processes we will keep around before
    319     // killing them; this is just a control to not let us go too crazy with
    320     // keeping around processes on devices with large amounts of RAM.
    321     static final int MAX_HIDDEN_APPS = 15;
    322 
    323     // We put empty content processes after any hidden processes that have
    324     // been idle for less than 15 seconds.
    325     static final long CONTENT_APP_IDLE_OFFSET = 15*1000;
    326 
    327     // We put empty content processes after any hidden processes that have
    328     // been idle for less than 120 seconds.
    329     static final long EMPTY_APP_IDLE_OFFSET = 120*1000;
    330 
    331     static {
    332         // These values are set in system/rootdir/init.rc on startup.
    333         FOREGROUND_APP_ADJ =
    334             Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_ADJ"));
    335         VISIBLE_APP_ADJ =
    336             Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_ADJ"));
    337         SECONDARY_SERVER_ADJ =
    338             Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_ADJ"));
    339         BACKUP_APP_ADJ =
    340             Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_ADJ"));
    341         HOME_APP_ADJ =
    342             Integer.valueOf(SystemProperties.get("ro.HOME_APP_ADJ"));
    343         HIDDEN_APP_MIN_ADJ =
    344             Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MIN_ADJ"));
    345         EMPTY_APP_ADJ =
    346             Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_ADJ"));
    347         HIDDEN_APP_MAX_ADJ = EMPTY_APP_ADJ-1;
    348         FOREGROUND_APP_MEM =
    349             Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_MEM"))*PAGE_SIZE;
    350         VISIBLE_APP_MEM =
    351             Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_MEM"))*PAGE_SIZE;
    352         SECONDARY_SERVER_MEM =
    353             Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_MEM"))*PAGE_SIZE;
    354         BACKUP_APP_MEM =
    355             Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_MEM"))*PAGE_SIZE;
    356         HOME_APP_MEM =
    357             Integer.valueOf(SystemProperties.get("ro.HOME_APP_MEM"))*PAGE_SIZE;
    358         HIDDEN_APP_MEM =
    359             Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MEM"))*PAGE_SIZE;
    360         EMPTY_APP_MEM =
    361             Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_MEM"))*PAGE_SIZE;
    362     }
    363 
    364     static final int MY_PID = Process.myPid();
    365 
    366     static final String[] EMPTY_STRING_ARRAY = new String[0];
    367 
    368     enum ActivityState {
    369         INITIALIZING,
    370         RESUMED,
    371         PAUSING,
    372         PAUSED,
    373         STOPPING,
    374         STOPPED,
    375         FINISHING,
    376         DESTROYING,
    377         DESTROYED
    378     }
    379 
    380     /**
    381      * The back history of all previous (and possibly still
    382      * running) activities.  It contains HistoryRecord objects.
    383      */
    384     final ArrayList mHistory = new ArrayList();
    385 
    386     /**
    387      * Description of a request to start a new activity, which has been held
    388      * due to app switches being disabled.
    389      */
    390     class PendingActivityLaunch {
    391         HistoryRecord r;
    392         HistoryRecord sourceRecord;
    393         Uri[] grantedUriPermissions;
    394         int grantedMode;
    395         boolean onlyIfNeeded;
    396     }
    397 
    398     final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
    399             = new ArrayList<PendingActivityLaunch>();
    400 
    401     /**
    402      * List of people waiting to find out about the next launched activity.
    403      */
    404     final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched
    405             = new ArrayList<IActivityManager.WaitResult>();
    406 
    407     /**
    408      * List of people waiting to find out about the next visible activity.
    409      */
    410     final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible
    411             = new ArrayList<IActivityManager.WaitResult>();
    412 
    413     /**
    414      * List of all active broadcasts that are to be executed immediately
    415      * (without waiting for another broadcast to finish).  Currently this only
    416      * contains broadcasts to registered receivers, to avoid spinning up
    417      * a bunch of processes to execute IntentReceiver components.
    418      */
    419     final ArrayList<BroadcastRecord> mParallelBroadcasts
    420             = new ArrayList<BroadcastRecord>();
    421 
    422     /**
    423      * List of all active broadcasts that are to be executed one at a time.
    424      * The object at the top of the list is the currently activity broadcasts;
    425      * those after it are waiting for the top to finish..
    426      */
    427     final ArrayList<BroadcastRecord> mOrderedBroadcasts
    428             = new ArrayList<BroadcastRecord>();
    429 
    430     /**
    431      * Historical data of past broadcasts, for debugging.
    432      */
    433     static final int MAX_BROADCAST_HISTORY = 100;
    434     final BroadcastRecord[] mBroadcastHistory
    435             = new BroadcastRecord[MAX_BROADCAST_HISTORY];
    436 
    437     /**
    438      * Set when we current have a BROADCAST_INTENT_MSG in flight.
    439      */
    440     boolean mBroadcastsScheduled = false;
    441 
    442     /**
    443      * Set to indicate whether to issue an onUserLeaving callback when a
    444      * newly launched activity is being brought in front of us.
    445      */
    446     boolean mUserLeaving = false;
    447 
    448     /**
    449      * When we are in the process of pausing an activity, before starting the
    450      * next one, this variable holds the activity that is currently being paused.
    451      */
    452     HistoryRecord mPausingActivity = null;
    453 
    454     /**
    455      * Current activity that is resumed, or null if there is none.
    456      */
    457     HistoryRecord mResumedActivity = null;
    458 
    459     /**
    460      * Activity we have told the window manager to have key focus.
    461      */
    462     HistoryRecord mFocusedActivity = null;
    463 
    464     /**
    465      * This is the last activity that we put into the paused state.  This is
    466      * used to determine if we need to do an activity transition while sleeping,
    467      * when we normally hold the top activity paused.
    468      */
    469     HistoryRecord mLastPausedActivity = null;
    470 
    471     /**
    472      * List of activities that are waiting for a new activity
    473      * to become visible before completing whatever operation they are
    474      * supposed to do.
    475      */
    476     final ArrayList mWaitingVisibleActivities = new ArrayList();
    477 
    478     /**
    479      * List of activities that are ready to be stopped, but waiting
    480      * for the next activity to settle down before doing so.  It contains
    481      * HistoryRecord objects.
    482      */
    483     final ArrayList<HistoryRecord> mStoppingActivities
    484             = new ArrayList<HistoryRecord>();
    485 
    486     /**
    487      * Animations that for the current transition have requested not to
    488      * be considered for the transition animation.
    489      */
    490     final ArrayList<HistoryRecord> mNoAnimActivities
    491             = new ArrayList<HistoryRecord>();
    492 
    493     /**
    494      * List of intents that were used to start the most recent tasks.
    495      */
    496     final ArrayList<TaskRecord> mRecentTasks
    497             = new ArrayList<TaskRecord>();
    498 
    499     /**
    500      * List of activities that are ready to be finished, but waiting
    501      * for the previous activity to settle down before doing so.  It contains
    502      * HistoryRecord objects.
    503      */
    504     final ArrayList mFinishingActivities = new ArrayList();
    505 
    506     /**
    507      * All of the applications we currently have running organized by name.
    508      * The keys are strings of the application package name (as
    509      * returned by the package manager), and the keys are ApplicationRecord
    510      * objects.
    511      */
    512     final ProcessMap<ProcessRecord> mProcessNames
    513             = new ProcessMap<ProcessRecord>();
    514 
    515     /**
    516      * The last time that various processes have crashed.
    517      */
    518     final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
    519 
    520     /**
    521      * Set of applications that we consider to be bad, and will reject
    522      * incoming broadcasts from (which the user has no control over).
    523      * Processes are added to this set when they have crashed twice within
    524      * a minimum amount of time; they are removed from it when they are
    525      * later restarted (hopefully due to some user action).  The value is the
    526      * time it was added to the list.
    527      */
    528     final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
    529 
    530     /**
    531      * All of the processes we currently have running organized by pid.
    532      * The keys are the pid running the application.
    533      *
    534      * <p>NOTE: This object is protected by its own lock, NOT the global
    535      * activity manager lock!
    536      */
    537     final SparseArray<ProcessRecord> mPidsSelfLocked
    538             = new SparseArray<ProcessRecord>();
    539 
    540     /**
    541      * All of the processes that have been forced to be foreground.  The key
    542      * is the pid of the caller who requested it (we hold a death
    543      * link on it).
    544      */
    545     abstract class ForegroundToken implements IBinder.DeathRecipient {
    546         int pid;
    547         IBinder token;
    548     }
    549     final SparseArray<ForegroundToken> mForegroundProcesses
    550             = new SparseArray<ForegroundToken>();
    551 
    552     /**
    553      * List of records for processes that someone had tried to start before the
    554      * system was ready.  We don't start them at that point, but ensure they
    555      * are started by the time booting is complete.
    556      */
    557     final ArrayList<ProcessRecord> mProcessesOnHold
    558             = new ArrayList<ProcessRecord>();
    559 
    560     /**
    561      * List of records for processes that we have started and are waiting
    562      * for them to call back.  This is really only needed when running in
    563      * single processes mode, in which case we do not have a unique pid for
    564      * each process.
    565      */
    566     final ArrayList<ProcessRecord> mStartingProcesses
    567             = new ArrayList<ProcessRecord>();
    568 
    569     /**
    570      * List of persistent applications that are in the process
    571      * of being started.
    572      */
    573     final ArrayList<ProcessRecord> mPersistentStartingProcesses
    574             = new ArrayList<ProcessRecord>();
    575 
    576     /**
    577      * Processes that are being forcibly torn down.
    578      */
    579     final ArrayList<ProcessRecord> mRemovedProcesses
    580             = new ArrayList<ProcessRecord>();
    581 
    582     /**
    583      * List of running applications, sorted by recent usage.
    584      * The first entry in the list is the least recently used.
    585      * It contains ApplicationRecord objects.  This list does NOT include
    586      * any persistent application records (since we never want to exit them).
    587      */
    588     final ArrayList<ProcessRecord> mLruProcesses
    589             = new ArrayList<ProcessRecord>();
    590 
    591     /**
    592      * List of processes that should gc as soon as things are idle.
    593      */
    594     final ArrayList<ProcessRecord> mProcessesToGc
    595             = new ArrayList<ProcessRecord>();
    596 
    597     /**
    598      * This is the process holding what we currently consider to be
    599      * the "home" activity.
    600      */
    601     private ProcessRecord mHomeProcess;
    602 
    603     /**
    604      * List of running activities, sorted by recent usage.
    605      * The first entry in the list is the least recently used.
    606      * It contains HistoryRecord objects.
    607      */
    608     private final ArrayList mLRUActivities = new ArrayList();
    609 
    610     /**
    611      * Set of PendingResultRecord objects that are currently active.
    612      */
    613     final HashSet mPendingResultRecords = new HashSet();
    614 
    615     /**
    616      * Set of IntentSenderRecord objects that are currently active.
    617      */
    618     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
    619             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
    620 
    621     /**
    622      * Intent broadcast that we have tried to start, but are
    623      * waiting for its application's process to be created.  We only
    624      * need one (instead of a list) because we always process broadcasts
    625      * one at a time, so no others can be started while waiting for this
    626      * one.
    627      */
    628     BroadcastRecord mPendingBroadcast = null;
    629 
    630     /**
    631      * Keeps track of all IIntentReceivers that have been registered for
    632      * broadcasts.  Hash keys are the receiver IBinder, hash value is
    633      * a ReceiverList.
    634      */
    635     final HashMap mRegisteredReceivers = new HashMap();
    636 
    637     /**
    638      * Resolver for broadcast intents to registered receivers.
    639      * Holds BroadcastFilter (subclass of IntentFilter).
    640      */
    641     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
    642             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
    643         @Override
    644         protected boolean allowFilterResult(
    645                 BroadcastFilter filter, List<BroadcastFilter> dest) {
    646             IBinder target = filter.receiverList.receiver.asBinder();
    647             for (int i=dest.size()-1; i>=0; i--) {
    648                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
    649                     return false;
    650                 }
    651             }
    652             return true;
    653         }
    654     };
    655 
    656     /**
    657      * State of all active sticky broadcasts.  Keys are the action of the
    658      * sticky Intent, values are an ArrayList of all broadcasted intents with
    659      * that action (which should usually be one).
    660      */
    661     final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
    662             new HashMap<String, ArrayList<Intent>>();
    663 
    664     /**
    665      * All currently running services.
    666      */
    667     final HashMap<ComponentName, ServiceRecord> mServices =
    668         new HashMap<ComponentName, ServiceRecord>();
    669 
    670     /**
    671      * All currently running services indexed by the Intent used to start them.
    672      */
    673     final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
    674         new HashMap<Intent.FilterComparison, ServiceRecord>();
    675 
    676     /**
    677      * All currently bound service connections.  Keys are the IBinder of
    678      * the client's IServiceConnection.
    679      */
    680     final HashMap<IBinder, ConnectionRecord> mServiceConnections
    681             = new HashMap<IBinder, ConnectionRecord>();
    682 
    683     /**
    684      * List of services that we have been asked to start,
    685      * but haven't yet been able to.  It is used to hold start requests
    686      * while waiting for their corresponding application thread to get
    687      * going.
    688      */
    689     final ArrayList<ServiceRecord> mPendingServices
    690             = new ArrayList<ServiceRecord>();
    691 
    692     /**
    693      * List of services that are scheduled to restart following a crash.
    694      */
    695     final ArrayList<ServiceRecord> mRestartingServices
    696             = new ArrayList<ServiceRecord>();
    697 
    698     /**
    699      * List of services that are in the process of being stopped.
    700      */
    701     final ArrayList<ServiceRecord> mStoppingServices
    702             = new ArrayList<ServiceRecord>();
    703 
    704     /**
    705      * Backup/restore process management
    706      */
    707     String mBackupAppName = null;
    708     BackupRecord mBackupTarget = null;
    709 
    710     /**
    711      * List of PendingThumbnailsRecord objects of clients who are still
    712      * waiting to receive all of the thumbnails for a task.
    713      */
    714     final ArrayList mPendingThumbnails = new ArrayList();
    715 
    716     /**
    717      * List of HistoryRecord objects that have been finished and must
    718      * still report back to a pending thumbnail receiver.
    719      */
    720     final ArrayList mCancelledThumbnails = new ArrayList();
    721 
    722     /**
    723      * All of the currently running global content providers.  Keys are a
    724      * string containing the provider name and values are a
    725      * ContentProviderRecord object containing the data about it.  Note
    726      * that a single provider may be published under multiple names, so
    727      * there may be multiple entries here for a single one in mProvidersByClass.
    728      */
    729     final HashMap mProvidersByName = new HashMap();
    730 
    731     /**
    732      * All of the currently running global content providers.  Keys are a
    733      * string containing the provider's implementation class and values are a
    734      * ContentProviderRecord object containing the data about it.
    735      */
    736     final HashMap mProvidersByClass = new HashMap();
    737 
    738     /**
    739      * List of content providers who have clients waiting for them.  The
    740      * application is currently being launched and the provider will be
    741      * removed from this list once it is published.
    742      */
    743     final ArrayList mLaunchingProviders = new ArrayList();
    744 
    745     /**
    746      * Global set of specific Uri permissions that have been granted.
    747      */
    748     final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
    749             = new SparseArray<HashMap<Uri, UriPermission>>();
    750 
    751     /**
    752      * Thread-local storage used to carry caller permissions over through
    753      * indirect content-provider access.
    754      * @see #ActivityManagerService.openContentUri()
    755      */
    756     private class Identity {
    757         public int pid;
    758         public int uid;
    759 
    760         Identity(int _pid, int _uid) {
    761             pid = _pid;
    762             uid = _uid;
    763         }
    764     }
    765     private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
    766 
    767     /**
    768      * All information we have collected about the runtime performance of
    769      * any user id that can impact battery performance.
    770      */
    771     final BatteryStatsService mBatteryStatsService;
    772 
    773     /**
    774      * information about component usage
    775      */
    776     final UsageStatsService mUsageStatsService;
    777 
    778     /**
    779      * Current configuration information.  HistoryRecord objects are given
    780      * a reference to this object to indicate which configuration they are
    781      * currently running in, so this object must be kept immutable.
    782      */
    783     Configuration mConfiguration = new Configuration();
    784 
    785     /**
    786      * Current sequencing integer of the configuration, for skipping old
    787      * configurations.
    788      */
    789     int mConfigurationSeq = 0;
    790 
    791     /**
    792      * Set when we know we are going to be calling updateConfiguration()
    793      * soon, so want to skip intermediate config checks.
    794      */
    795     boolean mConfigWillChange;
    796 
    797     /**
    798      * Hardware-reported OpenGLES version.
    799      */
    800     final int GL_ES_VERSION;
    801 
    802     /**
    803      * List of initialization arguments to pass to all processes when binding applications to them.
    804      * For example, references to the commonly used services.
    805      */
    806     HashMap<String, IBinder> mAppBindArgs;
    807 
    808     /**
    809      * Temporary to avoid allocations.  Protected by main lock.
    810      */
    811     final StringBuilder mStringBuilder = new StringBuilder(256);
    812 
    813     /**
    814      * Used to control how we initialize the service.
    815      */
    816     boolean mStartRunning = false;
    817     ComponentName mTopComponent;
    818     String mTopAction;
    819     String mTopData;
    820     boolean mSystemReady = false;
    821     boolean mBooting = false;
    822     boolean mWaitingUpdate = false;
    823     boolean mDidUpdate = false;
    824 
    825     Context mContext;
    826 
    827     int mFactoryTest;
    828 
    829     boolean mCheckedForSetup;
    830 
    831     /**
    832      * The time at which we will allow normal application switches again,
    833      * after a call to {@link #stopAppSwitches()}.
    834      */
    835     long mAppSwitchesAllowedTime;
    836 
    837     /**
    838      * This is set to true after the first switch after mAppSwitchesAllowedTime
    839      * is set; any switches after that will clear the time.
    840      */
    841     boolean mDidAppSwitch;
    842 
    843     /**
    844      * Set while we are wanting to sleep, to prevent any
    845      * activities from being started/resumed.
    846      */
    847     boolean mSleeping = false;
    848 
    849     /**
    850      * Set if we are shutting down the system, similar to sleeping.
    851      */
    852     boolean mShuttingDown = false;
    853 
    854     /**
    855      * Set when the system is going to sleep, until we have
    856      * successfully paused the current activity and released our wake lock.
    857      * At that point the system is allowed to actually sleep.
    858      */
    859     PowerManager.WakeLock mGoingToSleep;
    860 
    861     /**
    862      * We don't want to allow the device to go to sleep while in the process
    863      * of launching an activity.  This is primarily to allow alarm intent
    864      * receivers to launch an activity and get that to run before the device
    865      * goes back to sleep.
    866      */
    867     PowerManager.WakeLock mLaunchingActivity;
    868 
    869     /**
    870      * Task identifier that activities are currently being started
    871      * in.  Incremented each time a new task is created.
    872      * todo: Replace this with a TokenSpace class that generates non-repeating
    873      * integers that won't wrap.
    874      */
    875     int mCurTask = 1;
    876 
    877     /**
    878      * Current sequence id for oom_adj computation traversal.
    879      */
    880     int mAdjSeq = 0;
    881 
    882     /**
    883      * Current sequence id for process LRU updating.
    884      */
    885     int mLruSeq = 0;
    886 
    887     /**
    888      * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar
    889      * is set, indicating the user wants processes started in such a way
    890      * that they can use ANDROID_PROCESS_WRAPPER and know what will be
    891      * running in each process (thus no pre-initialized process, etc).
    892      */
    893     boolean mSimpleProcessManagement = false;
    894 
    895     /**
    896      * System monitoring: number of processes that died since the last
    897      * N procs were started.
    898      */
    899     int[] mProcDeaths = new int[20];
    900 
    901     /**
    902      * This is set if we had to do a delayed dexopt of an app before launching
    903      * it, to increasing the ANR timeouts in that case.
    904      */
    905     boolean mDidDexOpt;
    906 
    907     String mDebugApp = null;
    908     boolean mWaitForDebugger = false;
    909     boolean mDebugTransient = false;
    910     String mOrigDebugApp = null;
    911     boolean mOrigWaitForDebugger = false;
    912     boolean mAlwaysFinishActivities = false;
    913     IActivityController mController = null;
    914 
    915     final RemoteCallbackList<IActivityWatcher> mWatchers
    916             = new RemoteCallbackList<IActivityWatcher>();
    917 
    918     /**
    919      * Callback of last caller to {@link #requestPss}.
    920      */
    921     Runnable mRequestPssCallback;
    922 
    923     /**
    924      * Remaining processes for which we are waiting results from the last
    925      * call to {@link #requestPss}.
    926      */
    927     final ArrayList<ProcessRecord> mRequestPssList
    928             = new ArrayList<ProcessRecord>();
    929 
    930     /**
    931      * Runtime statistics collection thread.  This object's lock is used to
    932      * protect all related state.
    933      */
    934     final Thread mProcessStatsThread;
    935 
    936     /**
    937      * Used to collect process stats when showing not responding dialog.
    938      * Protected by mProcessStatsThread.
    939      */
    940     final ProcessStats mProcessStats = new ProcessStats(
    941             MONITOR_THREAD_CPU_USAGE);
    942     final AtomicLong mLastCpuTime = new AtomicLong(0);
    943     final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
    944 
    945     long mLastWriteTime = 0;
    946 
    947     long mInitialStartTime = 0;
    948 
    949     /**
    950      * Set to true after the system has finished booting.
    951      */
    952     boolean mBooted = false;
    953 
    954     int mProcessLimit = 0;
    955 
    956     WindowManagerService mWindowManager;
    957 
    958     static ActivityManagerService mSelf;
    959     static ActivityThread mSystemThread;
    960 
    961     private final class AppDeathRecipient implements IBinder.DeathRecipient {
    962         final ProcessRecord mApp;
    963         final int mPid;
    964         final IApplicationThread mAppThread;
    965 
    966         AppDeathRecipient(ProcessRecord app, int pid,
    967                 IApplicationThread thread) {
    968             if (localLOGV) Slog.v(
    969                 TAG, "New death recipient " + this
    970                 + " for thread " + thread.asBinder());
    971             mApp = app;
    972             mPid = pid;
    973             mAppThread = thread;
    974         }
    975 
    976         public void binderDied() {
    977             if (localLOGV) Slog.v(
    978                 TAG, "Death received in " + this
    979                 + " for thread " + mAppThread.asBinder());
    980             removeRequestedPss(mApp);
    981             synchronized(ActivityManagerService.this) {
    982                 appDiedLocked(mApp, mPid, mAppThread);
    983             }
    984         }
    985     }
    986 
    987     static final int SHOW_ERROR_MSG = 1;
    988     static final int SHOW_NOT_RESPONDING_MSG = 2;
    989     static final int SHOW_FACTORY_ERROR_MSG = 3;
    990     static final int UPDATE_CONFIGURATION_MSG = 4;
    991     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
    992     static final int WAIT_FOR_DEBUGGER_MSG = 6;
    993     static final int BROADCAST_INTENT_MSG = 7;
    994     static final int BROADCAST_TIMEOUT_MSG = 8;
    995     static final int PAUSE_TIMEOUT_MSG = 9;
    996     static final int IDLE_TIMEOUT_MSG = 10;
    997     static final int IDLE_NOW_MSG = 11;
    998     static final int SERVICE_TIMEOUT_MSG = 12;
    999     static final int UPDATE_TIME_ZONE = 13;
   1000     static final int SHOW_UID_ERROR_MSG = 14;
   1001     static final int IM_FEELING_LUCKY_MSG = 15;
   1002     static final int LAUNCH_TIMEOUT_MSG = 16;
   1003     static final int DESTROY_TIMEOUT_MSG = 17;
   1004     static final int RESUME_TOP_ACTIVITY_MSG = 19;
   1005     static final int PROC_START_TIMEOUT_MSG = 20;
   1006     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
   1007     static final int KILL_APPLICATION_MSG = 22;
   1008     static final int FINALIZE_PENDING_INTENT_MSG = 23;
   1009 
   1010     AlertDialog mUidAlert;
   1011 
   1012     final Handler mHandler = new Handler() {
   1013         //public Handler() {
   1014         //    if (localLOGV) Slog.v(TAG, "Handler started!");
   1015         //}
   1016 
   1017         public void handleMessage(Message msg) {
   1018             switch (msg.what) {
   1019             case SHOW_ERROR_MSG: {
   1020                 HashMap data = (HashMap) msg.obj;
   1021                 synchronized (ActivityManagerService.this) {
   1022                     ProcessRecord proc = (ProcessRecord)data.get("app");
   1023                     if (proc != null && proc.crashDialog != null) {
   1024                         Slog.e(TAG, "App already has crash dialog: " + proc);
   1025                         return;
   1026                     }
   1027                     AppErrorResult res = (AppErrorResult) data.get("result");
   1028                     if (!mSleeping && !mShuttingDown) {
   1029                         Dialog d = new AppErrorDialog(mContext, res, proc);
   1030                         d.show();
   1031                         proc.crashDialog = d;
   1032                     } else {
   1033                         // The device is asleep, so just pretend that the user
   1034                         // saw a crash dialog and hit "force quit".
   1035                         res.set(0);
   1036                     }
   1037                 }
   1038 
   1039                 ensureBootCompleted();
   1040             } break;
   1041             case SHOW_NOT_RESPONDING_MSG: {
   1042                 synchronized (ActivityManagerService.this) {
   1043                     HashMap data = (HashMap) msg.obj;
   1044                     ProcessRecord proc = (ProcessRecord)data.get("app");
   1045                     if (proc != null && proc.anrDialog != null) {
   1046                         Slog.e(TAG, "App already has anr dialog: " + proc);
   1047                         return;
   1048                     }
   1049 
   1050                     broadcastIntentLocked(null, null, new Intent("android.intent.action.ANR"),
   1051                             null, null, 0, null, null, null,
   1052                             false, false, MY_PID, Process.SYSTEM_UID);
   1053 
   1054                     Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
   1055                             mContext, proc, (HistoryRecord)data.get("activity"));
   1056                     d.show();
   1057                     proc.anrDialog = d;
   1058                 }
   1059 
   1060                 ensureBootCompleted();
   1061             } break;
   1062             case SHOW_FACTORY_ERROR_MSG: {
   1063                 Dialog d = new FactoryErrorDialog(
   1064                     mContext, msg.getData().getCharSequence("msg"));
   1065                 d.show();
   1066                 ensureBootCompleted();
   1067             } break;
   1068             case UPDATE_CONFIGURATION_MSG: {
   1069                 final ContentResolver resolver = mContext.getContentResolver();
   1070                 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
   1071             } break;
   1072             case GC_BACKGROUND_PROCESSES_MSG: {
   1073                 synchronized (ActivityManagerService.this) {
   1074                     performAppGcsIfAppropriateLocked();
   1075                 }
   1076             } break;
   1077             case WAIT_FOR_DEBUGGER_MSG: {
   1078                 synchronized (ActivityManagerService.this) {
   1079                     ProcessRecord app = (ProcessRecord)msg.obj;
   1080                     if (msg.arg1 != 0) {
   1081                         if (!app.waitedForDebugger) {
   1082                             Dialog d = new AppWaitingForDebuggerDialog(
   1083                                     ActivityManagerService.this,
   1084                                     mContext, app);
   1085                             app.waitDialog = d;
   1086                             app.waitedForDebugger = true;
   1087                             d.show();
   1088                         }
   1089                     } else {
   1090                         if (app.waitDialog != null) {
   1091                             app.waitDialog.dismiss();
   1092                             app.waitDialog = null;
   1093                         }
   1094                     }
   1095                 }
   1096             } break;
   1097             case BROADCAST_INTENT_MSG: {
   1098                 if (DEBUG_BROADCAST) Slog.v(
   1099                         TAG, "Received BROADCAST_INTENT_MSG");
   1100                 processNextBroadcast(true);
   1101             } break;
   1102             case BROADCAST_TIMEOUT_MSG: {
   1103                 if (mDidDexOpt) {
   1104                     mDidDexOpt = false;
   1105                     Message nmsg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
   1106                     mHandler.sendMessageDelayed(nmsg, BROADCAST_TIMEOUT);
   1107                     return;
   1108                 }
   1109                 // Only process broadcast timeouts if the system is ready. That way
   1110                 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
   1111                 // to do heavy lifting for system up
   1112                 if (mSystemReady) {
   1113                     broadcastTimeout();
   1114                 }
   1115             } break;
   1116             case PAUSE_TIMEOUT_MSG: {
   1117                 IBinder token = (IBinder)msg.obj;
   1118                 // We don't at this point know if the activity is fullscreen,
   1119                 // so we need to be conservative and assume it isn't.
   1120                 Slog.w(TAG, "Activity pause timeout for " + token);
   1121                 activityPaused(token, null, true);
   1122             } break;
   1123             case IDLE_TIMEOUT_MSG: {
   1124                 if (mDidDexOpt) {
   1125                     mDidDexOpt = false;
   1126                     Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
   1127                     nmsg.obj = msg.obj;
   1128                     mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
   1129                     return;
   1130                 }
   1131                 // We don't at this point know if the activity is fullscreen,
   1132                 // so we need to be conservative and assume it isn't.
   1133                 IBinder token = (IBinder)msg.obj;
   1134                 Slog.w(TAG, "Activity idle timeout for " + token);
   1135                 activityIdleInternal(token, true, null);
   1136             } break;
   1137             case DESTROY_TIMEOUT_MSG: {
   1138                 IBinder token = (IBinder)msg.obj;
   1139                 // We don't at this point know if the activity is fullscreen,
   1140                 // so we need to be conservative and assume it isn't.
   1141                 Slog.w(TAG, "Activity destroy timeout for " + token);
   1142                 activityDestroyed(token);
   1143             } break;
   1144             case IDLE_NOW_MSG: {
   1145                 IBinder token = (IBinder)msg.obj;
   1146                 activityIdle(token, null);
   1147             } break;
   1148             case SERVICE_TIMEOUT_MSG: {
   1149                 if (mDidDexOpt) {
   1150                     mDidDexOpt = false;
   1151                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   1152                     nmsg.obj = msg.obj;
   1153                     mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
   1154                     return;
   1155                 }
   1156                 serviceTimeout((ProcessRecord)msg.obj);
   1157             } break;
   1158             case UPDATE_TIME_ZONE: {
   1159                 synchronized (ActivityManagerService.this) {
   1160                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1161                         ProcessRecord r = mLruProcesses.get(i);
   1162                         if (r.thread != null) {
   1163                             try {
   1164                                 r.thread.updateTimeZone();
   1165                             } catch (RemoteException ex) {
   1166                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
   1167                             }
   1168                         }
   1169                     }
   1170                 }
   1171             } break;
   1172             case SHOW_UID_ERROR_MSG: {
   1173                 // XXX This is a temporary dialog, no need to localize.
   1174                 AlertDialog d = new BaseErrorDialog(mContext);
   1175                 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
   1176                 d.setCancelable(false);
   1177                 d.setTitle("System UIDs Inconsistent");
   1178                 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
   1179                 d.setButton("I'm Feeling Lucky",
   1180                         mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
   1181                 mUidAlert = d;
   1182                 d.show();
   1183             } break;
   1184             case IM_FEELING_LUCKY_MSG: {
   1185                 if (mUidAlert != null) {
   1186                     mUidAlert.dismiss();
   1187                     mUidAlert = null;
   1188                 }
   1189             } break;
   1190             case LAUNCH_TIMEOUT_MSG: {
   1191                 if (mDidDexOpt) {
   1192                     mDidDexOpt = false;
   1193                     Message nmsg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG);
   1194                     mHandler.sendMessageDelayed(nmsg, LAUNCH_TIMEOUT);
   1195                     return;
   1196                 }
   1197                 synchronized (ActivityManagerService.this) {
   1198                     if (mLaunchingActivity.isHeld()) {
   1199                         Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
   1200                         mLaunchingActivity.release();
   1201                     }
   1202                 }
   1203             } break;
   1204             case RESUME_TOP_ACTIVITY_MSG: {
   1205                 synchronized (ActivityManagerService.this) {
   1206                     resumeTopActivityLocked(null);
   1207                 }
   1208             } break;
   1209             case PROC_START_TIMEOUT_MSG: {
   1210                 if (mDidDexOpt) {
   1211                     mDidDexOpt = false;
   1212                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   1213                     nmsg.obj = msg.obj;
   1214                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
   1215                     return;
   1216                 }
   1217                 ProcessRecord app = (ProcessRecord)msg.obj;
   1218                 synchronized (ActivityManagerService.this) {
   1219                     processStartTimedOutLocked(app);
   1220                 }
   1221             } break;
   1222             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
   1223                 synchronized (ActivityManagerService.this) {
   1224                     doPendingActivityLaunchesLocked(true);
   1225                 }
   1226             } break;
   1227             case KILL_APPLICATION_MSG: {
   1228                 synchronized (ActivityManagerService.this) {
   1229                     int uid = msg.arg1;
   1230                     boolean restart = (msg.arg2 == 1);
   1231                     String pkg = (String) msg.obj;
   1232                     forceStopPackageLocked(pkg, uid, restart, false, true);
   1233                 }
   1234             } break;
   1235             case FINALIZE_PENDING_INTENT_MSG: {
   1236                 ((PendingIntentRecord)msg.obj).completeFinalize();
   1237             } break;
   1238             }
   1239         }
   1240     };
   1241 
   1242     public static void setSystemProcess() {
   1243         try {
   1244             ActivityManagerService m = mSelf;
   1245 
   1246             ServiceManager.addService("activity", m);
   1247             ServiceManager.addService("meminfo", new MemBinder(m));
   1248             if (MONITOR_CPU_USAGE) {
   1249                 ServiceManager.addService("cpuinfo", new CpuBinder(m));
   1250             }
   1251             ServiceManager.addService("permission", new PermissionController(m));
   1252 
   1253             ApplicationInfo info =
   1254                 mSelf.mContext.getPackageManager().getApplicationInfo(
   1255                         "android", STOCK_PM_FLAGS);
   1256             mSystemThread.installSystemApplicationInfo(info);
   1257 
   1258             synchronized (mSelf) {
   1259                 ProcessRecord app = mSelf.newProcessRecordLocked(
   1260                         mSystemThread.getApplicationThread(), info,
   1261                         info.processName);
   1262                 app.persistent = true;
   1263                 app.pid = MY_PID;
   1264                 app.maxAdj = SYSTEM_ADJ;
   1265                 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
   1266                 synchronized (mSelf.mPidsSelfLocked) {
   1267                     mSelf.mPidsSelfLocked.put(app.pid, app);
   1268                 }
   1269                 mSelf.updateLruProcessLocked(app, true, true);
   1270             }
   1271         } catch (PackageManager.NameNotFoundException e) {
   1272             throw new RuntimeException(
   1273                     "Unable to find android system package", e);
   1274         }
   1275     }
   1276 
   1277     public void setWindowManager(WindowManagerService wm) {
   1278         mWindowManager = wm;
   1279     }
   1280 
   1281     public static final Context main(int factoryTest) {
   1282         AThread thr = new AThread();
   1283         thr.start();
   1284 
   1285         synchronized (thr) {
   1286             while (thr.mService == null) {
   1287                 try {
   1288                     thr.wait();
   1289                 } catch (InterruptedException e) {
   1290                 }
   1291             }
   1292         }
   1293 
   1294         ActivityManagerService m = thr.mService;
   1295         mSelf = m;
   1296         ActivityThread at = ActivityThread.systemMain();
   1297         mSystemThread = at;
   1298         Context context = at.getSystemContext();
   1299         m.mContext = context;
   1300         m.mFactoryTest = factoryTest;
   1301         PowerManager pm =
   1302             (PowerManager)context.getSystemService(Context.POWER_SERVICE);
   1303         m.mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
   1304         m.mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
   1305         m.mLaunchingActivity.setReferenceCounted(false);
   1306 
   1307         m.mBatteryStatsService.publish(context);
   1308         m.mUsageStatsService.publish(context);
   1309 
   1310         synchronized (thr) {
   1311             thr.mReady = true;
   1312             thr.notifyAll();
   1313         }
   1314 
   1315         m.startRunning(null, null, null, null);
   1316 
   1317         return context;
   1318     }
   1319 
   1320     public static ActivityManagerService self() {
   1321         return mSelf;
   1322     }
   1323 
   1324     static class AThread extends Thread {
   1325         ActivityManagerService mService;
   1326         boolean mReady = false;
   1327 
   1328         public AThread() {
   1329             super("ActivityManager");
   1330         }
   1331 
   1332         public void run() {
   1333             Looper.prepare();
   1334 
   1335             android.os.Process.setThreadPriority(
   1336                     android.os.Process.THREAD_PRIORITY_FOREGROUND);
   1337 
   1338             ActivityManagerService m = new ActivityManagerService();
   1339 
   1340             synchronized (this) {
   1341                 mService = m;
   1342                 notifyAll();
   1343             }
   1344 
   1345             synchronized (this) {
   1346                 while (!mReady) {
   1347                     try {
   1348                         wait();
   1349                     } catch (InterruptedException e) {
   1350                     }
   1351                 }
   1352             }
   1353 
   1354             Looper.loop();
   1355         }
   1356     }
   1357 
   1358     static class MemBinder extends Binder {
   1359         ActivityManagerService mActivityManagerService;
   1360         MemBinder(ActivityManagerService activityManagerService) {
   1361             mActivityManagerService = activityManagerService;
   1362         }
   1363 
   1364         @Override
   1365         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1366             ActivityManagerService service = mActivityManagerService;
   1367             ArrayList<ProcessRecord> procs;
   1368             synchronized (mActivityManagerService) {
   1369                 if (args != null && args.length > 0
   1370                         && args[0].charAt(0) != '-') {
   1371                     procs = new ArrayList<ProcessRecord>();
   1372                     int pid = -1;
   1373                     try {
   1374                         pid = Integer.parseInt(args[0]);
   1375                     } catch (NumberFormatException e) {
   1376 
   1377                     }
   1378                     for (int i=service.mLruProcesses.size()-1; i>=0; i--) {
   1379                         ProcessRecord proc = service.mLruProcesses.get(i);
   1380                         if (proc.pid == pid) {
   1381                             procs.add(proc);
   1382                         } else if (proc.processName.equals(args[0])) {
   1383                             procs.add(proc);
   1384                         }
   1385                     }
   1386                     if (procs.size() <= 0) {
   1387                         pw.println("No process found for: " + args[0]);
   1388                         return;
   1389                     }
   1390                 } else {
   1391                     procs = new ArrayList<ProcessRecord>(service.mLruProcesses);
   1392                 }
   1393             }
   1394             dumpApplicationMemoryUsage(fd, pw, procs, "  ", args);
   1395         }
   1396     }
   1397 
   1398     static class CpuBinder extends Binder {
   1399         ActivityManagerService mActivityManagerService;
   1400         CpuBinder(ActivityManagerService activityManagerService) {
   1401             mActivityManagerService = activityManagerService;
   1402         }
   1403 
   1404         @Override
   1405         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1406             synchronized (mActivityManagerService.mProcessStatsThread) {
   1407                 pw.print(mActivityManagerService.mProcessStats.printCurrentState());
   1408             }
   1409         }
   1410     }
   1411 
   1412     private ActivityManagerService() {
   1413         String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT");
   1414         if (v != null && Integer.getInteger(v) != 0) {
   1415             mSimpleProcessManagement = true;
   1416         }
   1417         v = System.getenv("ANDROID_DEBUG_APP");
   1418         if (v != null) {
   1419             mSimpleProcessManagement = true;
   1420         }
   1421 
   1422         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
   1423 
   1424         File dataDir = Environment.getDataDirectory();
   1425         File systemDir = new File(dataDir, "system");
   1426         systemDir.mkdirs();
   1427         mBatteryStatsService = new BatteryStatsService(new File(
   1428                 systemDir, "batterystats.bin").toString());
   1429         mBatteryStatsService.getActiveStatistics().readLocked();
   1430         mBatteryStatsService.getActiveStatistics().writeLocked();
   1431 
   1432         mUsageStatsService = new UsageStatsService( new File(
   1433                 systemDir, "usagestats").toString());
   1434 
   1435         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
   1436             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
   1437 
   1438         mConfiguration.setToDefaults();
   1439         mConfiguration.locale = Locale.getDefault();
   1440         mProcessStats.init();
   1441 
   1442         // Add ourself to the Watchdog monitors.
   1443         Watchdog.getInstance().addMonitor(this);
   1444 
   1445         mProcessStatsThread = new Thread("ProcessStats") {
   1446             public void run() {
   1447                 while (true) {
   1448                     try {
   1449                         try {
   1450                             synchronized(this) {
   1451                                 final long now = SystemClock.uptimeMillis();
   1452                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
   1453                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
   1454                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
   1455                                 //        + ", write delay=" + nextWriteDelay);
   1456                                 if (nextWriteDelay < nextCpuDelay) {
   1457                                     nextCpuDelay = nextWriteDelay;
   1458                                 }
   1459                                 if (nextCpuDelay > 0) {
   1460                                     mProcessStatsMutexFree.set(true);
   1461                                     this.wait(nextCpuDelay);
   1462                                 }
   1463                             }
   1464                         } catch (InterruptedException e) {
   1465                         }
   1466                         updateCpuStatsNow();
   1467                     } catch (Exception e) {
   1468                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
   1469                     }
   1470                 }
   1471             }
   1472         };
   1473         mProcessStatsThread.start();
   1474     }
   1475 
   1476     @Override
   1477     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   1478             throws RemoteException {
   1479         try {
   1480             return super.onTransact(code, data, reply, flags);
   1481         } catch (RuntimeException e) {
   1482             // The activity manager only throws security exceptions, so let's
   1483             // log all others.
   1484             if (!(e instanceof SecurityException)) {
   1485                 Slog.e(TAG, "Activity Manager Crash", e);
   1486             }
   1487             throw e;
   1488         }
   1489     }
   1490 
   1491     void updateCpuStats() {
   1492         final long now = SystemClock.uptimeMillis();
   1493         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
   1494             return;
   1495         }
   1496         if (mProcessStatsMutexFree.compareAndSet(true, false)) {
   1497             synchronized (mProcessStatsThread) {
   1498                 mProcessStatsThread.notify();
   1499             }
   1500         }
   1501     }
   1502 
   1503     void updateCpuStatsNow() {
   1504         synchronized (mProcessStatsThread) {
   1505             mProcessStatsMutexFree.set(false);
   1506             final long now = SystemClock.uptimeMillis();
   1507             boolean haveNewCpuStats = false;
   1508 
   1509             if (MONITOR_CPU_USAGE &&
   1510                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
   1511                 mLastCpuTime.set(now);
   1512                 haveNewCpuStats = true;
   1513                 mProcessStats.update();
   1514                 //Slog.i(TAG, mProcessStats.printCurrentState());
   1515                 //Slog.i(TAG, "Total CPU usage: "
   1516                 //        + mProcessStats.getTotalCpuPercent() + "%");
   1517 
   1518                 // Slog the cpu usage if the property is set.
   1519                 if ("true".equals(SystemProperties.get("events.cpu"))) {
   1520                     int user = mProcessStats.getLastUserTime();
   1521                     int system = mProcessStats.getLastSystemTime();
   1522                     int iowait = mProcessStats.getLastIoWaitTime();
   1523                     int irq = mProcessStats.getLastIrqTime();
   1524                     int softIrq = mProcessStats.getLastSoftIrqTime();
   1525                     int idle = mProcessStats.getLastIdleTime();
   1526 
   1527                     int total = user + system + iowait + irq + softIrq + idle;
   1528                     if (total == 0) total = 1;
   1529 
   1530                     EventLog.writeEvent(EventLogTags.CPU,
   1531                             ((user+system+iowait+irq+softIrq) * 100) / total,
   1532                             (user * 100) / total,
   1533                             (system * 100) / total,
   1534                             (iowait * 100) / total,
   1535                             (irq * 100) / total,
   1536                             (softIrq * 100) / total);
   1537                 }
   1538             }
   1539 
   1540             long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
   1541             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
   1542             synchronized(bstats) {
   1543                 synchronized(mPidsSelfLocked) {
   1544                     if (haveNewCpuStats) {
   1545                         if (mBatteryStatsService.isOnBattery()) {
   1546                             final int N = mProcessStats.countWorkingStats();
   1547                             for (int i=0; i<N; i++) {
   1548                                 ProcessStats.Stats st
   1549                                         = mProcessStats.getWorkingStats(i);
   1550                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
   1551                                 if (pr != null) {
   1552                                     BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
   1553                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
   1554                                     ps.addSpeedStepTimes(cpuSpeedTimes);
   1555                                 } else {
   1556                                     BatteryStatsImpl.Uid.Proc ps =
   1557                                             bstats.getProcessStatsLocked(st.name, st.pid);
   1558                                     if (ps != null) {
   1559                                         ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
   1560                                         ps.addSpeedStepTimes(cpuSpeedTimes);
   1561                                     }
   1562                                 }
   1563                             }
   1564                         }
   1565                     }
   1566                 }
   1567 
   1568                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
   1569                     mLastWriteTime = now;
   1570                     mBatteryStatsService.getActiveStatistics().writeLocked();
   1571                 }
   1572             }
   1573         }
   1574     }
   1575 
   1576     /**
   1577      * Initialize the application bind args. These are passed to each
   1578      * process when the bindApplication() IPC is sent to the process. They're
   1579      * lazily setup to make sure the services are running when they're asked for.
   1580      */
   1581     private HashMap<String, IBinder> getCommonServicesLocked() {
   1582         if (mAppBindArgs == null) {
   1583             mAppBindArgs = new HashMap<String, IBinder>();
   1584 
   1585             // Setup the application init args
   1586             mAppBindArgs.put("package", ServiceManager.getService("package"));
   1587             mAppBindArgs.put("window", ServiceManager.getService("window"));
   1588             mAppBindArgs.put(Context.ALARM_SERVICE,
   1589                     ServiceManager.getService(Context.ALARM_SERVICE));
   1590         }
   1591         return mAppBindArgs;
   1592     }
   1593 
   1594     private final void setFocusedActivityLocked(HistoryRecord r) {
   1595         if (mFocusedActivity != r) {
   1596             mFocusedActivity = r;
   1597             mWindowManager.setFocusedApp(r, true);
   1598         }
   1599     }
   1600 
   1601     private final void updateLruProcessInternalLocked(ProcessRecord app,
   1602             boolean oomAdj, boolean updateActivityTime, int bestPos) {
   1603         // put it on the LRU to keep track of when it should be exited.
   1604         int lrui = mLruProcesses.indexOf(app);
   1605         if (lrui >= 0) mLruProcesses.remove(lrui);
   1606 
   1607         int i = mLruProcesses.size()-1;
   1608         int skipTop = 0;
   1609 
   1610         app.lruSeq = mLruSeq;
   1611 
   1612         // compute the new weight for this process.
   1613         if (updateActivityTime) {
   1614             app.lastActivityTime = SystemClock.uptimeMillis();
   1615         }
   1616         if (app.activities.size() > 0) {
   1617             // If this process has activities, we more strongly want to keep
   1618             // it around.
   1619             app.lruWeight = app.lastActivityTime;
   1620         } else if (app.pubProviders.size() > 0) {
   1621             // If this process contains content providers, we want to keep
   1622             // it a little more strongly.
   1623             app.lruWeight = app.lastActivityTime - CONTENT_APP_IDLE_OFFSET;
   1624             // Also don't let it kick out the first few "real" hidden processes.
   1625             skipTop = MIN_HIDDEN_APPS;
   1626         } else {
   1627             // If this process doesn't have activities, we less strongly
   1628             // want to keep it around, and generally want to avoid getting
   1629             // in front of any very recently used activities.
   1630             app.lruWeight = app.lastActivityTime - EMPTY_APP_IDLE_OFFSET;
   1631             // Also don't let it kick out the first few "real" hidden processes.
   1632             skipTop = MIN_HIDDEN_APPS;
   1633         }
   1634 
   1635         while (i >= 0) {
   1636             ProcessRecord p = mLruProcesses.get(i);
   1637             // If this app shouldn't be in front of the first N background
   1638             // apps, then skip over that many that are currently hidden.
   1639             if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) {
   1640                 skipTop--;
   1641             }
   1642             if (p.lruWeight <= app.lruWeight || i < bestPos) {
   1643                 mLruProcesses.add(i+1, app);
   1644                 break;
   1645             }
   1646             i--;
   1647         }
   1648         if (i < 0) {
   1649             mLruProcesses.add(0, app);
   1650         }
   1651 
   1652         // If the app is currently using a content provider or service,
   1653         // bump those processes as well.
   1654         if (app.connections.size() > 0) {
   1655             for (ConnectionRecord cr : app.connections) {
   1656                 if (cr.binding != null && cr.binding.service != null
   1657                         && cr.binding.service.app != null
   1658                         && cr.binding.service.app.lruSeq != mLruSeq) {
   1659                     updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
   1660                             updateActivityTime, i+1);
   1661                 }
   1662             }
   1663         }
   1664         if (app.conProviders.size() > 0) {
   1665             for (ContentProviderRecord cpr : app.conProviders.keySet()) {
   1666                 if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
   1667                     updateLruProcessInternalLocked(cpr.app, oomAdj,
   1668                             updateActivityTime, i+1);
   1669                 }
   1670             }
   1671         }
   1672 
   1673         //Slog.i(TAG, "Putting proc to front: " + app.processName);
   1674         if (oomAdj) {
   1675             updateOomAdjLocked();
   1676         }
   1677     }
   1678 
   1679     private final void updateLruProcessLocked(ProcessRecord app,
   1680             boolean oomAdj, boolean updateActivityTime) {
   1681         mLruSeq++;
   1682         updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
   1683     }
   1684 
   1685     private final boolean updateLRUListLocked(HistoryRecord r) {
   1686         final boolean hadit = mLRUActivities.remove(r);
   1687         mLRUActivities.add(r);
   1688         return hadit;
   1689     }
   1690 
   1691     private final HistoryRecord topRunningActivityLocked(HistoryRecord notTop) {
   1692         int i = mHistory.size()-1;
   1693         while (i >= 0) {
   1694             HistoryRecord r = (HistoryRecord)mHistory.get(i);
   1695             if (!r.finishing && r != notTop) {
   1696                 return r;
   1697             }
   1698             i--;
   1699         }
   1700         return null;
   1701     }
   1702 
   1703     private final HistoryRecord topRunningNonDelayedActivityLocked(HistoryRecord notTop) {
   1704         int i = mHistory.size()-1;
   1705         while (i >= 0) {
   1706             HistoryRecord r = (HistoryRecord)mHistory.get(i);
   1707             if (!r.finishing && !r.delayedResume && r != notTop) {
   1708                 return r;
   1709             }
   1710             i--;
   1711         }
   1712         return null;
   1713     }
   1714 
   1715     /**
   1716      * This is a simplified version of topRunningActivityLocked that provides a number of
   1717      * optional skip-over modes.  It is intended for use with the ActivityController hook only.
   1718      *
   1719      * @param token If non-null, any history records matching this token will be skipped.
   1720      * @param taskId If non-zero, we'll attempt to skip over records with the same task ID.
   1721      *
   1722      * @return Returns the HistoryRecord of the next activity on the stack.
   1723      */
   1724     private final HistoryRecord topRunningActivityLocked(IBinder token, int taskId) {
   1725         int i = mHistory.size()-1;
   1726         while (i >= 0) {
   1727             HistoryRecord r = (HistoryRecord)mHistory.get(i);
   1728             // Note: the taskId check depends on real taskId fields being non-zero
   1729             if (!r.finishing && (token != r) && (taskId != r.task.taskId)) {
   1730                 return r;
   1731             }
   1732             i--;
   1733         }
   1734         return null;
   1735     }
   1736 
   1737     private final ProcessRecord getProcessRecordLocked(
   1738             String processName, int uid) {
   1739         if (uid == Process.SYSTEM_UID) {
   1740             // The system gets to run in any process.  If there are multiple
   1741             // processes with the same uid, just pick the first (this
   1742             // should never happen).
   1743             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
   1744                     processName);
   1745             return procs != null ? procs.valueAt(0) : null;
   1746         }
   1747         ProcessRecord proc = mProcessNames.get(processName, uid);
   1748         return proc;
   1749     }
   1750 
   1751     private void ensurePackageDexOpt(String packageName) {
   1752         IPackageManager pm = ActivityThread.getPackageManager();
   1753         try {
   1754             if (pm.performDexOpt(packageName)) {
   1755                 mDidDexOpt = true;
   1756             }
   1757         } catch (RemoteException e) {
   1758         }
   1759     }
   1760 
   1761     private boolean isNextTransitionForward() {
   1762         int transit = mWindowManager.getPendingAppTransition();
   1763         return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
   1764                 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
   1765                 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
   1766     }
   1767 
   1768     private final boolean realStartActivityLocked(HistoryRecord r,
   1769             ProcessRecord app, boolean andResume, boolean checkConfig)
   1770             throws RemoteException {
   1771 
   1772         r.startFreezingScreenLocked(app, 0);
   1773         mWindowManager.setAppVisibility(r, true);
   1774 
   1775         // Have the window manager re-evaluate the orientation of
   1776         // the screen based on the new activity order.  Note that
   1777         // as a result of this, it can call back into the activity
   1778         // manager with a new orientation.  We don't care about that,
   1779         // because the activity is not currently running so we are
   1780         // just restarting it anyway.
   1781         if (checkConfig) {
   1782             Configuration config = mWindowManager.updateOrientationFromAppTokens(
   1783                     mConfiguration,
   1784                     r.mayFreezeScreenLocked(app) ? r : null);
   1785             updateConfigurationLocked(config, r);
   1786         }
   1787 
   1788         r.app = app;
   1789 
   1790         if (localLOGV) Slog.v(TAG, "Launching: " + r);
   1791 
   1792         int idx = app.activities.indexOf(r);
   1793         if (idx < 0) {
   1794             app.activities.add(r);
   1795         }
   1796         updateLruProcessLocked(app, true, true);
   1797 
   1798         try {
   1799             if (app.thread == null) {
   1800                 throw new RemoteException();
   1801             }
   1802             List<ResultInfo> results = null;
   1803             List<Intent> newIntents = null;
   1804             if (andResume) {
   1805                 results = r.results;
   1806                 newIntents = r.newIntents;
   1807             }
   1808             if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
   1809                     + " icicle=" + r.icicle
   1810                     + " with results=" + results + " newIntents=" + newIntents
   1811                     + " andResume=" + andResume);
   1812             if (andResume) {
   1813                 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
   1814                         System.identityHashCode(r),
   1815                         r.task.taskId, r.shortComponentName);
   1816             }
   1817             if (r.isHomeActivity) {
   1818                 mHomeProcess = app;
   1819             }
   1820             ensurePackageDexOpt(r.intent.getComponent().getPackageName());
   1821             app.thread.scheduleLaunchActivity(new Intent(r.intent), r,
   1822                     System.identityHashCode(r),
   1823                     r.info, r.icicle, results, newIntents, !andResume,
   1824                     isNextTransitionForward());
   1825         } catch (RemoteException e) {
   1826             if (r.launchFailed) {
   1827                 // This is the second time we failed -- finish activity
   1828                 // and give up.
   1829                 Slog.e(TAG, "Second failure launching "
   1830                       + r.intent.getComponent().flattenToShortString()
   1831                       + ", giving up", e);
   1832                 appDiedLocked(app, app.pid, app.thread);
   1833                 requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null,
   1834                         "2nd-crash");
   1835                 return false;
   1836             }
   1837 
   1838             // This is the first time we failed -- restart process and
   1839             // retry.
   1840             app.activities.remove(r);
   1841             throw e;
   1842         }
   1843 
   1844         r.launchFailed = false;
   1845         if (updateLRUListLocked(r)) {
   1846             Slog.w(TAG, "Activity " + r
   1847                   + " being launched, but already in LRU list");
   1848         }
   1849 
   1850         if (andResume) {
   1851             // As part of the process of launching, ActivityThread also performs
   1852             // a resume.
   1853             r.state = ActivityState.RESUMED;
   1854             r.icicle = null;
   1855             r.haveState = false;
   1856             r.stopped = false;
   1857             mResumedActivity = r;
   1858             r.task.touchActiveTime();
   1859             completeResumeLocked(r);
   1860             pauseIfSleepingLocked();
   1861         } else {
   1862             // This activity is not starting in the resumed state... which
   1863             // should look like we asked it to pause+stop (but remain visible),
   1864             // and it has done so and reported back the current icicle and
   1865             // other state.
   1866             r.state = ActivityState.STOPPED;
   1867             r.stopped = true;
   1868         }
   1869 
   1870         // Launch the new version setup screen if needed.  We do this -after-
   1871         // launching the initial activity (that is, home), so that it can have
   1872         // a chance to initialize itself while in the background, making the
   1873         // switch back to it faster and look better.
   1874         startSetupActivityLocked();
   1875 
   1876         return true;
   1877     }
   1878 
   1879     private final void startSpecificActivityLocked(HistoryRecord r,
   1880             boolean andResume, boolean checkConfig) {
   1881         // Is this activity's application already running?
   1882         ProcessRecord app = getProcessRecordLocked(r.processName,
   1883                 r.info.applicationInfo.uid);
   1884 
   1885         if (r.startTime == 0) {
   1886             r.startTime = SystemClock.uptimeMillis();
   1887             if (mInitialStartTime == 0) {
   1888                 mInitialStartTime = r.startTime;
   1889             }
   1890         } else if (mInitialStartTime == 0) {
   1891             mInitialStartTime = SystemClock.uptimeMillis();
   1892         }
   1893 
   1894         if (app != null && app.thread != null) {
   1895             try {
   1896                 realStartActivityLocked(r, app, andResume, checkConfig);
   1897                 return;
   1898             } catch (RemoteException e) {
   1899                 Slog.w(TAG, "Exception when starting activity "
   1900                         + r.intent.getComponent().flattenToShortString(), e);
   1901             }
   1902 
   1903             // If a dead object exception was thrown -- fall through to
   1904             // restart the application.
   1905         }
   1906 
   1907         startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
   1908                 "activity", r.intent.getComponent(), false);
   1909     }
   1910 
   1911     private final ProcessRecord startProcessLocked(String processName,
   1912             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
   1913             String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
   1914         ProcessRecord app = getProcessRecordLocked(processName, info.uid);
   1915         // We don't have to do anything more if:
   1916         // (1) There is an existing application record; and
   1917         // (2) The caller doesn't think it is dead, OR there is no thread
   1918         //     object attached to it so we know it couldn't have crashed; and
   1919         // (3) There is a pid assigned to it, so it is either starting or
   1920         //     already running.
   1921         if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
   1922                 + " app=" + app + " knownToBeDead=" + knownToBeDead
   1923                 + " thread=" + (app != null ? app.thread : null)
   1924                 + " pid=" + (app != null ? app.pid : -1));
   1925         if (app != null && app.pid > 0) {
   1926             if (!knownToBeDead || app.thread == null) {
   1927                 // We already have the app running, or are waiting for it to
   1928                 // come up (we have a pid but not yet its thread), so keep it.
   1929                 return app;
   1930             } else {
   1931                 // An application record is attached to a previous process,
   1932                 // clean it up now.
   1933                 handleAppDiedLocked(app, true);
   1934             }
   1935         }
   1936 
   1937         String hostingNameStr = hostingName != null
   1938                 ? hostingName.flattenToShortString() : null;
   1939 
   1940         if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
   1941             // If we are in the background, then check to see if this process
   1942             // is bad.  If so, we will just silently fail.
   1943             if (mBadProcesses.get(info.processName, info.uid) != null) {
   1944                 return null;
   1945             }
   1946         } else {
   1947             // When the user is explicitly starting a process, then clear its
   1948             // crash count so that we won't make it bad until they see at
   1949             // least one crash dialog again, and make the process good again
   1950             // if it had been bad.
   1951             mProcessCrashTimes.remove(info.processName, info.uid);
   1952             if (mBadProcesses.get(info.processName, info.uid) != null) {
   1953                 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
   1954                         info.processName);
   1955                 mBadProcesses.remove(info.processName, info.uid);
   1956                 if (app != null) {
   1957                     app.bad = false;
   1958                 }
   1959             }
   1960         }
   1961 
   1962         if (app == null) {
   1963             app = newProcessRecordLocked(null, info, processName);
   1964             mProcessNames.put(processName, info.uid, app);
   1965         } else {
   1966             // If this is a new package in the process, add the package to the list
   1967             app.addPackage(info.packageName);
   1968         }
   1969 
   1970         // If the system is not ready yet, then hold off on starting this
   1971         // process until it is.
   1972         if (!mSystemReady
   1973                 && !isAllowedWhileBooting(info)
   1974                 && !allowWhileBooting) {
   1975             if (!mProcessesOnHold.contains(app)) {
   1976                 mProcessesOnHold.add(app);
   1977             }
   1978             return app;
   1979         }
   1980 
   1981         startProcessLocked(app, hostingType, hostingNameStr);
   1982         return (app.pid != 0) ? app : null;
   1983     }
   1984 
   1985     boolean isAllowedWhileBooting(ApplicationInfo ai) {
   1986         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
   1987     }
   1988 
   1989     private final void startProcessLocked(ProcessRecord app,
   1990             String hostingType, String hostingNameStr) {
   1991         if (app.pid > 0 && app.pid != MY_PID) {
   1992             synchronized (mPidsSelfLocked) {
   1993                 mPidsSelfLocked.remove(app.pid);
   1994                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   1995             }
   1996             app.pid = 0;
   1997         }
   1998 
   1999         mProcessesOnHold.remove(app);
   2000 
   2001         updateCpuStats();
   2002 
   2003         System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
   2004         mProcDeaths[0] = 0;
   2005 
   2006         try {
   2007             int uid = app.info.uid;
   2008             int[] gids = null;
   2009             try {
   2010                 gids = mContext.getPackageManager().getPackageGids(
   2011                         app.info.packageName);
   2012             } catch (PackageManager.NameNotFoundException e) {
   2013                 Slog.w(TAG, "Unable to retrieve gids", e);
   2014             }
   2015             if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
   2016                 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
   2017                         && mTopComponent != null
   2018                         && app.processName.equals(mTopComponent.getPackageName())) {
   2019                     uid = 0;
   2020                 }
   2021                 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
   2022                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
   2023                     uid = 0;
   2024                 }
   2025             }
   2026             int debugFlags = 0;
   2027             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   2028                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
   2029             }
   2030             // Run the app in safe mode if its manifest requests so or the
   2031             // system is booted in safe mode.
   2032             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
   2033                 Zygote.systemInSafeMode == true) {
   2034                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
   2035             }
   2036             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
   2037                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   2038             }
   2039             if ("1".equals(SystemProperties.get("debug.assert"))) {
   2040                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
   2041             }
   2042             int pid = Process.start("android.app.ActivityThread",
   2043                     mSimpleProcessManagement ? app.processName : null, uid, uid,
   2044                     gids, debugFlags, null);
   2045             BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
   2046             synchronized (bs) {
   2047                 if (bs.isOnBattery()) {
   2048                     app.batteryStats.incStartsLocked();
   2049                 }
   2050             }
   2051 
   2052             EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid,
   2053                     app.processName, hostingType,
   2054                     hostingNameStr != null ? hostingNameStr : "");
   2055 
   2056             if (app.persistent) {
   2057                 Watchdog.getInstance().processStarted(app, app.processName, pid);
   2058             }
   2059 
   2060             StringBuilder buf = mStringBuilder;
   2061             buf.setLength(0);
   2062             buf.append("Start proc ");
   2063             buf.append(app.processName);
   2064             buf.append(" for ");
   2065             buf.append(hostingType);
   2066             if (hostingNameStr != null) {
   2067                 buf.append(" ");
   2068                 buf.append(hostingNameStr);
   2069             }
   2070             buf.append(": pid=");
   2071             buf.append(pid);
   2072             buf.append(" uid=");
   2073             buf.append(uid);
   2074             buf.append(" gids={");
   2075             if (gids != null) {
   2076                 for (int gi=0; gi<gids.length; gi++) {
   2077                     if (gi != 0) buf.append(", ");
   2078                     buf.append(gids[gi]);
   2079 
   2080                 }
   2081             }
   2082             buf.append("}");
   2083             Slog.i(TAG, buf.toString());
   2084             if (pid == 0 || pid == MY_PID) {
   2085                 // Processes are being emulated with threads.
   2086                 app.pid = MY_PID;
   2087                 app.removed = false;
   2088                 mStartingProcesses.add(app);
   2089             } else if (pid > 0) {
   2090                 app.pid = pid;
   2091                 app.removed = false;
   2092                 synchronized (mPidsSelfLocked) {
   2093                     this.mPidsSelfLocked.put(pid, app);
   2094                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   2095                     msg.obj = app;
   2096                     mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
   2097                 }
   2098             } else {
   2099                 app.pid = 0;
   2100                 RuntimeException e = new RuntimeException(
   2101                         "Failure starting process " + app.processName
   2102                         + ": returned pid=" + pid);
   2103                 Slog.e(TAG, e.getMessage(), e);
   2104             }
   2105         } catch (RuntimeException e) {
   2106             // XXX do better error recovery.
   2107             app.pid = 0;
   2108             Slog.e(TAG, "Failure starting process " + app.processName, e);
   2109         }
   2110     }
   2111 
   2112     private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {
   2113         if (mPausingActivity != null) {
   2114             RuntimeException e = new RuntimeException();
   2115             Slog.e(TAG, "Trying to pause when pause is already pending for "
   2116                   + mPausingActivity, e);
   2117         }
   2118         HistoryRecord prev = mResumedActivity;
   2119         if (prev == null) {
   2120             RuntimeException e = new RuntimeException();
   2121             Slog.e(TAG, "Trying to pause when nothing is resumed", e);
   2122             resumeTopActivityLocked(null);
   2123             return;
   2124         }
   2125         if (DEBUG_PAUSE) Slog.v(TAG, "Start pausing: " + prev);
   2126         mResumedActivity = null;
   2127         mPausingActivity = prev;
   2128         mLastPausedActivity = prev;
   2129         prev.state = ActivityState.PAUSING;
   2130         prev.task.touchActiveTime();
   2131 
   2132         updateCpuStats();
   2133 
   2134         if (prev.app != null && prev.app.thread != null) {
   2135             if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending pause: " + prev);
   2136             try {
   2137                 EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
   2138                         System.identityHashCode(prev),
   2139                         prev.shortComponentName);
   2140                 prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving,
   2141                         prev.configChangeFlags);
   2142                 updateUsageStats(prev, false);
   2143             } catch (Exception e) {
   2144                 // Ignore exception, if process died other code will cleanup.
   2145                 Slog.w(TAG, "Exception thrown during pause", e);
   2146                 mPausingActivity = null;
   2147                 mLastPausedActivity = null;
   2148             }
   2149         } else {
   2150             mPausingActivity = null;
   2151             mLastPausedActivity = null;
   2152         }
   2153 
   2154         // If we are not going to sleep, we want to ensure the device is
   2155         // awake until the next activity is started.
   2156         if (!mSleeping && !mShuttingDown) {
   2157             mLaunchingActivity.acquire();
   2158             if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
   2159                 // To be safe, don't allow the wake lock to be held for too long.
   2160                 Message msg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG);
   2161                 mHandler.sendMessageDelayed(msg, LAUNCH_TIMEOUT);
   2162             }
   2163         }
   2164 
   2165 
   2166         if (mPausingActivity != null) {
   2167             // Have the window manager pause its key dispatching until the new
   2168             // activity has started.  If we're pausing the activity just because
   2169             // the screen is being turned off and the UI is sleeping, don't interrupt
   2170             // key dispatch; the same activity will pick it up again on wakeup.
   2171             if (!uiSleeping) {
   2172                 prev.pauseKeyDispatchingLocked();
   2173             } else {
   2174                 if (DEBUG_PAUSE) Slog.v(TAG, "Key dispatch not paused for screen off");
   2175             }
   2176 
   2177             // Schedule a pause timeout in case the app doesn't respond.
   2178             // We don't give it much time because this directly impacts the
   2179             // responsiveness seen by the user.
   2180             Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
   2181             msg.obj = prev;
   2182             mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
   2183             if (DEBUG_PAUSE) Slog.v(TAG, "Waiting for pause to complete...");
   2184         } else {
   2185             // This activity failed to schedule the
   2186             // pause, so just treat it as being paused now.
   2187             if (DEBUG_PAUSE) Slog.v(TAG, "Activity not running, resuming next.");
   2188             resumeTopActivityLocked(null);
   2189         }
   2190     }
   2191 
   2192     private final void completePauseLocked() {
   2193         HistoryRecord prev = mPausingActivity;
   2194         if (DEBUG_PAUSE) Slog.v(TAG, "Complete pause: " + prev);
   2195 
   2196         if (prev != null) {
   2197             if (prev.finishing) {
   2198                 if (DEBUG_PAUSE) Slog.v(TAG, "Executing finish of activity: " + prev);
   2199                 prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE);
   2200             } else if (prev.app != null) {
   2201                 if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending stop: " + prev);
   2202                 if (prev.waitingVisible) {
   2203                     prev.waitingVisible = false;
   2204                     mWaitingVisibleActivities.remove(prev);
   2205                     if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(
   2206                             TAG, "Complete pause, no longer waiting: " + prev);
   2207                 }
   2208                 if (prev.configDestroy) {
   2209                     // The previous is being paused because the configuration
   2210                     // is changing, which means it is actually stopping...
   2211                     // To juggle the fact that we are also starting a new
   2212                     // instance right now, we need to first completely stop
   2213                     // the current instance before starting the new one.
   2214                     if (DEBUG_PAUSE) Slog.v(TAG, "Destroying after pause: " + prev);
   2215                     destroyActivityLocked(prev, true);
   2216                 } else {
   2217                     mStoppingActivities.add(prev);
   2218                     if (mStoppingActivities.size() > 3) {
   2219                         // If we already have a few activities waiting to stop,
   2220                         // then give up on things going idle and start clearing
   2221                         // them out.
   2222                         if (DEBUG_PAUSE) Slog.v(TAG, "To many pending stops, forcing idle");
   2223                         Message msg = Message.obtain();
   2224                         msg.what = ActivityManagerService.IDLE_NOW_MSG;
   2225                         mHandler.sendMessage(msg);
   2226                     }
   2227                 }
   2228             } else {
   2229                 if (DEBUG_PAUSE) Slog.v(TAG, "App died during pause, not stopping: " + prev);
   2230                 prev = null;
   2231             }
   2232             mPausingActivity = null;
   2233         }
   2234 
   2235         if (!mSleeping && !mShuttingDown) {
   2236             resumeTopActivityLocked(prev);
   2237         } else {
   2238             if (mGoingToSleep.isHeld()) {
   2239                 mGoingToSleep.release();
   2240             }
   2241             if (mShuttingDown) {
   2242                 notifyAll();
   2243             }
   2244         }
   2245 
   2246         if (prev != null) {
   2247             prev.resumeKeyDispatchingLocked();
   2248         }
   2249 
   2250         if (prev.app != null && prev.cpuTimeAtResume > 0 && mBatteryStatsService.isOnBattery()) {
   2251             long diff = 0;
   2252             synchronized (mProcessStatsThread) {
   2253                 diff = mProcessStats.getCpuTimeForPid(prev.app.pid) - prev.cpuTimeAtResume;
   2254             }
   2255             if (diff > 0) {
   2256                 BatteryStatsImpl bsi = mBatteryStatsService.getActiveStatistics();
   2257                 synchronized (bsi) {
   2258                     BatteryStatsImpl.Uid.Proc ps =
   2259                             bsi.getProcessStatsLocked(prev.info.applicationInfo.uid,
   2260                             prev.info.packageName);
   2261                     if (ps != null) {
   2262                         ps.addForegroundTimeLocked(diff);
   2263                     }
   2264                 }
   2265             }
   2266         }
   2267         prev.cpuTimeAtResume = 0; // reset it
   2268     }
   2269 
   2270     /**
   2271      * Once we know that we have asked an application to put an activity in
   2272      * the resumed state (either by launching it or explicitly telling it),
   2273      * this function updates the rest of our state to match that fact.
   2274      */
   2275     private final void completeResumeLocked(HistoryRecord next) {
   2276         next.idle = false;
   2277         next.results = null;
   2278         next.newIntents = null;
   2279 
   2280         // schedule an idle timeout in case the app doesn't do it for us.
   2281         Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
   2282         msg.obj = next;
   2283         mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
   2284 
   2285         if (false) {
   2286             // The activity was never told to pause, so just keep
   2287             // things going as-is.  To maintain our own state,
   2288             // we need to emulate it coming back and saying it is
   2289             // idle.
   2290             msg = mHandler.obtainMessage(IDLE_NOW_MSG);
   2291             msg.obj = next;
   2292             mHandler.sendMessage(msg);
   2293         }
   2294 
   2295         reportResumedActivityLocked(next);
   2296 
   2297         next.thumbnail = null;
   2298         setFocusedActivityLocked(next);
   2299         next.resumeKeyDispatchingLocked();
   2300         ensureActivitiesVisibleLocked(null, 0);
   2301         mWindowManager.executeAppTransition();
   2302         mNoAnimActivities.clear();
   2303 
   2304         // Mark the point when the activity is resuming
   2305         // TODO: To be more accurate, the mark should be before the onCreate,
   2306         //       not after the onResume. But for subsequent starts, onResume is fine.
   2307         if (next.app != null) {
   2308             synchronized (mProcessStatsThread) {
   2309                 next.cpuTimeAtResume = mProcessStats.getCpuTimeForPid(next.app.pid);
   2310             }
   2311         } else {
   2312             next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process
   2313         }
   2314     }
   2315 
   2316     /**
   2317      * Make sure that all activities that need to be visible (that is, they
   2318      * currently can be seen by the user) actually are.
   2319      */
   2320     private final void ensureActivitiesVisibleLocked(HistoryRecord top,
   2321             HistoryRecord starting, String onlyThisProcess, int configChanges) {
   2322         if (DEBUG_VISBILITY) Slog.v(
   2323                 TAG, "ensureActivitiesVisible behind " + top
   2324                 + " configChanges=0x" + Integer.toHexString(configChanges));
   2325 
   2326         // If the top activity is not fullscreen, then we need to
   2327         // make sure any activities under it are now visible.
   2328         final int count = mHistory.size();
   2329         int i = count-1;
   2330         while (mHistory.get(i) != top) {
   2331             i--;
   2332         }
   2333         HistoryRecord r;
   2334         boolean behindFullscreen = false;
   2335         for (; i>=0; i--) {
   2336             r = (HistoryRecord)mHistory.get(i);
   2337             if (DEBUG_VISBILITY) Slog.v(
   2338                     TAG, "Make visible? " + r + " finishing=" + r.finishing
   2339                     + " state=" + r.state);
   2340             if (r.finishing) {
   2341                 continue;
   2342             }
   2343 
   2344             final boolean doThisProcess = onlyThisProcess == null
   2345                     || onlyThisProcess.equals(r.processName);
   2346 
   2347             // First: if this is not the current activity being started, make
   2348             // sure it matches the current configuration.
   2349             if (r != starting && doThisProcess) {
   2350                 ensureActivityConfigurationLocked(r, 0);
   2351             }
   2352 
   2353             if (r.app == null || r.app.thread == null) {
   2354                 if (onlyThisProcess == null
   2355                         || onlyThisProcess.equals(r.processName)) {
   2356                     // This activity needs to be visible, but isn't even
   2357                     // running...  get it started, but don't resume it
   2358                     // at this point.
   2359                     if (DEBUG_VISBILITY) Slog.v(
   2360                             TAG, "Start and freeze screen for " + r);
   2361                     if (r != starting) {
   2362                         r.startFreezingScreenLocked(r.app, configChanges);
   2363                     }
   2364                     if (!r.visible) {
   2365                         if (DEBUG_VISBILITY) Slog.v(
   2366                                 TAG, "Starting and making visible: " + r);
   2367                         mWindowManager.setAppVisibility(r, true);
   2368                     }
   2369                     if (r != starting) {
   2370                         startSpecificActivityLocked(r, false, false);
   2371                     }
   2372                 }
   2373 
   2374             } else if (r.visible) {
   2375                 // If this activity is already visible, then there is nothing
   2376                 // else to do here.
   2377                 if (DEBUG_VISBILITY) Slog.v(
   2378                         TAG, "Skipping: already visible at " + r);
   2379                 r.stopFreezingScreenLocked(false);
   2380 
   2381             } else if (onlyThisProcess == null) {
   2382                 // This activity is not currently visible, but is running.
   2383                 // Tell it to become visible.
   2384                 r.visible = true;
   2385                 if (r.state != ActivityState.RESUMED && r != starting) {
   2386                     // If this activity is paused, tell it
   2387                     // to now show its window.
   2388                     if (DEBUG_VISBILITY) Slog.v(
   2389                             TAG, "Making visible and scheduling visibility: " + r);
   2390                     try {
   2391                         mWindowManager.setAppVisibility(r, true);
   2392                         r.app.thread.scheduleWindowVisibility(r, true);
   2393                         r.stopFreezingScreenLocked(false);
   2394                     } catch (Exception e) {
   2395                         // Just skip on any failure; we'll make it
   2396                         // visible when it next restarts.
   2397                         Slog.w(TAG, "Exception thrown making visibile: "
   2398                                 + r.intent.getComponent(), e);
   2399                     }
   2400                 }
   2401             }
   2402 
   2403             // Aggregate current change flags.
   2404             configChanges |= r.configChangeFlags;
   2405 
   2406             if (r.fullscreen) {
   2407                 // At this point, nothing else needs to be shown
   2408                 if (DEBUG_VISBILITY) Slog.v(
   2409                         TAG, "Stopping: fullscreen at " + r);
   2410                 behindFullscreen = true;
   2411                 i--;
   2412                 break;
   2413             }
   2414         }
   2415 
   2416         // Now for any activities that aren't visible to the user, make
   2417         // sure they no longer are keeping the screen frozen.
   2418         while (i >= 0) {
   2419             r = (HistoryRecord)mHistory.get(i);
   2420             if (DEBUG_VISBILITY) Slog.v(
   2421                     TAG, "Make invisible? " + r + " finishing=" + r.finishing
   2422                     + " state=" + r.state
   2423                     + " behindFullscreen=" + behindFullscreen);
   2424             if (!r.finishing) {
   2425                 if (behindFullscreen) {
   2426                     if (r.visible) {
   2427                         if (DEBUG_VISBILITY) Slog.v(
   2428                                 TAG, "Making invisible: " + r);
   2429                         r.visible = false;
   2430                         try {
   2431                             mWindowManager.setAppVisibility(r, false);
   2432                             if ((r.state == ActivityState.STOPPING
   2433                                     || r.state == ActivityState.STOPPED)
   2434                                     && r.app != null && r.app.thread != null) {
   2435                                 if (DEBUG_VISBILITY) Slog.v(
   2436                                         TAG, "Scheduling invisibility: " + r);
   2437                                 r.app.thread.scheduleWindowVisibility(r, false);
   2438                             }
   2439                         } catch (Exception e) {
   2440                             // Just skip on any failure; we'll make it
   2441                             // visible when it next restarts.
   2442                             Slog.w(TAG, "Exception thrown making hidden: "
   2443                                     + r.intent.getComponent(), e);
   2444                         }
   2445                     } else {
   2446                         if (DEBUG_VISBILITY) Slog.v(
   2447                                 TAG, "Already invisible: " + r);
   2448                     }
   2449                 } else if (r.fullscreen) {
   2450                     if (DEBUG_VISBILITY) Slog.v(
   2451                             TAG, "Now behindFullscreen: " + r);
   2452                     behindFullscreen = true;
   2453                 }
   2454             }
   2455             i--;
   2456         }
   2457     }
   2458 
   2459     /**
   2460      * Version of ensureActivitiesVisible that can easily be called anywhere.
   2461      */
   2462     private final void ensureActivitiesVisibleLocked(HistoryRecord starting,
   2463             int configChanges) {
   2464         HistoryRecord r = topRunningActivityLocked(null);
   2465         if (r != null) {
   2466             ensureActivitiesVisibleLocked(r, starting, null, configChanges);
   2467         }
   2468     }
   2469 
   2470     private void updateUsageStats(HistoryRecord resumedComponent, boolean resumed) {
   2471         if (resumed) {
   2472             mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
   2473         } else {
   2474             mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
   2475         }
   2476     }
   2477 
   2478     private boolean startHomeActivityLocked() {
   2479         if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
   2480                 && mTopAction == null) {
   2481             // We are running in factory test mode, but unable to find
   2482             // the factory test app, so just sit around displaying the
   2483             // error message and don't try to start anything.
   2484             return false;
   2485         }
   2486         Intent intent = new Intent(
   2487             mTopAction,
   2488             mTopData != null ? Uri.parse(mTopData) : null);
   2489         intent.setComponent(mTopComponent);
   2490         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   2491             intent.addCategory(Intent.CATEGORY_HOME);
   2492         }
   2493         ActivityInfo aInfo =
   2494             intent.resolveActivityInfo(mContext.getPackageManager(),
   2495                     STOCK_PM_FLAGS);
   2496         if (aInfo != null) {
   2497             intent.setComponent(new ComponentName(
   2498                     aInfo.applicationInfo.packageName, aInfo.name));
   2499             // Don't do this if the home app is currently being
   2500             // instrumented.
   2501             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
   2502                     aInfo.applicationInfo.uid);
   2503             if (app == null || app.instrumentationClass == null) {
   2504                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
   2505                 startActivityLocked(null, intent, null, null, 0, aInfo,
   2506                         null, null, 0, 0, 0, false, false);
   2507             }
   2508         }
   2509 
   2510 
   2511         return true;
   2512     }
   2513 
   2514     /**
   2515      * Starts the "new version setup screen" if appropriate.
   2516      */
   2517     private void startSetupActivityLocked() {
   2518         // Only do this once per boot.
   2519         if (mCheckedForSetup) {
   2520             return;
   2521         }
   2522 
   2523         // We will show this screen if the current one is a different
   2524         // version than the last one shown, and we are not running in
   2525         // low-level factory test mode.
   2526         final ContentResolver resolver = mContext.getContentResolver();
   2527         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
   2528                 Settings.Secure.getInt(resolver,
   2529                         Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
   2530             mCheckedForSetup = true;
   2531 
   2532             // See if we should be showing the platform update setup UI.
   2533             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
   2534             List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
   2535                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
   2536 
   2537             // We don't allow third party apps to replace this.
   2538             ResolveInfo ri = null;
   2539             for (int i=0; ris != null && i<ris.size(); i++) {
   2540                 if ((ris.get(i).activityInfo.applicationInfo.flags
   2541                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
   2542                     ri = ris.get(i);
   2543                     break;
   2544                 }
   2545             }
   2546 
   2547             if (ri != null) {
   2548                 String vers = ri.activityInfo.metaData != null
   2549                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
   2550                         : null;
   2551                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
   2552                     vers = ri.activityInfo.applicationInfo.metaData.getString(
   2553                             Intent.METADATA_SETUP_VERSION);
   2554                 }
   2555                 String lastVers = Settings.Secure.getString(
   2556                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
   2557                 if (vers != null && !vers.equals(lastVers)) {
   2558                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   2559                     intent.setComponent(new ComponentName(
   2560                             ri.activityInfo.packageName, ri.activityInfo.name));
   2561                     startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
   2562                             null, null, 0, 0, 0, false, false);
   2563                 }
   2564             }
   2565         }
   2566     }
   2567 
   2568     private void reportResumedActivityLocked(HistoryRecord r) {
   2569         //Slog.i(TAG, "**** REPORT RESUME: " + r);
   2570 
   2571         final int identHash = System.identityHashCode(r);
   2572         updateUsageStats(r, true);
   2573 
   2574         int i = mWatchers.beginBroadcast();
   2575         while (i > 0) {
   2576             i--;
   2577             IActivityWatcher w = mWatchers.getBroadcastItem(i);
   2578             if (w != null) {
   2579                 try {
   2580                     w.activityResuming(identHash);
   2581                 } catch (RemoteException e) {
   2582                 }
   2583             }
   2584         }
   2585         mWatchers.finishBroadcast();
   2586     }
   2587 
   2588     /**
   2589      * Ensure that the top activity in the stack is resumed.
   2590      *
   2591      * @param prev The previously resumed activity, for when in the process
   2592      * of pausing; can be null to call from elsewhere.
   2593      *
   2594      * @return Returns true if something is being resumed, or false if
   2595      * nothing happened.
   2596      */
   2597     private final boolean resumeTopActivityLocked(HistoryRecord prev) {
   2598         // Find the first activity that is not finishing.
   2599         HistoryRecord next = topRunningActivityLocked(null);
   2600 
   2601         // Remember how we'll process this pause/resume situation, and ensure
   2602         // that the state is reset however we wind up proceeding.
   2603         final boolean userLeaving = mUserLeaving;
   2604         mUserLeaving = false;
   2605 
   2606         if (next == null) {
   2607             // There are no more activities!  Let's just start up the
   2608             // Launcher...
   2609             return startHomeActivityLocked();
   2610         }
   2611 
   2612         next.delayedResume = false;
   2613 
   2614         // If the top activity is the resumed one, nothing to do.
   2615         if (mResumedActivity == next && next.state == ActivityState.RESUMED) {
   2616             // Make sure we have executed any pending transitions, since there
   2617             // should be nothing left to do at this point.
   2618             mWindowManager.executeAppTransition();
   2619             mNoAnimActivities.clear();
   2620             return false;
   2621         }
   2622 
   2623         // If we are sleeping, and there is no resumed activity, and the top
   2624         // activity is paused, well that is the state we want.
   2625         if ((mSleeping || mShuttingDown)
   2626                 && mLastPausedActivity == next && next.state == ActivityState.PAUSED) {
   2627             // Make sure we have executed any pending transitions, since there
   2628             // should be nothing left to do at this point.
   2629             mWindowManager.executeAppTransition();
   2630             mNoAnimActivities.clear();
   2631             return false;
   2632         }
   2633 
   2634         // The activity may be waiting for stop, but that is no longer
   2635         // appropriate for it.
   2636         mStoppingActivities.remove(next);
   2637         mWaitingVisibleActivities.remove(next);
   2638 
   2639         if (DEBUG_SWITCH) Slog.v(TAG, "Resuming " + next);
   2640 
   2641         // If we are currently pausing an activity, then don't do anything
   2642         // until that is done.
   2643         if (mPausingActivity != null) {
   2644             if (DEBUG_SWITCH) Slog.v(TAG, "Skip resume: pausing=" + mPausingActivity);
   2645             return false;
   2646         }
   2647 
   2648         // We need to start pausing the current activity so the top one
   2649         // can be resumed...
   2650         if (mResumedActivity != null) {
   2651             if (DEBUG_SWITCH) Slog.v(TAG, "Skip resume: need to start pausing");
   2652             startPausingLocked(userLeaving, false);
   2653             return true;
   2654         }
   2655 
   2656         if (prev != null && prev != next) {
   2657             if (!prev.waitingVisible && next != null && !next.nowVisible) {
   2658                 prev.waitingVisible = true;
   2659                 mWaitingVisibleActivities.add(prev);
   2660                 if (DEBUG_SWITCH) Slog.v(
   2661                         TAG, "Resuming top, waiting visible to hide: " + prev);
   2662             } else {
   2663                 // The next activity is already visible, so hide the previous
   2664                 // activity's windows right now so we can show the new one ASAP.
   2665                 // We only do this if the previous is finishing, which should mean
   2666                 // it is on top of the one being resumed so hiding it quickly
   2667                 // is good.  Otherwise, we want to do the normal route of allowing
   2668                 // the resumed activity to be shown so we can decide if the
   2669                 // previous should actually be hidden depending on whether the
   2670                 // new one is found to be full-screen or not.
   2671                 if (prev.finishing) {
   2672                     mWindowManager.setAppVisibility(prev, false);
   2673                     if (DEBUG_SWITCH) Slog.v(TAG, "Not waiting for visible to hide: "
   2674                             + prev + ", waitingVisible="
   2675                             + (prev != null ? prev.waitingVisible : null)
   2676                             + ", nowVisible=" + next.nowVisible);
   2677                 } else {
   2678                     if (DEBUG_SWITCH) Slog.v(TAG, "Previous already visible but still waiting to hide: "
   2679                         + prev + ", waitingVisible="
   2680                         + (prev != null ? prev.waitingVisible : null)
   2681                         + ", nowVisible=" + next.nowVisible);
   2682                 }
   2683             }
   2684         }
   2685 
   2686         // We are starting up the next activity, so tell the window manager
   2687         // that the previous one will be hidden soon.  This way it can know
   2688         // to ignore it when computing the desired screen orientation.
   2689         if (prev != null) {
   2690             if (prev.finishing) {
   2691                 if (DEBUG_TRANSITION) Slog.v(TAG,
   2692                         "Prepare close transition: prev=" + prev);
   2693                 if (mNoAnimActivities.contains(prev)) {
   2694                     mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
   2695                 } else {
   2696                     mWindowManager.prepareAppTransition(prev.task == next.task
   2697                             ? WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE
   2698                             : WindowManagerPolicy.TRANSIT_TASK_CLOSE);
   2699                 }
   2700                 mWindowManager.setAppWillBeHidden(prev);
   2701                 mWindowManager.setAppVisibility(prev, false);
   2702             } else {
   2703                 if (DEBUG_TRANSITION) Slog.v(TAG,
   2704                         "Prepare open transition: prev=" + prev);
   2705                 if (mNoAnimActivities.contains(next)) {
   2706                     mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
   2707                 } else {
   2708                     mWindowManager.prepareAppTransition(prev.task == next.task
   2709                             ? WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
   2710                             : WindowManagerPolicy.TRANSIT_TASK_OPEN);
   2711                 }
   2712             }
   2713             if (false) {
   2714                 mWindowManager.setAppWillBeHidden(prev);
   2715                 mWindowManager.setAppVisibility(prev, false);
   2716             }
   2717         } else if (mHistory.size() > 1) {
   2718             if (DEBUG_TRANSITION) Slog.v(TAG,
   2719                     "Prepare open transition: no previous");
   2720             if (mNoAnimActivities.contains(next)) {
   2721                 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
   2722             } else {
   2723                 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
   2724             }
   2725         }
   2726 
   2727         if (next.app != null && next.app.thread != null) {
   2728             if (DEBUG_SWITCH) Slog.v(TAG, "Resume running: " + next);
   2729 
   2730             // This activity is now becoming visible.
   2731             mWindowManager.setAppVisibility(next, true);
   2732 
   2733             HistoryRecord lastResumedActivity = mResumedActivity;
   2734             ActivityState lastState = next.state;
   2735 
   2736             updateCpuStats();
   2737 
   2738             next.state = ActivityState.RESUMED;
   2739             mResumedActivity = next;
   2740             next.task.touchActiveTime();
   2741             updateLruProcessLocked(next.app, true, true);
   2742             updateLRUListLocked(next);
   2743 
   2744             // Have the window manager re-evaluate the orientation of
   2745             // the screen based on the new activity order.
   2746             boolean updated;
   2747             synchronized (this) {
   2748                 Configuration config = mWindowManager.updateOrientationFromAppTokens(
   2749                         mConfiguration,
   2750                         next.mayFreezeScreenLocked(next.app) ? next : null);
   2751                 if (config != null) {
   2752                     next.frozenBeforeDestroy = true;
   2753                 }
   2754                 updated = updateConfigurationLocked(config, next);
   2755             }
   2756             if (!updated) {
   2757                 // The configuration update wasn't able to keep the existing
   2758                 // instance of the activity, and instead started a new one.
   2759                 // We should be all done, but let's just make sure our activity
   2760                 // is still at the top and schedule another run if something
   2761                 // weird happened.
   2762                 HistoryRecord nextNext = topRunningActivityLocked(null);
   2763                 if (DEBUG_SWITCH) Slog.i(TAG,
   2764                         "Activity config changed during resume: " + next
   2765                         + ", new next: " + nextNext);
   2766                 if (nextNext != next) {
   2767                     // Do over!
   2768                     mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
   2769                 }
   2770                 setFocusedActivityLocked(next);
   2771                 ensureActivitiesVisibleLocked(null, 0);
   2772                 mWindowManager.executeAppTransition();
   2773                 mNoAnimActivities.clear();
   2774                 return true;
   2775             }
   2776 
   2777             try {
   2778                 // Deliver all pending results.
   2779                 ArrayList a = next.results;
   2780                 if (a != null) {
   2781                     final int N = a.size();
   2782                     if (!next.finishing && N > 0) {
   2783                         if (DEBUG_RESULTS) Slog.v(
   2784                                 TAG, "Delivering results to " + next
   2785                                 + ": " + a);
   2786                         next.app.thread.scheduleSendResult(next, a);
   2787                     }
   2788                 }
   2789 
   2790                 if (next.newIntents != null) {
   2791                     next.app.thread.scheduleNewIntent(next.newIntents, next);
   2792                 }
   2793 
   2794                 EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY,
   2795                         System.identityHashCode(next),
   2796                         next.task.taskId, next.shortComponentName);
   2797 
   2798                 next.app.thread.scheduleResumeActivity(next,
   2799                         isNextTransitionForward());
   2800 
   2801                 pauseIfSleepingLocked();
   2802 
   2803             } catch (Exception e) {
   2804                 // Whoops, need to restart this activity!
   2805                 next.state = lastState;
   2806                 mResumedActivity = lastResumedActivity;
   2807                 Slog.i(TAG, "Restarting because process died: " + next);
   2808                 if (!next.hasBeenLaunched) {
   2809                     next.hasBeenLaunched = true;
   2810                 } else {
   2811                     if (SHOW_APP_STARTING_ICON) {
   2812                         mWindowManager.setAppStartingWindow(
   2813                                 next, next.packageName, next.theme,
   2814                                 next.nonLocalizedLabel,
   2815                                 next.labelRes, next.icon, null, true);
   2816                     }
   2817                 }
   2818                 startSpecificActivityLocked(next, true, false);
   2819                 return true;
   2820             }
   2821 
   2822             // From this point on, if something goes wrong there is no way
   2823             // to recover the activity.
   2824             try {
   2825                 next.visible = true;
   2826                 completeResumeLocked(next);
   2827             } catch (Exception e) {
   2828                 // If any exception gets thrown, toss away this
   2829                 // activity and try the next one.
   2830                 Slog.w(TAG, "Exception thrown during resume of " + next, e);
   2831                 requestFinishActivityLocked(next, Activity.RESULT_CANCELED, null,
   2832                         "resume-exception");
   2833                 return true;
   2834             }
   2835 
   2836             // Didn't need to use the icicle, and it is now out of date.
   2837             next.icicle = null;
   2838             next.haveState = false;
   2839             next.stopped = false;
   2840 
   2841         } else {
   2842             // Whoops, need to restart this activity!
   2843             if (!next.hasBeenLaunched) {
   2844                 next.hasBeenLaunched = true;
   2845             } else {
   2846                 if (SHOW_APP_STARTING_ICON) {
   2847                     mWindowManager.setAppStartingWindow(
   2848                             next, next.packageName, next.theme,
   2849                             next.nonLocalizedLabel,
   2850                             next.labelRes, next.icon, null, true);
   2851                 }
   2852                 if (DEBUG_SWITCH) Slog.v(TAG, "Restarting: " + next);
   2853             }
   2854             startSpecificActivityLocked(next, true, true);
   2855         }
   2856 
   2857         return true;
   2858     }
   2859 
   2860     private final void startActivityLocked(HistoryRecord r, boolean newTask,
   2861             boolean doResume) {
   2862         final int NH = mHistory.size();
   2863 
   2864         int addPos = -1;
   2865 
   2866         if (!newTask) {
   2867             // If starting in an existing task, find where that is...
   2868             HistoryRecord next = null;
   2869             boolean startIt = true;
   2870             for (int i = NH-1; i >= 0; i--) {
   2871                 HistoryRecord p = (HistoryRecord)mHistory.get(i);
   2872                 if (p.finishing) {
   2873                     continue;
   2874                 }
   2875                 if (p.task == r.task) {
   2876                     // Here it is!  Now, if this is not yet visible to the
   2877                     // user, then just add it without starting; it will
   2878                     // get started when the user navigates back to it.
   2879                     addPos = i+1;
   2880                     if (!startIt) {
   2881                         mHistory.add(addPos, r);
   2882                         r.inHistory = true;
   2883                         r.task.numActivities++;
   2884                         mWindowManager.addAppToken(addPos, r, r.task.taskId,
   2885                                 r.info.screenOrientation, r.fullscreen);
   2886                         if (VALIDATE_TOKENS) {
   2887                             mWindowManager.validateAppTokens(mHistory);
   2888                         }
   2889                         return;
   2890                     }
   2891                     break;
   2892                 }
   2893                 if (p.fullscreen) {
   2894                     startIt = false;
   2895                 }
   2896                 next = p;
   2897             }
   2898         }
   2899 
   2900         // Place a new activity at top of stack, so it is next to interact
   2901         // with the user.
   2902         if (addPos < 0) {
   2903             addPos = mHistory.size();
   2904         }
   2905 
   2906         // If we are not placing the new activity frontmost, we do not want
   2907         // to deliver the onUserLeaving callback to the actual frontmost
   2908         // activity
   2909         if (addPos < NH) {
   2910             mUserLeaving = false;
   2911             if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() behind front, mUserLeaving=false");
   2912         }
   2913 
   2914         // Slot the activity into the history stack and proceed
   2915         mHistory.add(addPos, r);
   2916         r.inHistory = true;
   2917         r.frontOfTask = newTask;
   2918         r.task.numActivities++;
   2919         if (NH > 0) {
   2920             // We want to show the starting preview window if we are
   2921             // switching to a new task, or the next activity's process is
   2922             // not currently running.
   2923             boolean showStartingIcon = newTask;
   2924             ProcessRecord proc = r.app;
   2925             if (proc == null) {
   2926                 proc = mProcessNames.get(r.processName, r.info.applicationInfo.uid);
   2927             }
   2928             if (proc == null || proc.thread == null) {
   2929                 showStartingIcon = true;
   2930             }
   2931             if (DEBUG_TRANSITION) Slog.v(TAG,
   2932                     "Prepare open transition: starting " + r);
   2933             if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
   2934                 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
   2935                 mNoAnimActivities.add(r);
   2936             } else if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
   2937                 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_OPEN);
   2938                 mNoAnimActivities.remove(r);
   2939             } else {
   2940                 mWindowManager.prepareAppTransition(newTask
   2941                         ? WindowManagerPolicy.TRANSIT_TASK_OPEN
   2942                         : WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
   2943                 mNoAnimActivities.remove(r);
   2944             }
   2945             mWindowManager.addAppToken(
   2946                     addPos, r, r.task.taskId, r.info.screenOrientation, r.fullscreen);
   2947             boolean doShow = true;
   2948             if (newTask) {
   2949                 // Even though this activity is starting fresh, we still need
   2950                 // to reset it to make sure we apply affinities to move any
   2951                 // existing activities from other tasks in to it.
   2952                 // If the caller has requested that the target task be
   2953                 // reset, then do so.
   2954                 if ((r.intent.getFlags()
   2955                         &Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
   2956                     resetTaskIfNeededLocked(r, r);
   2957                     doShow = topRunningNonDelayedActivityLocked(null) == r;
   2958                 }
   2959             }
   2960             if (SHOW_APP_STARTING_ICON && doShow) {
   2961                 // Figure out if we are transitioning from another activity that is
   2962                 // "has the same starting icon" as the next one.  This allows the
   2963                 // window manager to keep the previous window it had previously
   2964                 // created, if it still had one.
   2965                 HistoryRecord prev = mResumedActivity;
   2966                 if (prev != null) {
   2967                     // We don't want to reuse the previous starting preview if:
   2968                     // (1) The current activity is in a different task.
   2969                     if (prev.task != r.task) prev = null;
   2970                     // (2) The current activity is already displayed.
   2971                     else if (prev.nowVisible) prev = null;
   2972                 }
   2973                 mWindowManager.setAppStartingWindow(
   2974                         r, r.packageName, r.theme, r.nonLocalizedLabel,
   2975                         r.labelRes, r.icon, prev, showStartingIcon);
   2976             }
   2977         } else {
   2978             // If this is the first activity, don't do any fancy animations,
   2979             // because there is nothing for it to animate on top of.
   2980             mWindowManager.addAppToken(addPos, r, r.task.taskId,
   2981                     r.info.screenOrientation, r.fullscreen);
   2982         }
   2983         if (VALIDATE_TOKENS) {
   2984             mWindowManager.validateAppTokens(mHistory);
   2985         }
   2986 
   2987         if (doResume) {
   2988             resumeTopActivityLocked(null);
   2989         }
   2990     }
   2991 
   2992     /**
   2993      * Perform clear operation as requested by
   2994      * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
   2995      * stack to the given task, then look for
   2996      * an instance of that activity in the stack and, if found, finish all
   2997      * activities on top of it and return the instance.
   2998      *
   2999      * @param newR Description of the new activity being started.
   3000      * @return Returns the old activity that should be continue to be used,
   3001      * or null if none was found.
   3002      */
   3003     private final HistoryRecord performClearTaskLocked(int taskId,
   3004             HistoryRecord newR, int launchFlags, boolean doClear) {
   3005         int i = mHistory.size();
   3006 
   3007         // First find the requested task.
   3008         while (i > 0) {
   3009             i--;
   3010             HistoryRecord r = (HistoryRecord)mHistory.get(i);
   3011             if (r.task.taskId == taskId) {
   3012                 i++;
   3013                 break;
   3014             }
   3015         }
   3016 
   3017         // Now clear it.
   3018         while (i > 0) {
   3019             i--;
   3020             HistoryRecord r = (HistoryRecord)mHistory.get(i);
   3021             if (r.finishing) {
   3022                 continue;
   3023             }
   3024             if (r.task.taskId != taskId) {
   3025                 return null;
   3026             }
   3027             if (r.realActivity.equals(newR.realActivity)) {
   3028                 // Here it is!  Now finish everything in front...
   3029                 HistoryRecord ret = r;
   3030                 if (doClear) {
   3031                     while (i < (mHistory.size()-1)) {
   3032                         i++;
   3033                         r = (HistoryRecord)mHistory.get(i);
   3034                         if (r.finishing) {
   3035                             continue;
   3036                         }
   3037                         if (finishActivityLocked(r, i, Activity.RESULT_CANCELED,
   3038                                 null, "clear")) {
   3039                             i--;
   3040                         }
   3041                     }
   3042                 }
   3043 
   3044                 // Finally, if this is a normal launch mode (that is, not
   3045                 // expecting onNewIntent()), then we will finish the current
   3046                 // instance of the activity so a new fresh one can be started.
   3047                 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
   3048                         && (launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) {
   3049                     if (!ret.finishing) {
   3050                         int index = indexOfTokenLocked(ret);
   3051                         if (index >= 0) {
   3052                             finishActivityLocked(ret, index, Activity.RESULT_CANCELED,
   3053                                     null, "clear");
   3054                         }
   3055                         return null;
   3056                     }
   3057                 }
   3058 
   3059                 return ret;
   3060             }
   3061         }
   3062 
   3063         return null;
   3064     }
   3065 
   3066     /**
   3067      * Find the activity in the history stack within the given task.  Returns
   3068      * the index within the history at which it's found, or < 0 if not found.
   3069      */
   3070     private final int findActivityInHistoryLocked(HistoryRecord r, int task) {
   3071         int i = mHistory.size();
   3072         while (i > 0) {
   3073             i--;
   3074             HistoryRecord candidate = (HistoryRecord)mHistory.get(i);
   3075             if (candidate.task.taskId != task) {
   3076                 break;
   3077             }
   3078             if (candidate.realActivity.equals(r.realActivity)) {
   3079                 return i;
   3080             }
   3081         }
   3082 
   3083         return -1;
   3084     }
   3085 
   3086     /**
   3087      * Reorder the history stack so that the activity at the given index is
   3088      * brought to the front.
   3089      */
   3090     private final HistoryRecord moveActivityToFrontLocked(int where) {
   3091         HistoryRecord newTop = (HistoryRecord)mHistory.remove(where);
   3092         int top = mHistory.size();
   3093         HistoryRecord oldTop = (HistoryRecord)mHistory.get(top-1);
   3094         mHistory.add(top, newTop);
   3095         oldTop.frontOfTask = false;
   3096         newTop.frontOfTask = true;
   3097         return newTop;
   3098     }
   3099 
   3100     /**
   3101      * Deliver a new Intent to an existing activity, so that its onNewIntent()
   3102      * method will be called at the proper time.
   3103      */
   3104     private final void deliverNewIntentLocked(HistoryRecord r, Intent intent) {
   3105         boolean sent = false;
   3106         if (r.state == ActivityState.RESUMED
   3107                 && r.app != null && r.app.thread != null) {
   3108             try {
   3109                 ArrayList<Intent> ar = new ArrayList<Intent>();
   3110                 ar.add(new Intent(intent));
   3111                 r.app.thread.scheduleNewIntent(ar, r);
   3112                 sent = true;
   3113             } catch (Exception e) {
   3114                 Slog.w(TAG, "Exception thrown sending new intent to " + r, e);
   3115             }
   3116         }
   3117         if (!sent) {
   3118             r.addNewIntentLocked(new Intent(intent));
   3119         }
   3120     }
   3121 
   3122     private final void logStartActivity(int tag, HistoryRecord r,
   3123             TaskRecord task) {
   3124         EventLog.writeEvent(tag,
   3125                 System.identityHashCode(r), task.taskId,
   3126                 r.shortComponentName, r.intent.getAction(),
   3127                 r.intent.getType(), r.intent.getDataString(),
   3128                 r.intent.getFlags());
   3129     }
   3130 
   3131     private final int startActivityLocked(IApplicationThread caller,
   3132             Intent intent, String resolvedType,
   3133             Uri[] grantedUriPermissions,
   3134             int grantedMode, ActivityInfo aInfo, IBinder resultTo,
   3135             String resultWho, int requestCode,
   3136             int callingPid, int callingUid, boolean onlyIfNeeded,
   3137             boolean componentSpecified) {
   3138         Slog.i(TAG, "Starting activity: " + intent);
   3139 
   3140         HistoryRecord sourceRecord = null;
   3141         HistoryRecord resultRecord = null;
   3142         if (resultTo != null) {
   3143             int index = indexOfTokenLocked(resultTo);
   3144             if (DEBUG_RESULTS) Slog.v(
   3145                 TAG, "Sending result to " + resultTo + " (index " + index + ")");
   3146             if (index >= 0) {
   3147                 sourceRecord = (HistoryRecord)mHistory.get(index);
   3148                 if (requestCode >= 0 && !sourceRecord.finishing) {
   3149                     resultRecord = sourceRecord;
   3150                 }
   3151             }
   3152         }
   3153 
   3154         int launchFlags = intent.getFlags();
   3155 
   3156         if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
   3157                 && sourceRecord != null) {
   3158             // Transfer the result target from the source activity to the new
   3159             // one being started, including any failures.
   3160             if (requestCode >= 0) {
   3161                 return START_FORWARD_AND_REQUEST_CONFLICT;
   3162             }
   3163             resultRecord = sourceRecord.resultTo;
   3164             resultWho = sourceRecord.resultWho;
   3165             requestCode = sourceRecord.requestCode;
   3166             sourceRecord.resultTo = null;
   3167             if (resultRecord != null) {
   3168                 resultRecord.removeResultsLocked(
   3169                     sourceRecord, resultWho, requestCode);
   3170             }
   3171         }
   3172 
   3173         int err = START_SUCCESS;
   3174 
   3175         if (intent.getComponent() == null) {
   3176             // We couldn't find a class that can handle the given Intent.
   3177             // That's the end of that!
   3178             err = START_INTENT_NOT_RESOLVED;
   3179         }
   3180 
   3181         if (err == START_SUCCESS && aInfo == null) {
   3182             // We couldn't find the specific class specified in the Intent.
   3183             // Also the end of the line.
   3184             err = START_CLASS_NOT_FOUND;
   3185         }
   3186 
   3187         ProcessRecord callerApp = null;
   3188         if (err == START_SUCCESS && caller != null) {
   3189             callerApp = getRecordForAppLocked(caller);
   3190             if (callerApp != null) {
   3191                 callingPid = callerApp.pid;
   3192                 callingUid = callerApp.info.uid;
   3193             } else {
   3194                 Slog.w(TAG, "Unable to find app for caller " + caller
   3195                       + " (pid=" + callingPid + ") when starting: "
   3196                       + intent.toString());
   3197                 err = START_PERMISSION_DENIED;
   3198             }
   3199         }
   3200 
   3201         if (err != START_SUCCESS) {
   3202             if (resultRecord != null) {
   3203                 sendActivityResultLocked(-1,
   3204                     resultRecord, resultWho, requestCode,
   3205                     Activity.RESULT_CANCELED, null);
   3206             }
   3207             return err;
   3208         }
   3209 
   3210         final int perm = checkComponentPermission(aInfo.permission, callingPid,
   3211                 callingUid, aInfo.exported ? -1 : aInfo.applicationInfo.uid);
   3212         if (perm != PackageManager.PERMISSION_GRANTED) {
   3213             if (resultRecord != null) {
   3214                 sendActivityResultLocked(-1,
   3215                     resultRecord, resultWho, requestCode,
   3216                     Activity.RESULT_CANCELED, null);
   3217             }
   3218             String msg = "Permission Denial: starting " + intent.toString()
   3219                     + " from " + callerApp + " (pid=" + callingPid
   3220                     + ", uid=" + callingUid + ")"
   3221                     + " requires " + aInfo.permission;
   3222             Slog.w(TAG, msg);
   3223             throw new SecurityException(msg);
   3224         }
   3225 
   3226         if (mController != null) {
   3227             boolean abort = false;
   3228             try {
   3229                 // The Intent we give to the watcher has the extra data
   3230                 // stripped off, since it can contain private information.
   3231                 Intent watchIntent = intent.cloneFilter();
   3232                 abort = !mController.activityStarting(watchIntent,
   3233                         aInfo.applicationInfo.packageName);
   3234             } catch (RemoteException e) {
   3235                 mController = null;
   3236             }
   3237 
   3238             if (abort) {
   3239                 if (resultRecord != null) {
   3240                     sendActivityResultLocked(-1,
   3241                         resultRecord, resultWho, requestCode,
   3242                         Activity.RESULT_CANCELED, null);
   3243                 }
   3244                 // We pretend to the caller that it was really started, but
   3245                 // they will just get a cancel result.
   3246                 return START_SUCCESS;
   3247             }
   3248         }
   3249 
   3250         HistoryRecord r = new HistoryRecord(this, callerApp, callingUid,
   3251                 intent, resolvedType, aInfo, mConfiguration,
   3252                 resultRecord, resultWho, requestCode, componentSpecified);
   3253 
   3254         if (mResumedActivity == null
   3255                 || mResumedActivity.info.applicationInfo.uid != callingUid) {
   3256             if (!checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
   3257                 PendingActivityLaunch pal = new PendingActivityLaunch();
   3258                 pal.r = r;
   3259                 pal.sourceRecord = sourceRecord;
   3260                 pal.grantedUriPermissions = grantedUriPermissions;
   3261                 pal.grantedMode = grantedMode;
   3262                 pal.onlyIfNeeded = onlyIfNeeded;
   3263                 mPendingActivityLaunches.add(pal);
   3264                 return START_SWITCHES_CANCELED;
   3265             }
   3266         }
   3267 
   3268         if (mDidAppSwitch) {
   3269             // This is the second allowed switch since we stopped switches,
   3270             // so now just generally allow switches.  Use case: user presses
   3271             // home (switches disabled, switch to home, mDidAppSwitch now true);
   3272             // user taps a home icon (coming from home so allowed, we hit here
   3273             // and now allow anyone to switch again).
   3274             mAppSwitchesAllowedTime = 0;
   3275         } else {
   3276             mDidAppSwitch = true;
   3277         }
   3278 
   3279         doPendingActivityLaunchesLocked(false);
   3280 
   3281         return startActivityUncheckedLocked(r, sourceRecord,
   3282                 grantedUriPermissions, grantedMode, onlyIfNeeded, true);
   3283     }
   3284 
   3285     private final void doPendingActivityLaunchesLocked(boolean doResume) {
   3286         final int N = mPendingActivityLaunches.size();
   3287         if (N <= 0) {
   3288             return;
   3289         }
   3290         for (int i=0; i<N; i++) {
   3291             PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
   3292             startActivityUncheckedLocked(pal.r, pal.sourceRecord,
   3293                     pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
   3294                     doResume && i == (N-1));
   3295         }
   3296         mPendingActivityLaunches.clear();
   3297     }
   3298 
   3299     private final int startActivityUncheckedLocked(HistoryRecord r,
   3300             HistoryRecord sourceRecord, Uri[] grantedUriPermissions,
   3301             int grantedMode, boolean onlyIfNeeded, boolean doResume) {
   3302         final Intent intent = r.intent;
   3303         final int callingUid = r.launchedFromUid;
   3304 
   3305         int launchFlags = intent.getFlags();
   3306 
   3307         // We'll invoke onUserLeaving before onPause only if the launching
   3308         // activity did not explicitly state that this is an automated launch.
   3309         mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
   3310         if (DEBUG_USER_LEAVING) Slog.v(TAG,
   3311                 "startActivity() => mUserLeaving=" + mUserLeaving);
   3312 
   3313         // If the caller has asked not to resume at this point, we make note
   3314         // of this in the record so that we can skip it when trying to find
   3315         // the top running activity.
   3316         if (!doResume) {
   3317             r.delayedResume = true;
   3318         }
   3319 
   3320         HistoryRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
   3321                 != 0 ? r : null;
   3322 
   3323         // If the onlyIfNeeded flag is set, then we can do this if the activity
   3324         // being launched is the same as the one making the call...  or, as
   3325         // a special case, if we do not know the caller then we count the
   3326         // current top activity as the caller.
   3327         if (onlyIfNeeded) {
   3328             HistoryRecord checkedCaller = sourceRecord;
   3329             if (checkedCaller == null) {
   3330                 checkedCaller = topRunningNonDelayedActivityLocked(notTop);
   3331             }
   3332             if (!checkedCaller.realActivity.equals(r.realActivity)) {
   3333                 // Caller is not the same as launcher, so always needed.
   3334                 onlyIfNeeded = false;
   3335             }
   3336         }
   3337 
   3338         if (grantedUriPermissions != null && callingUid > 0) {
   3339             for (int i=0; i<grantedUriPermissions.length; i++) {
   3340                 grantUriPermissionLocked(callingUid, r.packageName,
   3341                         grantedUriPermissions[i], grantedMode, r);
   3342             }
   3343         }
   3344 
   3345         grantUriPermissionFromIntentLocked(callingUid, r.packageName,
   3346                 intent, r);
   3347 
   3348         if (sourceRecord == null) {
   3349             // This activity is not being started from another...  in this
   3350             // case we -always- start a new task.
   3351             if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
   3352                 Slog.w(TAG, "startActivity called from non-Activity context; forcing Intent.FLAG_ACTIVITY_NEW_TASK for: "
   3353                       + intent);
   3354                 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
   3355             }
   3356         } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
   3357             // The original activity who is starting us is running as a single
   3358             // instance...  this new activity it is starting must go on its
   3359             // own task.
   3360             launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
   3361         } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
   3362                 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
   3363             // The activity being started is a single instance...  it always
   3364             // gets launched into its own task.
   3365             launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
   3366         }
   3367 
   3368         if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
   3369             // For whatever reason this activity is being launched into a new
   3370             // task...  yet the caller has requested a result back.  Well, that
   3371             // is pretty messed up, so instead immediately send back a cancel
   3372             // and let the new task continue launched as normal without a
   3373             // dependency on its originator.
   3374             Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
   3375             sendActivityResultLocked(-1,
   3376                     r.resultTo, r.resultWho, r.requestCode,
   3377                 Activity.RESULT_CANCELED, null);
   3378             r.resultTo = null;
   3379         }
   3380 
   3381         boolean addingToTask = false;
   3382         if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
   3383                 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
   3384                 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
   3385                 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
   3386             // If bring to front is requested, and no result is requested, and
   3387             // we can find a task that was started with this same
   3388             // component, then instead of launching bring that one to the front.
   3389             if (r.resultTo == null) {
   3390                 // See if there is a task to bring to the front.  If this is
   3391                 // a SINGLE_INSTANCE activity, there can be one and only one
   3392                 // instance of it in the history, and it is always in its own
   3393                 // unique task, so we do a special search.
   3394                 HistoryRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
   3395                         ? findTaskLocked(intent, r.info)
   3396                         : findActivityLocked(intent, r.info);
   3397                 if (taskTop != null) {
   3398                     if (taskTop.task.intent == null) {
   3399                         // This task was started because of movement of
   3400                         // the activity based on affinity...  now that we
   3401                         // are actually launching it, we can assign the
   3402                         // base intent.
   3403                         taskTop.task.setIntent(intent, r.info);
   3404                     }
   3405                     // If the target task is not in the front, then we need
   3406                     // to bring it to the front...  except...  well, with
   3407                     // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
   3408                     // to have the same behavior as if a new instance was
   3409                     // being started, which means not bringing it to the front
   3410                     // if the caller is not itself in the front.
   3411                     HistoryRecord curTop = topRunningNonDelayedActivityLocked(notTop);
   3412                     if (curTop.task != taskTop.task) {
   3413                         r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
   3414                         boolean callerAtFront = sourceRecord == null
   3415                                 || curTop.task == sourceRecord.task;
   3416                         if (callerAtFront) {
   3417                             // We really do want to push this one into the
   3418                             // user's face, right now.
   3419                             moveTaskToFrontLocked(taskTop.task, r);
   3420                         }
   3421                     }
   3422                     // If the caller has requested that the target task be
   3423                     // reset, then do so.
   3424                     if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
   3425                         taskTop = resetTaskIfNeededLocked(taskTop, r);
   3426                     }
   3427                     if (onlyIfNeeded) {
   3428                         // We don't need to start a new activity, and
   3429                         // the client said not to do anything if that
   3430                         // is the case, so this is it!  And for paranoia, make
   3431                         // sure we have correctly resumed the top activity.
   3432                         if (doResume) {
   3433                             resumeTopActivityLocked(null);
   3434                         }
   3435                         return START_RETURN_INTENT_TO_CALLER;
   3436                     }
   3437                     if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
   3438                             || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
   3439                             || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
   3440                         // In this situation we want to remove all activities
   3441                         // from the task up to the one being started.  In most
   3442                         // cases this means we are resetting the task to its
   3443                         // initial state.
   3444                         HistoryRecord top = performClearTaskLocked(
   3445                                 taskTop.task.taskId, r, launchFlags, true);
   3446                         if (top != null) {
   3447                             if (top.frontOfTask) {
   3448                                 // Activity aliases may mean we use different
   3449                                 // intents for the top activity, so make sure
   3450                                 // the task now has the identity of the new
   3451                                 // intent.
   3452                                 top.task.setIntent(r.intent, r.info);
   3453                             }
   3454                             logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
   3455                             deliverNewIntentLocked(top, r.intent);
   3456                         } else {
   3457                             // A special case: we need to
   3458                             // start the activity because it is not currently
   3459                             // running, and the caller has asked to clear the
   3460                             // current task to have this activity at the top.
   3461                             addingToTask = true;
   3462                             // Now pretend like this activity is being started
   3463                             // by the top of its task, so it is put in the
   3464                             // right place.
   3465                             sourceRecord = taskTop;
   3466                         }
   3467                     } else if (r.realActivity.equals(taskTop.task.realActivity)) {
   3468                         // In this case the top activity on the task is the
   3469                         // same as the one being launched, so we take that
   3470                         // as a request to bring the task to the foreground.
   3471                         // If the top activity in the task is the root
   3472                         // activity, deliver this new intent to it if it
   3473                         // desires.
   3474                         if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
   3475                                 && taskTop.realActivity.equals(r.realActivity)) {
   3476                             logStartActivity(EventLogTags.AM_NEW_INTENT, r, taskTop.task);
   3477                             if (taskTop.frontOfTask) {
   3478                                 taskTop.task.setIntent(r.intent, r.info);
   3479                             }
   3480                             deliverNewIntentLocked(taskTop, r.intent);
   3481                         } else if (!r.intent.filterEquals(taskTop.task.intent)) {
   3482                             // In this case we are launching the root activity
   3483                             // of the task, but with a different intent.  We
   3484                             // should start a new instance on top.
   3485                             addingToTask = true;
   3486                             sourceRecord = taskTop;
   3487                         }
   3488                     } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
   3489                         // In this case an activity is being launched in to an
   3490                         // existing task, without resetting that task.  This
   3491                         // is typically the situation of launching an activity
   3492                         // from a notification or shortcut.  We want to place
   3493                         // the new activity on top of the current task.
   3494                         addingToTask = true;
   3495                         sourceRecord = taskTop;
   3496                     } else if (!taskTop.task.rootWasReset) {
   3497                         // In this case we are launching in to an existing task
   3498                         // that has not yet been started from its front door.
   3499                         // The current task has been brought to the front.
   3500                         // Ideally, we'd probably like to place this new task
   3501                         // at the bottom of its stack, but that's a little hard
   3502                         // to do with the current organization of the code so
   3503                         // for now we'll just drop it.
   3504                         taskTop.task.setIntent(r.intent, r.info);
   3505                     }
   3506                     if (!addingToTask) {
   3507                         // We didn't do anything...  but it was needed (a.k.a., client
   3508                         // don't use that intent!)  And for paranoia, make
   3509                         // sure we have correctly resumed the top activity.
   3510                         if (doResume) {
   3511                             resumeTopActivityLocked(null);
   3512                         }
   3513                         return START_TASK_TO_FRONT;
   3514                     }
   3515                 }
   3516             }
   3517         }
   3518 
   3519         //String uri = r.intent.toURI();
   3520         //Intent intent2 = new Intent(uri);
   3521         //Slog.i(TAG, "Given intent: " + r.intent);
   3522         //Slog.i(TAG, "URI is: " + uri);
   3523         //Slog.i(TAG, "To intent: " + intent2);
   3524 
   3525         if (r.packageName != null) {
   3526             // If the activity being launched is the same as the one currently
   3527             // at the top, then we need to check if it should only be launched
   3528             // once.
   3529             HistoryRecord top = topRunningNonDelayedActivityLocked(notTop);
   3530             if (top != null && r.resultTo == null) {
   3531                 if (top.realActivity.equals(r.realActivity)) {
   3532                     if (top.app != null && top.app.thread != null) {
   3533                         if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
   3534                             || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
   3535                             || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
   3536                             logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task);
   3537                             // For paranoia, make sure we have correctly
   3538                             // resumed the top activity.
   3539                             if (doResume) {
   3540                                 resumeTopActivityLocked(null);
   3541                             }
   3542                             if (onlyIfNeeded) {
   3543                                 // We don't need to start a new activity, and
   3544                                 // the client said not to do anything if that
   3545                                 // is the case, so this is it!
   3546                                 return START_RETURN_INTENT_TO_CALLER;
   3547                             }
   3548                             deliverNewIntentLocked(top, r.intent);
   3549                             return START_DELIVERED_TO_TOP;
   3550                         }
   3551                     }
   3552                 }
   3553             }
   3554 
   3555         } else {
   3556             if (r.resultTo != null) {
   3557                 sendActivityResultLocked(-1,
   3558                         r.resultTo, r.resultWho, r.requestCode,
   3559                     Activity.RESULT_CANCELED, null);
   3560             }
   3561             return START_CLASS_NOT_FOUND;
   3562         }
   3563 
   3564         boolean newTask = false;
   3565 
   3566         // Should this be considered a new task?
   3567         if (r.resultTo == null && !addingToTask
   3568                 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
   3569             // todo: should do better management of integers.
   3570             mCurTask++;
   3571             if (mCurTask <= 0) {
   3572                 mCurTask = 1;
   3573             }
   3574             r.task = new TaskRecord(mCurTask, r.info, intent,
   3575                     (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
   3576             if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
   3577                     + " in new task " + r.task);
   3578             newTask = true;
   3579             addRecentTaskLocked(r.task);
   3580 
   3581         } else if (sourceRecord != null) {
   3582             if (!addingToTask &&
   3583                     (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
   3584                 // In this case, we are adding the activity to an existing
   3585                 // task, but the caller has asked to clear that task if the
   3586                 // activity is already running.
   3587                 HistoryRecord top = performClearTaskLocked(
   3588                         sourceRecord.task.taskId, r, launchFlags, true);
   3589                 if (top != null) {
   3590                     logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
   3591                     deliverNewIntentLocked(top, r.intent);
   3592                     // For paranoia, make sure we have correctly
   3593                     // resumed the top activity.
   3594                     if (doResume) {
   3595                         resumeTopActivityLocked(null);
   3596                     }
   3597                     return START_DELIVERED_TO_TOP;
   3598                 }
   3599             } else if (!addingToTask &&
   3600                     (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
   3601                 // In this case, we are launching an activity in our own task
   3602                 // that may already be running somewhere in the history, and
   3603                 // we want to shuffle it to the front of the stack if so.
   3604                 int where = findActivityInHistoryLocked(r, sourceRecord.task.taskId);
   3605                 if (where >= 0) {
   3606                     HistoryRecord top = moveActivityToFrontLocked(where);
   3607                     logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
   3608                     deliverNewIntentLocked(top, r.intent);
   3609                     if (doResume) {
   3610                         resumeTopActivityLocked(null);
   3611                     }
   3612                     return START_DELIVERED_TO_TOP;
   3613                 }
   3614             }
   3615             // An existing activity is starting this new activity, so we want
   3616             // to keep the new one in the same task as the one that is starting
   3617             // it.
   3618             r.task = sourceRecord.task;
   3619             if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
   3620                     + " in existing task " + r.task);
   3621 
   3622         } else {
   3623             // This not being started from an existing activity, and not part
   3624             // of a new task...  just put it in the top task, though these days
   3625             // this case should never happen.
   3626             final int N = mHistory.size();
   3627             HistoryRecord prev =
   3628                 N > 0 ? (HistoryRecord)mHistory.get(N-1) : null;
   3629             r.task = prev != null
   3630                 ? prev.task
   3631                 : new TaskRecord(mCurTask, r.info, intent,
   3632                         (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
   3633             if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
   3634                     + " in new guessed " + r.task);
   3635         }
   3636         if (newTask) {
   3637             EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.task.taskId);
   3638         }
   3639         logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
   3640         startActivityLocked(r, newTask, doResume);
   3641         return START_SUCCESS;
   3642     }
   3643 
   3644     void reportActivityLaunchedLocked(boolean timeout, HistoryRecord r,
   3645             long thisTime, long totalTime) {
   3646         for (int i=mWaitingActivityLaunched.size()-1; i>=0; i--) {
   3647             WaitResult w = mWaitingActivityLaunched.get(i);
   3648             w.timeout = timeout;
   3649             if (r != null) {
   3650                 w.who = new ComponentName(r.info.packageName, r.info.name);
   3651             }
   3652             w.thisTime = thisTime;
   3653             w.totalTime = totalTime;
   3654         }
   3655         notify();
   3656     }
   3657 
   3658     void reportActivityVisibleLocked(HistoryRecord r) {
   3659         for (int i=mWaitingActivityVisible.size()-1; i>=0; i--) {
   3660             WaitResult w = mWaitingActivityVisible.get(i);
   3661             w.timeout = false;
   3662             if (r != null) {
   3663                 w.who = new ComponentName(r.info.packageName, r.info.name);
   3664             }
   3665             w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
   3666             w.thisTime = w.totalTime;
   3667         }
   3668         notify();
   3669     }
   3670 
   3671     private final int startActivityMayWait(IApplicationThread caller,
   3672             Intent intent, String resolvedType, Uri[] grantedUriPermissions,
   3673             int grantedMode, IBinder resultTo,
   3674             String resultWho, int requestCode, boolean onlyIfNeeded,
   3675             boolean debug, WaitResult outResult, Configuration config) {
   3676         // Refuse possible leaked file descriptors
   3677         if (intent != null && intent.hasFileDescriptors()) {
   3678             throw new IllegalArgumentException("File descriptors passed in Intent");
   3679         }
   3680 
   3681         final boolean componentSpecified = intent.getComponent() != null;
   3682 
   3683         // Don't modify the client's object!
   3684         intent = new Intent(intent);
   3685 
   3686         // Collect information about the target of the Intent.
   3687         ActivityInfo aInfo;
   3688         try {
   3689             ResolveInfo rInfo =
   3690                 ActivityThread.getPackageManager().resolveIntent(
   3691                         intent, resolvedType,
   3692                         PackageManager.MATCH_DEFAULT_ONLY
   3693                         | STOCK_PM_FLAGS);
   3694             aInfo = rInfo != null ? rInfo.activityInfo : null;
   3695         } catch (RemoteException e) {
   3696             aInfo = null;
   3697         }
   3698 
   3699         if (aInfo != null) {
   3700             // Store the found target back into the intent, because now that
   3701             // we have it we never want to do this again.  For example, if the
   3702             // user navigates back to this point in the history, we should
   3703             // always restart the exact same activity.
   3704             intent.setComponent(new ComponentName(
   3705                     aInfo.applicationInfo.packageName, aInfo.name));
   3706 
   3707             // Don't debug things in the system process
   3708             if (debug) {
   3709                 if (!aInfo.processName.equals("system")) {
   3710                     setDebugApp(aInfo.processName, true, false);
   3711                 }
   3712             }
   3713         }
   3714 
   3715         synchronized (this) {
   3716             int callingPid;
   3717             int callingUid;
   3718             if (caller == null) {
   3719                 callingPid = Binder.getCallingPid();
   3720                 callingUid = Binder.getCallingUid();
   3721             } else {
   3722                 callingPid = callingUid = -1;
   3723             }
   3724 
   3725             mConfigWillChange = config != null && mConfiguration.diff(config) != 0;
   3726             if (DEBUG_CONFIGURATION) Slog.v(TAG,
   3727                     "Starting activity when config will change = " + mConfigWillChange);
   3728 
   3729             final long origId = Binder.clearCallingIdentity();
   3730 
   3731             int res = startActivityLocked(caller, intent, resolvedType,
   3732                     grantedUriPermissions, grantedMode, aInfo,
   3733                     resultTo, resultWho, requestCode, callingPid, callingUid,
   3734                     onlyIfNeeded, componentSpecified);
   3735 
   3736             if (mConfigWillChange) {
   3737                 // If the caller also wants to switch to a new configuration,
   3738                 // do so now.  This allows a clean switch, as we are waiting
   3739                 // for the current activity to pause (so we will not destroy
   3740                 // it), and have not yet started the next activity.
   3741                 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   3742                         "updateConfiguration()");
   3743                 mConfigWillChange = false;
   3744                 if (DEBUG_CONFIGURATION) Slog.v(TAG,
   3745                         "Updating to new configuration after starting activity.");
   3746                 updateConfigurationLocked(config, null);
   3747             }
   3748 
   3749             Binder.restoreCallingIdentity(origId);
   3750 
   3751             if (outResult != null) {
   3752                 outResult.result = res;
   3753                 if (res == IActivityManager.START_SUCCESS) {
   3754                     mWaitingActivityLaunched.add(outResult);
   3755                     do {
   3756                         try {
   3757                             wait();
   3758                         } catch (InterruptedException e) {
   3759                         }
   3760                     } while (!outResult.timeout && outResult.who == null);
   3761                 } else if (res == IActivityManager.START_TASK_TO_FRONT) {
   3762                     HistoryRecord r = this.topRunningActivityLocked(null);
   3763                     if (r.nowVisible) {
   3764                         outResult.timeout = false;
   3765                         outResult.who = new ComponentName(r.info.packageName, r.info.name);
   3766                         outResult.totalTime = 0;
   3767                         outResult.thisTime = 0;
   3768                     } else {
   3769                         outResult.thisTime = SystemClock.uptimeMillis();
   3770                         mWaitingActivityVisible.add(outResult);
   3771                         do {
   3772                             try {
   3773                                 wait();
   3774                             } catch (InterruptedException e) {
   3775                             }
   3776                         } while (!outResult.timeout && outResult.who == null);
   3777                     }
   3778                 }
   3779             }
   3780 
   3781             return res;
   3782         }
   3783     }
   3784 
   3785     public final int startActivity(IApplicationThread caller,
   3786             Intent intent, String resolvedType, Uri[] grantedUriPermissions,
   3787             int grantedMode, IBinder resultTo,
   3788             String resultWho, int requestCode, boolean onlyIfNeeded,
   3789             boolean debug) {
   3790         return startActivityMayWait(caller, intent, resolvedType,
   3791                 grantedUriPermissions, grantedMode, resultTo, resultWho,
   3792                 requestCode, onlyIfNeeded, debug, null, null);
   3793     }
   3794 
   3795     public final WaitResult startActivityAndWait(IApplicationThread caller,
   3796             Intent intent, String resolvedType, Uri[] grantedUriPermissions,
   3797             int grantedMode, IBinder resultTo,
   3798             String resultWho, int requestCode, boolean onlyIfNeeded,
   3799             boolean debug) {
   3800         WaitResult res = new WaitResult();
   3801         startActivityMayWait(caller, intent, resolvedType,
   3802                 grantedUriPermissions, grantedMode, resultTo, resultWho,
   3803                 requestCode, onlyIfNeeded, debug, res, null);
   3804         return res;
   3805     }
   3806 
   3807     public final int startActivityWithConfig(IApplicationThread caller,
   3808             Intent intent, String resolvedType, Uri[] grantedUriPermissions,
   3809             int grantedMode, IBinder resultTo,
   3810             String resultWho, int requestCode, boolean onlyIfNeeded,
   3811             boolean debug, Configuration config) {
   3812         return startActivityMayWait(caller, intent, resolvedType,
   3813                 grantedUriPermissions, grantedMode, resultTo, resultWho,
   3814                 requestCode, onlyIfNeeded, debug, null, config);
   3815     }
   3816 
   3817      public int startActivityIntentSender(IApplicationThread caller,
   3818             IntentSender intent, Intent fillInIntent, String resolvedType,
   3819             IBinder resultTo, String resultWho, int requestCode,
   3820             int flagsMask, int flagsValues) {
   3821         // Refuse possible leaked file descriptors
   3822         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
   3823             throw new IllegalArgumentException("File descriptors passed in Intent");
   3824         }
   3825 
   3826         IIntentSender sender = intent.getTarget();
   3827         if (!(sender instanceof PendingIntentRecord)) {
   3828             throw new IllegalArgumentException("Bad PendingIntent object");
   3829         }
   3830 
   3831         PendingIntentRecord pir = (PendingIntentRecord)sender;
   3832 
   3833         synchronized (this) {
   3834             // If this is coming from the currently resumed activity, it is
   3835             // effectively saying that app switches are allowed at this point.
   3836             if (mResumedActivity != null
   3837                     && mResumedActivity.info.applicationInfo.uid ==
   3838                             Binder.getCallingUid()) {
   3839                 mAppSwitchesAllowedTime = 0;
   3840             }
   3841         }
   3842 
   3843         return pir.sendInner(0, fillInIntent, resolvedType,
   3844                 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
   3845     }
   3846 
   3847     public boolean startNextMatchingActivity(IBinder callingActivity,
   3848             Intent intent) {
   3849         // Refuse possible leaked file descriptors
   3850         if (intent != null && intent.hasFileDescriptors() == true) {
   3851             throw new IllegalArgumentException("File descriptors passed in Intent");
   3852         }
   3853 
   3854         synchronized (this) {
   3855             int index = indexOfTokenLocked(callingActivity);
   3856             if (index < 0) {
   3857                 return false;
   3858             }
   3859             HistoryRecord r = (HistoryRecord)mHistory.get(index);
   3860             if (r.app == null || r.app.thread == null) {
   3861                 // The caller is not running...  d'oh!
   3862                 return false;
   3863             }
   3864             intent = new Intent(intent);
   3865             // The caller is not allowed to change the data.
   3866             intent.setDataAndType(r.intent.getData(), r.intent.getType());
   3867             // And we are resetting to find the next component...
   3868             intent.setComponent(null);
   3869 
   3870             ActivityInfo aInfo = null;
   3871             try {
   3872                 List<ResolveInfo> resolves =
   3873                     ActivityThread.getPackageManager().queryIntentActivities(
   3874                             intent, r.resolvedType,
   3875                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
   3876 
   3877                 // Look for the original activity in the list...
   3878                 final int N = resolves != null ? resolves.size() : 0;
   3879                 for (int i=0; i<N; i++) {
   3880                     ResolveInfo rInfo = resolves.get(i);
   3881                     if (rInfo.activityInfo.packageName.equals(r.packageName)
   3882                             && rInfo.activityInfo.name.equals(r.info.name)) {
   3883                         // We found the current one...  the next matching is
   3884                         // after it.
   3885                         i++;
   3886                         if (i<N) {
   3887                             aInfo = resolves.get(i).activityInfo;
   3888                         }
   3889                         break;
   3890                     }
   3891                 }
   3892             } catch (RemoteException e) {
   3893             }
   3894 
   3895             if (aInfo == null) {
   3896                 // Nobody who is next!
   3897                 return false;
   3898             }
   3899 
   3900             intent.setComponent(new ComponentName(
   3901                     aInfo.applicationInfo.packageName, aInfo.name));
   3902             intent.setFlags(intent.getFlags()&~(
   3903                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
   3904                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
   3905                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
   3906                     Intent.FLAG_ACTIVITY_NEW_TASK));
   3907 
   3908             // Okay now we need to start the new activity, replacing the
   3909             // currently running activity.  This is a little tricky because
   3910             // we want to start the new one as if the current one is finished,
   3911             // but not finish the current one first so that there is no flicker.
   3912             // And thus...
   3913             final boolean wasFinishing = r.finishing;
   3914             r.finishing = true;
   3915 
   3916             // Propagate reply information over to the new activity.
   3917             final HistoryRecord resultTo = r.resultTo;
   3918             final String resultWho = r.resultWho;
   3919             final int requestCode = r.requestCode;
   3920             r.resultTo = null;
   3921             if (resultTo != null) {
   3922                 resultTo.removeResultsLocked(r, resultWho, requestCode);
   3923             }
   3924 
   3925             final long origId = Binder.clearCallingIdentity();
   3926             // XXX we are not dealing with propagating grantedUriPermissions...
   3927             // those are not yet exposed to user code, so there is no need.
   3928             int res = startActivityLocked(r.app.thread, intent,
   3929                     r.resolvedType, null, 0, aInfo, resultTo, resultWho,
   3930                     requestCode, -1, r.launchedFromUid, false, false);
   3931             Binder.restoreCallingIdentity(origId);
   3932 
   3933             r.finishing = wasFinishing;
   3934             if (res != START_SUCCESS) {
   3935                 return false;
   3936             }
   3937             return true;
   3938         }
   3939     }
   3940 
   3941     public final int startActivityInPackage(int uid,
   3942             Intent intent, String resolvedType, IBinder resultTo,
   3943             String resultWho, int requestCode, boolean onlyIfNeeded) {
   3944 
   3945         // This is so super not safe, that only the system (or okay root)
   3946         // can do it.
   3947         final int callingUid = Binder.getCallingUid();
   3948         if (callingUid != 0 && callingUid != Process.myUid()) {
   3949             throw new SecurityException(
   3950                     "startActivityInPackage only available to the system");
   3951         }
   3952 
   3953         final boolean componentSpecified = intent.getComponent() != null;
   3954 
   3955         // Don't modify the client's object!
   3956         intent = new Intent(intent);
   3957 
   3958         // Collect information about the target of the Intent.
   3959         ActivityInfo aInfo;
   3960         try {
   3961             ResolveInfo rInfo =
   3962                 ActivityThread.getPackageManager().resolveIntent(
   3963                         intent, resolvedType,
   3964                         PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
   3965             aInfo = rInfo != null ? rInfo.activityInfo : null;
   3966         } catch (RemoteException e) {
   3967             aInfo = null;
   3968         }
   3969 
   3970         if (aInfo != null) {
   3971             // Store the found target back into the intent, because now that
   3972             // we have it we never want to do this again.  For example, if the
   3973             // user navigates back to this point in the history, we should
   3974             // always restart the exact same activity.
   3975             intent.setComponent(new ComponentName(
   3976                     aInfo.applicationInfo.packageName, aInfo.name));
   3977         }
   3978 
   3979         synchronized(this) {
   3980             return startActivityLocked(null, intent, resolvedType,
   3981                     null, 0, aInfo, resultTo, resultWho, requestCode, -1, uid,
   3982                     onlyIfNeeded, componentSpecified);
   3983         }
   3984     }
   3985 
   3986     private final void addRecentTaskLocked(TaskRecord task) {
   3987         // Remove any existing entries that are the same kind of task.
   3988         int N = mRecentTasks.size();
   3989         for (int i=0; i<N; i++) {
   3990             TaskRecord tr = mRecentTasks.get(i);
   3991             if ((task.affinity != null && task.affinity.equals(tr.affinity))
   3992                     || (task.intent != null && task.intent.filterEquals(tr.intent))) {
   3993                 mRecentTasks.remove(i);
   3994                 i--;
   3995                 N--;
   3996                 if (task.intent == null) {
   3997                     // If the new recent task we are adding is not fully
   3998                     // specified, then replace it with the existing recent task.
   3999                     task = tr;
   4000                 }
   4001             }
   4002         }
   4003         if (N >= MAX_RECENT_TASKS) {
   4004             mRecentTasks.remove(N-1);
   4005         }
   4006         mRecentTasks.add(0, task);
   4007     }
   4008 
   4009     public void setRequestedOrientation(IBinder token,
   4010             int requestedOrientation) {
   4011         synchronized (this) {
   4012             int index = indexOfTokenLocked(token);
   4013             if (index < 0) {
   4014                 return;
   4015             }
   4016             HistoryRecord r = (HistoryRecord)mHistory.get(index);
   4017             final long origId = Binder.clearCallingIdentity();
   4018             mWindowManager.setAppOrientation(r, requestedOrientation);
   4019             Configuration config = mWindowManager.updateOrientationFromAppTokens(
   4020                     mConfiguration,
   4021                     r.mayFreezeScreenLocked(r.app) ? r : null);
   4022             if (config != null) {
   4023                 r.frozenBeforeDestroy = true;
   4024                 if (!updateConfigurationLocked(config, r)) {
   4025                     resumeTopActivityLocked(null);
   4026                 }
   4027             }
   4028             Binder.restoreCallingIdentity(origId);
   4029         }
   4030     }
   4031 
   4032     public int getRequestedOrientation(IBinder token) {
   4033         synchronized (this) {
   4034             int index = indexOfTokenLocked(token);
   4035             if (index < 0) {
   4036                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
   4037             }
   4038             HistoryRecord r = (HistoryRecord)mHistory.get(index);
   4039             return mWindowManager.getAppOrientation(r);
   4040         }
   4041     }
   4042 
   4043     private final void stopActivityLocked(HistoryRecord r) {
   4044         if (DEBUG_SWITCH) Slog.d(TAG, "Stopping: " + r);
   4045         if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
   4046                 || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
   4047             if (!r.finishing) {
   4048                 requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null,
   4049                         "no-history");
   4050             }
   4051         } else if (r.app != null && r.app.thread != null) {
   4052             if (mFocusedActivity == r) {
   4053                 setFocusedActivityLocked(topRunningActivityLocked(null));
   4054             }
   4055             r.resumeKeyDispatchingLocked();
   4056             try {
   4057                 r.stopped = false;
   4058                 r.state = ActivityState.STOPPING;
   4059                 if (DEBUG_VISBILITY) Slog.v(
   4060                         TAG, "Stopping visible=" + r.visible + " for " + r);
   4061                 if (!r.visible) {
   4062                     mWindowManager.setAppVisibility(r, false);
   4063                 }
   4064                 r.app.thread.scheduleStopActivity(r, r.visible, r.configChangeFlags);
   4065             } catch (Exception e) {
   4066                 // Maybe just ignore exceptions here...  if the process
   4067                 // has crashed, our death notification will clean things
   4068                 // up.
   4069                 Slog.w(TAG, "Exception thrown during pause", e);
   4070                 // Just in case, assume it to be stopped.
   4071                 r.stopped = true;
   4072                 r.state = ActivityState.STOPPED;
   4073                 if (r.configDestroy) {
   4074                     destroyActivityLocked(r, true);
   4075                 }
   4076             }
   4077         }
   4078     }
   4079 
   4080     /**
   4081      * @return Returns true if the activity is being finished, false if for
   4082      * some reason it is being left as-is.
   4083      */
   4084     private final boolean requestFinishActivityLocked(IBinder token, int resultCode,
   4085             Intent resultData, String reason) {
   4086         if (DEBUG_RESULTS) Slog.v(
   4087             TAG, "Finishing activity: token=" + token
   4088             + ", result=" + resultCode + ", data=" + resultData);
   4089 
   4090         int index = indexOfTokenLocked(token);
   4091         if (index < 0) {
   4092             return false;
   4093         }
   4094         HistoryRecord r = (HistoryRecord)mHistory.get(index);
   4095 
   4096         // Is this the last activity left?
   4097         boolean lastActivity = true;
   4098         for (int i=mHistory.size()-1; i>=0; i--) {
   4099             HistoryRecord p = (HistoryRecord)mHistory.get(i);
   4100             if (!p.finishing && p != r) {
   4101                 lastActivity = false;
   4102                 break;
   4103             }
   4104         }
   4105 
   4106         // If this is the last activity, but it is the home activity, then
   4107         // just don't finish it.
   4108         if (lastActivity) {
   4109             if (r.intent.hasCategory(Intent.CATEGORY_HOME)) {
   4110                 return false;
   4111             }
   4112         }
   4113 
   4114         finishActivityLocked(r, index, resultCode, resultData, reason);
   4115         return true;
   4116     }
   4117 
   4118     /**
   4119      * @return Returns true if this activity has been removed from the history
   4120      * list, or false if it is still in the list and will be removed later.
   4121      */
   4122     private final boolean finishActivityLocked(HistoryRecord r, int index,
   4123             int resultCode, Intent resultData, String reason) {
   4124         if (r.finishing) {
   4125             Slog.w(TAG, "Duplicate finish request for " + r);
   4126             return false;
   4127         }
   4128 
   4129         r.finishing = true;
   4130         EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
   4131                 System.identityHashCode(r),
   4132                 r.task.taskId, r.shortComponentName, reason);
   4133         r.task.numActivities--;
   4134         if (index < (mHistory.size()-1)) {
   4135             HistoryRecord next = (HistoryRecord)mHistory.get(index+1);
   4136             if (next.task == r.task) {
   4137                 if (r.frontOfTask) {
   4138                     // The next activity is now the front of the task.
   4139                     next.frontOfTask = true;
   4140                 }
   4141                 if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
   4142                     // If the caller asked that this activity (and all above it)
   4143                     // be cleared when the task is reset, don't lose that information,
   4144                     // but propagate it up to the next activity.
   4145                     next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
   4146                 }
   4147             }
   4148         }
   4149 
   4150         r.pauseKeyDispatchingLocked();
   4151         if (mFocusedActivity == r) {
   4152             setFocusedActivityLocked(topRunningActivityLocked(null));
   4153         }
   4154 
   4155         // send the result
   4156         HistoryRecord resultTo = r.resultTo;
   4157         if (resultTo != null) {
   4158             if (DEBUG_RESULTS) Slog.v(TAG, "Adding result to " + resultTo
   4159                     + " who=" + r.resultWho + " req=" + r.requestCode
   4160                     + " res=" + resultCode + " data=" + resultData);
   4161             if (r.info.applicationInfo.uid > 0) {
   4162                 grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid,
   4163                         r.packageName, resultData, r);
   4164             }
   4165             resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode,
   4166                                      resultData);
   4167             r.resultTo = null;
   4168         }
   4169         else if (DEBUG_RESULTS) Slog.v(TAG, "No result destination from " + r);
   4170 
   4171         // Make sure this HistoryRecord is not holding on to other resources,
   4172         // because clients have remote IPC references to this object so we
   4173         // can't assume that will go away and want to avoid circular IPC refs.
   4174         r.results = null;
   4175         r.pendingResults = null;
   4176         r.newIntents = null;
   4177         r.icicle = null;
   4178 
   4179         if (mPendingThumbnails.size() > 0) {
   4180             // There are clients waiting to receive thumbnails so, in case
   4181             // this is an activity that someone is waiting for, add it
   4182             // to the pending list so we can correctly update the clients.
   4183             mCancelledThumbnails.add(r);
   4184         }
   4185 
   4186         if (mResumedActivity == r) {
   4187             boolean endTask = index <= 0
   4188                     || ((HistoryRecord)mHistory.get(index-1)).task != r.task;
   4189             if (DEBUG_TRANSITION) Slog.v(TAG,
   4190                     "Prepare close transition: finishing " + r);
   4191             mWindowManager.prepareAppTransition(endTask
   4192                     ? WindowManagerPolicy.TRANSIT_TASK_CLOSE
   4193                     : WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE);
   4194 
   4195             // Tell window manager to prepare for this one to be removed.
   4196             mWindowManager.setAppVisibility(r, false);
   4197 
   4198             if (mPausingActivity == null) {
   4199                 if (DEBUG_PAUSE) Slog.v(TAG, "Finish needs to pause: " + r);
   4200                 if (DEBUG_USER_LEAVING) Slog.v(TAG, "finish() => pause with userLeaving=false");
   4201                 startPausingLocked(false, false);
   4202             }
   4203 
   4204         } else if (r.state != ActivityState.PAUSING) {
   4205             // If the activity is PAUSING, we will complete the finish once
   4206             // it is done pausing; else we can just directly finish it here.
   4207             if (DEBUG_PAUSE) Slog.v(TAG, "Finish not pausing: " + r);
   4208             return finishCurrentActivityLocked(r, index,
   4209                     FINISH_AFTER_PAUSE) == null;
   4210         } else {
   4211             if (DEBUG_PAUSE) Slog.v(TAG, "Finish waiting for pause of: " + r);
   4212         }
   4213 
   4214         return false;
   4215     }
   4216 
   4217     private static final int FINISH_IMMEDIATELY = 0;
   4218     private static final int FINISH_AFTER_PAUSE = 1;
   4219     private static final int FINISH_AFTER_VISIBLE = 2;
   4220 
   4221     private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r,
   4222             int mode) {
   4223         final int index = indexOfTokenLocked(r);
   4224         if (index < 0) {
   4225             return null;
   4226         }
   4227 
   4228         return finishCurrentActivityLocked(r, index, mode);
   4229     }
   4230 
   4231     private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r,
   4232             int index, int mode) {
   4233         // First things first: if this activity is currently visible,
   4234         // and the resumed activity is not yet visible, then hold off on
   4235         // finishing until the resumed one becomes visible.
   4236         if (mode == FINISH_AFTER_VISIBLE && r.nowVisible) {
   4237             if (!mStoppingActivities.contains(r)) {
   4238                 mStoppingActivities.add(r);
   4239                 if (mStoppingActivities.size() > 3) {
   4240                     // If we already have a few activities waiting to stop,
   4241                     // then give up on things going idle and start clearing
   4242                     // them out.
   4243                     Message msg = Message.obtain();
   4244                     msg.what = ActivityManagerService.IDLE_NOW_MSG;
   4245                     mHandler.sendMessage(msg);
   4246                 }
   4247             }
   4248             r.state = ActivityState.STOPPING;
   4249             updateOomAdjLocked();
   4250             return r;
   4251         }
   4252 
   4253         // make sure the record is cleaned out of other places.
   4254         mStoppingActivities.remove(r);
   4255         mWaitingVisibleActivities.remove(r);
   4256         if (mResumedActivity == r) {
   4257             mResumedActivity = null;
   4258         }
   4259         final ActivityState prevState = r.state;
   4260         r.state = ActivityState.FINISHING;
   4261 
   4262         if (mode == FINISH_IMMEDIATELY
   4263                 || prevState == ActivityState.STOPPED
   4264                 || prevState == ActivityState.INITIALIZING) {
   4265             // If this activity is already stopped, we can just finish
   4266             // it right now.
   4267             return destroyActivityLocked(r, true) ? null : r;
   4268         } else {
   4269             // Need to go through the full pause cycle to get this
   4270             // activity into the stopped state and then finish it.
   4271             if (localLOGV) Slog.v(TAG, "Enqueueing pending finish: " + r);
   4272             mFinishingActivities.add(r);
   4273             resumeTopActivityLocked(null);
   4274         }
   4275         return r;
   4276     }
   4277 
   4278     /**
   4279      * This is the internal entry point for handling Activity.finish().
   4280      *
   4281      * @param token The Binder token referencing the Activity we want to finish.
   4282      * @param resultCode Result code, if any, from this Activity.
   4283      * @param resultData Result data (Intent), if any, from this Activity.
   4284      *
   4285      * @return Returns true if the activity successfully finished, or false if it is still running.
   4286      */
   4287     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
   4288         // Refuse possible leaked file descriptors
   4289         if (resultData != null && resultData.hasFileDescriptors() == true) {
   4290             throw new IllegalArgumentException("File descriptors passed in Intent");
   4291         }
   4292 
   4293         synchronized(this) {
   4294             if (mController != null) {
   4295                 // Find the first activity that is not finishing.
   4296                 HistoryRecord next = topRunningActivityLocked(token, 0);
   4297                 if (next != null) {
   4298                     // ask watcher if this is allowed
   4299                     boolean resumeOK = true;
   4300                     try {
   4301                         resumeOK = mController.activityResuming(next.packageName);
   4302                     } catch (RemoteException e) {
   4303                         mController = null;
   4304                     }
   4305 
   4306                     if (!resumeOK) {
   4307                         return false;
   4308                     }
   4309                 }
   4310             }
   4311             final long origId = Binder.clearCallingIdentity();
   4312             boolean res = requestFinishActivityLocked(token, resultCode,
   4313                     resultData, "app-request");
   4314             Binder.restoreCallingIdentity(origId);
   4315             return res;
   4316         }
   4317     }
   4318 
   4319     void sendActivityResultLocked(int callingUid, HistoryRecord r,
   4320             String resultWho, int requestCode, int resultCode, Intent data) {
   4321 
   4322         if (callingUid > 0) {
   4323             grantUriPermissionFromIntentLocked(callingUid, r.packageName,
   4324                     data, r);
   4325         }
   4326 
   4327         if (DEBUG_RESULTS) Slog.v(TAG, "Send activity result to " + r
   4328                 + " : who=" + resultWho + " req=" + requestCode
   4329                 + " res=" + resultCode + " data=" + data);
   4330         if (mResumedActivity == r && r.app != null && r.app.thread != null) {
   4331             try {
   4332                 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
   4333                 list.add(new ResultInfo(resultWho, requestCode,
   4334                         resultCode, data));
   4335                 r.app.thread.scheduleSendResult(r, list);
   4336                 return;
   4337             } catch (Exception e) {
   4338                 Slog.w(TAG, "Exception thrown sending result to " + r, e);
   4339             }
   4340         }
   4341 
   4342         r.addResultLocked(null, resultWho, requestCode, resultCode, data);
   4343     }
   4344 
   4345     public final void finishSubActivity(IBinder token, String resultWho,
   4346             int requestCode) {
   4347         synchronized(this) {
   4348             int index = indexOfTokenLocked(token);
   4349             if (index < 0) {
   4350                 return;
   4351             }
   4352             HistoryRecord self = (HistoryRecord)mHistory.get(index);
   4353 
   4354             final long origId = Binder.clearCallingIdentity();
   4355 
   4356             int i;
   4357             for (i=mHistory.size()-1; i>=0; i--) {
   4358                 HistoryRecord r = (HistoryRecord)mHistory.get(i);
   4359                 if (r.resultTo == self && r.requestCode == requestCode) {
   4360                     if ((r.resultWho == null && resultWho == null) ||
   4361                         (r.resultWho != null && r.resultWho.equals(resultWho))) {
   4362                         finishActivityLocked(r, i,
   4363                                 Activity.RESULT_CANCELED, null, "request-sub");
   4364                     }
   4365                 }
   4366             }
   4367 
   4368             Binder.restoreCallingIdentity(origId);
   4369         }
   4370     }
   4371 
   4372     public boolean willActivityBeVisible(IBinder token) {
   4373         synchronized(this) {
   4374             int i;
   4375             for (i=mHistory.size()-1; i>=0; i--) {
   4376                 HistoryRecord r = (HistoryRecord)mHistory.get(i);
   4377                 if (r == token) {
   4378                     return true;
   4379                 }
   4380                 if (r.fullscreen && !r.finishing) {
   4381                     return false;
   4382                 }
   4383             }
   4384             return true;
   4385         }
   4386     }
   4387 
   4388     public void overridePendingTransition(IBinder token, String packageName,
   4389             int enterAnim, int exitAnim) {
   4390         synchronized(this) {
   4391             int index = indexOfTokenLocked(token);
   4392             if (index < 0) {
   4393                 return;
   4394             }
   4395             HistoryRecord self = (HistoryRecord)mHistory.get(index);
   4396 
   4397             final long origId = Binder.clearCallingIdentity();
   4398 
   4399             if (self.state == ActivityState.RESUMED
   4400                     || self.state == ActivityState.PAUSING) {
   4401                 mWindowManager.overridePendingAppTransition(packageName,
   4402                         enterAnim, exitAnim);
   4403             }
   4404 
   4405             Binder.restoreCallingIdentity(origId);
   4406         }
   4407     }
   4408 
   4409     /**
   4410      * Perform clean-up of service connections in an activity record.
   4411      */
   4412     private final void cleanUpActivityServicesLocked(HistoryRecord r) {
   4413         // Throw away any services that have been bound by this activity.
   4414         if (r.connections != null) {
   4415             Iterator<ConnectionRecord> it = r.connections.iterator();
   4416             while (it.hasNext()) {
   4417                 ConnectionRecord c = it.next();
   4418                 removeConnectionLocked(c, null, r);
   4419             }
   4420             r.connections = null;
   4421         }
   4422     }
   4423 
   4424     /**
   4425      * Perform the common clean-up of an activity record.  This is called both
   4426      * as part of destroyActivityLocked() (when destroying the client-side
   4427      * representation) and cleaning things up as a result of its hosting
   4428      * processing going away, in which case there is no remaining client-side
   4429      * state to destroy so only the cleanup here is needed.
   4430      */
   4431     private final void cleanUpActivityLocked(HistoryRecord r, boolean cleanServices) {
   4432         if (mResumedActivity == r) {
   4433             mResumedActivity = null;
   4434         }
   4435         if (mFocusedActivity == r) {
   4436             mFocusedActivity = null;
   4437         }
   4438 
   4439         r.configDestroy = false;
   4440         r.frozenBeforeDestroy = false;
   4441 
   4442         // Make sure this record is no longer in the pending finishes list.
   4443         // This could happen, for example, if we are trimming activities
   4444         // down to the max limit while they are still waiting to finish.
   4445         mFinishingActivities.remove(r);
   4446         mWaitingVisibleActivities.remove(r);
   4447 
   4448         // Remove any pending results.
   4449         if (r.finishing && r.pendingResults != null) {
   4450             for (WeakReference<PendingIntentRecord> apr : r.pendingResults) {
   4451                 PendingIntentRecord rec = apr.get();
   4452                 if (rec != null) {
   4453                     cancelIntentSenderLocked(rec, false);
   4454                 }
   4455             }
   4456             r.pendingResults = null;
   4457         }
   4458 
   4459         if (cleanServices) {
   4460             cleanUpActivityServicesLocked(r);
   4461         }
   4462 
   4463         if (mPendingThumbnails.size() > 0) {
   4464             // There are clients waiting to receive thumbnails so, in case
   4465             // this is an activity that someone is waiting for, add it
   4466             // to the pending list so we can correctly update the clients.
   4467             mCancelledThumbnails.add(r);
   4468         }
   4469 
   4470         // Get rid of any pending idle timeouts.
   4471         mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
   4472         mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
   4473     }
   4474 
   4475     private final void removeActivityFromHistoryLocked(HistoryRecord r) {
   4476         if (r.state != ActivityState.DESTROYED) {
   4477             mHistory.remove(r);
   4478             r.inHistory = false;
   4479             r.state = ActivityState.DESTROYED;
   4480             mWindowManager.removeAppToken(r);
   4481             if (VALIDATE_TOKENS) {
   4482                 mWindowManager.validateAppTokens(mHistory);
   4483             }
   4484             cleanUpActivityServicesLocked(r);
   4485             removeActivityUriPermissionsLocked(r);
   4486         }
   4487     }
   4488 
   4489     /**
   4490      * Destroy the current CLIENT SIDE instance of an activity.  This may be
   4491      * called both when actually finishing an activity, or when performing
   4492      * a configuration switch where we destroy the current client-side object
   4493      * but then create a new client-side object for this same HistoryRecord.
   4494      */
   4495     private final boolean destroyActivityLocked(HistoryRecord r,
   4496             boolean removeFromApp) {
   4497         if (DEBUG_SWITCH) Slog.v(
   4498             TAG, "Removing activity: token=" + r
   4499               + ", app=" + (r.app != null ? r.app.processName : "(null)"));
   4500         EventLog.writeEvent(EventLogTags.AM_DESTROY_ACTIVITY,
   4501                 System.identityHashCode(r),
   4502                 r.task.taskId, r.shortComponentName);
   4503 
   4504         boolean removedFromHistory = false;
   4505 
   4506         cleanUpActivityLocked(r, false);
   4507 
   4508         final boolean hadApp = r.app != null;
   4509 
   4510         if (hadApp) {
   4511             if (removeFromApp) {
   4512                 int idx = r.app.activities.indexOf(r);
   4513                 if (idx >= 0) {
   4514                     r.app.activities.remove(idx);
   4515                 }
   4516                 if (r.persistent) {
   4517                     decPersistentCountLocked(r.app);
   4518                 }
   4519                 if (r.app.activities.size() == 0) {
   4520                     // No longer have activities, so update location in
   4521                     // LRU list.
   4522                     updateLruProcessLocked(r.app, true, false);
   4523                 }
   4524             }
   4525 
   4526             boolean skipDestroy = false;
   4527 
   4528             try {
   4529                 if (DEBUG_SWITCH) Slog.i(TAG, "Destroying: " + r);
   4530                 r.app.thread.scheduleDestroyActivity(r, r.finishing,
   4531                         r.configChangeFlags);
   4532             } catch (Exception e) {
   4533                 // We can just ignore exceptions here...  if the process
   4534                 // has crashed, our death notification will clean things
   4535                 // up.
   4536                 //Slog.w(TAG, "Exception thrown during finish", e);
   4537                 if (r.finishing) {
   4538                     removeActivityFromHistoryLocked(r);
   4539                     removedFromHistory = true;
   4540                     skipDestroy = true;
   4541                 }
   4542             }
   4543 
   4544             r.app = null;
   4545             r.nowVisible = false;
   4546 
   4547             if (r.finishing && !skipDestroy) {
   4548                 r.state = ActivityState.DESTROYING;
   4549                 Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG);
   4550                 msg.obj = r;
   4551                 mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT);
   4552             } else {
   4553                 r.state = ActivityState.DESTROYED;
   4554             }
   4555         } else {
   4556             // remove this record from the history.
   4557             if (r.finishing) {
   4558                 removeActivityFromHistoryLocked(r);
   4559                 removedFromHistory = true;
   4560             } else {
   4561                 r.state = ActivityState.DESTROYED;
   4562             }
   4563         }
   4564 
   4565         r.configChangeFlags = 0;
   4566 
   4567         if (!mLRUActivities.remove(r) && hadApp) {
   4568             Slog.w(TAG, "Activity " + r + " being finished, but not in LRU list");
   4569         }
   4570 
   4571         return removedFromHistory;
   4572     }
   4573 
   4574     private static void removeHistoryRecordsForAppLocked(ArrayList list, ProcessRecord app) {
   4575         int i = list.size();
   4576         if (localLOGV) Slog.v(
   4577             TAG, "Removing app " + app + " from list " + list
   4578             + " with " + i + " entries");
   4579         while (i > 0) {
   4580             i--;
   4581             HistoryRecord r = (HistoryRecord)list.get(i);
   4582             if (localLOGV) Slog.v(
   4583                 TAG, "Record #" + i + " " + r + ": app=" + r.app);
   4584             if (r.app == app) {
   4585                 if (localLOGV) Slog.v(TAG, "Removing this entry!");
   4586                 list.remove(i);
   4587             }
   4588         }
   4589     }
   4590 
   4591     /**
   4592      * Main function for removing an existing process from the activity manager
   4593      * as a result of that process going away.  Clears out all connections
   4594      * to the process.
   4595      */
   4596     private final void handleAppDiedLocked(ProcessRecord app,
   4597             boolean restarting) {
   4598         cleanUpApplicationRecordLocked(app, restarting, -1);
   4599         if (!restarting) {
   4600             mLruProcesses.remove(app);
   4601         }
   4602 
   4603         // Just in case...
   4604         if (mPausingActivity != null && mPausingActivity.app == app) {
   4605             if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " + mPausingActivity);
   4606             mPausingActivity = null;
   4607         }
   4608         if (mLastPausedActivity != null && mLastPausedActivity.app == app) {
   4609             mLastPausedActivity = null;
   4610         }
   4611 
   4612         // Remove this application's activities from active lists.
   4613         removeHistoryRecordsForAppLocked(mLRUActivities, app);
   4614         removeHistoryRecordsForAppLocked(mStoppingActivities, app);
   4615         removeHistoryRecordsForAppLocked(mWaitingVisibleActivities, app);
   4616         removeHistoryRecordsForAppLocked(mFinishingActivities, app);
   4617 
   4618         boolean atTop = true;
   4619         boolean hasVisibleActivities = false;
   4620 
   4621         // Clean out the history list.
   4622         int i = mHistory.size();
   4623         if (localLOGV) Slog.v(
   4624             TAG, "Removing app " + app + " from history with " + i + " entries");
   4625         while (i > 0) {
   4626             i--;
   4627             HistoryRecord r = (HistoryRecord)mHistory.get(i);
   4628             if (localLOGV) Slog.v(
   4629                 TAG, "Record #" + i + " " + r + ": app=" + r.app);
   4630             if (r.app == app) {
   4631                 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
   4632                     if (localLOGV) Slog.v(
   4633                         TAG, "Removing this entry!  frozen=" + r.haveState
   4634                         + " finishing=" + r.finishing);
   4635                     mHistory.remove(i);
   4636 
   4637                     r.inHistory = false;
   4638                     mWindowManager.removeAppToken(r);
   4639                     if (VALIDATE_TOKENS) {
   4640                         mWindowManager.validateAppTokens(mHistory);
   4641                     }
   4642                     removeActivityUriPermissionsLocked(r);
   4643 
   4644                 } else {
   4645                     // We have the current state for this activity, so
   4646                     // it can be restarted later when needed.
   4647                     if (localLOGV) Slog.v(
   4648                         TAG, "Keeping entry, setting app to null");
   4649                     if (r.visible) {
   4650                         hasVisibleActivities = true;
   4651                     }
   4652                     r.app = null;
   4653                     r.nowVisible = false;
   4654                     if (!r.haveState) {
   4655                         r.icicle = null;
   4656                     }
   4657                 }
   4658 
   4659                 cleanUpActivityLocked(r, true);
   4660                 r.state = ActivityState.STOPPED;
   4661             }
   4662             atTop = false;
   4663         }
   4664 
   4665         app.activities.clear();
   4666 
   4667         if (app.instrumentationClass != null) {
   4668             Slog.w(TAG, "Crash of app " + app.processName
   4669                   + " running instrumentation " + app.instrumentationClass);
   4670             Bundle info = new Bundle();
   4671             info.putString("shortMsg", "Process crashed.");
   4672             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
   4673         }
   4674 
   4675         if (!restarting) {
   4676             if (!resumeTopActivityLocked(null)) {
   4677                 // If there was nothing to resume, and we are not already
   4678                 // restarting this process, but there is a visible activity that
   4679                 // is hosted by the process...  then make sure all visible
   4680                 // activities are running, taking care of restarting this
   4681                 // process.
   4682                 if (hasVisibleActivities) {
   4683                     ensureActivitiesVisibleLocked(null, 0);
   4684                 }
   4685             }
   4686         }
   4687     }
   4688 
   4689     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
   4690         IBinder threadBinder = thread.asBinder();
   4691 
   4692         // Find the application record.
   4693         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   4694             ProcessRecord rec = mLruProcesses.get(i);
   4695             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
   4696                 return i;
   4697             }
   4698         }
   4699         return -1;
   4700     }
   4701 
   4702     private final ProcessRecord getRecordForAppLocked(
   4703             IApplicationThread thread) {
   4704         if (thread == null) {
   4705             return null;
   4706         }
   4707 
   4708         int appIndex = getLRURecordIndexForAppLocked(thread);
   4709         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
   4710     }
   4711 
   4712     private final void appDiedLocked(ProcessRecord app, int pid,
   4713             IApplicationThread thread) {
   4714 
   4715         mProcDeaths[0]++;
   4716 
   4717         // Clean up already done if the process has been re-started.
   4718         if (app.pid == pid && app.thread != null &&
   4719                 app.thread.asBinder() == thread.asBinder()) {
   4720             if (!app.killedBackground) {
   4721                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   4722                         + ") has died.");
   4723             }
   4724             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
   4725             if (localLOGV) Slog.v(
   4726                 TAG, "Dying app: " + app + ", pid: " + pid
   4727                 + ", thread: " + thread.asBinder());
   4728             boolean doLowMem = app.instrumentationClass == null;
   4729             handleAppDiedLocked(app, false);
   4730 
   4731             if (doLowMem) {
   4732                 // If there are no longer any background processes running,
   4733                 // and the app that died was not running instrumentation,
   4734                 // then tell everyone we are now low on memory.
   4735                 boolean haveBg = false;
   4736                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   4737                     ProcessRecord rec = mLruProcesses.get(i);
   4738                     if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
   4739                         haveBg = true;
   4740                         break;
   4741                     }
   4742                 }
   4743 
   4744                 if (!haveBg) {
   4745                     Slog.i(TAG, "Low Memory: No more background processes.");
   4746                     EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
   4747                     long now = SystemClock.uptimeMillis();
   4748                     for (int i=mLruProcesses.size()-1; i>=0; i--) {
   4749                         ProcessRecord rec = mLruProcesses.get(i);
   4750                         if (rec != app && rec.thread != null &&
   4751                                 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
   4752                             // The low memory report is overriding any current
   4753                             // state for a GC request.  Make sure to do
   4754                             // visible/foreground processes first.
   4755                             if (rec.setAdj <= VISIBLE_APP_ADJ) {
   4756                                 rec.lastRequestedGc = 0;
   4757                             } else {
   4758                                 rec.lastRequestedGc = rec.lastLowMemory;
   4759                             }
   4760                             rec.reportLowMemory = true;
   4761                             rec.lastLowMemory = now;
   4762                             mProcessesToGc.remove(rec);
   4763                             addProcessToGcListLocked(rec);
   4764                         }
   4765                     }
   4766                     scheduleAppGcsLocked();
   4767                 }
   4768             }
   4769         } else if (app.pid != pid) {
   4770             // A new process has already been started.
   4771             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   4772                     + ") has died and restarted (pid " + app.pid + ").");
   4773             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
   4774         } else if (DEBUG_PROCESSES) {
   4775             Slog.d(TAG, "Received spurious death notification for thread "
   4776                     + thread.asBinder());
   4777         }
   4778     }
   4779 
   4780     /**
   4781      * If a stack trace dump file is configured, dump process stack traces.
   4782      * @param clearTraces causes the dump file to be erased prior to the new
   4783      *    traces being written, if true; when false, the new traces will be
   4784      *    appended to any existing file content.
   4785      * @param pids of dalvik VM processes to dump stack traces for
   4786      * @return file containing stack traces, or null if no dump file is configured
   4787      */
   4788     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> pids) {
   4789         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   4790         if (tracesPath == null || tracesPath.length() == 0) {
   4791             return null;
   4792         }
   4793 
   4794         File tracesFile = new File(tracesPath);
   4795         try {
   4796             File tracesDir = tracesFile.getParentFile();
   4797             if (!tracesDir.exists()) tracesFile.mkdirs();
   4798             FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
   4799 
   4800             if (clearTraces && tracesFile.exists()) tracesFile.delete();
   4801             tracesFile.createNewFile();
   4802             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   4803         } catch (IOException e) {
   4804             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
   4805             return null;
   4806         }
   4807 
   4808         // Use a FileObserver to detect when traces finish writing.
   4809         // The order of traces is considered important to maintain for legibility.
   4810         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
   4811             public synchronized void onEvent(int event, String path) { notify(); }
   4812         };
   4813 
   4814         try {
   4815             observer.startWatching();
   4816             int num = pids.size();
   4817             for (int i = 0; i < num; i++) {
   4818                 synchronized (observer) {
   4819                     Process.sendSignal(pids.get(i), Process.SIGNAL_QUIT);
   4820                     observer.wait(200);  // Wait for write-close, give up after 200msec
   4821                 }
   4822             }
   4823         } catch (InterruptedException e) {
   4824             Log.wtf(TAG, e);
   4825         } finally {
   4826             observer.stopWatching();
   4827         }
   4828 
   4829         return tracesFile;
   4830     }
   4831 
   4832     final void appNotResponding(ProcessRecord app, HistoryRecord activity,
   4833             HistoryRecord parent, final String annotation) {
   4834         ArrayList<Integer> pids = new ArrayList<Integer>(20);
   4835 
   4836         synchronized (this) {
   4837             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
   4838             if (mShuttingDown) {
   4839                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
   4840                 return;
   4841             } else if (app.notResponding) {
   4842                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
   4843                 return;
   4844             } else if (app.crashing) {
   4845                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
   4846                 return;
   4847             }
   4848 
   4849             // In case we come through here for the same app before completing
   4850             // this one, mark as anring now so we will bail out.
   4851             app.notResponding = true;
   4852 
   4853             // Log the ANR to the event log.
   4854             EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
   4855                     annotation);
   4856 
   4857             // Dump thread traces as quickly as we can, starting with "interesting" processes.
   4858             pids.add(app.pid);
   4859 
   4860             int parentPid = app.pid;
   4861             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
   4862             if (parentPid != app.pid) pids.add(parentPid);
   4863 
   4864             if (MY_PID != app.pid && MY_PID != parentPid) pids.add(MY_PID);
   4865 
   4866             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   4867                 ProcessRecord r = mLruProcesses.get(i);
   4868                 if (r != null && r.thread != null) {
   4869                     int pid = r.pid;
   4870                     if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) pids.add(pid);
   4871                 }
   4872             }
   4873         }
   4874 
   4875         File tracesFile = dumpStackTraces(true, pids);
   4876 
   4877         // Log the ANR to the main log.
   4878         StringBuilder info = mStringBuilder;
   4879         info.setLength(0);
   4880         info.append("ANR in ").append(app.processName);
   4881         if (activity != null && activity.shortComponentName != null) {
   4882             info.append(" (").append(activity.shortComponentName).append(")");
   4883         }
   4884         info.append("\n");
   4885         if (annotation != null) {
   4886             info.append("Reason: ").append(annotation).append("\n");
   4887         }
   4888         if (parent != null && parent != activity) {
   4889             info.append("Parent: ").append(parent.shortComponentName).append("\n");
   4890         }
   4891 
   4892         String cpuInfo = null;
   4893         if (MONITOR_CPU_USAGE) {
   4894             updateCpuStatsNow();
   4895             synchronized (mProcessStatsThread) {
   4896                 cpuInfo = mProcessStats.printCurrentState();
   4897             }
   4898             info.append(cpuInfo);
   4899         }
   4900 
   4901         Slog.e(TAG, info.toString());
   4902         if (tracesFile == null) {
   4903             // There is no trace file, so dump (only) the alleged culprit's threads to the log
   4904             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
   4905         }
   4906 
   4907         addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
   4908 
   4909         if (mController != null) {
   4910             try {
   4911                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
   4912                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
   4913                 if (res != 0) {
   4914                     if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
   4915                     return;
   4916                 }
   4917             } catch (RemoteException e) {
   4918                 mController = null;
   4919             }
   4920         }
   4921 
   4922         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
   4923         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
   4924                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
   4925 
   4926         synchronized (this) {
   4927             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
   4928                 Process.killProcess(app.pid);
   4929                 return;
   4930             }
   4931 
   4932             // Set the app's notResponding state, and look up the errorReportReceiver
   4933             makeAppNotRespondingLocked(app,
   4934                     activity != null ? activity.shortComponentName : null,
   4935                     annotation != null ? "ANR " + annotation : "ANR",
   4936                     info.toString());
   4937 
   4938             // Bring up the infamous App Not Responding dialog
   4939             Message msg = Message.obtain();
   4940             HashMap map = new HashMap();
   4941             msg.what = SHOW_NOT_RESPONDING_MSG;
   4942             msg.obj = map;
   4943             map.put("app", app);
   4944             if (activity != null) {
   4945                 map.put("activity", activity);
   4946             }
   4947 
   4948             mHandler.sendMessage(msg);
   4949         }
   4950     }
   4951 
   4952     private final void decPersistentCountLocked(ProcessRecord app)
   4953     {
   4954         app.persistentActivities--;
   4955         if (app.persistentActivities > 0) {
   4956             // Still more of 'em...
   4957             return;
   4958         }
   4959         if (app.persistent) {
   4960             // Ah, but the application itself is persistent.  Whatever!
   4961             return;
   4962         }
   4963 
   4964         // App is no longer persistent...  make sure it and the ones
   4965         // following it in the LRU list have the correc oom_adj.
   4966         updateOomAdjLocked();
   4967     }
   4968 
   4969     public void setPersistent(IBinder token, boolean isPersistent) {
   4970         if (checkCallingPermission(android.Manifest.permission.PERSISTENT_ACTIVITY)
   4971                 != PackageManager.PERMISSION_GRANTED) {
   4972             String msg = "Permission Denial: setPersistent() from pid="
   4973                     + Binder.getCallingPid()
   4974                     + ", uid=" + Binder.getCallingUid()
   4975                     + " requires " + android.Manifest.permission.PERSISTENT_ACTIVITY;
   4976             Slog.w(TAG, msg);
   4977             throw new SecurityException(msg);
   4978         }
   4979 
   4980         synchronized(this) {
   4981             int index = indexOfTokenLocked(token);
   4982             if (index < 0) {
   4983                 return;
   4984             }
   4985             HistoryRecord r = (HistoryRecord)mHistory.get(index);
   4986             ProcessRecord app = r.app;
   4987 
   4988             if (localLOGV) Slog.v(
   4989                 TAG, "Setting persistence " + isPersistent + ": " + r);
   4990 
   4991             if (isPersistent) {
   4992                 if (r.persistent) {
   4993                     // Okay okay, I heard you already!
   4994                     if (localLOGV) Slog.v(TAG, "Already persistent!");
   4995                     return;
   4996                 }
   4997                 r.persistent = true;
   4998                 app.persistentActivities++;
   4999                 if (localLOGV) Slog.v(TAG, "Num persistent now: " + app.persistentActivities);
   5000                 if (app.persistentActivities > 1) {
   5001                     // We aren't the first...
   5002                     if (localLOGV) Slog.v(TAG, "Not the first!");
   5003                     return;
   5004                 }
   5005                 if (app.persistent) {
   5006                     // This would be redundant.
   5007                     if (localLOGV) Slog.v(TAG, "App is persistent!");
   5008                     return;
   5009                 }
   5010 
   5011                 // App is now persistent...  make sure it and the ones
   5012                 // following it now have the correct oom_adj.
   5013                 final long origId = Binder.clearCallingIdentity();
   5014                 updateOomAdjLocked();
   5015                 Binder.restoreCallingIdentity(origId);
   5016 
   5017             } else {
   5018                 if (!r.persistent) {
   5019                     // Okay okay, I heard you already!
   5020                     return;
   5021                 }
   5022                 r.persistent = false;
   5023                 final long origId = Binder.clearCallingIdentity();
   5024                 decPersistentCountLocked(app);
   5025                 Binder.restoreCallingIdentity(origId);
   5026 
   5027             }
   5028         }
   5029     }
   5030 
   5031     public boolean clearApplicationUserData(final String packageName,
   5032             final IPackageDataObserver observer) {
   5033         int uid = Binder.getCallingUid();
   5034         int pid = Binder.getCallingPid();
   5035         long callingId = Binder.clearCallingIdentity();
   5036         try {
   5037             IPackageManager pm = ActivityThread.getPackageManager();
   5038             int pkgUid = -1;
   5039             synchronized(this) {
   5040                 try {
   5041                     pkgUid = pm.getPackageUid(packageName);
   5042                 } catch (RemoteException e) {
   5043                 }
   5044                 if (pkgUid == -1) {
   5045                     Slog.w(TAG, "Invalid packageName:" + packageName);
   5046                     return false;
   5047                 }
   5048                 if (uid == pkgUid || checkComponentPermission(
   5049                         android.Manifest.permission.CLEAR_APP_USER_DATA,
   5050                         pid, uid, -1)
   5051                         == PackageManager.PERMISSION_GRANTED) {
   5052                     forceStopPackageLocked(packageName, pkgUid);
   5053                 } else {
   5054                     throw new SecurityException(pid+" does not have permission:"+
   5055                             android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
   5056                                     "for process:"+packageName);
   5057                 }
   5058             }
   5059 
   5060             try {
   5061                 //clear application user data
   5062                 pm.clearApplicationUserData(packageName, observer);
   5063                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
   5064                         Uri.fromParts("package", packageName, null));
   5065                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
   5066                 synchronized (this) {
   5067                     broadcastIntentLocked(null, null, intent,
   5068                             null, null, 0, null, null, null,
   5069                             false, false, MY_PID, Process.SYSTEM_UID);
   5070                 }
   5071             } catch (RemoteException e) {
   5072             }
   5073         } finally {
   5074             Binder.restoreCallingIdentity(callingId);
   5075         }
   5076         return true;
   5077     }
   5078 
   5079     public void killBackgroundProcesses(final String packageName) {
   5080         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   5081                 != PackageManager.PERMISSION_GRANTED &&
   5082                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
   5083                         != PackageManager.PERMISSION_GRANTED) {
   5084             String msg = "Permission Denial: killBackgroundProcesses() from pid="
   5085                     + Binder.getCallingPid()
   5086                     + ", uid=" + Binder.getCallingUid()
   5087                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   5088             Slog.w(TAG, msg);
   5089             throw new SecurityException(msg);
   5090         }
   5091 
   5092         long callingId = Binder.clearCallingIdentity();
   5093         try {
   5094             IPackageManager pm = ActivityThread.getPackageManager();
   5095             int pkgUid = -1;
   5096             synchronized(this) {
   5097                 try {
   5098                     pkgUid = pm.getPackageUid(packageName);
   5099                 } catch (RemoteException e) {
   5100                 }
   5101                 if (pkgUid == -1) {
   5102                     Slog.w(TAG, "Invalid packageName: " + packageName);
   5103                     return;
   5104                 }
   5105                 killPackageProcessesLocked(packageName, pkgUid,
   5106                         SECONDARY_SERVER_ADJ, false, true);
   5107             }
   5108         } finally {
   5109             Binder.restoreCallingIdentity(callingId);
   5110         }
   5111     }
   5112 
   5113     public void forceStopPackage(final String packageName) {
   5114         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   5115                 != PackageManager.PERMISSION_GRANTED) {
   5116             String msg = "Permission Denial: forceStopPackage() from pid="
   5117                     + Binder.getCallingPid()
   5118                     + ", uid=" + Binder.getCallingUid()
   5119                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   5120             Slog.w(TAG, msg);
   5121             throw new SecurityException(msg);
   5122         }
   5123 
   5124         long callingId = Binder.clearCallingIdentity();
   5125         try {
   5126             IPackageManager pm = ActivityThread.getPackageManager();
   5127             int pkgUid = -1;
   5128             synchronized(this) {
   5129                 try {
   5130                     pkgUid = pm.getPackageUid(packageName);
   5131                 } catch (RemoteException e) {
   5132                 }
   5133                 if (pkgUid == -1) {
   5134                     Slog.w(TAG, "Invalid packageName: " + packageName);
   5135                     return;
   5136                 }
   5137                 forceStopPackageLocked(packageName, pkgUid);
   5138             }
   5139         } finally {
   5140             Binder.restoreCallingIdentity(callingId);
   5141         }
   5142     }
   5143 
   5144     /*
   5145      * The pkg name and uid have to be specified.
   5146      * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
   5147      */
   5148     public void killApplicationWithUid(String pkg, int uid) {
   5149         if (pkg == null) {
   5150             return;
   5151         }
   5152         // Make sure the uid is valid.
   5153         if (uid < 0) {
   5154             Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
   5155             return;
   5156         }
   5157         int callerUid = Binder.getCallingUid();
   5158         // Only the system server can kill an application
   5159         if (callerUid == Process.SYSTEM_UID) {
   5160             // Post an aysnc message to kill the application
   5161             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
   5162             msg.arg1 = uid;
   5163             msg.arg2 = 0;
   5164             msg.obj = pkg;
   5165             mHandler.sendMessage(msg);
   5166         } else {
   5167             throw new SecurityException(callerUid + " cannot kill pkg: " +
   5168                     pkg);
   5169         }
   5170     }
   5171 
   5172     public void closeSystemDialogs(String reason) {
   5173         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
   5174         if (reason != null) {
   5175             intent.putExtra("reason", reason);
   5176         }
   5177 
   5178         final int uid = Binder.getCallingUid();
   5179         final long origId = Binder.clearCallingIdentity();
   5180         synchronized (this) {
   5181             int i = mWatchers.beginBroadcast();
   5182             while (i > 0) {
   5183                 i--;
   5184                 IActivityWatcher w = mWatchers.getBroadcastItem(i);
   5185                 if (w != null) {
   5186                     try {
   5187                         w.closingSystemDialogs(reason);
   5188                     } catch (RemoteException e) {
   5189                     }
   5190                 }
   5191             }
   5192             mWatchers.finishBroadcast();
   5193 
   5194             mWindowManager.closeSystemDialogs(reason);
   5195 
   5196             for (i=mHistory.size()-1; i>=0; i--) {
   5197                 HistoryRecord r = (HistoryRecord)mHistory.get(i);
   5198                 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
   5199                     finishActivityLocked(r, i,
   5200                             Activity.RESULT_CANCELED, null, "close-sys");
   5201                 }
   5202             }
   5203 
   5204             broadcastIntentLocked(null, null, intent, null,
   5205                     null, 0, null, null, null, false, false, -1, uid);
   5206         }
   5207         Binder.restoreCallingIdentity(origId);
   5208     }
   5209 
   5210     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
   5211             throws RemoteException {
   5212         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
   5213         for (int i=pids.length-1; i>=0; i--) {
   5214             infos[i] = new Debug.MemoryInfo();
   5215             Debug.getMemoryInfo(pids[i], infos[i]);
   5216         }
   5217         return infos;
   5218     }
   5219 
   5220     public void killApplicationProcess(String processName, int uid) {
   5221         if (processName == null) {
   5222             return;
   5223         }
   5224 
   5225         int callerUid = Binder.getCallingUid();
   5226         // Only the system server can kill an application
   5227         if (callerUid == Process.SYSTEM_UID) {
   5228             synchronized (this) {
   5229                 ProcessRecord app = getProcessRecordLocked(processName, uid);
   5230                 if (app != null) {
   5231                     try {
   5232                         app.thread.scheduleSuicide();
   5233                     } catch (RemoteException e) {
   5234                         // If the other end already died, then our work here is done.
   5235                     }
   5236                 } else {
   5237                     Slog.w(TAG, "Process/uid not found attempting kill of "
   5238                             + processName + " / " + uid);
   5239                 }
   5240             }
   5241         } else {
   5242             throw new SecurityException(callerUid + " cannot kill app process: " +
   5243                     processName);
   5244         }
   5245     }
   5246 
   5247     private void forceStopPackageLocked(final String packageName, int uid) {
   5248         forceStopPackageLocked(packageName, uid, false, false, true);
   5249         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
   5250                 Uri.fromParts("package", packageName, null));
   5251         intent.putExtra(Intent.EXTRA_UID, uid);
   5252         broadcastIntentLocked(null, null, intent,
   5253                 null, null, 0, null, null, null,
   5254                 false, false, MY_PID, Process.SYSTEM_UID);
   5255     }
   5256 
   5257     private final boolean killPackageProcessesLocked(String packageName, int uid,
   5258             int minOomAdj, boolean callerWillRestart, boolean doit) {
   5259         ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   5260 
   5261         // Remove all processes this package may have touched: all with the
   5262         // same UID (except for the system or root user), and all whose name
   5263         // matches the package name.
   5264         final String procNamePrefix = packageName + ":";
   5265         for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   5266             final int NA = apps.size();
   5267             for (int ia=0; ia<NA; ia++) {
   5268                 ProcessRecord app = apps.valueAt(ia);
   5269                 if (app.removed) {
   5270                     if (doit) {
   5271                         procs.add(app);
   5272                     }
   5273                 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
   5274                         || app.processName.equals(packageName)
   5275                         || app.processName.startsWith(procNamePrefix)) {
   5276                     if (app.setAdj >= minOomAdj) {
   5277                         if (!doit) {
   5278                             return true;
   5279                         }
   5280                         app.removed = true;
   5281                         procs.add(app);
   5282                     }
   5283                 }
   5284             }
   5285         }
   5286 
   5287         int N = procs.size();
   5288         for (int i=0; i<N; i++) {
   5289             removeProcessLocked(procs.get(i), callerWillRestart);
   5290         }
   5291         return N > 0;
   5292     }
   5293 
   5294     private final boolean forceStopPackageLocked(String name, int uid,
   5295             boolean callerWillRestart, boolean purgeCache, boolean doit) {
   5296         int i, N;
   5297 
   5298         if (uid < 0) {
   5299             try {
   5300                 uid = ActivityThread.getPackageManager().getPackageUid(name);
   5301             } catch (RemoteException e) {
   5302             }
   5303         }
   5304 
   5305         if (doit) {
   5306             Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
   5307 
   5308             Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
   5309             while (badApps.hasNext()) {
   5310                 SparseArray<Long> ba = badApps.next();
   5311                 if (ba.get(uid) != null) {
   5312                     badApps.remove();
   5313                 }
   5314             }
   5315         }
   5316 
   5317         boolean didSomething = killPackageProcessesLocked(name, uid, -100,
   5318                 callerWillRestart, doit);
   5319 
   5320         for (i=mHistory.size()-1; i>=0; i--) {
   5321             HistoryRecord r = (HistoryRecord)mHistory.get(i);
   5322             if (r.packageName.equals(name)) {
   5323                 if (!doit) {
   5324                     return true;
   5325                 }
   5326                 didSomething = true;
   5327                 Slog.i(TAG, "  Force finishing activity " + r);
   5328                 if (r.app != null) {
   5329                     r.app.removed = true;
   5330                 }
   5331                 r.app = null;
   5332                 finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
   5333             }
   5334         }
   5335 
   5336         ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
   5337         for (ServiceRecord service : mServices.values()) {
   5338             if (service.packageName.equals(name)) {
   5339                 if (!doit) {
   5340                     return true;
   5341                 }
   5342                 didSomething = true;
   5343                 Slog.i(TAG, "  Force stopping service " + service);
   5344                 if (service.app != null) {
   5345                     service.app.removed = true;
   5346                 }
   5347                 service.app = null;
   5348                 services.add(service);
   5349             }
   5350         }
   5351 
   5352         N = services.size();
   5353         for (i=0; i<N; i++) {
   5354             bringDownServiceLocked(services.get(i), true);
   5355         }
   5356 
   5357         if (doit) {
   5358             if (purgeCache) {
   5359                 AttributeCache ac = AttributeCache.instance();
   5360                 if (ac != null) {
   5361                     ac.removePackage(name);
   5362                 }
   5363             }
   5364             resumeTopActivityLocked(null);
   5365         }
   5366 
   5367         return didSomething;
   5368     }
   5369 
   5370     private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
   5371         final String name = app.processName;
   5372         final int uid = app.info.uid;
   5373         if (DEBUG_PROCESSES) Slog.d(
   5374             TAG, "Force removing process " + app + " (" + name
   5375             + "/" + uid + ")");
   5376 
   5377         mProcessNames.remove(name, uid);
   5378         boolean needRestart = false;
   5379         if (app.pid > 0 && app.pid != MY_PID) {
   5380             int pid = app.pid;
   5381             synchronized (mPidsSelfLocked) {
   5382                 mPidsSelfLocked.remove(pid);
   5383                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   5384             }
   5385             handleAppDiedLocked(app, true);
   5386             mLruProcesses.remove(app);
   5387             Process.killProcess(pid);
   5388 
   5389             if (app.persistent) {
   5390                 if (!callerWillRestart) {
   5391                     addAppLocked(app.info);
   5392                 } else {
   5393                     needRestart = true;
   5394                 }
   5395             }
   5396         } else {
   5397             mRemovedProcesses.add(app);
   5398         }
   5399 
   5400         return needRestart;
   5401     }
   5402 
   5403     private final void processStartTimedOutLocked(ProcessRecord app) {
   5404         final int pid = app.pid;
   5405         boolean gone = false;
   5406         synchronized (mPidsSelfLocked) {
   5407             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
   5408             if (knownApp != null && knownApp.thread == null) {
   5409                 mPidsSelfLocked.remove(pid);
   5410                 gone = true;
   5411             }
   5412         }
   5413 
   5414         if (gone) {
   5415             Slog.w(TAG, "Process " + app + " failed to attach");
   5416             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
   5417                     app.processName);
   5418             mProcessNames.remove(app.processName, app.info.uid);
   5419             // Take care of any launching providers waiting for this process.
   5420             checkAppInLaunchingProvidersLocked(app, true);
   5421             // Take care of any services that are waiting for the process.
   5422             for (int i=0; i<mPendingServices.size(); i++) {
   5423                 ServiceRecord sr = mPendingServices.get(i);
   5424                 if (app.info.uid == sr.appInfo.uid
   5425                         && app.processName.equals(sr.processName)) {
   5426                     Slog.w(TAG, "Forcing bringing down service: " + sr);
   5427                     mPendingServices.remove(i);
   5428                     i--;
   5429                     bringDownServiceLocked(sr, true);
   5430                 }
   5431             }
   5432             Process.killProcess(pid);
   5433             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
   5434                 Slog.w(TAG, "Unattached app died before backup, skipping");
   5435                 try {
   5436                     IBackupManager bm = IBackupManager.Stub.asInterface(
   5437                             ServiceManager.getService(Context.BACKUP_SERVICE));
   5438                     bm.agentDisconnected(app.info.packageName);
   5439                 } catch (RemoteException e) {
   5440                     // Can't happen; the backup manager is local
   5441                 }
   5442             }
   5443             if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
   5444                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   5445                 mPendingBroadcast = null;
   5446                 scheduleBroadcastsLocked();
   5447             }
   5448         } else {
   5449             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
   5450         }
   5451     }
   5452 
   5453     private final boolean attachApplicationLocked(IApplicationThread thread,
   5454             int pid) {
   5455 
   5456         // Find the application record that is being attached...  either via
   5457         // the pid if we are running in multiple processes, or just pull the
   5458         // next app record if we are emulating process with anonymous threads.
   5459         ProcessRecord app;
   5460         if (pid != MY_PID && pid >= 0) {
   5461             synchronized (mPidsSelfLocked) {
   5462                 app = mPidsSelfLocked.get(pid);
   5463             }
   5464         } else if (mStartingProcesses.size() > 0) {
   5465             app = mStartingProcesses.remove(0);
   5466             app.setPid(pid);
   5467         } else {
   5468             app = null;
   5469         }
   5470 
   5471         if (app == null) {
   5472             Slog.w(TAG, "No pending application record for pid " + pid
   5473                     + " (IApplicationThread " + thread + "); dropping process");
   5474             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
   5475             if (pid > 0 && pid != MY_PID) {
   5476                 Process.killProcess(pid);
   5477             } else {
   5478                 try {
   5479                     thread.scheduleExit();
   5480                 } catch (Exception e) {
   5481                     // Ignore exceptions.
   5482                 }
   5483             }
   5484             return false;
   5485         }
   5486 
   5487         // If this application record is still attached to a previous
   5488         // process, clean it up now.
   5489         if (app.thread != null) {
   5490             handleAppDiedLocked(app, true);
   5491         }
   5492 
   5493         // Tell the process all about itself.
   5494 
   5495         if (localLOGV) Slog.v(
   5496                 TAG, "Binding process pid " + pid + " to record " + app);
   5497 
   5498         String processName = app.processName;
   5499         try {
   5500             thread.asBinder().linkToDeath(new AppDeathRecipient(
   5501                     app, pid, thread), 0);
   5502         } catch (RemoteException e) {
   5503             app.resetPackageList();
   5504             startProcessLocked(app, "link fail", processName);
   5505             return false;
   5506         }
   5507 
   5508         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
   5509 
   5510         app.thread = thread;
   5511         app.curAdj = app.setAdj = -100;
   5512         app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
   5513         app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   5514         app.forcingToForeground = null;
   5515         app.foregroundServices = false;
   5516         app.debugging = false;
   5517 
   5518         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   5519 
   5520         boolean normalMode = mSystemReady || isAllowedWhileBooting(app.info);
   5521         List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
   5522 
   5523         if (!normalMode) {
   5524             Slog.i(TAG, "Launching preboot mode app: " + app);
   5525         }
   5526 
   5527         if (localLOGV) Slog.v(
   5528             TAG, "New app record " + app
   5529             + " thread=" + thread.asBinder() + " pid=" + pid);
   5530         try {
   5531             int testMode = IApplicationThread.DEBUG_OFF;
   5532             if (mDebugApp != null && mDebugApp.equals(processName)) {
   5533                 testMode = mWaitForDebugger
   5534                     ? IApplicationThread.DEBUG_WAIT
   5535                     : IApplicationThread.DEBUG_ON;
   5536                 app.debugging = true;
   5537                 if (mDebugTransient) {
   5538                     mDebugApp = mOrigDebugApp;
   5539                     mWaitForDebugger = mOrigWaitForDebugger;
   5540                 }
   5541             }
   5542 
   5543             // If the app is being launched for restore or full backup, set it up specially
   5544             boolean isRestrictedBackupMode = false;
   5545             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
   5546                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
   5547                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
   5548             }
   5549 
   5550             ensurePackageDexOpt(app.instrumentationInfo != null
   5551                     ? app.instrumentationInfo.packageName
   5552                     : app.info.packageName);
   5553             if (app.instrumentationClass != null) {
   5554                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
   5555             }
   5556             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
   5557                     + processName + " with config " + mConfiguration);
   5558             thread.bindApplication(processName, app.instrumentationInfo != null
   5559                     ? app.instrumentationInfo : app.info, providers,
   5560                     app.instrumentationClass, app.instrumentationProfileFile,
   5561                     app.instrumentationArguments, app.instrumentationWatcher, testMode,
   5562                     isRestrictedBackupMode || !normalMode,
   5563                     mConfiguration, getCommonServicesLocked());
   5564             updateLruProcessLocked(app, false, true);
   5565             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
   5566         } catch (Exception e) {
   5567             // todo: Yikes!  What should we do?  For now we will try to
   5568             // start another process, but that could easily get us in
   5569             // an infinite loop of restarting processes...
   5570             Slog.w(TAG, "Exception thrown during bind!", e);
   5571 
   5572             app.resetPackageList();
   5573             startProcessLocked(app, "bind fail", processName);
   5574             return false;
   5575         }
   5576 
   5577         // Remove this record from the list of starting applications.
   5578         mPersistentStartingProcesses.remove(app);
   5579         mProcessesOnHold.remove(app);
   5580 
   5581         boolean badApp = false;
   5582         boolean didSomething = false;
   5583 
   5584         // See if the top visible activity is waiting to run in this process...
   5585         HistoryRecord hr = topRunningActivityLocked(null);
   5586         if (hr != null && normalMode) {
   5587             if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
   5588                     && processName.equals(hr.processName)) {
   5589                 try {
   5590                     if (realStartActivityLocked(hr, app, true, true)) {
   5591                         didSomething = true;
   5592                     }
   5593                 } catch (Exception e) {
   5594                     Slog.w(TAG, "Exception in new application when starting activity "
   5595                           + hr.intent.getComponent().flattenToShortString(), e);
   5596                     badApp = true;
   5597                 }
   5598             } else {
   5599                 ensureActivitiesVisibleLocked(hr, null, processName, 0);
   5600             }
   5601         }
   5602 
   5603         // Find any services that should be running in this process...
   5604         if (!badApp && mPendingServices.size() > 0) {
   5605             ServiceRecord sr = null;
   5606             try {
   5607                 for (int i=0; i<mPendingServices.size(); i++) {
   5608                     sr = mPendingServices.get(i);
   5609                     if (app.info.uid != sr.appInfo.uid
   5610                             || !processName.equals(sr.processName)) {
   5611                         continue;
   5612                     }
   5613 
   5614                     mPendingServices.remove(i);
   5615                     i--;
   5616                     realStartServiceLocked(sr, app);
   5617                     didSomething = true;
   5618                 }
   5619             } catch (Exception e) {
   5620                 Slog.w(TAG, "Exception in new application when starting service "
   5621                       + sr.shortName, e);
   5622                 badApp = true;
   5623             }
   5624         }
   5625 
   5626         // Check if the next broadcast receiver is in this process...
   5627         BroadcastRecord br = mPendingBroadcast;
   5628         if (!badApp && br != null && br.curApp == app) {
   5629             try {
   5630                 mPendingBroadcast = null;
   5631                 processCurBroadcastLocked(br, app);
   5632                 didSomething = true;
   5633             } catch (Exception e) {
   5634                 Slog.w(TAG, "Exception in new application when starting receiver "
   5635                       + br.curComponent.flattenToShortString(), e);
   5636                 badApp = true;
   5637                 logBroadcastReceiverDiscard(br);
   5638                 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
   5639                         br.resultExtras, br.resultAbort, true);
   5640                 scheduleBroadcastsLocked();
   5641                 // We need to reset the state if we fails to start the receiver.
   5642                 br.state = BroadcastRecord.IDLE;
   5643             }
   5644         }
   5645 
   5646         // Check whether the next backup agent is in this process...
   5647         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
   5648             if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
   5649             ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
   5650             try {
   5651                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, mBackupTarget.backupMode);
   5652             } catch (Exception e) {
   5653                 Slog.w(TAG, "Exception scheduling backup agent creation: ");
   5654                 e.printStackTrace();
   5655             }
   5656         }
   5657 
   5658         if (badApp) {
   5659             // todo: Also need to kill application to deal with all
   5660             // kinds of exceptions.
   5661             handleAppDiedLocked(app, false);
   5662             return false;
   5663         }
   5664 
   5665         if (!didSomething) {
   5666             updateOomAdjLocked();
   5667         }
   5668 
   5669         return true;
   5670     }
   5671 
   5672     public final void attachApplication(IApplicationThread thread) {
   5673         synchronized (this) {
   5674             int callingPid = Binder.getCallingPid();
   5675             final long origId = Binder.clearCallingIdentity();
   5676             attachApplicationLocked(thread, callingPid);
   5677             Binder.restoreCallingIdentity(origId);
   5678         }
   5679     }
   5680 
   5681     public final void activityIdle(IBinder token, Configuration config) {
   5682         final long origId = Binder.clearCallingIdentity();
   5683         activityIdleInternal(token, false, config);
   5684         Binder.restoreCallingIdentity(origId);
   5685     }
   5686 
   5687     final ArrayList<HistoryRecord> processStoppingActivitiesLocked(
   5688             boolean remove) {
   5689         int N = mStoppingActivities.size();
   5690         if (N <= 0) return null;
   5691 
   5692         ArrayList<HistoryRecord> stops = null;
   5693 
   5694         final boolean nowVisible = mResumedActivity != null
   5695                 && mResumedActivity.nowVisible
   5696                 && !mResumedActivity.waitingVisible;
   5697         for (int i=0; i<N; i++) {
   5698             HistoryRecord s = mStoppingActivities.get(i);
   5699             if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
   5700                     + nowVisible + " waitingVisible=" + s.waitingVisible
   5701                     + " finishing=" + s.finishing);
   5702             if (s.waitingVisible && nowVisible) {
   5703                 mWaitingVisibleActivities.remove(s);
   5704                 s.waitingVisible = false;
   5705                 if (s.finishing) {
   5706                     // If this activity is finishing, it is sitting on top of
   5707                     // everyone else but we now know it is no longer needed...
   5708                     // so get rid of it.  Otherwise, we need to go through the
   5709                     // normal flow and hide it once we determine that it is
   5710                     // hidden by the activities in front of it.
   5711                     if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
   5712                     mWindowManager.setAppVisibility(s, false);
   5713                 }
   5714             }
   5715             if (!s.waitingVisible && remove) {
   5716                 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
   5717                 if (stops == null) {
   5718                     stops = new ArrayList<HistoryRecord>();
   5719                 }
   5720                 stops.add(s);
   5721                 mStoppingActivities.remove(i);
   5722                 N--;
   5723                 i--;
   5724             }
   5725         }
   5726 
   5727         return stops;
   5728     }
   5729 
   5730     void enableScreenAfterBoot() {
   5731         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
   5732                 SystemClock.uptimeMillis());
   5733         mWindowManager.enableScreenAfterBoot();
   5734     }
   5735 
   5736     final void activityIdleInternal(IBinder token, boolean fromTimeout,
   5737             Configuration config) {
   5738         if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
   5739 
   5740         ArrayList<HistoryRecord> stops = null;
   5741         ArrayList<HistoryRecord> finishes = null;
   5742         ArrayList<HistoryRecord> thumbnails = null;
   5743         int NS = 0;
   5744         int NF = 0;
   5745         int NT = 0;
   5746         IApplicationThread sendThumbnail = null;
   5747         boolean booting = false;
   5748         boolean enableScreen = false;
   5749 
   5750         synchronized (this) {
   5751             if (token != null) {
   5752                 mHandler.removeMessages(IDLE_TIMEOUT_MSG, token);
   5753             }
   5754 
   5755             // Get the activity record.
   5756             int index = indexOfTokenLocked(token);
   5757             if (index >= 0) {
   5758                 HistoryRecord r = (HistoryRecord)mHistory.get(index);
   5759 
   5760                 if (fromTimeout) {
   5761                     reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
   5762                 }
   5763 
   5764                 // This is a hack to semi-deal with a race condition
   5765                 // in the client where it can be constructed with a
   5766                 // newer configuration from when we asked it to launch.
   5767                 // We'll update with whatever configuration it now says
   5768                 // it used to launch.
   5769                 if (config != null) {
   5770                     r.configuration = config;
   5771                 }
   5772 
   5773                 // No longer need to keep the device awake.
   5774                 if (mResumedActivity == r && mLaunchingActivity.isHeld()) {
   5775                     mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
   5776                     mLaunchingActivity.release();
   5777                 }
   5778 
   5779                 // We are now idle.  If someone is waiting for a thumbnail from
   5780                 // us, we can now deliver.
   5781                 r.idle = true;
   5782                 scheduleAppGcsLocked();
   5783                 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
   5784                     sendThumbnail = r.app.thread;
   5785                     r.thumbnailNeeded = false;
   5786                 }
   5787 
   5788                 // If this activity is fullscreen, set up to hide those under it.
   5789 
   5790                 if (DEBUG_VISBILITY) Slog.v(TAG, "Idle activity for " + r);
   5791                 ensureActivitiesVisibleLocked(null, 0);
   5792 
   5793                 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
   5794                 if (!mBooted && !fromTimeout) {
   5795                     mBooted = true;
   5796                     enableScreen = true;
   5797                 }
   5798 
   5799             } else if (fromTimeout) {
   5800                 reportActivityLaunchedLocked(fromTimeout, null, -1, -1);
   5801             }
   5802 
   5803             // Atomically retrieve all of the other things to do.
   5804             stops = processStoppingActivitiesLocked(true);
   5805             NS = stops != null ? stops.size() : 0;
   5806             if ((NF=mFinishingActivities.size()) > 0) {
   5807                 finishes = new ArrayList<HistoryRecord>(mFinishingActivities);
   5808                 mFinishingActivities.clear();
   5809             }
   5810             if ((NT=mCancelledThumbnails.size()) > 0) {
   5811                 thumbnails = new ArrayList<HistoryRecord>(mCancelledThumbnails);
   5812                 mCancelledThumbnails.clear();
   5813             }
   5814 
   5815             booting = mBooting;
   5816             mBooting = false;
   5817         }
   5818 
   5819         int i;
   5820 
   5821         // Send thumbnail if requested.
   5822         if (sendThumbnail != null) {
   5823             try {
   5824                 sendThumbnail.requestThumbnail(token);
   5825             } catch (Exception e) {
   5826                 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
   5827                 sendPendingThumbnail(null, token, null, null, true);
   5828             }
   5829         }
   5830 
   5831         // Stop any activities that are scheduled to do so but have been
   5832         // waiting for the next one to start.
   5833         for (i=0; i<NS; i++) {
   5834             HistoryRecord r = (HistoryRecord)stops.get(i);
   5835             synchronized (this) {
   5836                 if (r.finishing) {
   5837                     finishCurrentActivityLocked(r, FINISH_IMMEDIATELY);
   5838                 } else {
   5839                     stopActivityLocked(r);
   5840                 }
   5841             }
   5842         }
   5843 
   5844         // Finish any activities that are scheduled to do so but have been
   5845         // waiting for the next one to start.
   5846         for (i=0; i<NF; i++) {
   5847             HistoryRecord r = (HistoryRecord)finishes.get(i);
   5848             synchronized (this) {
   5849                 destroyActivityLocked(r, true);
   5850             }
   5851         }
   5852 
   5853         // Report back to any thumbnail receivers.
   5854         for (i=0; i<NT; i++) {
   5855             HistoryRecord r = (HistoryRecord)thumbnails.get(i);
   5856             sendPendingThumbnail(r, null, null, null, true);
   5857         }
   5858 
   5859         if (booting) {
   5860             finishBooting();
   5861         }
   5862 
   5863         trimApplications();
   5864         //dump();
   5865         //mWindowManager.dump();
   5866 
   5867         if (enableScreen) {
   5868             enableScreenAfterBoot();
   5869         }
   5870     }
   5871 
   5872     final void finishBooting() {
   5873         IntentFilter pkgFilter = new IntentFilter();
   5874         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
   5875         pkgFilter.addDataScheme("package");
   5876         mContext.registerReceiver(new BroadcastReceiver() {
   5877             @Override
   5878             public void onReceive(Context context, Intent intent) {
   5879                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
   5880                 if (pkgs != null) {
   5881                     for (String pkg : pkgs) {
   5882                         if (forceStopPackageLocked(pkg, -1, false, false, false)) {
   5883                             setResultCode(Activity.RESULT_OK);
   5884                             return;
   5885                         }
   5886                     }
   5887                 }
   5888             }
   5889         }, pkgFilter);
   5890 
   5891         synchronized (this) {
   5892             // Ensure that any processes we had put on hold are now started
   5893             // up.
   5894             final int NP = mProcessesOnHold.size();
   5895             if (NP > 0) {
   5896                 ArrayList<ProcessRecord> procs =
   5897                     new ArrayList<ProcessRecord>(mProcessesOnHold);
   5898                 for (int ip=0; ip<NP; ip++) {
   5899                     this.startProcessLocked(procs.get(ip), "on-hold", null);
   5900                 }
   5901             }
   5902 
   5903             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   5904                 // Tell anyone interested that we are done booting!
   5905                 broadcastIntentLocked(null, null,
   5906                         new Intent(Intent.ACTION_BOOT_COMPLETED, null),
   5907                         null, null, 0, null, null,
   5908                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
   5909                         false, false, MY_PID, Process.SYSTEM_UID);
   5910             }
   5911         }
   5912     }
   5913 
   5914     final void ensureBootCompleted() {
   5915         boolean booting;
   5916         boolean enableScreen;
   5917         synchronized (this) {
   5918             booting = mBooting;
   5919             mBooting = false;
   5920             enableScreen = !mBooted;
   5921             mBooted = true;
   5922         }
   5923 
   5924         if (booting) {
   5925             finishBooting();
   5926         }
   5927 
   5928         if (enableScreen) {
   5929             enableScreenAfterBoot();
   5930         }
   5931     }
   5932 
   5933     public final void activityPaused(IBinder token, Bundle icicle) {
   5934         // Refuse possible leaked file descriptors
   5935         if (icicle != null && icicle.hasFileDescriptors()) {
   5936             throw new IllegalArgumentException("File descriptors passed in Bundle");
   5937         }
   5938 
   5939         final long origId = Binder.clearCallingIdentity();
   5940         activityPaused(token, icicle, false);
   5941         Binder.restoreCallingIdentity(origId);
   5942     }
   5943 
   5944     final void activityPaused(IBinder token, Bundle icicle, boolean timeout) {
   5945         if (DEBUG_PAUSE) Slog.v(
   5946             TAG, "Activity paused: token=" + token + ", icicle=" + icicle
   5947             + ", timeout=" + timeout);
   5948 
   5949         HistoryRecord r = null;
   5950 
   5951         synchronized (this) {
   5952             int index = indexOfTokenLocked(token);
   5953             if (index >= 0) {
   5954                 r = (HistoryRecord)mHistory.get(index);
   5955                 if (!timeout) {
   5956                     r.icicle = icicle;
   5957                     r.haveState = true;
   5958                 }
   5959                 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
   5960                 if (mPausingActivity == r) {
   5961                     r.state = ActivityState.PAUSED;
   5962                     completePauseLocked();
   5963                 } else {
   5964                 	EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
   5965                 	        System.identityHashCode(r), r.shortComponentName,
   5966                 			mPausingActivity != null
   5967                 			    ? mPausingActivity.shortComponentName : "(none)");
   5968                 }
   5969             }
   5970         }
   5971     }
   5972 
   5973     public final void activityStopped(IBinder token, Bitmap thumbnail,
   5974             CharSequence description) {
   5975         if (localLOGV) Slog.v(
   5976             TAG, "Activity stopped: token=" + token);
   5977 
   5978         HistoryRecord r = null;
   5979 
   5980         final long origId = Binder.clearCallingIdentity();
   5981 
   5982         synchronized (this) {
   5983             int index = indexOfTokenLocked(token);
   5984             if (index >= 0) {
   5985                 r = (HistoryRecord)mHistory.get(index);
   5986                 r.thumbnail = thumbnail;
   5987                 r.description = description;
   5988                 r.stopped = true;
   5989                 r.state = ActivityState.STOPPED;
   5990                 if (!r.finishing) {
   5991                     if (r.configDestroy) {
   5992                         destroyActivityLocked(r, true);
   5993                         resumeTopActivityLocked(null);
   5994                     }
   5995                 }
   5996             }
   5997         }
   5998 
   5999         if (r != null) {
   6000             sendPendingThumbnail(r, null, null, null, false);
   6001         }
   6002 
   6003         trimApplications();
   6004 
   6005         Binder.restoreCallingIdentity(origId);
   6006     }
   6007 
   6008     public final void activityDestroyed(IBinder token) {
   6009         if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
   6010         synchronized (this) {
   6011             mHandler.removeMessages(DESTROY_TIMEOUT_MSG, token);
   6012 
   6013             int index = indexOfTokenLocked(token);
   6014             if (index >= 0) {
   6015                 HistoryRecord r = (HistoryRecord)mHistory.get(index);
   6016                 if (r.state == ActivityState.DESTROYING) {
   6017                     final long origId = Binder.clearCallingIdentity();
   6018                     removeActivityFromHistoryLocked(r);
   6019                     Binder.restoreCallingIdentity(origId);
   6020                 }
   6021             }
   6022         }
   6023     }
   6024 
   6025     public String getCallingPackage(IBinder token) {
   6026         synchronized (this) {
   6027             HistoryRecord r = getCallingRecordLocked(token);
   6028             return r != null && r.app != null ? r.info.packageName : null;
   6029         }
   6030     }
   6031 
   6032     public ComponentName getCallingActivity(IBinder token) {
   6033         synchronized (this) {
   6034             HistoryRecord r = getCallingRecordLocked(token);
   6035             return r != null ? r.intent.getComponent() : null;
   6036         }
   6037     }
   6038 
   6039     private HistoryRecord getCallingRecordLocked(IBinder token) {
   6040         int index = indexOfTokenLocked(token);
   6041         if (index >= 0) {
   6042             HistoryRecord r = (HistoryRecord)mHistory.get(index);
   6043             if (r != null) {
   6044                 return r.resultTo;
   6045             }
   6046         }
   6047         return null;
   6048     }
   6049 
   6050     public ComponentName getActivityClassForToken(IBinder token) {
   6051         synchronized(this) {
   6052             int index = indexOfTokenLocked(token);
   6053             if (index >= 0) {
   6054                 HistoryRecord r = (HistoryRecord)mHistory.get(index);
   6055                 return r.intent.getComponent();
   6056             }
   6057             return null;
   6058         }
   6059     }
   6060 
   6061     public String getPackageForToken(IBinder token) {
   6062         synchronized(this) {
   6063             int index = indexOfTokenLocked(token);
   6064             if (index >= 0) {
   6065                 HistoryRecord r = (HistoryRecord)mHistory.get(index);
   6066                 return r.packageName;
   6067             }
   6068             return null;
   6069         }
   6070     }
   6071 
   6072     public IIntentSender getIntentSender(int type,
   6073             String packageName, IBinder token, String resultWho,
   6074             int requestCode, Intent intent, String resolvedType, int flags) {
   6075         // Refuse possible leaked file descriptors
   6076         if (intent != null && intent.hasFileDescriptors() == true) {
   6077             throw new IllegalArgumentException("File descriptors passed in Intent");
   6078         }
   6079 
   6080         if (type == INTENT_SENDER_BROADCAST) {
   6081             if ((intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   6082                 throw new IllegalArgumentException(
   6083                         "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   6084             }
   6085         }
   6086 
   6087         synchronized(this) {
   6088             int callingUid = Binder.getCallingUid();
   6089             try {
   6090                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
   6091                         Process.supportsProcesses()) {
   6092                     int uid = ActivityThread.getPackageManager()
   6093                             .getPackageUid(packageName);
   6094                     if (uid != Binder.getCallingUid()) {
   6095                         String msg = "Permission Denial: getIntentSender() from pid="
   6096                             + Binder.getCallingPid()
   6097                             + ", uid=" + Binder.getCallingUid()
   6098                             + ", (need uid=" + uid + ")"
   6099                             + " is not allowed to send as package " + packageName;
   6100                         Slog.w(TAG, msg);
   6101                         throw new SecurityException(msg);
   6102                     }
   6103                 }
   6104             } catch (RemoteException e) {
   6105                 throw new SecurityException(e);
   6106             }
   6107             HistoryRecord activity = null;
   6108             if (type == INTENT_SENDER_ACTIVITY_RESULT) {
   6109                 int index = indexOfTokenLocked(token);
   6110                 if (index < 0) {
   6111                     return null;
   6112                 }
   6113                 activity = (HistoryRecord)mHistory.get(index);
   6114                 if (activity.finishing) {
   6115                     return null;
   6116                 }
   6117             }
   6118 
   6119             final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
   6120             final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
   6121             final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
   6122             flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
   6123                     |PendingIntent.FLAG_UPDATE_CURRENT);
   6124 
   6125             PendingIntentRecord.Key key = new PendingIntentRecord.Key(
   6126                     type, packageName, activity, resultWho,
   6127                     requestCode, intent, resolvedType, flags);
   6128             WeakReference<PendingIntentRecord> ref;
   6129             ref = mIntentSenderRecords.get(key);
   6130             PendingIntentRecord rec = ref != null ? ref.get() : null;
   6131             if (rec != null) {
   6132                 if (!cancelCurrent) {
   6133                     if (updateCurrent) {
   6134                         rec.key.requestIntent.replaceExtras(intent);
   6135                     }
   6136                     return rec;
   6137                 }
   6138                 rec.canceled = true;
   6139                 mIntentSenderRecords.remove(key);
   6140             }
   6141             if (noCreate) {
   6142                 return rec;
   6143             }
   6144             rec = new PendingIntentRecord(this, key, callingUid);
   6145             mIntentSenderRecords.put(key, rec.ref);
   6146             if (type == INTENT_SENDER_ACTIVITY_RESULT) {
   6147                 if (activity.pendingResults == null) {
   6148                     activity.pendingResults
   6149                             = new HashSet<WeakReference<PendingIntentRecord>>();
   6150                 }
   6151                 activity.pendingResults.add(rec.ref);
   6152             }
   6153             return rec;
   6154         }
   6155     }
   6156 
   6157     public void cancelIntentSender(IIntentSender sender) {
   6158         if (!(sender instanceof PendingIntentRecord)) {
   6159             return;
   6160         }
   6161         synchronized(this) {
   6162             PendingIntentRecord rec = (PendingIntentRecord)sender;
   6163             try {
   6164                 int uid = ActivityThread.getPackageManager()
   6165                         .getPackageUid(rec.key.packageName);
   6166                 if (uid != Binder.getCallingUid()) {
   6167                     String msg = "Permission Denial: cancelIntentSender() from pid="
   6168                         + Binder.getCallingPid()
   6169                         + ", uid=" + Binder.getCallingUid()
   6170                         + " is not allowed to cancel packges "
   6171                         + rec.key.packageName;
   6172                     Slog.w(TAG, msg);
   6173                     throw new SecurityException(msg);
   6174                 }
   6175             } catch (RemoteException e) {
   6176                 throw new SecurityException(e);
   6177             }
   6178             cancelIntentSenderLocked(rec, true);
   6179         }
   6180     }
   6181 
   6182     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
   6183         rec.canceled = true;
   6184         mIntentSenderRecords.remove(rec.key);
   6185         if (cleanActivity && rec.key.activity != null) {
   6186             rec.key.activity.pendingResults.remove(rec.ref);
   6187         }
   6188     }
   6189 
   6190     public String getPackageForIntentSender(IIntentSender pendingResult) {
   6191         if (!(pendingResult instanceof PendingIntentRecord)) {
   6192             return null;
   6193         }
   6194         try {
   6195             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   6196             return res.key.packageName;
   6197         } catch (ClassCastException e) {
   6198         }
   6199         return null;
   6200     }
   6201 
   6202     public void setProcessLimit(int max) {
   6203         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   6204                 "setProcessLimit()");
   6205         mProcessLimit = max;
   6206     }
   6207 
   6208     public int getProcessLimit() {
   6209         return mProcessLimit;
   6210     }
   6211 
   6212     void foregroundTokenDied(ForegroundToken token) {
   6213         synchronized (ActivityManagerService.this) {
   6214             synchronized (mPidsSelfLocked) {
   6215                 ForegroundToken cur
   6216                     = mForegroundProcesses.get(token.pid);
   6217                 if (cur != token) {
   6218                     return;
   6219                 }
   6220                 mForegroundProcesses.remove(token.pid);
   6221                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
   6222                 if (pr == null) {
   6223                     return;
   6224                 }
   6225                 pr.forcingToForeground = null;
   6226                 pr.foregroundServices = false;
   6227             }
   6228             updateOomAdjLocked();
   6229         }
   6230     }
   6231 
   6232     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
   6233         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   6234                 "setProcessForeground()");
   6235         synchronized(this) {
   6236             boolean changed = false;
   6237 
   6238             synchronized (mPidsSelfLocked) {
   6239                 ProcessRecord pr = mPidsSelfLocked.get(pid);
   6240                 if (pr == null) {
   6241                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
   6242                     return;
   6243                 }
   6244                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
   6245                 if (oldToken != null) {
   6246                     oldToken.token.unlinkToDeath(oldToken, 0);
   6247                     mForegroundProcesses.remove(pid);
   6248                     pr.forcingToForeground = null;
   6249                     changed = true;
   6250                 }
   6251                 if (isForeground && token != null) {
   6252                     ForegroundToken newToken = new ForegroundToken() {
   6253                         public void binderDied() {
   6254                             foregroundTokenDied(this);
   6255                         }
   6256                     };
   6257                     newToken.pid = pid;
   6258                     newToken.token = token;
   6259                     try {
   6260                         token.linkToDeath(newToken, 0);
   6261                         mForegroundProcesses.put(pid, newToken);
   6262                         pr.forcingToForeground = token;
   6263                         changed = true;
   6264                     } catch (RemoteException e) {
   6265                         // If the process died while doing this, we will later
   6266                         // do the cleanup with the process death link.
   6267                     }
   6268                 }
   6269             }
   6270 
   6271             if (changed) {
   6272                 updateOomAdjLocked();
   6273             }
   6274         }
   6275     }
   6276 
   6277     // =========================================================
   6278     // PERMISSIONS
   6279     // =========================================================
   6280 
   6281     static class PermissionController extends IPermissionController.Stub {
   6282         ActivityManagerService mActivityManagerService;
   6283         PermissionController(ActivityManagerService activityManagerService) {
   6284             mActivityManagerService = activityManagerService;
   6285         }
   6286 
   6287         public boolean checkPermission(String permission, int pid, int uid) {
   6288             return mActivityManagerService.checkPermission(permission, pid,
   6289                     uid) == PackageManager.PERMISSION_GRANTED;
   6290         }
   6291     }
   6292 
   6293     /**
   6294      * This can be called with or without the global lock held.
   6295      */
   6296     int checkComponentPermission(String permission, int pid, int uid,
   6297             int reqUid) {
   6298         // We might be performing an operation on behalf of an indirect binder
   6299         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
   6300         // client identity accordingly before proceeding.
   6301         Identity tlsIdentity = sCallerIdentity.get();
   6302         if (tlsIdentity != null) {
   6303             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
   6304                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
   6305             uid = tlsIdentity.uid;
   6306             pid = tlsIdentity.pid;
   6307         }
   6308 
   6309         // Root, system server and our own process get to do everything.
   6310         if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
   6311             !Process.supportsProcesses()) {
   6312             return PackageManager.PERMISSION_GRANTED;
   6313         }
   6314         // If the target requires a specific UID, always fail for others.
   6315         if (reqUid >= 0 && uid != reqUid) {
   6316             Slog.w(TAG, "Permission denied: checkComponentPermission() reqUid=" + reqUid);
   6317             return PackageManager.PERMISSION_DENIED;
   6318         }
   6319         if (permission == null) {
   6320             return PackageManager.PERMISSION_GRANTED;
   6321         }
   6322         try {
   6323             return ActivityThread.getPackageManager()
   6324                     .checkUidPermission(permission, uid);
   6325         } catch (RemoteException e) {
   6326             // Should never happen, but if it does... deny!
   6327             Slog.e(TAG, "PackageManager is dead?!?", e);
   6328         }
   6329         return PackageManager.PERMISSION_DENIED;
   6330     }
   6331 
   6332     /**
   6333      * As the only public entry point for permissions checking, this method
   6334      * can enforce the semantic that requesting a check on a null global
   6335      * permission is automatically denied.  (Internally a null permission
   6336      * string is used when calling {@link #checkComponentPermission} in cases
   6337      * when only uid-based security is needed.)
   6338      *
   6339      * This can be called with or without the global lock held.
   6340      */
   6341     public int checkPermission(String permission, int pid, int uid) {
   6342         if (permission == null) {
   6343             return PackageManager.PERMISSION_DENIED;
   6344         }
   6345         return checkComponentPermission(permission, pid, uid, -1);
   6346     }
   6347 
   6348     /**
   6349      * Binder IPC calls go through the public entry point.
   6350      * This can be called with or without the global lock held.
   6351      */
   6352     int checkCallingPermission(String permission) {
   6353         return checkPermission(permission,
   6354                 Binder.getCallingPid(),
   6355                 Binder.getCallingUid());
   6356     }
   6357 
   6358     /**
   6359      * This can be called with or without the global lock held.
   6360      */
   6361     void enforceCallingPermission(String permission, String func) {
   6362         if (checkCallingPermission(permission)
   6363                 == PackageManager.PERMISSION_GRANTED) {
   6364             return;
   6365         }
   6366 
   6367         String msg = "Permission Denial: " + func + " from pid="
   6368                 + Binder.getCallingPid()
   6369                 + ", uid=" + Binder.getCallingUid()
   6370                 + " requires " + permission;
   6371         Slog.w(TAG, msg);
   6372         throw new SecurityException(msg);
   6373     }
   6374 
   6375     private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
   6376             ProviderInfo pi, int uid, int modeFlags) {
   6377         try {
   6378             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   6379                 if ((pi.readPermission != null) &&
   6380                         (pm.checkUidPermission(pi.readPermission, uid)
   6381                                 != PackageManager.PERMISSION_GRANTED)) {
   6382                     return false;
   6383                 }
   6384             }
   6385             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   6386                 if ((pi.writePermission != null) &&
   6387                         (pm.checkUidPermission(pi.writePermission, uid)
   6388                                 != PackageManager.PERMISSION_GRANTED)) {
   6389                     return false;
   6390                 }
   6391             }
   6392             return true;
   6393         } catch (RemoteException e) {
   6394             return false;
   6395         }
   6396     }
   6397 
   6398     private final boolean checkUriPermissionLocked(Uri uri, int uid,
   6399             int modeFlags) {
   6400         // Root gets to do everything.
   6401         if (uid == 0 || !Process.supportsProcesses()) {
   6402             return true;
   6403         }
   6404         HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   6405         if (perms == null) return false;
   6406         UriPermission perm = perms.get(uri);
   6407         if (perm == null) return false;
   6408         return (modeFlags&perm.modeFlags) == modeFlags;
   6409     }
   6410 
   6411     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
   6412         // Another redirected-binder-call permissions check as in
   6413         // {@link checkComponentPermission}.
   6414         Identity tlsIdentity = sCallerIdentity.get();
   6415         if (tlsIdentity != null) {
   6416             uid = tlsIdentity.uid;
   6417             pid = tlsIdentity.pid;
   6418         }
   6419 
   6420         // Our own process gets to do everything.
   6421         if (pid == MY_PID) {
   6422             return PackageManager.PERMISSION_GRANTED;
   6423         }
   6424         synchronized(this) {
   6425             return checkUriPermissionLocked(uri, uid, modeFlags)
   6426                     ? PackageManager.PERMISSION_GRANTED
   6427                     : PackageManager.PERMISSION_DENIED;
   6428         }
   6429     }
   6430 
   6431     private void grantUriPermissionLocked(int callingUid,
   6432             String targetPkg, Uri uri, int modeFlags, HistoryRecord activity) {
   6433         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   6434                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   6435         if (modeFlags == 0) {
   6436             return;
   6437         }
   6438 
   6439         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   6440                 "Requested grant " + targetPkg + " permission to " + uri);
   6441 
   6442         final IPackageManager pm = ActivityThread.getPackageManager();
   6443 
   6444         // If this is not a content: uri, we can't do anything with it.
   6445         if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
   6446             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   6447                     "Can't grant URI permission for non-content URI: " + uri);
   6448             return;
   6449         }
   6450 
   6451         String name = uri.getAuthority();
   6452         ProviderInfo pi = null;
   6453         ContentProviderRecord cpr
   6454                 = (ContentProviderRecord)mProvidersByName.get(name);
   6455         if (cpr != null) {
   6456             pi = cpr.info;
   6457         } else {
   6458             try {
   6459                 pi = pm.resolveContentProvider(name,
   6460                         PackageManager.GET_URI_PERMISSION_PATTERNS);
   6461             } catch (RemoteException ex) {
   6462             }
   6463         }
   6464         if (pi == null) {
   6465             Slog.w(TAG, "No content provider found for: " + name);
   6466             return;
   6467         }
   6468 
   6469         int targetUid;
   6470         try {
   6471             targetUid = pm.getPackageUid(targetPkg);
   6472             if (targetUid < 0) {
   6473                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   6474                         "Can't grant URI permission no uid for: " + targetPkg);
   6475                 return;
   6476             }
   6477         } catch (RemoteException ex) {
   6478             return;
   6479         }
   6480 
   6481         // First...  does the target actually need this permission?
   6482         if (checkHoldingPermissionsLocked(pm, pi, targetUid, modeFlags)) {
   6483             // No need to grant the target this permission.
   6484             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   6485                     "Target " + targetPkg + " already has full permission to " + uri);
   6486             return;
   6487         }
   6488 
   6489         // Second...  is the provider allowing granting of URI permissions?
   6490         if (!pi.grantUriPermissions) {
   6491             throw new SecurityException("Provider " + pi.packageName
   6492                     + "/" + pi.name
   6493                     + " does not allow granting of Uri permissions (uri "
   6494                     + uri + ")");
   6495         }
   6496         if (pi.uriPermissionPatterns != null) {
   6497             final int N = pi.uriPermissionPatterns.length;
   6498             boolean allowed = false;
   6499             for (int i=0; i<N; i++) {
   6500                 if (pi.uriPermissionPatterns[i] != null
   6501                         && pi.uriPermissionPatterns[i].match(uri.getPath())) {
   6502                     allowed = true;
   6503                     break;
   6504                 }
   6505             }
   6506             if (!allowed) {
   6507                 throw new SecurityException("Provider " + pi.packageName
   6508                         + "/" + pi.name
   6509                         + " does not allow granting of permission to path of Uri "
   6510                         + uri);
   6511             }
   6512         }
   6513 
   6514         // Third...  does the caller itself have permission to access
   6515         // this uri?
   6516         if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) {
   6517             if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
   6518                 throw new SecurityException("Uid " + callingUid
   6519                         + " does not have permission to uri " + uri);
   6520             }
   6521         }
   6522 
   6523         // Okay!  So here we are: the caller has the assumed permission
   6524         // to the uri, and the target doesn't.  Let's now give this to
   6525         // the target.
   6526 
   6527         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   6528                 "Granting " + targetPkg + " permission to " + uri);
   6529 
   6530         HashMap<Uri, UriPermission> targetUris
   6531                 = mGrantedUriPermissions.get(targetUid);
   6532         if (targetUris == null) {
   6533             targetUris = new HashMap<Uri, UriPermission>();
   6534             mGrantedUriPermissions.put(targetUid, targetUris);
   6535         }
   6536 
   6537         UriPermission perm = targetUris.get(uri);
   6538         if (perm == null) {
   6539             perm = new UriPermission(targetUid, uri);
   6540             targetUris.put(uri, perm);
   6541 
   6542         }
   6543         perm.modeFlags |= modeFlags;
   6544         if (activity == null) {
   6545             perm.globalModeFlags |= modeFlags;
   6546         } else if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   6547             perm.readActivities.add(activity);
   6548             if (activity.readUriPermissions == null) {
   6549                 activity.readUriPermissions = new HashSet<UriPermission>();
   6550             }
   6551             activity.readUriPermissions.add(perm);
   6552         } else if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   6553             perm.writeActivities.add(activity);
   6554             if (activity.writeUriPermissions == null) {
   6555                 activity.writeUriPermissions = new HashSet<UriPermission>();
   6556             }
   6557             activity.writeUriPermissions.add(perm);
   6558         }
   6559     }
   6560 
   6561     private void grantUriPermissionFromIntentLocked(int callingUid,
   6562             String targetPkg, Intent intent, HistoryRecord activity) {
   6563         if (intent == null) {
   6564             return;
   6565         }
   6566         Uri data = intent.getData();
   6567         if (data == null) {
   6568             return;
   6569         }
   6570         grantUriPermissionLocked(callingUid, targetPkg, data,
   6571                 intent.getFlags(), activity);
   6572     }
   6573 
   6574     public void grantUriPermission(IApplicationThread caller, String targetPkg,
   6575             Uri uri, int modeFlags) {
   6576         synchronized(this) {
   6577             final ProcessRecord r = getRecordForAppLocked(caller);
   6578             if (r == null) {
   6579                 throw new SecurityException("Unable to find app for caller "
   6580                         + caller
   6581                         + " when granting permission to uri " + uri);
   6582             }
   6583             if (targetPkg == null) {
   6584                 Slog.w(TAG, "grantUriPermission: null target");
   6585                 return;
   6586             }
   6587             if (uri == null) {
   6588                 Slog.w(TAG, "grantUriPermission: null uri");
   6589                 return;
   6590             }
   6591 
   6592             grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
   6593                     null);
   6594         }
   6595     }
   6596 
   6597     private void removeUriPermissionIfNeededLocked(UriPermission perm) {
   6598         if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
   6599                 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
   6600             HashMap<Uri, UriPermission> perms
   6601                     = mGrantedUriPermissions.get(perm.uid);
   6602             if (perms != null) {
   6603                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   6604                         "Removing " + perm.uid + " permission to " + perm.uri);
   6605                 perms.remove(perm.uri);
   6606                 if (perms.size() == 0) {
   6607                     mGrantedUriPermissions.remove(perm.uid);
   6608                 }
   6609             }
   6610         }
   6611     }
   6612 
   6613     private void removeActivityUriPermissionsLocked(HistoryRecord activity) {
   6614         if (activity.readUriPermissions != null) {
   6615             for (UriPermission perm : activity.readUriPermissions) {
   6616                 perm.readActivities.remove(activity);
   6617                 if (perm.readActivities.size() == 0 && (perm.globalModeFlags
   6618                         &Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0) {
   6619                     perm.modeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
   6620                     removeUriPermissionIfNeededLocked(perm);
   6621                 }
   6622             }
   6623         }
   6624         if (activity.writeUriPermissions != null) {
   6625             for (UriPermission perm : activity.writeUriPermissions) {
   6626                 perm.writeActivities.remove(activity);
   6627                 if (perm.writeActivities.size() == 0 && (perm.globalModeFlags
   6628                         &Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0) {
   6629                     perm.modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
   6630                     removeUriPermissionIfNeededLocked(perm);
   6631                 }
   6632             }
   6633         }
   6634     }
   6635 
   6636     private void revokeUriPermissionLocked(int callingUid, Uri uri,
   6637             int modeFlags) {
   6638         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   6639                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   6640         if (modeFlags == 0) {
   6641             return;
   6642         }
   6643 
   6644         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   6645                 "Revoking all granted permissions to " + uri);
   6646 
   6647         final IPackageManager pm = ActivityThread.getPackageManager();
   6648 
   6649         final String authority = uri.getAuthority();
   6650         ProviderInfo pi = null;
   6651         ContentProviderRecord cpr
   6652                 = (ContentProviderRecord)mProvidersByName.get(authority);
   6653         if (cpr != null) {
   6654             pi = cpr.info;
   6655         } else {
   6656             try {
   6657                 pi = pm.resolveContentProvider(authority,
   6658                         PackageManager.GET_URI_PERMISSION_PATTERNS);
   6659             } catch (RemoteException ex) {
   6660             }
   6661         }
   6662         if (pi == null) {
   6663             Slog.w(TAG, "No content provider found for: " + authority);
   6664             return;
   6665         }
   6666 
   6667         // Does the caller have this permission on the URI?
   6668         if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) {
   6669             // Right now, if you are not the original owner of the permission,
   6670             // you are not allowed to revoke it.
   6671             //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
   6672                 throw new SecurityException("Uid " + callingUid
   6673                         + " does not have permission to uri " + uri);
   6674             //}
   6675         }
   6676 
   6677         // Go through all of the permissions and remove any that match.
   6678         final List<String> SEGMENTS = uri.getPathSegments();
   6679         if (SEGMENTS != null) {
   6680             final int NS = SEGMENTS.size();
   6681             int N = mGrantedUriPermissions.size();
   6682             for (int i=0; i<N; i++) {
   6683                 HashMap<Uri, UriPermission> perms
   6684                         = mGrantedUriPermissions.valueAt(i);
   6685                 Iterator<UriPermission> it = perms.values().iterator();
   6686             toploop:
   6687                 while (it.hasNext()) {
   6688                     UriPermission perm = it.next();
   6689                     Uri targetUri = perm.uri;
   6690                     if (!authority.equals(targetUri.getAuthority())) {
   6691                         continue;
   6692                     }
   6693                     List<String> targetSegments = targetUri.getPathSegments();
   6694                     if (targetSegments == null) {
   6695                         continue;
   6696                     }
   6697                     if (targetSegments.size() < NS) {
   6698                         continue;
   6699                     }
   6700                     for (int j=0; j<NS; j++) {
   6701                         if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
   6702                             continue toploop;
   6703                         }
   6704                     }
   6705                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   6706                             "Revoking " + perm.uid + " permission to " + perm.uri);
   6707                     perm.clearModes(modeFlags);
   6708                     if (perm.modeFlags == 0) {
   6709                         it.remove();
   6710                     }
   6711                 }
   6712                 if (perms.size() == 0) {
   6713                     mGrantedUriPermissions.remove(
   6714                             mGrantedUriPermissions.keyAt(i));
   6715                     N--;
   6716                     i--;
   6717                 }
   6718             }
   6719         }
   6720     }
   6721 
   6722     public void revokeUriPermission(IApplicationThread caller, Uri uri,
   6723             int modeFlags) {
   6724         synchronized(this) {
   6725             final ProcessRecord r = getRecordForAppLocked(caller);
   6726             if (r == null) {
   6727                 throw new SecurityException("Unable to find app for caller "
   6728                         + caller
   6729                         + " when revoking permission to uri " + uri);
   6730             }
   6731             if (uri == null) {
   6732                 Slog.w(TAG, "revokeUriPermission: null uri");
   6733                 return;
   6734             }
   6735 
   6736             modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   6737                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   6738             if (modeFlags == 0) {
   6739                 return;
   6740             }
   6741 
   6742             final IPackageManager pm = ActivityThread.getPackageManager();
   6743 
   6744             final String authority = uri.getAuthority();
   6745             ProviderInfo pi = null;
   6746             ContentProviderRecord cpr
   6747                     = (ContentProviderRecord)mProvidersByName.get(authority);
   6748             if (cpr != null) {
   6749                 pi = cpr.info;
   6750             } else {
   6751                 try {
   6752                     pi = pm.resolveContentProvider(authority,
   6753                             PackageManager.GET_URI_PERMISSION_PATTERNS);
   6754                 } catch (RemoteException ex) {
   6755                 }
   6756             }
   6757             if (pi == null) {
   6758                 Slog.w(TAG, "No content provider found for: " + authority);
   6759                 return;
   6760             }
   6761 
   6762             revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
   6763         }
   6764     }
   6765 
   6766     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
   6767         synchronized (this) {
   6768             ProcessRecord app =
   6769                 who != null ? getRecordForAppLocked(who) : null;
   6770             if (app == null) return;
   6771 
   6772             Message msg = Message.obtain();
   6773             msg.what = WAIT_FOR_DEBUGGER_MSG;
   6774             msg.obj = app;
   6775             msg.arg1 = waiting ? 1 : 0;
   6776             mHandler.sendMessage(msg);
   6777         }
   6778     }
   6779 
   6780     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
   6781         outInfo.availMem = Process.getFreeMemory();
   6782         outInfo.threshold = HOME_APP_MEM;
   6783         outInfo.lowMemory = outInfo.availMem <
   6784                 (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
   6785     }
   6786 
   6787     // =========================================================
   6788     // TASK MANAGEMENT
   6789     // =========================================================
   6790 
   6791     public List getTasks(int maxNum, int flags,
   6792                          IThumbnailReceiver receiver) {
   6793         ArrayList list = new ArrayList();
   6794 
   6795         PendingThumbnailsRecord pending = null;
   6796         IApplicationThread topThumbnail = null;
   6797         HistoryRecord topRecord = null;
   6798 
   6799         synchronized(this) {
   6800             if (localLOGV) Slog.v(
   6801                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
   6802                 + ", receiver=" + receiver);
   6803 
   6804             if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
   6805                     != PackageManager.PERMISSION_GRANTED) {
   6806                 if (receiver != null) {
   6807                     // If the caller wants to wait for pending thumbnails,
   6808                     // it ain't gonna get them.
   6809                     try {
   6810                         receiver.finished();
   6811                     } catch (RemoteException ex) {
   6812                     }
   6813                 }
   6814                 String msg = "Permission Denial: getTasks() from pid="
   6815                         + Binder.getCallingPid()
   6816                         + ", uid=" + Binder.getCallingUid()
   6817                         + " requires " + android.Manifest.permission.GET_TASKS;
   6818                 Slog.w(TAG, msg);
   6819                 throw new SecurityException(msg);
   6820             }
   6821 
   6822             int pos = mHistory.size()-1;
   6823             HistoryRecord next =
   6824                 pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null;
   6825             HistoryRecord top = null;
   6826             CharSequence topDescription = null;
   6827             TaskRecord curTask = null;
   6828             int numActivities = 0;
   6829             int numRunning = 0;
   6830             while (pos >= 0 && maxNum > 0) {
   6831                 final HistoryRecord r = next;
   6832                 pos--;
   6833                 next = pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null;
   6834 
   6835                 // Initialize state for next task if needed.
   6836                 if (top == null ||
   6837                         (top.state == ActivityState.INITIALIZING
   6838                             && top.task == r.task)) {
   6839                     top = r;
   6840                     topDescription = r.description;
   6841                     curTask = r.task;
   6842                     numActivities = numRunning = 0;
   6843                 }
   6844 
   6845                 // Add 'r' into the current task.
   6846                 numActivities++;
   6847                 if (r.app != null && r.app.thread != null) {
   6848                     numRunning++;
   6849                 }
   6850                 if (topDescription == null) {
   6851                     topDescription = r.description;
   6852                 }
   6853 
   6854                 if (localLOGV) Slog.v(
   6855                     TAG, r.intent.getComponent().flattenToShortString()
   6856                     + ": task=" + r.task);
   6857 
   6858                 // If the next one is a different task, generate a new
   6859                 // TaskInfo entry for what we have.
   6860                 if (next == null || next.task != curTask) {
   6861                     ActivityManager.RunningTaskInfo ci
   6862                             = new ActivityManager.RunningTaskInfo();
   6863                     ci.id = curTask.taskId;
   6864                     ci.baseActivity = r.intent.getComponent();
   6865                     ci.topActivity = top.intent.getComponent();
   6866                     ci.thumbnail = top.thumbnail;
   6867                     ci.description = topDescription;
   6868                     ci.numActivities = numActivities;
   6869                     ci.numRunning = numRunning;
   6870                     //System.out.println(
   6871                     //    "#" + maxNum + ": " + " descr=" + ci.description);
   6872                     if (ci.thumbnail == null && receiver != null) {
   6873                         if (localLOGV) Slog.v(
   6874                             TAG, "State=" + top.state + "Idle=" + top.idle
   6875                             + " app=" + top.app
   6876                             + " thr=" + (top.app != null ? top.app.thread : null));
   6877                         if (top.state == ActivityState.RESUMED
   6878                                 || top.state == ActivityState.PAUSING) {
   6879                             if (top.idle && top.app != null
   6880                                 && top.app.thread != null) {
   6881                                 topRecord = top;
   6882                                 topThumbnail = top.app.thread;
   6883                             } else {
   6884                                 top.thumbnailNeeded = true;
   6885                             }
   6886                         }
   6887                         if (pending == null) {
   6888                             pending = new PendingThumbnailsRecord(receiver);
   6889                         }
   6890                         pending.pendingRecords.add(top);
   6891                     }
   6892                     list.add(ci);
   6893                     maxNum--;
   6894                     top = null;
   6895                 }
   6896             }
   6897 
   6898             if (pending != null) {
   6899                 mPendingThumbnails.add(pending);
   6900             }
   6901         }
   6902 
   6903         if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
   6904 
   6905         if (topThumbnail != null) {
   6906             if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
   6907             try {
   6908                 topThumbnail.requestThumbnail(topRecord);
   6909             } catch (Exception e) {
   6910                 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
   6911                 sendPendingThumbnail(null, topRecord, null, null, true);
   6912             }
   6913         }
   6914 
   6915         if (pending == null && receiver != null) {
   6916             // In this case all thumbnails were available and the client
   6917             // is being asked to be told when the remaining ones come in...
   6918             // which is unusually, since the top-most currently running
   6919             // activity should never have a canned thumbnail!  Oh well.
   6920             try {
   6921                 receiver.finished();
   6922             } catch (RemoteException ex) {
   6923             }
   6924         }
   6925 
   6926         return list;
   6927     }
   6928 
   6929     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
   6930             int flags) {
   6931         synchronized (this) {
   6932             enforceCallingPermission(android.Manifest.permission.GET_TASKS,
   6933                     "getRecentTasks()");
   6934 
   6935             IPackageManager pm = ActivityThread.getPackageManager();
   6936 
   6937             final int N = mRecentTasks.size();
   6938             ArrayList<ActivityManager.RecentTaskInfo> res
   6939                     = new ArrayList<ActivityManager.RecentTaskInfo>(
   6940                             maxNum < N ? maxNum : N);
   6941             for (int i=0; i<N && maxNum > 0; i++) {
   6942                 TaskRecord tr = mRecentTasks.get(i);
   6943                 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
   6944                         || (tr.intent == null)
   6945                         || ((tr.intent.getFlags()
   6946                                 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
   6947                     ActivityManager.RecentTaskInfo rti
   6948                             = new ActivityManager.RecentTaskInfo();
   6949                     rti.id = tr.numActivities > 0 ? tr.taskId : -1;
   6950                     rti.baseIntent = new Intent(
   6951                             tr.intent != null ? tr.intent : tr.affinityIntent);
   6952                     rti.origActivity = tr.origActivity;
   6953 
   6954                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
   6955                         // Check whether this activity is currently available.
   6956                         try {
   6957                             if (rti.origActivity != null) {
   6958                                 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
   6959                                     continue;
   6960                                 }
   6961                             } else if (rti.baseIntent != null) {
   6962                                 if (pm.queryIntentActivities(rti.baseIntent,
   6963                                         null, 0) == null) {
   6964                                     continue;
   6965                                 }
   6966                             }
   6967                         } catch (RemoteException e) {
   6968                             // Will never happen.
   6969                         }
   6970                     }
   6971 
   6972                     res.add(rti);
   6973                     maxNum--;
   6974                 }
   6975             }
   6976             return res;
   6977         }
   6978     }
   6979 
   6980     private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
   6981         int j;
   6982         TaskRecord startTask = ((HistoryRecord)mHistory.get(startIndex)).task;
   6983         TaskRecord jt = startTask;
   6984 
   6985         // First look backwards
   6986         for (j=startIndex-1; j>=0; j--) {
   6987             HistoryRecord r = (HistoryRecord)mHistory.get(j);
   6988             if (r.task != jt) {
   6989                 jt = r.task;
   6990                 if (affinity.equals(jt.affinity)) {
   6991                     return j;
   6992                 }
   6993             }
   6994         }
   6995 
   6996         // Now look forwards
   6997         final int N = mHistory.size();
   6998         jt = startTask;
   6999         for (j=startIndex+1; j<N; j++) {
   7000             HistoryRecord r = (HistoryRecord)mHistory.get(j);
   7001             if (r.task != jt) {
   7002                 if (affinity.equals(jt.affinity)) {
   7003                     return j;
   7004                 }
   7005                 jt = r.task;
   7006             }
   7007         }
   7008 
   7009         // Might it be at the top?
   7010         if (affinity.equals(((HistoryRecord)mHistory.get(N-1)).task.affinity)) {
   7011             return N-1;
   7012         }
   7013 
   7014         return -1;
   7015     }
   7016 
   7017     /**
   7018      * Perform a reset of the given task, if needed as part of launching it.
   7019      * Returns the new HistoryRecord at the top of the task.
   7020      */
   7021     private final HistoryRecord resetTaskIfNeededLocked(HistoryRecord taskTop,
   7022             HistoryRecord newActivity) {
   7023         boolean forceReset = (newActivity.info.flags
   7024                 &ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0;
   7025         if (taskTop.task.getInactiveDuration() > ACTIVITY_INACTIVE_RESET_TIME) {
   7026             if ((newActivity.info.flags
   7027                     &ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE) == 0) {
   7028                 forceReset = true;
   7029             }
   7030         }
   7031 
   7032         final TaskRecord task = taskTop.task;
   7033 
   7034         // We are going to move through the history list so that we can look
   7035         // at each activity 'target' with 'below' either the interesting
   7036         // activity immediately below it in the stack or null.
   7037         HistoryRecord target = null;
   7038         int targetI = 0;
   7039         int taskTopI = -1;
   7040         int replyChainEnd = -1;
   7041         int lastReparentPos = -1;
   7042         for (int i=mHistory.size()-1; i>=-1; i--) {
   7043             HistoryRecord below = i >= 0 ? (HistoryRecord)mHistory.get(i) : null;
   7044 
   7045             if (below != null && below.finishing) {
   7046                 continue;
   7047             }
   7048             if (target == null) {
   7049                 target = below;
   7050                 targetI = i;
   7051                 // If we were in the middle of a reply chain before this
   7052                 // task, it doesn't appear like the root of the chain wants
   7053                 // anything interesting, so drop it.
   7054                 replyChainEnd = -1;
   7055                 continue;
   7056             }
   7057 
   7058             final int flags = target.info.flags;
   7059 
   7060             final boolean finishOnTaskLaunch =
   7061                 (flags&ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0;
   7062             final boolean allowTaskReparenting =
   7063                 (flags&ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0;
   7064 
   7065             if (target.task == task) {
   7066                 // We are inside of the task being reset...  we'll either
   7067                 // finish this activity, push it out for another task,
   7068                 // or leave it as-is.  We only do this
   7069                 // for activities that are not the root of the task (since
   7070                 // if we finish the root, we may no longer have the task!).
   7071                 if (taskTopI < 0) {
   7072                     taskTopI = targetI;
   7073                 }
   7074                 if (below != null && below.task == task) {
   7075                     final boolean clearWhenTaskReset =
   7076                             (target.intent.getFlags()
   7077                                     &Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0;
   7078                     if (!finishOnTaskLaunch && !clearWhenTaskReset && target.resultTo != null) {
   7079                         // If this activity is sending a reply to a previous
   7080                         // activity, we can't do anything with it now until
   7081                         // we reach the start of the reply chain.
   7082                         // XXX note that we are assuming the result is always
   7083                         // to the previous activity, which is almost always
   7084                         // the case but we really shouldn't count on.
   7085                         if (replyChainEnd < 0) {
   7086                             replyChainEnd = targetI;
   7087                         }
   7088                     } else if (!finishOnTaskLaunch && !clearWhenTaskReset && allowTaskReparenting
   7089                             && target.taskAffinity != null
   7090                             && !target.taskAffinity.equals(task.affinity)) {
   7091                         // If this activity has an affinity for another
   7092                         // task, then we need to move it out of here.  We will
   7093                         // move it as far out of the way as possible, to the
   7094                         // bottom of the activity stack.  This also keeps it
   7095                         // correctly ordered with any activities we previously
   7096                         // moved.
   7097                         HistoryRecord p = (HistoryRecord)mHistory.get(0);
   7098                         if (target.taskAffinity != null
   7099                                 && target.taskAffinity.equals(p.task.affinity)) {
   7100                             // If the activity currently at the bottom has the
   7101                             // same task affinity as the one we are moving,
   7102                             // then merge it into the same task.
   7103                             target.task = p.task;
   7104                             if (DEBUG_TASKS) Slog.v(TAG, "Start pushing activity " + target
   7105                                     + " out to bottom task " + p.task);
   7106                         } else {
   7107                             mCurTask++;
   7108                             if (mCurTask <= 0) {
   7109                                 mCurTask = 1;
   7110                             }
   7111                             target.task = new TaskRecord(mCurTask, target.info, null,
   7112                                     (target.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
   7113                             target.task.affinityIntent = target.intent;
   7114                             if (DEBUG_TASKS) Slog.v(TAG, "Start pushing activity " + target
   7115                                     + " out to new task " + target.task);
   7116                         }
   7117                         mWindowManager.setAppGroupId(target, task.taskId);
   7118                         if (replyChainEnd < 0) {
   7119                             replyChainEnd = targetI;
   7120                         }
   7121                         int dstPos = 0;
   7122                         for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
   7123                             p = (HistoryRecord)mHistory.get(srcPos);
   7124                             if (p.finishing) {
   7125                                 continue;
   7126                             }
   7127                             if (DEBUG_TASKS) Slog.v(TAG, "Pushing next activity " + p
   7128                                     + " out to target's task " + target.task);
   7129                             task.numActivities--;
   7130                             p.task = target.task;
   7131                             target.task.numActivities++;
   7132                             mHistory.remove(srcPos);
   7133                             mHistory.add(dstPos, p);
   7134                             mWindowManager.moveAppToken(dstPos, p);
   7135                             mWindowManager.setAppGroupId(p, p.task.taskId);
   7136                             dstPos++;
   7137                             if (VALIDATE_TOKENS) {
   7138                                 mWindowManager.validateAppTokens(mHistory);
   7139                             }
   7140                             i++;
   7141                         }
   7142                         if (taskTop == p) {
   7143                             taskTop = below;
   7144                         }
   7145                         if (taskTopI == replyChainEnd) {
   7146                             taskTopI = -1;
   7147                         }
   7148                         replyChainEnd = -1;
   7149                         addRecentTaskLocked(target.task);
   7150                     } else if (forceReset || finishOnTaskLaunch
   7151                             || clearWhenTaskReset) {
   7152                         // If the activity should just be removed -- either
   7153                         // because it asks for it, or the task should be
   7154                         // cleared -- then finish it and anything that is
   7155                         // part of its reply chain.
   7156                         if (clearWhenTaskReset) {
   7157                             // In this case, we want to finish this activity
   7158                             // and everything above it, so be sneaky and pretend
   7159                             // like these are all in the reply chain.
   7160                             replyChainEnd = targetI+1;
   7161                             while (replyChainEnd < mHistory.size() &&
   7162                                     ((HistoryRecord)mHistory.get(
   7163                                                 replyChainEnd)).task == task) {
   7164                                 replyChainEnd++;
   7165                             }
   7166                             replyChainEnd--;
   7167                         } else if (replyChainEnd < 0) {
   7168                             replyChainEnd = targetI;
   7169                         }
   7170                         HistoryRecord p = null;
   7171                         for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
   7172                             p = (HistoryRecord)mHistory.get(srcPos);
   7173                             if (p.finishing) {
   7174                                 continue;
   7175                             }
   7176                             if (finishActivityLocked(p, srcPos,
   7177                                     Activity.RESULT_CANCELED, null, "reset")) {
   7178                                 replyChainEnd--;
   7179                                 srcPos--;
   7180                             }
   7181                         }
   7182                         if (taskTop == p) {
   7183                             taskTop = below;
   7184                         }
   7185                         if (taskTopI == replyChainEnd) {
   7186                             taskTopI = -1;
   7187                         }
   7188                         replyChainEnd = -1;
   7189                     } else {
   7190                         // If we were in the middle of a chain, well the
   7191                         // activity that started it all doesn't want anything
   7192                         // special, so leave it all as-is.
   7193                         replyChainEnd = -1;
   7194                     }
   7195                 } else {
   7196                     // Reached the bottom of the task -- any reply chain
   7197                     // should be left as-is.
   7198                     replyChainEnd = -1;
   7199                 }
   7200 
   7201             } else if (target.resultTo != null) {
   7202                 // If this activity is sending a reply to a previous
   7203                 // activity, we can't do anything with it now until
   7204                 // we reach the start of the reply chain.
   7205                 // XXX note that we are assuming the result is always
   7206                 // to the previous activity, which is almost always
   7207                 // the case but we really shouldn't count on.
   7208                 if (replyChainEnd < 0) {
   7209                     replyChainEnd = targetI;
   7210                 }
   7211 
   7212             } else if (taskTopI >= 0 && allowTaskReparenting
   7213                     && task.affinity != null
   7214                     && task.affinity.equals(target.taskAffinity)) {
   7215                 // We are inside of another task...  if this activity has
   7216                 // an affinity for our task, then either remove it if we are
   7217                 // clearing or move it over to our task.  Note that
   7218                 // we currently punt on the case where we are resetting a
   7219                 // task that is not at the top but who has activities above
   7220                 // with an affinity to it...  this is really not a normal
   7221                 // case, and we will need to later pull that task to the front
   7222                 // and usually at that point we will do the reset and pick
   7223                 // up those remaining activities.  (This only happens if
   7224                 // someone starts an activity in a new task from an activity
   7225                 // in a task that is not currently on top.)
   7226                 if (forceReset || finishOnTaskLaunch) {
   7227                     if (replyChainEnd < 0) {
   7228                         replyChainEnd = targetI;
   7229                     }
   7230                     HistoryRecord p = null;
   7231                     for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
   7232                         p = (HistoryRecord)mHistory.get(srcPos);
   7233                         if (p.finishing) {
   7234                             continue;
   7235                         }
   7236                         if (finishActivityLocked(p, srcPos,
   7237                                 Activity.RESULT_CANCELED, null, "reset")) {
   7238                             taskTopI--;
   7239                             lastReparentPos--;
   7240                             replyChainEnd--;
   7241                             srcPos--;
   7242                         }
   7243                     }
   7244                     replyChainEnd = -1;
   7245                 } else {
   7246                     if (replyChainEnd < 0) {
   7247                         replyChainEnd = targetI;
   7248                     }
   7249                     for (int srcPos=replyChainEnd; srcPos>=targetI; srcPos--) {
   7250                         HistoryRecord p = (HistoryRecord)mHistory.get(srcPos);
   7251                         if (p.finishing) {
   7252                             continue;
   7253                         }
   7254                         if (lastReparentPos < 0) {
   7255                             lastReparentPos = taskTopI;
   7256                             taskTop = p;
   7257                         } else {
   7258                             lastReparentPos--;
   7259                         }
   7260                         mHistory.remove(srcPos);
   7261                         p.task.numActivities--;
   7262                         p.task = task;
   7263                         mHistory.add(lastReparentPos, p);
   7264                         if (DEBUG_TASKS) Slog.v(TAG, "Pulling activity " + p
   7265                                 + " in to resetting task " + task);
   7266                         task.numActivities++;
   7267                         mWindowManager.moveAppToken(lastReparentPos, p);
   7268                         mWindowManager.setAppGroupId(p, p.task.taskId);
   7269                         if (VALIDATE_TOKENS) {
   7270                             mWindowManager.validateAppTokens(mHistory);
   7271                         }
   7272                     }
   7273                     replyChainEnd = -1;
   7274 
   7275                     // Now we've moved it in to place...  but what if this is
   7276                     // a singleTop activity and we have put it on top of another
   7277                     // instance of the same activity?  Then we drop the instance
   7278                     // below so it remains singleTop.
   7279                     if (target.info.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
   7280                         for (int j=lastReparentPos-1; j>=0; j--) {
   7281                             HistoryRecord p = (HistoryRecord)mHistory.get(j);
   7282                             if (p.finishing) {
   7283                                 continue;
   7284                             }
   7285                             if (p.intent.getComponent().equals(target.intent.getComponent())) {
   7286                                 if (finishActivityLocked(p, j,
   7287                                         Activity.RESULT_CANCELED, null, "replace")) {
   7288                                     taskTopI--;
   7289                                     lastReparentPos--;
   7290                                 }
   7291                             }
   7292                         }
   7293                     }
   7294                 }
   7295             }
   7296 
   7297             target = below;
   7298             targetI = i;
   7299         }
   7300 
   7301         return taskTop;
   7302     }
   7303 
   7304     /**
   7305      * TODO: Add mController hook
   7306      */
   7307     public void moveTaskToFront(int task) {
   7308         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   7309                 "moveTaskToFront()");
   7310 
   7311         synchronized(this) {
   7312             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   7313                     Binder.getCallingUid(), "Task to front")) {
   7314                 return;
   7315             }
   7316             final long origId = Binder.clearCallingIdentity();
   7317             try {
   7318                 int N = mRecentTasks.size();
   7319                 for (int i=0; i<N; i++) {
   7320                     TaskRecord tr = mRecentTasks.get(i);
   7321                     if (tr.taskId == task) {
   7322                         moveTaskToFrontLocked(tr, null);
   7323                         return;
   7324                     }
   7325                 }
   7326                 for (int i=mHistory.size()-1; i>=0; i--) {
   7327                     HistoryRecord hr = (HistoryRecord)mHistory.get(i);
   7328                     if (hr.task.taskId == task) {
   7329                         moveTaskToFrontLocked(hr.task, null);
   7330                         return;
   7331                     }
   7332                 }
   7333             } finally {
   7334                 Binder.restoreCallingIdentity(origId);
   7335             }
   7336         }
   7337     }
   7338 
   7339     private final void moveTaskToFrontLocked(TaskRecord tr, HistoryRecord reason) {
   7340         if (DEBUG_SWITCH) Slog.v(TAG, "moveTaskToFront: " + tr);
   7341 
   7342         final int task = tr.taskId;
   7343         int top = mHistory.size()-1;
   7344 
   7345         if (top < 0 || ((HistoryRecord)mHistory.get(top)).task.taskId == task) {
   7346             // nothing to do!
   7347             return;
   7348         }
   7349 
   7350         ArrayList moved = new ArrayList();
   7351 
   7352         // Applying the affinities may have removed entries from the history,
   7353         // so get the size again.
   7354         top = mHistory.size()-1;
   7355         int pos = top;
   7356 
   7357         // Shift all activities with this task up to the top
   7358         // of the stack, keeping them in the same internal order.
   7359         while (pos >= 0) {
   7360             HistoryRecord r = (HistoryRecord)mHistory.get(pos);
   7361             if (localLOGV) Slog.v(
   7362                 TAG, "At " + pos + " ckp " + r.task + ": " + r);
   7363             boolean first = true;
   7364             if (r.task.taskId == task) {
   7365                 if (localLOGV) Slog.v(TAG, "Removing and adding at " + top);
   7366                 mHistory.remove(pos);
   7367                 mHistory.add(top, r);
   7368                 moved.add(0, r);
   7369                 top--;
   7370                 if (first) {
   7371                     addRecentTaskLocked(r.task);
   7372                     first = false;
   7373                 }
   7374             }
   7375             pos--;
   7376         }
   7377 
   7378         if (DEBUG_TRANSITION) Slog.v(TAG,
   7379                 "Prepare to front transition: task=" + tr);
   7380         if (reason != null &&
   7381                 (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
   7382             mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
   7383             HistoryRecord r = topRunningActivityLocked(null);
   7384             if (r != null) {
   7385                 mNoAnimActivities.add(r);
   7386             }
   7387         } else {
   7388             mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT);
   7389         }
   7390 
   7391         mWindowManager.moveAppTokensToTop(moved);
   7392         if (VALIDATE_TOKENS) {
   7393             mWindowManager.validateAppTokens(mHistory);
   7394         }
   7395 
   7396         finishTaskMoveLocked(task);
   7397         EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, task);
   7398     }
   7399 
   7400     private final void finishTaskMoveLocked(int task) {
   7401         resumeTopActivityLocked(null);
   7402     }
   7403 
   7404     public void moveTaskToBack(int task) {
   7405         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   7406                 "moveTaskToBack()");
   7407 
   7408         synchronized(this) {
   7409             if (mResumedActivity != null && mResumedActivity.task.taskId == task) {
   7410                 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   7411                         Binder.getCallingUid(), "Task to back")) {
   7412                     return;
   7413                 }
   7414             }
   7415             final long origId = Binder.clearCallingIdentity();
   7416             moveTaskToBackLocked(task, null);
   7417             Binder.restoreCallingIdentity(origId);
   7418         }
   7419     }
   7420 
   7421     /**
   7422      * Moves an activity, and all of the other activities within the same task, to the bottom
   7423      * of the history stack.  The activity's order within the task is unchanged.
   7424      *
   7425      * @param token A reference to the activity we wish to move
   7426      * @param nonRoot If false then this only works if the activity is the root
   7427      *                of a task; if true it will work for any activity in a task.
   7428      * @return Returns true if the move completed, false if not.
   7429      */
   7430     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
   7431         synchronized(this) {
   7432             final long origId = Binder.clearCallingIdentity();
   7433             int taskId = getTaskForActivityLocked(token, !nonRoot);
   7434             if (taskId >= 0) {
   7435                 return moveTaskToBackLocked(taskId, null);
   7436             }
   7437             Binder.restoreCallingIdentity(origId);
   7438         }
   7439         return false;
   7440     }
   7441 
   7442     /**
   7443      * Worker method for rearranging history stack.  Implements the function of moving all
   7444      * activities for a specific task (gathering them if disjoint) into a single group at the
   7445      * bottom of the stack.
   7446      *
   7447      * If a watcher is installed, the action is preflighted and the watcher has an opportunity
   7448      * to premeptively cancel the move.
   7449      *
   7450      * @param task The taskId to collect and move to the bottom.
   7451      * @return Returns true if the move completed, false if not.
   7452      */
   7453     private final boolean moveTaskToBackLocked(int task, HistoryRecord reason) {
   7454         Slog.i(TAG, "moveTaskToBack: " + task);
   7455 
   7456         // If we have a watcher, preflight the move before committing to it.  First check
   7457         // for *other* available tasks, but if none are available, then try again allowing the
   7458         // current task to be selected.
   7459         if (mController != null) {
   7460             HistoryRecord next = topRunningActivityLocked(null, task);
   7461             if (next == null) {
   7462                 next = topRunningActivityLocked(null, 0);
   7463             }
   7464             if (next != null) {
   7465                 // ask watcher if this is allowed
   7466                 boolean moveOK = true;
   7467                 try {
   7468                     moveOK = mController.activityResuming(next.packageName);
   7469                 } catch (RemoteException e) {
   7470                     mController = null;
   7471                 }
   7472                 if (!moveOK) {
   7473                     return false;
   7474                 }
   7475             }
   7476         }
   7477 
   7478         ArrayList moved = new ArrayList();
   7479 
   7480         if (DEBUG_TRANSITION) Slog.v(TAG,
   7481                 "Prepare to back transition: task=" + task);
   7482 
   7483         final int N = mHistory.size();
   7484         int bottom = 0;
   7485         int pos = 0;
   7486 
   7487         // Shift all activities with this task down to the bottom
   7488         // of the stack, keeping them in the same internal order.
   7489         while (pos < N) {
   7490             HistoryRecord r = (HistoryRecord)mHistory.get(pos);
   7491             if (localLOGV) Slog.v(
   7492                 TAG, "At " + pos + " ckp " + r.task + ": " + r);
   7493             if (r.task.taskId == task) {
   7494                 if (localLOGV) Slog.v(TAG, "Removing and adding at " + (N-1));
   7495                 mHistory.remove(pos);
   7496                 mHistory.add(bottom, r);
   7497                 moved.add(r);
   7498                 bottom++;
   7499             }
   7500             pos++;
   7501         }
   7502 
   7503         if (reason != null &&
   7504                 (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
   7505             mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
   7506             HistoryRecord r = topRunningActivityLocked(null);
   7507             if (r != null) {
   7508                 mNoAnimActivities.add(r);
   7509             }
   7510         } else {
   7511             mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_BACK);
   7512         }
   7513         mWindowManager.moveAppTokensToBottom(moved);
   7514         if (VALIDATE_TOKENS) {
   7515             mWindowManager.validateAppTokens(mHistory);
   7516         }
   7517 
   7518         finishTaskMoveLocked(task);
   7519         return true;
   7520     }
   7521 
   7522     public void moveTaskBackwards(int task) {
   7523         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   7524                 "moveTaskBackwards()");
   7525 
   7526         synchronized(this) {
   7527             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   7528                     Binder.getCallingUid(), "Task backwards")) {
   7529                 return;
   7530             }
   7531             final long origId = Binder.clearCallingIdentity();
   7532             moveTaskBackwardsLocked(task);
   7533             Binder.restoreCallingIdentity(origId);
   7534         }
   7535     }
   7536 
   7537     private final void moveTaskBackwardsLocked(int task) {
   7538         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
   7539     }
   7540 
   7541     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
   7542         synchronized(this) {
   7543             return getTaskForActivityLocked(token, onlyRoot);
   7544         }
   7545     }
   7546 
   7547     int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
   7548         final int N = mHistory.size();
   7549         TaskRecord lastTask = null;
   7550         for (int i=0; i<N; i++) {
   7551             HistoryRecord r = (HistoryRecord)mHistory.get(i);
   7552             if (r == token) {
   7553                 if (!onlyRoot || lastTask != r.task) {
   7554                     return r.task.taskId;
   7555                 }
   7556                 return -1;
   7557             }
   7558             lastTask = r.task;
   7559         }
   7560 
   7561         return -1;
   7562     }
   7563 
   7564     /**
   7565      * Returns the top activity in any existing task matching the given
   7566      * Intent.  Returns null if no such task is found.
   7567      */
   7568     private HistoryRecord findTaskLocked(Intent intent, ActivityInfo info) {
   7569         ComponentName cls = intent.getComponent();
   7570         if (info.targetActivity != null) {
   7571             cls = new ComponentName(info.packageName, info.targetActivity);
   7572         }
   7573 
   7574         TaskRecord cp = null;
   7575 
   7576         final int N = mHistory.size();
   7577         for (int i=(N-1); i>=0; i--) {
   7578             HistoryRecord r = (HistoryRecord)mHistory.get(i);
   7579             if (!r.finishing && r.task != cp
   7580                     && r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
   7581                 cp = r.task;
   7582                 //Slog.i(TAG, "Comparing existing cls=" + r.task.intent.getComponent().flattenToShortString()
   7583                 //        + "/aff=" + r.task.affinity + " to new cls="
   7584                 //        + intent.getComponent().flattenToShortString() + "/aff=" + taskAffinity);
   7585                 if (r.task.affinity != null) {
   7586                     if (r.task.affinity.equals(info.taskAffinity)) {
   7587                         //Slog.i(TAG, "Found matching affinity!");
   7588                         return r;
   7589                     }
   7590                 } else if (r.task.intent != null
   7591                         && r.task.intent.getComponent().equals(cls)) {
   7592                     //Slog.i(TAG, "Found matching class!");
   7593                     //dump();
   7594                     //Slog.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
   7595                     return r;
   7596                 } else if (r.task.affinityIntent != null
   7597                         && r.task.affinityIntent.getComponent().equals(cls)) {
   7598                     //Slog.i(TAG, "Found matching class!");
   7599                     //dump();
   7600                     //Slog.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
   7601                     return r;
   7602                 }
   7603             }
   7604         }
   7605 
   7606         return null;
   7607     }
   7608 
   7609     /**
   7610      * Returns the first activity (starting from the top of the stack) that
   7611      * is the same as the given activity.  Returns null if no such activity
   7612      * is found.
   7613      */
   7614     private HistoryRecord findActivityLocked(Intent intent, ActivityInfo info) {
   7615         ComponentName cls = intent.getComponent();
   7616         if (info.targetActivity != null) {
   7617             cls = new ComponentName(info.packageName, info.targetActivity);
   7618         }
   7619 
   7620         final int N = mHistory.size();
   7621         for (int i=(N-1); i>=0; i--) {
   7622             HistoryRecord r = (HistoryRecord)mHistory.get(i);
   7623             if (!r.finishing) {
   7624                 if (r.intent.getComponent().equals(cls)) {
   7625                     //Slog.i(TAG, "Found matching class!");
   7626                     //dump();
   7627                     //Slog.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
   7628                     return r;
   7629                 }
   7630             }
   7631         }
   7632 
   7633         return null;
   7634     }
   7635 
   7636     public void finishOtherInstances(IBinder token, ComponentName className) {
   7637         synchronized(this) {
   7638             final long origId = Binder.clearCallingIdentity();
   7639 
   7640             int N = mHistory.size();
   7641             TaskRecord lastTask = null;
   7642             for (int i=0; i<N; i++) {
   7643                 HistoryRecord r = (HistoryRecord)mHistory.get(i);
   7644                 if (r.realActivity.equals(className)
   7645                         && r != token && lastTask != r.task) {
   7646                     if (finishActivityLocked(r, i, Activity.RESULT_CANCELED,
   7647                             null, "others")) {
   7648                         i--;
   7649                         N--;
   7650                     }
   7651                 }
   7652                 lastTask = r.task;
   7653             }
   7654 
   7655             Binder.restoreCallingIdentity(origId);
   7656         }
   7657     }
   7658 
   7659     // =========================================================
   7660     // THUMBNAILS
   7661     // =========================================================
   7662 
   7663     public void reportThumbnail(IBinder token,
   7664             Bitmap thumbnail, CharSequence description) {
   7665         //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
   7666         final long origId = Binder.clearCallingIdentity();
   7667         sendPendingThumbnail(null, token, thumbnail, description, true);
   7668         Binder.restoreCallingIdentity(origId);
   7669     }
   7670 
   7671     final void sendPendingThumbnail(HistoryRecord r, IBinder token,
   7672             Bitmap thumbnail, CharSequence description, boolean always) {
   7673         TaskRecord task = null;
   7674         ArrayList receivers = null;
   7675 
   7676         //System.out.println("Send pending thumbnail: " + r);
   7677 
   7678         synchronized(this) {
   7679             if (r == null) {
   7680                 int index = indexOfTokenLocked(token);
   7681                 if (index < 0) {
   7682                     return;
   7683                 }
   7684                 r = (HistoryRecord)mHistory.get(index);
   7685             }
   7686             if (thumbnail == null) {
   7687                 thumbnail = r.thumbnail;
   7688                 description = r.description;
   7689             }
   7690             if (thumbnail == null && !always) {
   7691                 // If there is no thumbnail, and this entry is not actually
   7692                 // going away, then abort for now and pick up the next
   7693                 // thumbnail we get.
   7694                 return;
   7695             }
   7696             task = r.task;
   7697 
   7698             int N = mPendingThumbnails.size();
   7699             int i=0;
   7700             while (i<N) {
   7701                 PendingThumbnailsRecord pr =
   7702                     (PendingThumbnailsRecord)mPendingThumbnails.get(i);
   7703                 //System.out.println("Looking in " + pr.pendingRecords);
   7704                 if (pr.pendingRecords.remove(r)) {
   7705                     if (receivers == null) {
   7706                         receivers = new ArrayList();
   7707                     }
   7708                     receivers.add(pr);
   7709                     if (pr.pendingRecords.size() == 0) {
   7710                         pr.finished = true;
   7711                         mPendingThumbnails.remove(i);
   7712                         N--;
   7713                         continue;
   7714                     }
   7715                 }
   7716                 i++;
   7717             }
   7718         }
   7719 
   7720         if (receivers != null) {
   7721             final int N = receivers.size();
   7722             for (int i=0; i<N; i++) {
   7723                 try {
   7724                     PendingThumbnailsRecord pr =
   7725                         (PendingThumbnailsRecord)receivers.get(i);
   7726                     pr.receiver.newThumbnail(
   7727                         task != null ? task.taskId : -1, thumbnail, description);
   7728                     if (pr.finished) {
   7729                         pr.receiver.finished();
   7730                     }
   7731                 } catch (Exception e) {
   7732                     Slog.w(TAG, "Exception thrown when sending thumbnail", e);
   7733                 }
   7734             }
   7735         }
   7736     }
   7737 
   7738     // =========================================================
   7739     // CONTENT PROVIDERS
   7740     // =========================================================
   7741 
   7742     private final List generateApplicationProvidersLocked(ProcessRecord app) {
   7743         List providers = null;
   7744         try {
   7745             providers = ActivityThread.getPackageManager().
   7746                 queryContentProviders(app.processName, app.info.uid,
   7747                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
   7748         } catch (RemoteException ex) {
   7749         }
   7750         if (providers != null) {
   7751             final int N = providers.size();
   7752             for (int i=0; i<N; i++) {
   7753                 ProviderInfo cpi =
   7754                     (ProviderInfo)providers.get(i);
   7755                 ContentProviderRecord cpr =
   7756                     (ContentProviderRecord)mProvidersByClass.get(cpi.name);
   7757                 if (cpr == null) {
   7758                     cpr = new ContentProviderRecord(cpi, app.info);
   7759                     mProvidersByClass.put(cpi.name, cpr);
   7760                 }
   7761                 app.pubProviders.put(cpi.name, cpr);
   7762                 app.addPackage(cpi.applicationInfo.packageName);
   7763                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
   7764             }
   7765         }
   7766         return providers;
   7767     }
   7768 
   7769     private final String checkContentProviderPermissionLocked(
   7770             ProviderInfo cpi, ProcessRecord r, int mode) {
   7771         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
   7772         final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
   7773         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
   7774                 cpi.exported ? -1 : cpi.applicationInfo.uid)
   7775                 == PackageManager.PERMISSION_GRANTED
   7776                 && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) {
   7777             return null;
   7778         }
   7779         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
   7780                 cpi.exported ? -1 : cpi.applicationInfo.uid)
   7781                 == PackageManager.PERMISSION_GRANTED) {
   7782             return null;
   7783         }
   7784 
   7785         PathPermission[] pps = cpi.pathPermissions;
   7786         if (pps != null) {
   7787             int i = pps.length;
   7788             while (i > 0) {
   7789                 i--;
   7790                 PathPermission pp = pps[i];
   7791                 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
   7792                         cpi.exported ? -1 : cpi.applicationInfo.uid)
   7793                         == PackageManager.PERMISSION_GRANTED
   7794                         && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) {
   7795                     return null;
   7796                 }
   7797                 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
   7798                         cpi.exported ? -1 : cpi.applicationInfo.uid)
   7799                         == PackageManager.PERMISSION_GRANTED) {
   7800                     return null;
   7801                 }
   7802             }
   7803         }
   7804 
   7805         String msg = "Permission Denial: opening provider " + cpi.name
   7806                 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   7807                 + ", uid=" + callingUid + ") requires "
   7808                 + cpi.readPermission + " or " + cpi.writePermission;
   7809         Slog.w(TAG, msg);
   7810         return msg;
   7811     }
   7812 
   7813     private final ContentProviderHolder getContentProviderImpl(
   7814         IApplicationThread caller, String name) {
   7815         ContentProviderRecord cpr;
   7816         ProviderInfo cpi = null;
   7817 
   7818         synchronized(this) {
   7819             ProcessRecord r = null;
   7820             if (caller != null) {
   7821                 r = getRecordForAppLocked(caller);
   7822                 if (r == null) {
   7823                     throw new SecurityException(
   7824                             "Unable to find app for caller " + caller
   7825                           + " (pid=" + Binder.getCallingPid()
   7826                           + ") when getting content provider " + name);
   7827                 }
   7828             }
   7829 
   7830             // First check if this content provider has been published...
   7831             cpr = (ContentProviderRecord)mProvidersByName.get(name);
   7832             if (cpr != null) {
   7833                 cpi = cpr.info;
   7834                 if (checkContentProviderPermissionLocked(cpi, r, -1) != null) {
   7835                     return new ContentProviderHolder(cpi,
   7836                             cpi.readPermission != null
   7837                                     ? cpi.readPermission : cpi.writePermission);
   7838                 }
   7839 
   7840                 if (r != null && cpr.canRunHere(r)) {
   7841                     // This provider has been published or is in the process
   7842                     // of being published...  but it is also allowed to run
   7843                     // in the caller's process, so don't make a connection
   7844                     // and just let the caller instantiate its own instance.
   7845                     if (cpr.provider != null) {
   7846                         // don't give caller the provider object, it needs
   7847                         // to make its own.
   7848                         cpr = new ContentProviderRecord(cpr);
   7849                     }
   7850                     return cpr;
   7851                 }
   7852 
   7853                 final long origId = Binder.clearCallingIdentity();
   7854 
   7855                 // In this case the provider instance already exists, so we can
   7856                 // return it right away.
   7857                 if (r != null) {
   7858                     if (DEBUG_PROVIDER) Slog.v(TAG,
   7859                             "Adding provider requested by "
   7860                             + r.processName + " from process "
   7861                             + cpr.info.processName);
   7862                     Integer cnt = r.conProviders.get(cpr);
   7863                     if (cnt == null) {
   7864                         r.conProviders.put(cpr, new Integer(1));
   7865                     } else {
   7866                         r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
   7867                     }
   7868                     cpr.clients.add(r);
   7869                     if (cpr.app != null && r.setAdj >= VISIBLE_APP_ADJ) {
   7870                         // If this is a visible app accessing the provider,
   7871                         // make sure to count it as being accessed and thus
   7872                         // back up on the LRU list.  This is good because
   7873                         // content providers are often expensive to start.
   7874                         updateLruProcessLocked(cpr.app, false, true);
   7875                     }
   7876                 } else {
   7877                     cpr.externals++;
   7878                 }
   7879 
   7880                 if (cpr.app != null) {
   7881                     updateOomAdjLocked(cpr.app);
   7882                 }
   7883 
   7884                 Binder.restoreCallingIdentity(origId);
   7885 
   7886             } else {
   7887                 try {
   7888                     cpi = ActivityThread.getPackageManager().
   7889                         resolveContentProvider(name,
   7890                                 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
   7891                 } catch (RemoteException ex) {
   7892                 }
   7893                 if (cpi == null) {
   7894                     return null;
   7895                 }
   7896 
   7897                 if (checkContentProviderPermissionLocked(cpi, r, -1) != null) {
   7898                     return new ContentProviderHolder(cpi,
   7899                             cpi.readPermission != null
   7900                                     ? cpi.readPermission : cpi.writePermission);
   7901                 }
   7902 
   7903                 if (!mSystemReady && !mDidUpdate && !mWaitingUpdate
   7904                         && !cpi.processName.equals("system")) {
   7905                     // If this content provider does not run in the system
   7906                     // process, and the system is not yet ready to run other
   7907                     // processes, then fail fast instead of hanging.
   7908                     throw new IllegalArgumentException(
   7909                             "Attempt to launch content provider before system ready");
   7910                 }
   7911 
   7912                 cpr = (ContentProviderRecord)mProvidersByClass.get(cpi.name);
   7913                 final boolean firstClass = cpr == null;
   7914                 if (firstClass) {
   7915                     try {
   7916                         ApplicationInfo ai =
   7917                             ActivityThread.getPackageManager().
   7918                                 getApplicationInfo(
   7919                                         cpi.applicationInfo.packageName,
   7920                                         STOCK_PM_FLAGS);
   7921                         if (ai == null) {
   7922                             Slog.w(TAG, "No package info for content provider "
   7923                                     + cpi.name);
   7924                             return null;
   7925                         }
   7926                         cpr = new ContentProviderRecord(cpi, ai);
   7927                     } catch (RemoteException ex) {
   7928                         // pm is in same process, this will never happen.
   7929                     }
   7930                 }
   7931 
   7932                 if (r != null && cpr.canRunHere(r)) {
   7933                     // If this is a multiprocess provider, then just return its
   7934                     // info and allow the caller to instantiate it.  Only do
   7935                     // this if the provider is the same user as the caller's
   7936                     // process, or can run as root (so can be in any process).
   7937                     return cpr;
   7938                 }
   7939 
   7940                 if (DEBUG_PROVIDER) {
   7941                     RuntimeException e = new RuntimeException("here");
   7942                     Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
   7943                           + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
   7944                 }
   7945 
   7946                 // This is single process, and our app is now connecting to it.
   7947                 // See if we are already in the process of launching this
   7948                 // provider.
   7949                 final int N = mLaunchingProviders.size();
   7950                 int i;
   7951                 for (i=0; i<N; i++) {
   7952                     if (mLaunchingProviders.get(i) == cpr) {
   7953                         break;
   7954                     }
   7955                 }
   7956 
   7957                 // If the provider is not already being launched, then get it
   7958                 // started.
   7959                 if (i >= N) {
   7960                     final long origId = Binder.clearCallingIdentity();
   7961                     ProcessRecord proc = startProcessLocked(cpi.processName,
   7962                             cpr.appInfo, false, 0, "content provider",
   7963                             new ComponentName(cpi.applicationInfo.packageName,
   7964                                     cpi.name), false);
   7965                     if (proc == null) {
   7966                         Slog.w(TAG, "Unable to launch app "
   7967                                 + cpi.applicationInfo.packageName + "/"
   7968                                 + cpi.applicationInfo.uid + " for provider "
   7969                                 + name + ": process is bad");
   7970                         return null;
   7971                     }
   7972                     cpr.launchingApp = proc;
   7973                     mLaunchingProviders.add(cpr);
   7974                     Binder.restoreCallingIdentity(origId);
   7975                 }
   7976 
   7977                 // Make sure the provider is published (the same provider class
   7978                 // may be published under multiple names).
   7979                 if (firstClass) {
   7980                     mProvidersByClass.put(cpi.name, cpr);
   7981                 }
   7982                 mProvidersByName.put(name, cpr);
   7983 
   7984                 if (r != null) {
   7985                     if (DEBUG_PROVIDER) Slog.v(TAG,
   7986                             "Adding provider requested by "
   7987                             + r.processName + " from process "
   7988                             + cpr.info.processName);
   7989                     Integer cnt = r.conProviders.get(cpr);
   7990                     if (cnt == null) {
   7991                         r.conProviders.put(cpr, new Integer(1));
   7992                     } else {
   7993                         r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
   7994                     }
   7995                     cpr.clients.add(r);
   7996                 } else {
   7997                     cpr.externals++;
   7998                 }
   7999             }
   8000         }
   8001 
   8002         // Wait for the provider to be published...
   8003         synchronized (cpr) {
   8004             while (cpr.provider == null) {
   8005                 if (cpr.launchingApp == null) {
   8006                     Slog.w(TAG, "Unable to launch app "
   8007                             + cpi.applicationInfo.packageName + "/"
   8008                             + cpi.applicationInfo.uid + " for provider "
   8009                             + name + ": launching app became null");
   8010                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
   8011                             cpi.applicationInfo.packageName,
   8012                             cpi.applicationInfo.uid, name);
   8013                     return null;
   8014                 }
   8015                 try {
   8016                     cpr.wait();
   8017                 } catch (InterruptedException ex) {
   8018                 }
   8019             }
   8020         }
   8021         return cpr;
   8022     }
   8023 
   8024     public final ContentProviderHolder getContentProvider(
   8025             IApplicationThread caller, String name) {
   8026         if (caller == null) {
   8027             String msg = "null IApplicationThread when getting content provider "
   8028                     + name;
   8029             Slog.w(TAG, msg);
   8030             throw new SecurityException(msg);
   8031         }
   8032 
   8033         return getContentProviderImpl(caller, name);
   8034     }
   8035 
   8036     private ContentProviderHolder getContentProviderExternal(String name) {
   8037         return getContentProviderImpl(null, name);
   8038     }
   8039 
   8040     /**
   8041      * Drop a content provider from a ProcessRecord's bookkeeping
   8042      * @param cpr
   8043      */
   8044     public void removeContentProvider(IApplicationThread caller, String name) {
   8045         synchronized (this) {
   8046             ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name);
   8047             if(cpr == null) {
   8048                 // remove from mProvidersByClass
   8049                 if (DEBUG_PROVIDER) Slog.v(TAG, name +
   8050                         " provider not found in providers list");
   8051                 return;
   8052             }
   8053             final ProcessRecord r = getRecordForAppLocked(caller);
   8054             if (r == null) {
   8055                 throw new SecurityException(
   8056                         "Unable to find app for caller " + caller +
   8057                         " when removing content provider " + name);
   8058             }
   8059             //update content provider record entry info
   8060             ContentProviderRecord localCpr = (ContentProviderRecord)
   8061                     mProvidersByClass.get(cpr.info.name);
   8062             if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
   8063                     + r.info.processName + " from process "
   8064                     + localCpr.appInfo.processName);
   8065             if (localCpr.app == r) {
   8066                 //should not happen. taken care of as a local provider
   8067                 Slog.w(TAG, "removeContentProvider called on local provider: "
   8068                         + cpr.info.name + " in process " + r.processName);
   8069                 return;
   8070             } else {
   8071                 Integer cnt = r.conProviders.get(localCpr);
   8072                 if (cnt == null || cnt.intValue() <= 1) {
   8073                     localCpr.clients.remove(r);
   8074                     r.conProviders.remove(localCpr);
   8075                 } else {
   8076                     r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
   8077                 }
   8078             }
   8079             updateOomAdjLocked();
   8080         }
   8081     }
   8082 
   8083     private void removeContentProviderExternal(String name) {
   8084         synchronized (this) {
   8085             ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name);
   8086             if(cpr == null) {
   8087                 //remove from mProvidersByClass
   8088                 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
   8089                 return;
   8090             }
   8091 
   8092             //update content provider record entry info
   8093             ContentProviderRecord localCpr = (ContentProviderRecord) mProvidersByClass.get(cpr.info.name);
   8094             localCpr.externals--;
   8095             if (localCpr.externals < 0) {
   8096                 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
   8097             }
   8098             updateOomAdjLocked();
   8099         }
   8100     }
   8101 
   8102     public final void publishContentProviders(IApplicationThread caller,
   8103             List<ContentProviderHolder> providers) {
   8104         if (providers == null) {
   8105             return;
   8106         }
   8107 
   8108         synchronized(this) {
   8109             final ProcessRecord r = getRecordForAppLocked(caller);
   8110             if (r == null) {
   8111                 throw new SecurityException(
   8112                         "Unable to find app for caller " + caller
   8113                       + " (pid=" + Binder.getCallingPid()
   8114                       + ") when publishing content providers");
   8115             }
   8116 
   8117             final long origId = Binder.clearCallingIdentity();
   8118 
   8119             final int N = providers.size();
   8120             for (int i=0; i<N; i++) {
   8121                 ContentProviderHolder src = providers.get(i);
   8122                 if (src == null || src.info == null || src.provider == null) {
   8123                     continue;
   8124                 }
   8125                 ContentProviderRecord dst =
   8126                     (ContentProviderRecord)r.pubProviders.get(src.info.name);
   8127                 if (dst != null) {
   8128                     mProvidersByClass.put(dst.info.name, dst);
   8129                     String names[] = dst.info.authority.split(";");
   8130                     for (int j = 0; j < names.length; j++) {
   8131                         mProvidersByName.put(names[j], dst);
   8132                     }
   8133 
   8134                     int NL = mLaunchingProviders.size();
   8135                     int j;
   8136                     for (j=0; j<NL; j++) {
   8137                         if (mLaunchingProviders.get(j) == dst) {
   8138                             mLaunchingProviders.remove(j);
   8139                             j--;
   8140                             NL--;
   8141                         }
   8142                     }
   8143                     synchronized (dst) {
   8144                         dst.provider = src.provider;
   8145                         dst.app = r;
   8146                         dst.notifyAll();
   8147                     }
   8148                     updateOomAdjLocked(r);
   8149                 }
   8150             }
   8151 
   8152             Binder.restoreCallingIdentity(origId);
   8153         }
   8154     }
   8155 
   8156     public static final void installSystemProviders() {
   8157         List providers;
   8158         synchronized (mSelf) {
   8159             ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
   8160             providers = mSelf.generateApplicationProvidersLocked(app);
   8161             if (providers != null) {
   8162                 for (int i=providers.size()-1; i>=0; i--) {
   8163                     ProviderInfo pi = (ProviderInfo)providers.get(i);
   8164                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   8165                         Slog.w(TAG, "Not installing system proc provider " + pi.name
   8166                                 + ": not system .apk");
   8167                         providers.remove(i);
   8168                     }
   8169                 }
   8170             }
   8171         }
   8172         if (providers != null) {
   8173             mSystemThread.installSystemProviders(providers);
   8174         }
   8175     }
   8176 
   8177     // =========================================================
   8178     // GLOBAL MANAGEMENT
   8179     // =========================================================
   8180 
   8181     final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
   8182             ApplicationInfo info, String customProcess) {
   8183         String proc = customProcess != null ? customProcess : info.processName;
   8184         BatteryStatsImpl.Uid.Proc ps = null;
   8185         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   8186         synchronized (stats) {
   8187             ps = stats.getProcessStatsLocked(info.uid, proc);
   8188         }
   8189         return new ProcessRecord(ps, thread, info, proc);
   8190     }
   8191 
   8192     final ProcessRecord addAppLocked(ApplicationInfo info) {
   8193         ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
   8194 
   8195         if (app == null) {
   8196             app = newProcessRecordLocked(null, info, null);
   8197             mProcessNames.put(info.processName, info.uid, app);
   8198             updateLruProcessLocked(app, true, true);
   8199         }
   8200 
   8201         if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
   8202                 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
   8203             app.persistent = true;
   8204             app.maxAdj = CORE_SERVER_ADJ;
   8205         }
   8206         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
   8207             mPersistentStartingProcesses.add(app);
   8208             startProcessLocked(app, "added application", app.processName);
   8209         }
   8210 
   8211         return app;
   8212     }
   8213 
   8214     public void unhandledBack() {
   8215         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
   8216                 "unhandledBack()");
   8217 
   8218         synchronized(this) {
   8219             int count = mHistory.size();
   8220             if (DEBUG_SWITCH) Slog.d(
   8221                 TAG, "Performing unhandledBack(): stack size = " + count);
   8222             if (count > 1) {
   8223                 final long origId = Binder.clearCallingIdentity();
   8224                 finishActivityLocked((HistoryRecord)mHistory.get(count-1),
   8225                         count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
   8226                 Binder.restoreCallingIdentity(origId);
   8227             }
   8228         }
   8229     }
   8230 
   8231     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
   8232         String name = uri.getAuthority();
   8233         ContentProviderHolder cph = getContentProviderExternal(name);
   8234         ParcelFileDescriptor pfd = null;
   8235         if (cph != null) {
   8236             // We record the binder invoker's uid in thread-local storage before
   8237             // going to the content provider to open the file.  Later, in the code
   8238             // that handles all permissions checks, we look for this uid and use
   8239             // that rather than the Activity Manager's own uid.  The effect is that
   8240             // we do the check against the caller's permissions even though it looks
   8241             // to the content provider like the Activity Manager itself is making
   8242             // the request.
   8243             sCallerIdentity.set(new Identity(
   8244                     Binder.getCallingPid(), Binder.getCallingUid()));
   8245             try {
   8246                 pfd = cph.provider.openFile(uri, "r");
   8247             } catch (FileNotFoundException e) {
   8248                 // do nothing; pfd will be returned null
   8249             } finally {
   8250                 // Ensure that whatever happens, we clean up the identity state
   8251                 sCallerIdentity.remove();
   8252             }
   8253 
   8254             // We've got the fd now, so we're done with the provider.
   8255             removeContentProviderExternal(name);
   8256         } else {
   8257             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
   8258         }
   8259         return pfd;
   8260     }
   8261 
   8262     public void goingToSleep() {
   8263         synchronized(this) {
   8264             mSleeping = true;
   8265             mWindowManager.setEventDispatching(false);
   8266 
   8267             if (mResumedActivity != null) {
   8268                 pauseIfSleepingLocked();
   8269             } else {
   8270                 Slog.w(TAG, "goingToSleep with no resumed activity!");
   8271             }
   8272         }
   8273     }
   8274 
   8275     public boolean shutdown(int timeout) {
   8276         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
   8277                 != PackageManager.PERMISSION_GRANTED) {
   8278             throw new SecurityException("Requires permission "
   8279                     + android.Manifest.permission.SHUTDOWN);
   8280         }
   8281 
   8282         boolean timedout = false;
   8283 
   8284         synchronized(this) {
   8285             mShuttingDown = true;
   8286             mWindowManager.setEventDispatching(false);
   8287 
   8288             if (mResumedActivity != null) {
   8289                 pauseIfSleepingLocked();
   8290                 final long endTime = System.currentTimeMillis() + timeout;
   8291                 while (mResumedActivity != null || mPausingActivity != null) {
   8292                     long delay = endTime - System.currentTimeMillis();
   8293                     if (delay <= 0) {
   8294                         Slog.w(TAG, "Activity manager shutdown timed out");
   8295                         timedout = true;
   8296                         break;
   8297                     }
   8298                     try {
   8299                         this.wait();
   8300                     } catch (InterruptedException e) {
   8301                     }
   8302                 }
   8303             }
   8304         }
   8305 
   8306         mUsageStatsService.shutdown();
   8307         mBatteryStatsService.shutdown();
   8308 
   8309         return timedout;
   8310     }
   8311 
   8312     void pauseIfSleepingLocked() {
   8313         if (mSleeping || mShuttingDown) {
   8314             if (!mGoingToSleep.isHeld()) {
   8315                 mGoingToSleep.acquire();
   8316                 if (mLaunchingActivity.isHeld()) {
   8317                     mLaunchingActivity.release();
   8318                     mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
   8319                 }
   8320             }
   8321 
   8322             // If we are not currently pausing an activity, get the current
   8323             // one to pause.  If we are pausing one, we will just let that stuff
   8324             // run and release the wake lock when all done.
   8325             if (mPausingActivity == null) {
   8326                 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep needs to pause...");
   8327                 if (DEBUG_USER_LEAVING) Slog.v(TAG, "Sleep => pause with userLeaving=false");
   8328                 startPausingLocked(false, true);
   8329             }
   8330         }
   8331     }
   8332 
   8333     public void wakingUp() {
   8334         synchronized(this) {
   8335             if (mGoingToSleep.isHeld()) {
   8336                 mGoingToSleep.release();
   8337             }
   8338             mWindowManager.setEventDispatching(true);
   8339             mSleeping = false;
   8340             resumeTopActivityLocked(null);
   8341         }
   8342     }
   8343 
   8344     public void stopAppSwitches() {
   8345         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   8346                 != PackageManager.PERMISSION_GRANTED) {
   8347             throw new SecurityException("Requires permission "
   8348                     + android.Manifest.permission.STOP_APP_SWITCHES);
   8349         }
   8350 
   8351         synchronized(this) {
   8352             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
   8353                     + APP_SWITCH_DELAY_TIME;
   8354             mDidAppSwitch = false;
   8355             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   8356             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   8357             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
   8358         }
   8359     }
   8360 
   8361     public void resumeAppSwitches() {
   8362         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   8363                 != PackageManager.PERMISSION_GRANTED) {
   8364             throw new SecurityException("Requires permission "
   8365                     + android.Manifest.permission.STOP_APP_SWITCHES);
   8366         }
   8367 
   8368         synchronized(this) {
   8369             // Note that we don't execute any pending app switches... we will
   8370             // let those wait until either the timeout, or the next start
   8371             // activity request.
   8372             mAppSwitchesAllowedTime = 0;
   8373         }
   8374     }
   8375 
   8376     boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
   8377             String name) {
   8378         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
   8379             return true;
   8380         }
   8381 
   8382         final int perm = checkComponentPermission(
   8383                 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
   8384                 callingUid, -1);
   8385         if (perm == PackageManager.PERMISSION_GRANTED) {
   8386             return true;
   8387         }
   8388 
   8389         Slog.w(TAG, name + " request from " + callingUid + " stopped");
   8390         return false;
   8391     }
   8392 
   8393     public void setDebugApp(String packageName, boolean waitForDebugger,
   8394             boolean persistent) {
   8395         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
   8396                 "setDebugApp()");
   8397 
   8398         // Note that this is not really thread safe if there are multiple
   8399         // callers into it at the same time, but that's not a situation we
   8400         // care about.
   8401         if (persistent) {
   8402             final ContentResolver resolver = mContext.getContentResolver();
   8403             Settings.System.putString(
   8404                 resolver, Settings.System.DEBUG_APP,
   8405                 packageName);
   8406             Settings.System.putInt(
   8407                 resolver, Settings.System.WAIT_FOR_DEBUGGER,
   8408                 waitForDebugger ? 1 : 0);
   8409         }
   8410 
   8411         synchronized (this) {
   8412             if (!persistent) {
   8413                 mOrigDebugApp = mDebugApp;
   8414                 mOrigWaitForDebugger = mWaitForDebugger;
   8415             }
   8416             mDebugApp = packageName;
   8417             mWaitForDebugger = waitForDebugger;
   8418             mDebugTransient = !persistent;
   8419             if (packageName != null) {
   8420                 final long origId = Binder.clearCallingIdentity();
   8421                 forceStopPackageLocked(packageName, -1, false, false, true);
   8422                 Binder.restoreCallingIdentity(origId);
   8423             }
   8424         }
   8425     }
   8426 
   8427     public void setAlwaysFinish(boolean enabled) {
   8428         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
   8429                 "setAlwaysFinish()");
   8430 
   8431         Settings.System.putInt(
   8432                 mContext.getContentResolver(),
   8433                 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
   8434 
   8435         synchronized (this) {
   8436             mAlwaysFinishActivities = enabled;
   8437         }
   8438     }
   8439 
   8440     public void setActivityController(IActivityController controller) {
   8441         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   8442                 "setActivityController()");
   8443         synchronized (this) {
   8444             mController = controller;
   8445         }
   8446     }
   8447 
   8448     public boolean isUserAMonkey() {
   8449         // For now the fact that there is a controller implies
   8450         // we have a monkey.
   8451         synchronized (this) {
   8452             return mController != null;
   8453         }
   8454     }
   8455 
   8456     public void registerActivityWatcher(IActivityWatcher watcher) {
   8457         synchronized (this) {
   8458             mWatchers.register(watcher);
   8459         }
   8460     }
   8461 
   8462     public void unregisterActivityWatcher(IActivityWatcher watcher) {
   8463         synchronized (this) {
   8464             mWatchers.unregister(watcher);
   8465         }
   8466     }
   8467 
   8468     public final void enterSafeMode() {
   8469         synchronized(this) {
   8470             // It only makes sense to do this before the system is ready
   8471             // and started launching other packages.
   8472             if (!mSystemReady) {
   8473                 try {
   8474                     ActivityThread.getPackageManager().enterSafeMode();
   8475                 } catch (RemoteException e) {
   8476                 }
   8477 
   8478                 View v = LayoutInflater.from(mContext).inflate(
   8479                         com.android.internal.R.layout.safe_mode, null);
   8480                 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
   8481                 lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
   8482                 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
   8483                 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
   8484                 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
   8485                 lp.format = v.getBackground().getOpacity();
   8486                 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
   8487                         | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
   8488                 ((WindowManager)mContext.getSystemService(
   8489                         Context.WINDOW_SERVICE)).addView(v, lp);
   8490             }
   8491         }
   8492     }
   8493 
   8494     public void noteWakeupAlarm(IIntentSender sender) {
   8495         if (!(sender instanceof PendingIntentRecord)) {
   8496             return;
   8497         }
   8498         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   8499         synchronized (stats) {
   8500             if (mBatteryStatsService.isOnBattery()) {
   8501                 mBatteryStatsService.enforceCallingPermission();
   8502                 PendingIntentRecord rec = (PendingIntentRecord)sender;
   8503                 int MY_UID = Binder.getCallingUid();
   8504                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
   8505                 BatteryStatsImpl.Uid.Pkg pkg =
   8506                     stats.getPackageStatsLocked(uid, rec.key.packageName);
   8507                 pkg.incWakeupsLocked();
   8508             }
   8509         }
   8510     }
   8511 
   8512     public boolean killPids(int[] pids, String pReason) {
   8513         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   8514             throw new SecurityException("killPids only available to the system");
   8515         }
   8516         String reason = (pReason == null) ? "Unknown" : pReason;
   8517         // XXX Note: don't acquire main activity lock here, because the window
   8518         // manager calls in with its locks held.
   8519 
   8520         boolean killed = false;
   8521         synchronized (mPidsSelfLocked) {
   8522             int[] types = new int[pids.length];
   8523             int worstType = 0;
   8524             for (int i=0; i<pids.length; i++) {
   8525                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   8526                 if (proc != null) {
   8527                     int type = proc.setAdj;
   8528                     types[i] = type;
   8529                     if (type > worstType) {
   8530                         worstType = type;
   8531                     }
   8532                 }
   8533             }
   8534 
   8535             // If the worse oom_adj is somewhere in the hidden proc LRU range,
   8536             // then constrain it so we will kill all hidden procs.
   8537             if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
   8538                 worstType = HIDDEN_APP_MIN_ADJ;
   8539             }
   8540             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
   8541             for (int i=0; i<pids.length; i++) {
   8542                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   8543                 if (proc == null) {
   8544                     continue;
   8545                 }
   8546                 int adj = proc.setAdj;
   8547                 if (adj >= worstType && !proc.killedBackground) {
   8548                     Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
   8549                     EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
   8550                             proc.processName, adj, reason);
   8551                     killed = true;
   8552                     proc.killedBackground = true;
   8553                     Process.killProcessQuiet(pids[i]);
   8554                 }
   8555             }
   8556         }
   8557         return killed;
   8558     }
   8559 
   8560     public void reportPss(IApplicationThread caller, int pss) {
   8561         Watchdog.PssRequestor req;
   8562         String name;
   8563         ProcessRecord callerApp;
   8564         synchronized (this) {
   8565             if (caller == null) {
   8566                 return;
   8567             }
   8568             callerApp = getRecordForAppLocked(caller);
   8569             if (callerApp == null) {
   8570                 return;
   8571             }
   8572             callerApp.lastPss = pss;
   8573             req = callerApp;
   8574             name = callerApp.processName;
   8575         }
   8576         Watchdog.getInstance().reportPss(req, name, pss);
   8577         if (!callerApp.persistent) {
   8578             removeRequestedPss(callerApp);
   8579         }
   8580     }
   8581 
   8582     public void requestPss(Runnable completeCallback) {
   8583         ArrayList<ProcessRecord> procs;
   8584         synchronized (this) {
   8585             mRequestPssCallback = completeCallback;
   8586             mRequestPssList.clear();
   8587             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   8588                 ProcessRecord proc = mLruProcesses.get(i);
   8589                 if (!proc.persistent) {
   8590                     mRequestPssList.add(proc);
   8591                 }
   8592             }
   8593             procs = new ArrayList<ProcessRecord>(mRequestPssList);
   8594         }
   8595 
   8596         int oldPri = Process.getThreadPriority(Process.myTid());
   8597         Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
   8598         for (int i=procs.size()-1; i>=0; i--) {
   8599             ProcessRecord proc = procs.get(i);
   8600             proc.lastPss = 0;
   8601             proc.requestPss();
   8602         }
   8603         Process.setThreadPriority(oldPri);
   8604     }
   8605 
   8606     void removeRequestedPss(ProcessRecord proc) {
   8607         Runnable callback = null;
   8608         synchronized (this) {
   8609             if (mRequestPssList.remove(proc)) {
   8610                 if (mRequestPssList.size() == 0) {
   8611                     callback = mRequestPssCallback;
   8612                     mRequestPssCallback = null;
   8613                 }
   8614             }
   8615         }
   8616 
   8617         if (callback != null) {
   8618             callback.run();
   8619         }
   8620     }
   8621 
   8622     public void collectPss(Watchdog.PssStats stats) {
   8623         stats.mEmptyPss = 0;
   8624         stats.mEmptyCount = 0;
   8625         stats.mBackgroundPss = 0;
   8626         stats.mBackgroundCount = 0;
   8627         stats.mServicePss = 0;
   8628         stats.mServiceCount = 0;
   8629         stats.mVisiblePss = 0;
   8630         stats.mVisibleCount = 0;
   8631         stats.mForegroundPss = 0;
   8632         stats.mForegroundCount = 0;
   8633         stats.mNoPssCount = 0;
   8634         synchronized (this) {
   8635             int i;
   8636             int NPD = mProcDeaths.length < stats.mProcDeaths.length
   8637                     ? mProcDeaths.length : stats.mProcDeaths.length;
   8638             int aggr = 0;
   8639             for (i=0; i<NPD; i++) {
   8640                 aggr += mProcDeaths[i];
   8641                 stats.mProcDeaths[i] = aggr;
   8642             }
   8643             while (i<stats.mProcDeaths.length) {
   8644                 stats.mProcDeaths[i] = 0;
   8645                 i++;
   8646             }
   8647 
   8648             for (i=mLruProcesses.size()-1; i>=0; i--) {
   8649                 ProcessRecord proc = mLruProcesses.get(i);
   8650                 if (proc.persistent) {
   8651                     continue;
   8652                 }
   8653                 //Slog.i(TAG, "Proc " + proc + ": pss=" + proc.lastPss);
   8654                 if (proc.lastPss == 0) {
   8655                     stats.mNoPssCount++;
   8656                     continue;
   8657                 }
   8658                 if (proc.setAdj >= HIDDEN_APP_MIN_ADJ) {
   8659                     if (proc.empty) {
   8660                         stats.mEmptyPss += proc.lastPss;
   8661                         stats.mEmptyCount++;
   8662                     } else {
   8663                         stats.mBackgroundPss += proc.lastPss;
   8664                         stats.mBackgroundCount++;
   8665                     }
   8666                 } else if (proc.setAdj >= VISIBLE_APP_ADJ) {
   8667                     stats.mVisiblePss += proc.lastPss;
   8668                     stats.mVisibleCount++;
   8669                 } else {
   8670                     stats.mForegroundPss += proc.lastPss;
   8671                     stats.mForegroundCount++;
   8672                 }
   8673             }
   8674         }
   8675     }
   8676 
   8677     public final void startRunning(String pkg, String cls, String action,
   8678             String data) {
   8679         synchronized(this) {
   8680             if (mStartRunning) {
   8681                 return;
   8682             }
   8683             mStartRunning = true;
   8684             mTopComponent = pkg != null && cls != null
   8685                     ? new ComponentName(pkg, cls) : null;
   8686             mTopAction = action != null ? action : Intent.ACTION_MAIN;
   8687             mTopData = data;
   8688             if (!mSystemReady) {
   8689                 return;
   8690             }
   8691         }
   8692 
   8693         systemReady(null);
   8694     }
   8695 
   8696     private void retrieveSettings() {
   8697         final ContentResolver resolver = mContext.getContentResolver();
   8698         String debugApp = Settings.System.getString(
   8699             resolver, Settings.System.DEBUG_APP);
   8700         boolean waitForDebugger = Settings.System.getInt(
   8701             resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
   8702         boolean alwaysFinishActivities = Settings.System.getInt(
   8703             resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
   8704 
   8705         Configuration configuration = new Configuration();
   8706         Settings.System.getConfiguration(resolver, configuration);
   8707 
   8708         synchronized (this) {
   8709             mDebugApp = mOrigDebugApp = debugApp;
   8710             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
   8711             mAlwaysFinishActivities = alwaysFinishActivities;
   8712             // This happens before any activities are started, so we can
   8713             // change mConfiguration in-place.
   8714             mConfiguration.updateFrom(configuration);
   8715             mConfigurationSeq = mConfiguration.seq = 1;
   8716             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
   8717         }
   8718     }
   8719 
   8720     public boolean testIsSystemReady() {
   8721         // no need to synchronize(this) just to read & return the value
   8722         return mSystemReady;
   8723     }
   8724 
   8725     public void systemReady(final Runnable goingCallback) {
   8726         // In the simulator, startRunning will never have been called, which
   8727         // normally sets a few crucial variables. Do it here instead.
   8728         if (!Process.supportsProcesses()) {
   8729             mStartRunning = true;
   8730             mTopAction = Intent.ACTION_MAIN;
   8731         }
   8732 
   8733         synchronized(this) {
   8734             if (mSystemReady) {
   8735                 if (goingCallback != null) goingCallback.run();
   8736                 return;
   8737             }
   8738 
   8739             // Check to see if there are any update receivers to run.
   8740             if (!mDidUpdate) {
   8741                 if (mWaitingUpdate) {
   8742                     return;
   8743                 }
   8744                 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
   8745                 List<ResolveInfo> ris = null;
   8746                 try {
   8747                     ris = ActivityThread.getPackageManager().queryIntentReceivers(
   8748                                 intent, null, 0);
   8749                 } catch (RemoteException e) {
   8750                 }
   8751                 if (ris != null) {
   8752                     for (int i=ris.size()-1; i>=0; i--) {
   8753                         if ((ris.get(i).activityInfo.applicationInfo.flags
   8754                                 &ApplicationInfo.FLAG_SYSTEM) == 0) {
   8755                             ris.remove(i);
   8756                         }
   8757                     }
   8758                     intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
   8759                     for (int i=0; i<ris.size(); i++) {
   8760                         ActivityInfo ai = ris.get(i).activityInfo;
   8761                         intent.setComponent(new ComponentName(ai.packageName, ai.name));
   8762                         IIntentReceiver finisher = null;
   8763                         if (i == ris.size()-1) {
   8764                             finisher = new IIntentReceiver.Stub() {
   8765                                 public void performReceive(Intent intent, int resultCode,
   8766                                         String data, Bundle extras, boolean ordered,
   8767                                         boolean sticky)
   8768                                         throws RemoteException {
   8769                                     synchronized (ActivityManagerService.this) {
   8770                                         mDidUpdate = true;
   8771                                     }
   8772                                     systemReady(goingCallback);
   8773                                 }
   8774                             };
   8775                         }
   8776                         Slog.i(TAG, "Sending system update to: " + intent.getComponent());
   8777                         broadcastIntentLocked(null, null, intent, null, finisher,
   8778                                 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
   8779                         if (finisher != null) {
   8780                             mWaitingUpdate = true;
   8781                         }
   8782                     }
   8783                 }
   8784                 if (mWaitingUpdate) {
   8785                     return;
   8786                 }
   8787                 mDidUpdate = true;
   8788             }
   8789 
   8790             mSystemReady = true;
   8791             if (!mStartRunning) {
   8792                 return;
   8793             }
   8794         }
   8795 
   8796         ArrayList<ProcessRecord> procsToKill = null;
   8797         synchronized(mPidsSelfLocked) {
   8798             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
   8799                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   8800                 if (!isAllowedWhileBooting(proc.info)){
   8801                     if (procsToKill == null) {
   8802                         procsToKill = new ArrayList<ProcessRecord>();
   8803                     }
   8804                     procsToKill.add(proc);
   8805                 }
   8806             }
   8807         }
   8808 
   8809         if (procsToKill != null) {
   8810             synchronized(this) {
   8811                 for (int i=procsToKill.size()-1; i>=0; i--) {
   8812                     ProcessRecord proc = procsToKill.get(i);
   8813                     Slog.i(TAG, "Removing system update proc: " + proc);
   8814                     removeProcessLocked(proc, true);
   8815                 }
   8816             }
   8817         }
   8818 
   8819         Slog.i(TAG, "System now ready");
   8820         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
   8821             SystemClock.uptimeMillis());
   8822 
   8823         synchronized(this) {
   8824             // Make sure we have no pre-ready processes sitting around.
   8825 
   8826             if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
   8827                 ResolveInfo ri = mContext.getPackageManager()
   8828                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
   8829                                 STOCK_PM_FLAGS);
   8830                 CharSequence errorMsg = null;
   8831                 if (ri != null) {
   8832                     ActivityInfo ai = ri.activityInfo;
   8833                     ApplicationInfo app = ai.applicationInfo;
   8834                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   8835                         mTopAction = Intent.ACTION_FACTORY_TEST;
   8836                         mTopData = null;
   8837                         mTopComponent = new ComponentName(app.packageName,
   8838                                 ai.name);
   8839                     } else {
   8840                         errorMsg = mContext.getResources().getText(
   8841                                 com.android.internal.R.string.factorytest_not_system);
   8842                     }
   8843                 } else {
   8844                     errorMsg = mContext.getResources().getText(
   8845                             com.android.internal.R.string.factorytest_no_action);
   8846                 }
   8847                 if (errorMsg != null) {
   8848                     mTopAction = null;
   8849                     mTopData = null;
   8850                     mTopComponent = null;
   8851                     Message msg = Message.obtain();
   8852                     msg.what = SHOW_FACTORY_ERROR_MSG;
   8853                     msg.getData().putCharSequence("msg", errorMsg);
   8854                     mHandler.sendMessage(msg);
   8855                 }
   8856             }
   8857         }
   8858 
   8859         retrieveSettings();
   8860 
   8861         if (goingCallback != null) goingCallback.run();
   8862 
   8863         synchronized (this) {
   8864             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   8865                 try {
   8866                     List apps = ActivityThread.getPackageManager().
   8867                         getPersistentApplications(STOCK_PM_FLAGS);
   8868                     if (apps != null) {
   8869                         int N = apps.size();
   8870                         int i;
   8871                         for (i=0; i<N; i++) {
   8872                             ApplicationInfo info
   8873                                 = (ApplicationInfo)apps.get(i);
   8874                             if (info != null &&
   8875                                     !info.packageName.equals("android")) {
   8876                                 addAppLocked(info);
   8877                             }
   8878                         }
   8879                     }
   8880                 } catch (RemoteException ex) {
   8881                     // pm is in same process, this will never happen.
   8882                 }
   8883             }
   8884 
   8885             // Start up initial activity.
   8886             mBooting = true;
   8887 
   8888             try {
   8889                 if (ActivityThread.getPackageManager().hasSystemUidErrors()) {
   8890                     Message msg = Message.obtain();
   8891                     msg.what = SHOW_UID_ERROR_MSG;
   8892                     mHandler.sendMessage(msg);
   8893                 }
   8894             } catch (RemoteException e) {
   8895             }
   8896 
   8897             resumeTopActivityLocked(null);
   8898         }
   8899     }
   8900 
   8901     private boolean makeAppCrashingLocked(ProcessRecord app,
   8902             String shortMsg, String longMsg, String stackTrace) {
   8903         app.crashing = true;
   8904         app.crashingReport = generateProcessError(app,
   8905                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
   8906         startAppProblemLocked(app);
   8907         app.stopFreezingAllLocked();
   8908         return handleAppCrashLocked(app);
   8909     }
   8910 
   8911     private void makeAppNotRespondingLocked(ProcessRecord app,
   8912             String activity, String shortMsg, String longMsg) {
   8913         app.notResponding = true;
   8914         app.notRespondingReport = generateProcessError(app,
   8915                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
   8916                 activity, shortMsg, longMsg, null);
   8917         startAppProblemLocked(app);
   8918         app.stopFreezingAllLocked();
   8919     }
   8920 
   8921     /**
   8922      * Generate a process error record, suitable for attachment to a ProcessRecord.
   8923      *
   8924      * @param app The ProcessRecord in which the error occurred.
   8925      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
   8926      *                      ActivityManager.AppErrorStateInfo
   8927      * @param activity The activity associated with the crash, if known.
   8928      * @param shortMsg Short message describing the crash.
   8929      * @param longMsg Long message describing the crash.
   8930      * @param stackTrace Full crash stack trace, may be null.
   8931      *
   8932      * @return Returns a fully-formed AppErrorStateInfo record.
   8933      */
   8934     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
   8935             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
   8936         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
   8937 
   8938         report.condition = condition;
   8939         report.processName = app.processName;
   8940         report.pid = app.pid;
   8941         report.uid = app.info.uid;
   8942         report.tag = activity;
   8943         report.shortMsg = shortMsg;
   8944         report.longMsg = longMsg;
   8945         report.stackTrace = stackTrace;
   8946 
   8947         return report;
   8948     }
   8949 
   8950     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
   8951         synchronized (this) {
   8952             app.crashing = false;
   8953             app.crashingReport = null;
   8954             app.notResponding = false;
   8955             app.notRespondingReport = null;
   8956             if (app.anrDialog == fromDialog) {
   8957                 app.anrDialog = null;
   8958             }
   8959             if (app.waitDialog == fromDialog) {
   8960                 app.waitDialog = null;
   8961             }
   8962             if (app.pid > 0 && app.pid != MY_PID) {
   8963                 handleAppCrashLocked(app);
   8964                 Slog.i(ActivityManagerService.TAG, "Killing "
   8965                         + app.processName + " (pid=" + app.pid + "): user's request");
   8966                 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   8967                         app.processName, app.setAdj, "user's request after error");
   8968                 Process.killProcess(app.pid);
   8969             }
   8970         }
   8971     }
   8972 
   8973     private boolean handleAppCrashLocked(ProcessRecord app) {
   8974         long now = SystemClock.uptimeMillis();
   8975 
   8976         Long crashTime = mProcessCrashTimes.get(app.info.processName,
   8977                 app.info.uid);
   8978         if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
   8979             // This process loses!
   8980             Slog.w(TAG, "Process " + app.info.processName
   8981                     + " has crashed too many times: killing!");
   8982             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
   8983                     app.info.processName, app.info.uid);
   8984             killServicesLocked(app, false);
   8985             for (int i=mHistory.size()-1; i>=0; i--) {
   8986                 HistoryRecord r = (HistoryRecord)mHistory.get(i);
   8987                 if (r.app == app) {
   8988                     Slog.w(TAG, "  Force finishing activity "
   8989                         + r.intent.getComponent().flattenToShortString());
   8990                     finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
   8991                 }
   8992             }
   8993             if (!app.persistent) {
   8994                 // We don't want to start this process again until the user
   8995                 // explicitly does so...  but for persistent process, we really
   8996                 // need to keep it running.  If a persistent process is actually
   8997                 // repeatedly crashing, then badness for everyone.
   8998                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
   8999                         app.info.processName);
   9000                 mBadProcesses.put(app.info.processName, app.info.uid, now);
   9001                 app.bad = true;
   9002                 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
   9003                 app.removed = true;
   9004                 removeProcessLocked(app, false);
   9005                 return false;
   9006             }
   9007         } else {
   9008             HistoryRecord r = topRunningActivityLocked(null);
   9009             if (r.app == app) {
   9010                 // If the top running activity is from this crashing
   9011                 // process, then terminate it to avoid getting in a loop.
   9012                 Slog.w(TAG, "  Force finishing activity "
   9013                         + r.intent.getComponent().flattenToShortString());
   9014                 int index = indexOfTokenLocked(r);
   9015                 finishActivityLocked(r, index,
   9016                         Activity.RESULT_CANCELED, null, "crashed");
   9017                 // Also terminate an activities below it that aren't yet
   9018                 // stopped, to avoid a situation where one will get
   9019                 // re-start our crashing activity once it gets resumed again.
   9020                 index--;
   9021                 if (index >= 0) {
   9022                     r = (HistoryRecord)mHistory.get(index);
   9023                     if (r.state == ActivityState.RESUMED
   9024                             || r.state == ActivityState.PAUSING
   9025                             || r.state == ActivityState.PAUSED) {
   9026                         if (!r.isHomeActivity) {
   9027                             Slog.w(TAG, "  Force finishing activity "
   9028                                     + r.intent.getComponent().flattenToShortString());
   9029                             finishActivityLocked(r, index,
   9030                                     Activity.RESULT_CANCELED, null, "crashed");
   9031                         }
   9032                     }
   9033                 }
   9034             }
   9035         }
   9036 
   9037         // Bump up the crash count of any services currently running in the proc.
   9038         if (app.services.size() != 0) {
   9039             // Any services running in the application need to be placed
   9040             // back in the pending list.
   9041             Iterator it = app.services.iterator();
   9042             while (it.hasNext()) {
   9043                 ServiceRecord sr = (ServiceRecord)it.next();
   9044                 sr.crashCount++;
   9045             }
   9046         }
   9047 
   9048         mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
   9049         return true;
   9050     }
   9051 
   9052     void startAppProblemLocked(ProcessRecord app) {
   9053         app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
   9054                 mContext, app.info.packageName, app.info.flags);
   9055         skipCurrentReceiverLocked(app);
   9056     }
   9057 
   9058     void skipCurrentReceiverLocked(ProcessRecord app) {
   9059         boolean reschedule = false;
   9060         BroadcastRecord r = app.curReceiver;
   9061         if (r != null) {
   9062             // The current broadcast is waiting for this app's receiver
   9063             // to be finished.  Looks like that's not going to happen, so
   9064             // let the broadcast continue.
   9065             logBroadcastReceiverDiscard(r);
   9066             finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
   9067                     r.resultExtras, r.resultAbort, true);
   9068             reschedule = true;
   9069         }
   9070         r = mPendingBroadcast;
   9071         if (r != null && r.curApp == app) {
   9072             if (DEBUG_BROADCAST) Slog.v(TAG,
   9073                     "skip & discard pending app " + r);
   9074             logBroadcastReceiverDiscard(r);
   9075             finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
   9076                     r.resultExtras, r.resultAbort, true);
   9077             reschedule = true;
   9078         }
   9079         if (reschedule) {
   9080             scheduleBroadcastsLocked();
   9081         }
   9082     }
   9083 
   9084     /**
   9085      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
   9086      * The application process will exit immediately after this call returns.
   9087      * @param app object of the crashing app, null for the system server
   9088      * @param crashInfo describing the exception
   9089      */
   9090     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
   9091         ProcessRecord r = findAppProcess(app);
   9092 
   9093         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
   9094                 app == null ? "system" : (r == null ? "unknown" : r.processName),
   9095                 r == null ? -1 : r.info.flags,
   9096                 crashInfo.exceptionClassName,
   9097                 crashInfo.exceptionMessage,
   9098                 crashInfo.throwFileName,
   9099                 crashInfo.throwLineNumber);
   9100 
   9101         addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
   9102 
   9103         crashApplication(r, crashInfo);
   9104     }
   9105 
   9106     /**
   9107      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
   9108      * @param app object of the crashing app, null for the system server
   9109      * @param tag reported by the caller
   9110      * @param crashInfo describing the context of the error
   9111      * @return true if the process should exit immediately (WTF is fatal)
   9112      */
   9113     public boolean handleApplicationWtf(IBinder app, String tag,
   9114             ApplicationErrorReport.CrashInfo crashInfo) {
   9115         ProcessRecord r = findAppProcess(app);
   9116 
   9117         EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
   9118                 app == null ? "system" : (r == null ? "unknown" : r.processName),
   9119                 r == null ? -1 : r.info.flags,
   9120                 tag, crashInfo.exceptionMessage);
   9121 
   9122         addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
   9123 
   9124         if (Settings.Secure.getInt(mContext.getContentResolver(),
   9125                 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
   9126             crashApplication(r, crashInfo);
   9127             return true;
   9128         } else {
   9129             return false;
   9130         }
   9131     }
   9132 
   9133     /**
   9134      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
   9135      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
   9136      */
   9137     private ProcessRecord findAppProcess(IBinder app) {
   9138         if (app == null) {
   9139             return null;
   9140         }
   9141 
   9142         synchronized (this) {
   9143             for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   9144                 final int NA = apps.size();
   9145                 for (int ia=0; ia<NA; ia++) {
   9146                     ProcessRecord p = apps.valueAt(ia);
   9147                     if (p.thread != null && p.thread.asBinder() == app) {
   9148                         return p;
   9149                     }
   9150                 }
   9151             }
   9152 
   9153             Slog.w(TAG, "Can't find mystery application: " + app);
   9154             return null;
   9155         }
   9156     }
   9157 
   9158     /**
   9159      * Write a description of an error (crash, WTF, ANR) to the drop box.
   9160      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
   9161      * @param process which caused the error, null means the system server
   9162      * @param activity which triggered the error, null if unknown
   9163      * @param parent activity related to the error, null if unknown
   9164      * @param subject line related to the error, null if absent
   9165      * @param report in long form describing the error, null if absent
   9166      * @param logFile to include in the report, null if none
   9167      * @param crashInfo giving an application stack trace, null if absent
   9168      */
   9169     public void addErrorToDropBox(String eventType,
   9170             ProcessRecord process, HistoryRecord activity, HistoryRecord parent, String subject,
   9171             final String report, final File logFile,
   9172             final ApplicationErrorReport.CrashInfo crashInfo) {
   9173         // NOTE -- this must never acquire the ActivityManagerService lock,
   9174         // otherwise the watchdog may be prevented from resetting the system.
   9175 
   9176         String prefix;
   9177         if (process == null || process.pid == MY_PID) {
   9178             prefix = "system_server_";
   9179         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   9180             prefix = "system_app_";
   9181         } else {
   9182             prefix = "data_app_";
   9183         }
   9184 
   9185         final String dropboxTag = prefix + eventType;
   9186         final DropBoxManager dbox = (DropBoxManager)
   9187                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   9188 
   9189         // Exit early if the dropbox isn't configured to accept this report type.
   9190         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   9191 
   9192         final StringBuilder sb = new StringBuilder(1024);
   9193         if (process == null || process.pid == MY_PID) {
   9194             sb.append("Process: system_server\n");
   9195         } else {
   9196             sb.append("Process: ").append(process.processName).append("\n");
   9197         }
   9198         if (process != null) {
   9199             int flags = process.info.flags;
   9200             IPackageManager pm = ActivityThread.getPackageManager();
   9201             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
   9202             for (String pkg : process.pkgList) {
   9203                 sb.append("Package: ").append(pkg);
   9204                 try {
   9205                     PackageInfo pi = pm.getPackageInfo(pkg, 0);
   9206                     if (pi != null) {
   9207                         sb.append(" v").append(pi.versionCode);
   9208                         if (pi.versionName != null) {
   9209                             sb.append(" (").append(pi.versionName).append(")");
   9210                         }
   9211                     }
   9212                 } catch (RemoteException e) {
   9213                     Slog.e(TAG, "Error getting package info: " + pkg, e);
   9214                 }
   9215                 sb.append("\n");
   9216             }
   9217         }
   9218         if (activity != null) {
   9219             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
   9220         }
   9221         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
   9222             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
   9223         }
   9224         if (parent != null && parent != activity) {
   9225             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
   9226         }
   9227         if (subject != null) {
   9228             sb.append("Subject: ").append(subject).append("\n");
   9229         }
   9230         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   9231         sb.append("\n");
   9232 
   9233         // Do the rest in a worker thread to avoid blocking the caller on I/O
   9234         // (After this point, we shouldn't access AMS internal data structures.)
   9235         Thread worker = new Thread("Error dump: " + dropboxTag) {
   9236             @Override
   9237             public void run() {
   9238                 if (report != null) {
   9239                     sb.append(report);
   9240                 }
   9241                 if (logFile != null) {
   9242                     try {
   9243                         sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
   9244                     } catch (IOException e) {
   9245                         Slog.e(TAG, "Error reading " + logFile, e);
   9246                     }
   9247                 }
   9248                 if (crashInfo != null && crashInfo.stackTrace != null) {
   9249                     sb.append(crashInfo.stackTrace);
   9250                 }
   9251 
   9252                 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
   9253                 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
   9254                 if (lines > 0) {
   9255                     sb.append("\n");
   9256 
   9257                     // Merge several logcat streams, and take the last N lines
   9258                     InputStreamReader input = null;
   9259                     try {
   9260                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
   9261                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
   9262                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
   9263 
   9264                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
   9265                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
   9266                         input = new InputStreamReader(logcat.getInputStream());
   9267 
   9268                         int num;
   9269                         char[] buf = new char[8192];
   9270                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
   9271                     } catch (IOException e) {
   9272                         Slog.e(TAG, "Error running logcat", e);
   9273                     } finally {
   9274                         if (input != null) try { input.close(); } catch (IOException e) {}
   9275                     }
   9276                 }
   9277 
   9278                 dbox.addText(dropboxTag, sb.toString());
   9279             }
   9280         };
   9281 
   9282         if (process == null || process.pid == MY_PID) {
   9283             worker.run();  // We may be about to die -- need to run this synchronously
   9284         } else {
   9285             worker.start();
   9286         }
   9287     }
   9288 
   9289     /**
   9290      * Bring up the "unexpected error" dialog box for a crashing app.
   9291      * Deal with edge cases (intercepts from instrumented applications,
   9292      * ActivityController, error intent receivers, that sort of thing).
   9293      * @param r the application crashing
   9294      * @param crashInfo describing the failure
   9295      */
   9296     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
   9297         long timeMillis = System.currentTimeMillis();
   9298         String shortMsg = crashInfo.exceptionClassName;
   9299         String longMsg = crashInfo.exceptionMessage;
   9300         String stackTrace = crashInfo.stackTrace;
   9301         if (shortMsg != null && longMsg != null) {
   9302             longMsg = shortMsg + ": " + longMsg;
   9303         } else if (shortMsg != null) {
   9304             longMsg = shortMsg;
   9305         }
   9306 
   9307         AppErrorResult result = new AppErrorResult();
   9308         synchronized (this) {
   9309             if (mController != null) {
   9310                 try {
   9311                     String name = r != null ? r.processName : null;
   9312                     int pid = r != null ? r.pid : Binder.getCallingPid();
   9313                     if (!mController.appCrashed(name, pid,
   9314                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
   9315                         Slog.w(TAG, "Force-killing crashed app " + name
   9316                                 + " at watcher's request");
   9317                         Process.killProcess(pid);
   9318                         return;
   9319                     }
   9320                 } catch (RemoteException e) {
   9321                     mController = null;
   9322                 }
   9323             }
   9324 
   9325             final long origId = Binder.clearCallingIdentity();
   9326 
   9327             // If this process is running instrumentation, finish it.
   9328             if (r != null && r.instrumentationClass != null) {
   9329                 Slog.w(TAG, "Error in app " + r.processName
   9330                       + " running instrumentation " + r.instrumentationClass + ":");
   9331                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
   9332                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
   9333                 Bundle info = new Bundle();
   9334                 info.putString("shortMsg", shortMsg);
   9335                 info.putString("longMsg", longMsg);
   9336                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
   9337                 Binder.restoreCallingIdentity(origId);
   9338                 return;
   9339             }
   9340 
   9341             // If we can't identify the process or it's already exceeded its crash quota,
   9342             // quit right away without showing a crash dialog.
   9343             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
   9344                 Binder.restoreCallingIdentity(origId);
   9345                 return;
   9346             }
   9347 
   9348             Message msg = Message.obtain();
   9349             msg.what = SHOW_ERROR_MSG;
   9350             HashMap data = new HashMap();
   9351             data.put("result", result);
   9352             data.put("app", r);
   9353             msg.obj = data;
   9354             mHandler.sendMessage(msg);
   9355 
   9356             Binder.restoreCallingIdentity(origId);
   9357         }
   9358 
   9359         int res = result.get();
   9360 
   9361         Intent appErrorIntent = null;
   9362         synchronized (this) {
   9363             if (r != null) {
   9364                 mProcessCrashTimes.put(r.info.processName, r.info.uid,
   9365                         SystemClock.uptimeMillis());
   9366             }
   9367             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
   9368                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
   9369             }
   9370         }
   9371 
   9372         if (appErrorIntent != null) {
   9373             try {
   9374                 mContext.startActivity(appErrorIntent);
   9375             } catch (ActivityNotFoundException e) {
   9376                 Slog.w(TAG, "bug report receiver dissappeared", e);
   9377             }
   9378         }
   9379     }
   9380 
   9381     Intent createAppErrorIntentLocked(ProcessRecord r,
   9382             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   9383         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
   9384         if (report == null) {
   9385             return null;
   9386         }
   9387         Intent result = new Intent(Intent.ACTION_APP_ERROR);
   9388         result.setComponent(r.errorReportReceiver);
   9389         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
   9390         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   9391         return result;
   9392     }
   9393 
   9394     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
   9395             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   9396         if (r.errorReportReceiver == null) {
   9397             return null;
   9398         }
   9399 
   9400         if (!r.crashing && !r.notResponding) {
   9401             return null;
   9402         }
   9403 
   9404         ApplicationErrorReport report = new ApplicationErrorReport();
   9405         report.packageName = r.info.packageName;
   9406         report.installerPackageName = r.errorReportReceiver.getPackageName();
   9407         report.processName = r.processName;
   9408         report.time = timeMillis;
   9409         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   9410 
   9411         if (r.crashing) {
   9412             report.type = ApplicationErrorReport.TYPE_CRASH;
   9413             report.crashInfo = crashInfo;
   9414         } else if (r.notResponding) {
   9415             report.type = ApplicationErrorReport.TYPE_ANR;
   9416             report.anrInfo = new ApplicationErrorReport.AnrInfo();
   9417 
   9418             report.anrInfo.activity = r.notRespondingReport.tag;
   9419             report.anrInfo.cause = r.notRespondingReport.shortMsg;
   9420             report.anrInfo.info = r.notRespondingReport.longMsg;
   9421         }
   9422 
   9423         return report;
   9424     }
   9425 
   9426     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
   9427         // assume our apps are happy - lazy create the list
   9428         List<ActivityManager.ProcessErrorStateInfo> errList = null;
   9429 
   9430         synchronized (this) {
   9431 
   9432             // iterate across all processes
   9433             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   9434                 ProcessRecord app = mLruProcesses.get(i);
   9435                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
   9436                     // This one's in trouble, so we'll generate a report for it
   9437                     // crashes are higher priority (in case there's a crash *and* an anr)
   9438                     ActivityManager.ProcessErrorStateInfo report = null;
   9439                     if (app.crashing) {
   9440                         report = app.crashingReport;
   9441                     } else if (app.notResponding) {
   9442                         report = app.notRespondingReport;
   9443                     }
   9444 
   9445                     if (report != null) {
   9446                         if (errList == null) {
   9447                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
   9448                         }
   9449                         errList.add(report);
   9450                     } else {
   9451                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
   9452                                 " crashing = " + app.crashing +
   9453                                 " notResponding = " + app.notResponding);
   9454                     }
   9455                 }
   9456             }
   9457         }
   9458 
   9459         return errList;
   9460     }
   9461 
   9462     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
   9463         // Lazy instantiation of list
   9464         List<ActivityManager.RunningAppProcessInfo> runList = null;
   9465         synchronized (this) {
   9466             // Iterate across all processes
   9467             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   9468                 ProcessRecord app = mLruProcesses.get(i);
   9469                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
   9470                     // Generate process state info for running application
   9471                     ActivityManager.RunningAppProcessInfo currApp =
   9472                         new ActivityManager.RunningAppProcessInfo(app.processName,
   9473                                 app.pid, app.getPackageList());
   9474                     currApp.uid = app.info.uid;
   9475                     int adj = app.curAdj;
   9476                     if (adj >= EMPTY_APP_ADJ) {
   9477                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
   9478                     } else if (adj >= HIDDEN_APP_MIN_ADJ) {
   9479                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   9480                         currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
   9481                     } else if (adj >= HOME_APP_ADJ) {
   9482                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   9483                         currApp.lru = 0;
   9484                     } else if (adj >= SECONDARY_SERVER_ADJ) {
   9485                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   9486                     } else if (adj >= VISIBLE_APP_ADJ) {
   9487                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
   9488                     } else {
   9489                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
   9490                     }
   9491                     currApp.importanceReasonCode = app.adjTypeCode;
   9492                     if (app.adjSource instanceof ProcessRecord) {
   9493                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
   9494                     } else if (app.adjSource instanceof HistoryRecord) {
   9495                         HistoryRecord r = (HistoryRecord)app.adjSource;
   9496                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
   9497                     }
   9498                     if (app.adjTarget instanceof ComponentName) {
   9499                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
   9500                     }
   9501                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
   9502                     //        + " lru=" + currApp.lru);
   9503                     if (runList == null) {
   9504                         runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
   9505                     }
   9506                     runList.add(currApp);
   9507                 }
   9508             }
   9509         }
   9510         return runList;
   9511     }
   9512 
   9513     public List<ApplicationInfo> getRunningExternalApplications() {
   9514         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
   9515         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
   9516         if (runningApps != null && runningApps.size() > 0) {
   9517             Set<String> extList = new HashSet<String>();
   9518             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
   9519                 if (app.pkgList != null) {
   9520                     for (String pkg : app.pkgList) {
   9521                         extList.add(pkg);
   9522                     }
   9523                 }
   9524             }
   9525             IPackageManager pm = ActivityThread.getPackageManager();
   9526             for (String pkg : extList) {
   9527                 try {
   9528                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
   9529                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
   9530                         retList.add(info);
   9531                     }
   9532                 } catch (RemoteException e) {
   9533                 }
   9534             }
   9535         }
   9536         return retList;
   9537     }
   9538 
   9539     @Override
   9540     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   9541         if (checkCallingPermission(android.Manifest.permission.DUMP)
   9542                 != PackageManager.PERMISSION_GRANTED) {
   9543             pw.println("Permission Denial: can't dump ActivityManager from from pid="
   9544                     + Binder.getCallingPid()
   9545                     + ", uid=" + Binder.getCallingUid()
   9546                     + " without permission "
   9547                     + android.Manifest.permission.DUMP);
   9548             return;
   9549         }
   9550 
   9551         boolean dumpAll = false;
   9552 
   9553         int opti = 0;
   9554         while (opti < args.length) {
   9555             String opt = args[opti];
   9556             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   9557                 break;
   9558             }
   9559             opti++;
   9560             if ("-a".equals(opt)) {
   9561                 dumpAll = true;
   9562             } else if ("-h".equals(opt)) {
   9563                 pw.println("Activity manager dump options:");
   9564                 pw.println("  [-a] [-h] [cmd] ...");
   9565                 pw.println("  cmd may be one of:");
   9566                 pw.println("    activities: activity stack state");
   9567                 pw.println("    broadcasts: broadcast state");
   9568                 pw.println("    intents: pending intent state");
   9569                 pw.println("    processes: process state");
   9570                 pw.println("    providers: content provider state");
   9571                 pw.println("    services: service state");
   9572                 pw.println("    service [name]: service client-side state");
   9573                 return;
   9574             } else {
   9575                 pw.println("Unknown argument: " + opt + "; use -h for help");
   9576             }
   9577         }
   9578 
   9579         // Is the caller requesting to dump a particular piece of data?
   9580         if (opti < args.length) {
   9581             String cmd = args[opti];
   9582             opti++;
   9583             if ("activities".equals(cmd) || "a".equals(cmd)) {
   9584                 synchronized (this) {
   9585                     dumpActivitiesLocked(fd, pw, args, opti, true, true);
   9586                 }
   9587                 return;
   9588             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
   9589                 synchronized (this) {
   9590                     dumpBroadcastsLocked(fd, pw, args, opti, true);
   9591                 }
   9592                 return;
   9593             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
   9594                 synchronized (this) {
   9595                     dumpPendingIntentsLocked(fd, pw, args, opti, true);
   9596                 }
   9597                 return;
   9598             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
   9599                 synchronized (this) {
   9600                     dumpProcessesLocked(fd, pw, args, opti, true);
   9601                 }
   9602                 return;
   9603             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
   9604                 synchronized (this) {
   9605                     dumpProvidersLocked(fd, pw, args, opti, true);
   9606                 }
   9607                 return;
   9608             } else if ("service".equals(cmd)) {
   9609                 dumpService(fd, pw, args, opti, true);
   9610                 return;
   9611             } else if ("services".equals(cmd) || "s".equals(cmd)) {
   9612                 synchronized (this) {
   9613                     dumpServicesLocked(fd, pw, args, opti, true);
   9614                 }
   9615                 return;
   9616             }
   9617         }
   9618 
   9619         // No piece of data specified, dump everything.
   9620         synchronized (this) {
   9621             boolean needSep;
   9622             if (dumpAll) {
   9623                 pw.println("Providers in Current Activity Manager State:");
   9624             }
   9625             needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
   9626             if (needSep) {
   9627                 pw.println(" ");
   9628             }
   9629             if (dumpAll) {
   9630                 pw.println("-------------------------------------------------------------------------------");
   9631                 pw.println("Broadcasts in Current Activity Manager State:");
   9632             }
   9633             needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
   9634             if (needSep) {
   9635                 pw.println(" ");
   9636             }
   9637             if (dumpAll) {
   9638                 pw.println("-------------------------------------------------------------------------------");
   9639                 pw.println("Services in Current Activity Manager State:");
   9640             }
   9641             needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll);
   9642             if (needSep) {
   9643                 pw.println(" ");
   9644             }
   9645             if (dumpAll) {
   9646                 pw.println("-------------------------------------------------------------------------------");
   9647                 pw.println("PendingIntents in Current Activity Manager State:");
   9648             }
   9649             needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
   9650             if (needSep) {
   9651                 pw.println(" ");
   9652             }
   9653             if (dumpAll) {
   9654                 pw.println("-------------------------------------------------------------------------------");
   9655                 pw.println("Activities in Current Activity Manager State:");
   9656             }
   9657             needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, !dumpAll);
   9658             if (needSep) {
   9659                 pw.println(" ");
   9660             }
   9661             if (dumpAll) {
   9662                 pw.println("-------------------------------------------------------------------------------");
   9663                 pw.println("Processes in Current Activity Manager State:");
   9664             }
   9665             dumpProcessesLocked(fd, pw, args, opti, dumpAll);
   9666         }
   9667     }
   9668 
   9669     boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   9670             int opti, boolean dumpAll, boolean needHeader) {
   9671         if (needHeader) {
   9672             pw.println("  Activity stack:");
   9673         }
   9674         dumpHistoryList(pw, mHistory, "  ", "Hist", true);
   9675         pw.println(" ");
   9676         pw.println("  Running activities (most recent first):");
   9677         dumpHistoryList(pw, mLRUActivities, "  ", "Run", false);
   9678         if (mWaitingVisibleActivities.size() > 0) {
   9679             pw.println(" ");
   9680             pw.println("  Activities waiting for another to become visible:");
   9681             dumpHistoryList(pw, mWaitingVisibleActivities, "  ", "Wait", false);
   9682         }
   9683         if (mStoppingActivities.size() > 0) {
   9684             pw.println(" ");
   9685             pw.println("  Activities waiting to stop:");
   9686             dumpHistoryList(pw, mStoppingActivities, "  ", "Stop", false);
   9687         }
   9688         if (mFinishingActivities.size() > 0) {
   9689             pw.println(" ");
   9690             pw.println("  Activities waiting to finish:");
   9691             dumpHistoryList(pw, mFinishingActivities, "  ", "Fin", false);
   9692         }
   9693 
   9694         pw.println(" ");
   9695         pw.println("  mPausingActivity: " + mPausingActivity);
   9696         pw.println("  mResumedActivity: " + mResumedActivity);
   9697         pw.println("  mFocusedActivity: " + mFocusedActivity);
   9698         pw.println("  mLastPausedActivity: " + mLastPausedActivity);
   9699 
   9700         if (dumpAll && mRecentTasks.size() > 0) {
   9701             pw.println(" ");
   9702             pw.println("Recent tasks in Current Activity Manager State:");
   9703 
   9704             final int N = mRecentTasks.size();
   9705             for (int i=0; i<N; i++) {
   9706                 TaskRecord tr = mRecentTasks.get(i);
   9707                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
   9708                         pw.println(tr);
   9709                 mRecentTasks.get(i).dump(pw, "    ");
   9710             }
   9711         }
   9712 
   9713         pw.println(" ");
   9714         pw.println("  mCurTask: " + mCurTask);
   9715 
   9716         return true;
   9717     }
   9718 
   9719     boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   9720             int opti, boolean dumpAll) {
   9721         boolean needSep = false;
   9722         int numPers = 0;
   9723 
   9724         if (dumpAll) {
   9725             for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
   9726                 final int NA = procs.size();
   9727                 for (int ia=0; ia<NA; ia++) {
   9728                     if (!needSep) {
   9729                         pw.println("  All known processes:");
   9730                         needSep = true;
   9731                     }
   9732                     ProcessRecord r = procs.valueAt(ia);
   9733                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
   9734                         pw.print(" UID "); pw.print(procs.keyAt(ia));
   9735                         pw.print(" "); pw.println(r);
   9736                     r.dump(pw, "    ");
   9737                     if (r.persistent) {
   9738                         numPers++;
   9739                     }
   9740                 }
   9741             }
   9742         }
   9743 
   9744         if (mLruProcesses.size() > 0) {
   9745             if (needSep) pw.println(" ");
   9746             needSep = true;
   9747             pw.println("  Running processes (most recent first):");
   9748             dumpProcessList(pw, this, mLruProcesses, "    ",
   9749                     "App ", "PERS", true);
   9750             needSep = true;
   9751         }
   9752 
   9753         synchronized (mPidsSelfLocked) {
   9754             if (mPidsSelfLocked.size() > 0) {
   9755                 if (needSep) pw.println(" ");
   9756                 needSep = true;
   9757                 pw.println("  PID mappings:");
   9758                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   9759                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
   9760                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
   9761                 }
   9762             }
   9763         }
   9764 
   9765         if (mForegroundProcesses.size() > 0) {
   9766             if (needSep) pw.println(" ");
   9767             needSep = true;
   9768             pw.println("  Foreground Processes:");
   9769             for (int i=0; i<mForegroundProcesses.size(); i++) {
   9770                 pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
   9771                         pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
   9772             }
   9773         }
   9774 
   9775         if (mPersistentStartingProcesses.size() > 0) {
   9776             if (needSep) pw.println(" ");
   9777             needSep = true;
   9778             pw.println("  Persisent processes that are starting:");
   9779             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
   9780                     "Starting Norm", "Restarting PERS", false);
   9781         }
   9782 
   9783         if (mStartingProcesses.size() > 0) {
   9784             if (needSep) pw.println(" ");
   9785             needSep = true;
   9786             pw.println("  Processes that are starting:");
   9787             dumpProcessList(pw, this, mStartingProcesses, "    ",
   9788                     "Starting Norm", "Starting PERS", false);
   9789         }
   9790 
   9791         if (mRemovedProcesses.size() > 0) {
   9792             if (needSep) pw.println(" ");
   9793             needSep = true;
   9794             pw.println("  Processes that are being removed:");
   9795             dumpProcessList(pw, this, mRemovedProcesses, "    ",
   9796                     "Removed Norm", "Removed PERS", false);
   9797         }
   9798 
   9799         if (mProcessesOnHold.size() > 0) {
   9800             if (needSep) pw.println(" ");
   9801             needSep = true;
   9802             pw.println("  Processes that are on old until the system is ready:");
   9803             dumpProcessList(pw, this, mProcessesOnHold, "    ",
   9804                     "OnHold Norm", "OnHold PERS", false);
   9805         }
   9806 
   9807         if (mProcessesToGc.size() > 0) {
   9808             if (needSep) pw.println(" ");
   9809             needSep = true;
   9810             pw.println("  Processes that are waiting to GC:");
   9811             long now = SystemClock.uptimeMillis();
   9812             for (int i=0; i<mProcessesToGc.size(); i++) {
   9813                 ProcessRecord proc = mProcessesToGc.get(i);
   9814                 pw.print("    Process "); pw.println(proc);
   9815                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
   9816                         pw.print(", last gced=");
   9817                         pw.print(now-proc.lastRequestedGc);
   9818                         pw.print(" ms ago, last lowMem=");
   9819                         pw.print(now-proc.lastLowMemory);
   9820                         pw.println(" ms ago");
   9821 
   9822             }
   9823         }
   9824 
   9825         if (mProcessCrashTimes.getMap().size() > 0) {
   9826             if (needSep) pw.println(" ");
   9827             needSep = true;
   9828             pw.println("  Time since processes crashed:");
   9829             long now = SystemClock.uptimeMillis();
   9830             for (Map.Entry<String, SparseArray<Long>> procs
   9831                     : mProcessCrashTimes.getMap().entrySet()) {
   9832                 SparseArray<Long> uids = procs.getValue();
   9833                 final int N = uids.size();
   9834                 for (int i=0; i<N; i++) {
   9835                     pw.print("    Process "); pw.print(procs.getKey());
   9836                             pw.print(" uid "); pw.print(uids.keyAt(i));
   9837                             pw.print(": last crashed ");
   9838                             pw.print((now-uids.valueAt(i)));
   9839                             pw.println(" ms ago");
   9840                 }
   9841             }
   9842         }
   9843 
   9844         if (mBadProcesses.getMap().size() > 0) {
   9845             if (needSep) pw.println(" ");
   9846             needSep = true;
   9847             pw.println("  Bad processes:");
   9848             for (Map.Entry<String, SparseArray<Long>> procs
   9849                     : mBadProcesses.getMap().entrySet()) {
   9850                 SparseArray<Long> uids = procs.getValue();
   9851                 final int N = uids.size();
   9852                 for (int i=0; i<N; i++) {
   9853                     pw.print("    Bad process "); pw.print(procs.getKey());
   9854                             pw.print(" uid "); pw.print(uids.keyAt(i));
   9855                             pw.print(": crashed at time ");
   9856                             pw.println(uids.valueAt(i));
   9857                 }
   9858             }
   9859         }
   9860 
   9861         pw.println(" ");
   9862         pw.println("  mHomeProcess: " + mHomeProcess);
   9863         pw.println("  mConfiguration: " + mConfiguration);
   9864         pw.println("  mConfigWillChange: " + mConfigWillChange);
   9865         pw.println("  mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
   9866         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
   9867                 || mOrigWaitForDebugger) {
   9868             pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
   9869                     + " mDebugTransient=" + mDebugTransient
   9870                     + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
   9871         }
   9872         if (mAlwaysFinishActivities || mController != null) {
   9873             pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
   9874                     + " mController=" + mController);
   9875         }
   9876         if (dumpAll) {
   9877             pw.println("  Total persistent processes: " + numPers);
   9878             pw.println("  mStartRunning=" + mStartRunning
   9879                     + " mSystemReady=" + mSystemReady
   9880                     + " mBooting=" + mBooting
   9881                     + " mBooted=" + mBooted
   9882                     + " mFactoryTest=" + mFactoryTest);
   9883             pw.println("  mGoingToSleep=" + mGoingToSleep);
   9884             pw.println("  mLaunchingActivity=" + mLaunchingActivity);
   9885             pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
   9886         }
   9887 
   9888         return true;
   9889     }
   9890 
   9891     /**
   9892      * There are three ways to call this:
   9893      *  - no service specified: dump all the services
   9894      *  - a flattened component name that matched an existing service was specified as the
   9895      *    first arg: dump that one service
   9896      *  - the first arg isn't the flattened component name of an existing service:
   9897      *    dump all services whose component contains the first arg as a substring
   9898      */
   9899     protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args,
   9900             int opti, boolean dumpAll) {
   9901         String[] newArgs;
   9902         String componentNameString;
   9903         ServiceRecord r;
   9904         if (opti >= args.length) {
   9905             componentNameString = null;
   9906             newArgs = EMPTY_STRING_ARRAY;
   9907             r = null;
   9908         } else {
   9909             componentNameString = args[opti];
   9910             opti++;
   9911             ComponentName componentName = ComponentName.unflattenFromString(componentNameString);
   9912             r = componentName != null ? mServices.get(componentName) : null;
   9913             newArgs = new String[args.length - opti];
   9914             if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   9915         }
   9916 
   9917         if (r != null) {
   9918             dumpService(fd, pw, r, newArgs);
   9919         } else {
   9920             for (ServiceRecord r1 : mServices.values()) {
   9921                 if (componentNameString == null
   9922                         || r1.name.flattenToString().contains(componentNameString)) {
   9923                     dumpService(fd, pw, r1, newArgs);
   9924                 }
   9925             }
   9926         }
   9927     }
   9928 
   9929     /**
   9930      * Invokes IApplicationThread.dumpService() on the thread of the specified service if
   9931      * there is a thread associated with the service.
   9932      */
   9933     private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args) {
   9934         pw.println("  Service " + r.name.flattenToString());
   9935         if (r.app != null && r.app.thread != null) {
   9936             try {
   9937                 // flush anything that is already in the PrintWriter since the thread is going
   9938                 // to write to the file descriptor directly
   9939                 pw.flush();
   9940                 r.app.thread.dumpService(fd, r, args);
   9941                 pw.print("\n");
   9942             } catch (RemoteException e) {
   9943                 pw.println("got a RemoteException while dumping the service");
   9944             }
   9945         }
   9946     }
   9947 
   9948     boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   9949             int opti, boolean dumpAll) {
   9950         boolean needSep = false;
   9951 
   9952         if (dumpAll) {
   9953             if (mRegisteredReceivers.size() > 0) {
   9954                 pw.println(" ");
   9955                 pw.println("  Registered Receivers:");
   9956                 Iterator it = mRegisteredReceivers.values().iterator();
   9957                 while (it.hasNext()) {
   9958                     ReceiverList r = (ReceiverList)it.next();
   9959                     pw.print("  * "); pw.println(r);
   9960                     r.dump(pw, "    ");
   9961                 }
   9962             }
   9963 
   9964             pw.println(" ");
   9965             pw.println("Receiver Resolver Table:");
   9966             mReceiverResolver.dump(pw, null, "  ", null);
   9967             needSep = true;
   9968         }
   9969 
   9970         if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
   9971                 || mPendingBroadcast != null) {
   9972             if (mParallelBroadcasts.size() > 0) {
   9973                 pw.println(" ");
   9974                 pw.println("  Active broadcasts:");
   9975             }
   9976             for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
   9977                 pw.println("  Broadcast #" + i + ":");
   9978                 mParallelBroadcasts.get(i).dump(pw, "    ");
   9979             }
   9980             if (mOrderedBroadcasts.size() > 0) {
   9981                 pw.println(" ");
   9982                 pw.println("  Active ordered broadcasts:");
   9983             }
   9984             for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
   9985                 pw.println("  Serialized Broadcast #" + i + ":");
   9986                 mOrderedBroadcasts.get(i).dump(pw, "    ");
   9987             }
   9988             pw.println(" ");
   9989             pw.println("  Pending broadcast:");
   9990             if (mPendingBroadcast != null) {
   9991                 mPendingBroadcast.dump(pw, "    ");
   9992             } else {
   9993                 pw.println("    (null)");
   9994             }
   9995             needSep = true;
   9996         }
   9997 
   9998         if (dumpAll) {
   9999             pw.println(" ");
   10000             pw.println("  Historical broadcasts:");
   10001             for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
   10002                 BroadcastRecord r = mBroadcastHistory[i];
   10003                 if (r == null) {
   10004                     break;
   10005                 }
   10006                 pw.println("  Historical Broadcast #" + i + ":");
   10007                 r.dump(pw, "    ");
   10008             }
   10009             needSep = true;
   10010         }
   10011 
   10012         if (mStickyBroadcasts != null) {
   10013             pw.println(" ");
   10014             pw.println("  Sticky broadcasts:");
   10015             StringBuilder sb = new StringBuilder(128);
   10016             for (Map.Entry<String, ArrayList<Intent>> ent
   10017                     : mStickyBroadcasts.entrySet()) {
   10018                 pw.print("  * Sticky action "); pw.print(ent.getKey());
   10019                         pw.println(":");
   10020                 ArrayList<Intent> intents = ent.getValue();
   10021                 final int N = intents.size();
   10022                 for (int i=0; i<N; i++) {
   10023                     sb.setLength(0);
   10024                     sb.append("    Intent: ");
   10025                     intents.get(i).toShortString(sb, true, false);
   10026                     pw.println(sb.toString());
   10027                     Bundle bundle = intents.get(i).getExtras();
   10028                     if (bundle != null) {
   10029                         pw.print("      ");
   10030                         pw.println(bundle.toString());
   10031                     }
   10032                 }
   10033             }
   10034             needSep = true;
   10035         }
   10036 
   10037         if (dumpAll) {
   10038             pw.println(" ");
   10039             pw.println("  mBroadcastsScheduled=" + mBroadcastsScheduled);
   10040             pw.println("  mHandler:");
   10041             mHandler.dump(new PrintWriterPrinter(pw), "    ");
   10042             needSep = true;
   10043         }
   10044 
   10045         return needSep;
   10046     }
   10047 
   10048     boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   10049             int opti, boolean dumpAll) {
   10050         boolean needSep = false;
   10051 
   10052         if (dumpAll) {
   10053             if (mServices.size() > 0) {
   10054                 pw.println("  Active services:");
   10055                 Iterator<ServiceRecord> it = mServices.values().iterator();
   10056                 while (it.hasNext()) {
   10057                     ServiceRecord r = it.next();
   10058                     pw.print("  * "); pw.println(r);
   10059                     r.dump(pw, "    ");
   10060                 }
   10061                 needSep = true;
   10062             }
   10063         }
   10064 
   10065         if (mPendingServices.size() > 0) {
   10066             if (needSep) pw.println(" ");
   10067             pw.println("  Pending services:");
   10068             for (int i=0; i<mPendingServices.size(); i++) {
   10069                 ServiceRecord r = mPendingServices.get(i);
   10070                 pw.print("  * Pending "); pw.println(r);
   10071                 r.dump(pw, "    ");
   10072             }
   10073             needSep = true;
   10074         }
   10075 
   10076         if (mRestartingServices.size() > 0) {
   10077             if (needSep) pw.println(" ");
   10078             pw.println("  Restarting services:");
   10079             for (int i=0; i<mRestartingServices.size(); i++) {
   10080                 ServiceRecord r = mRestartingServices.get(i);
   10081                 pw.print("  * Restarting "); pw.println(r);
   10082                 r.dump(pw, "    ");
   10083             }
   10084             needSep = true;
   10085         }
   10086 
   10087         if (mStoppingServices.size() > 0) {
   10088             if (needSep) pw.println(" ");
   10089             pw.println("  Stopping services:");
   10090             for (int i=0; i<mStoppingServices.size(); i++) {
   10091                 ServiceRecord r = mStoppingServices.get(i);
   10092                 pw.print("  * Stopping "); pw.println(r);
   10093                 r.dump(pw, "    ");
   10094             }
   10095             needSep = true;
   10096         }
   10097 
   10098         if (dumpAll) {
   10099             if (mServiceConnections.size() > 0) {
   10100                 if (needSep) pw.println(" ");
   10101                 pw.println("  Connection bindings to services:");
   10102                 Iterator<ConnectionRecord> it
   10103                         = mServiceConnections.values().iterator();
   10104                 while (it.hasNext()) {
   10105                     ConnectionRecord r = it.next();
   10106                     pw.print("  * "); pw.println(r);
   10107                     r.dump(pw, "    ");
   10108                 }
   10109                 needSep = true;
   10110             }
   10111         }
   10112 
   10113         return needSep;
   10114     }
   10115 
   10116     boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   10117             int opti, boolean dumpAll) {
   10118         boolean needSep = false;
   10119 
   10120         if (dumpAll) {
   10121             if (mProvidersByClass.size() > 0) {
   10122                 if (needSep) pw.println(" ");
   10123                 pw.println("  Published content providers (by class):");
   10124                 Iterator it = mProvidersByClass.entrySet().iterator();
   10125                 while (it.hasNext()) {
   10126                     Map.Entry e = (Map.Entry)it.next();
   10127                     ContentProviderRecord r = (ContentProviderRecord)e.getValue();
   10128                     pw.print("  * "); pw.println(r);
   10129                     r.dump(pw, "    ");
   10130                 }
   10131                 needSep = true;
   10132             }
   10133 
   10134             if (mProvidersByName.size() > 0) {
   10135                 pw.println(" ");
   10136                 pw.println("  Authority to provider mappings:");
   10137                 Iterator it = mProvidersByName.entrySet().iterator();
   10138                 while (it.hasNext()) {
   10139                     Map.Entry e = (Map.Entry)it.next();
   10140                     ContentProviderRecord r = (ContentProviderRecord)e.getValue();
   10141                     pw.print("  "); pw.print(e.getKey()); pw.print(": ");
   10142                             pw.println(r);
   10143                 }
   10144                 needSep = true;
   10145             }
   10146         }
   10147 
   10148         if (mLaunchingProviders.size() > 0) {
   10149             if (needSep) pw.println(" ");
   10150             pw.println("  Launching content providers:");
   10151             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
   10152                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
   10153                         pw.println(mLaunchingProviders.get(i));
   10154             }
   10155             needSep = true;
   10156         }
   10157 
   10158         if (mGrantedUriPermissions.size() > 0) {
   10159             pw.println();
   10160             pw.println("Granted Uri Permissions:");
   10161             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
   10162                 int uid = mGrantedUriPermissions.keyAt(i);
   10163                 HashMap<Uri, UriPermission> perms
   10164                         = mGrantedUriPermissions.valueAt(i);
   10165                 pw.print("  * UID "); pw.print(uid);
   10166                         pw.println(" holds:");
   10167                 for (UriPermission perm : perms.values()) {
   10168                     pw.print("    "); pw.println(perm);
   10169                     perm.dump(pw, "      ");
   10170                 }
   10171             }
   10172             needSep = true;
   10173         }
   10174 
   10175         return needSep;
   10176     }
   10177 
   10178     boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   10179             int opti, boolean dumpAll) {
   10180         boolean needSep = false;
   10181 
   10182         if (dumpAll) {
   10183             if (this.mIntentSenderRecords.size() > 0) {
   10184                 Iterator<WeakReference<PendingIntentRecord>> it
   10185                         = mIntentSenderRecords.values().iterator();
   10186                 while (it.hasNext()) {
   10187                     WeakReference<PendingIntentRecord> ref = it.next();
   10188                     PendingIntentRecord rec = ref != null ? ref.get(): null;
   10189                     needSep = true;
   10190                     if (rec != null) {
   10191                         pw.print("  * "); pw.println(rec);
   10192                         rec.dump(pw, "    ");
   10193                     } else {
   10194                         pw.print("  * "); pw.print(ref);
   10195                     }
   10196                 }
   10197             }
   10198         }
   10199 
   10200         return needSep;
   10201     }
   10202 
   10203     private static final void dumpHistoryList(PrintWriter pw, List list,
   10204             String prefix, String label, boolean complete) {
   10205         TaskRecord lastTask = null;
   10206         for (int i=list.size()-1; i>=0; i--) {
   10207             HistoryRecord r = (HistoryRecord)list.get(i);
   10208             final boolean full = complete || !r.inHistory;
   10209             if (lastTask != r.task) {
   10210                 lastTask = r.task;
   10211                 pw.print(prefix);
   10212                 pw.print(full ? "* " : "  ");
   10213                 pw.println(lastTask);
   10214                 if (full) {
   10215                     lastTask.dump(pw, prefix + "  ");
   10216                 }
   10217             }
   10218             pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
   10219             pw.print(" #"); pw.print(i); pw.print(": ");
   10220             pw.println(r);
   10221             if (full) {
   10222                 r.dump(pw, prefix + "      ");
   10223             }
   10224         }
   10225     }
   10226 
   10227     private static String buildOomTag(String prefix, String space, int val, int base) {
   10228         if (val == base) {
   10229             if (space == null) return prefix;
   10230             return prefix + "  ";
   10231         }
   10232         return prefix + "+" + Integer.toString(val-base);
   10233     }
   10234 
   10235     private static final int dumpProcessList(PrintWriter pw,
   10236             ActivityManagerService service, List list,
   10237             String prefix, String normalLabel, String persistentLabel,
   10238             boolean inclOomAdj) {
   10239         int numPers = 0;
   10240         for (int i=list.size()-1; i>=0; i--) {
   10241             ProcessRecord r = (ProcessRecord)list.get(i);
   10242             if (false) {
   10243                 pw.println(prefix + (r.persistent ? persistentLabel : normalLabel)
   10244                       + " #" + i + ":");
   10245                 r.dump(pw, prefix + "  ");
   10246             } else if (inclOomAdj) {
   10247                 String oomAdj;
   10248                 if (r.setAdj >= EMPTY_APP_ADJ) {
   10249                     oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ);
   10250                 } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
   10251                     oomAdj = buildOomTag("bak", "  ", r.setAdj, HIDDEN_APP_MIN_ADJ);
   10252                 } else if (r.setAdj >= HOME_APP_ADJ) {
   10253                     oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ);
   10254                 } else if (r.setAdj >= SECONDARY_SERVER_ADJ) {
   10255                     oomAdj = buildOomTag("svc", "  ", r.setAdj, SECONDARY_SERVER_ADJ);
   10256                 } else if (r.setAdj >= BACKUP_APP_ADJ) {
   10257                     oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ);
   10258                 } else if (r.setAdj >= VISIBLE_APP_ADJ) {
   10259                     oomAdj = buildOomTag("vis  ", null, r.setAdj, VISIBLE_APP_ADJ);
   10260                 } else if (r.setAdj >= FOREGROUND_APP_ADJ) {
   10261                     oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ);
   10262                 } else if (r.setAdj >= CORE_SERVER_ADJ) {
   10263                     oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ);
   10264                 } else if (r.setAdj >= SYSTEM_ADJ) {
   10265                     oomAdj = buildOomTag("sys  ", null, r.setAdj, SYSTEM_ADJ);
   10266                 } else {
   10267                     oomAdj = Integer.toString(r.setAdj);
   10268                 }
   10269                 String schedGroup;
   10270                 switch (r.setSchedGroup) {
   10271                     case Process.THREAD_GROUP_BG_NONINTERACTIVE:
   10272                         schedGroup = "B";
   10273                         break;
   10274                     case Process.THREAD_GROUP_DEFAULT:
   10275                         schedGroup = "F";
   10276                         break;
   10277                     default:
   10278                         schedGroup = Integer.toString(r.setSchedGroup);
   10279                         break;
   10280                 }
   10281                 pw.println(String.format("%s%s #%2d: adj=%s/%s %s (%s)",
   10282                         prefix, (r.persistent ? persistentLabel : normalLabel),
   10283                         i, oomAdj, schedGroup, r.toShortString(), r.adjType));
   10284                 if (r.adjSource != null || r.adjTarget != null) {
   10285                     pw.println(prefix + "          " + r.adjTarget
   10286                             + "<=" + r.adjSource);
   10287                 }
   10288             } else {
   10289                 pw.println(String.format("%s%s #%2d: %s",
   10290                         prefix, (r.persistent ? persistentLabel : normalLabel),
   10291                         i, r.toString()));
   10292             }
   10293             if (r.persistent) {
   10294                 numPers++;
   10295             }
   10296         }
   10297         return numPers;
   10298     }
   10299 
   10300     static final void dumpApplicationMemoryUsage(FileDescriptor fd,
   10301             PrintWriter pw, List list, String prefix, String[] args) {
   10302         final boolean isCheckinRequest = scanArgs(args, "--checkin");
   10303         long uptime = SystemClock.uptimeMillis();
   10304         long realtime = SystemClock.elapsedRealtime();
   10305 
   10306         if (isCheckinRequest) {
   10307             // short checkin version
   10308             pw.println(uptime + "," + realtime);
   10309             pw.flush();
   10310         } else {
   10311             pw.println("Applications Memory Usage (kB):");
   10312             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   10313         }
   10314         for (int i = list.size() - 1 ; i >= 0 ; i--) {
   10315             ProcessRecord r = (ProcessRecord)list.get(i);
   10316             if (r.thread != null) {
   10317                 if (!isCheckinRequest) {
   10318                     pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
   10319                     pw.flush();
   10320                 }
   10321                 try {
   10322                     r.thread.asBinder().dump(fd, args);
   10323                 } catch (RemoteException e) {
   10324                     if (!isCheckinRequest) {
   10325                         pw.println("Got RemoteException!");
   10326                         pw.flush();
   10327                     }
   10328                 }
   10329             }
   10330         }
   10331     }
   10332 
   10333     /**
   10334      * Searches array of arguments for the specified string
   10335      * @param args array of argument strings
   10336      * @param value value to search for
   10337      * @return true if the value is contained in the array
   10338      */
   10339     private static boolean scanArgs(String[] args, String value) {
   10340         if (args != null) {
   10341             for (String arg : args) {
   10342                 if (value.equals(arg)) {
   10343                     return true;
   10344                 }
   10345             }
   10346         }
   10347         return false;
   10348     }
   10349 
   10350     private final int indexOfTokenLocked(IBinder token) {
   10351         int count = mHistory.size();
   10352 
   10353         // convert the token to an entry in the history.
   10354         int index = -1;
   10355         for (int i=count-1; i>=0; i--) {
   10356             Object o = mHistory.get(i);
   10357             if (o == token) {
   10358                 index = i;
   10359                 break;
   10360             }
   10361         }
   10362 
   10363         return index;
   10364     }
   10365 
   10366     private final void killServicesLocked(ProcessRecord app,
   10367             boolean allowRestart) {
   10368         // Report disconnected services.
   10369         if (false) {
   10370             // XXX we are letting the client link to the service for
   10371             // death notifications.
   10372             if (app.services.size() > 0) {
   10373                 Iterator it = app.services.iterator();
   10374                 while (it.hasNext()) {
   10375                     ServiceRecord r = (ServiceRecord)it.next();
   10376                     if (r.connections.size() > 0) {
   10377                         Iterator<ConnectionRecord> jt
   10378                                 = r.connections.values().iterator();
   10379                         while (jt.hasNext()) {
   10380                             ConnectionRecord c = jt.next();
   10381                             if (c.binding.client != app) {
   10382                                 try {
   10383                                     //c.conn.connected(r.className, null);
   10384                                 } catch (Exception e) {
   10385                                     // todo: this should be asynchronous!
   10386                                     Slog.w(TAG, "Exception thrown disconnected servce "
   10387                                           + r.shortName
   10388                                           + " from app " + app.processName, e);
   10389                                 }
   10390                             }
   10391                         }
   10392                     }
   10393                 }
   10394             }
   10395         }
   10396 
   10397         // Clean up any connections this application has to other services.
   10398         if (app.connections.size() > 0) {
   10399             Iterator<ConnectionRecord> it = app.connections.iterator();
   10400             while (it.hasNext()) {
   10401                 ConnectionRecord r = it.next();
   10402                 removeConnectionLocked(r, app, null);
   10403             }
   10404         }
   10405         app.connections.clear();
   10406 
   10407         if (app.services.size() != 0) {
   10408             // Any services running in the application need to be placed
   10409             // back in the pending list.
   10410             Iterator it = app.services.iterator();
   10411             while (it.hasNext()) {
   10412                 ServiceRecord sr = (ServiceRecord)it.next();
   10413                 synchronized (sr.stats.getBatteryStats()) {
   10414                     sr.stats.stopLaunchedLocked();
   10415                 }
   10416                 sr.app = null;
   10417                 sr.executeNesting = 0;
   10418                 mStoppingServices.remove(sr);
   10419 
   10420                 boolean hasClients = sr.bindings.size() > 0;
   10421                 if (hasClients) {
   10422                     Iterator<IntentBindRecord> bindings
   10423                             = sr.bindings.values().iterator();
   10424                     while (bindings.hasNext()) {
   10425                         IntentBindRecord b = bindings.next();
   10426                         if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
   10427                                 + ": shouldUnbind=" + b.hasBound);
   10428                         b.binder = null;
   10429                         b.requested = b.received = b.hasBound = false;
   10430                     }
   10431                 }
   10432 
   10433                 if (sr.crashCount >= 2) {
   10434                     Slog.w(TAG, "Service crashed " + sr.crashCount
   10435                             + " times, stopping: " + sr);
   10436                     EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
   10437                             sr.crashCount, sr.shortName, app.pid);
   10438                     bringDownServiceLocked(sr, true);
   10439                 } else if (!allowRestart) {
   10440                     bringDownServiceLocked(sr, true);
   10441                 } else {
   10442                     boolean canceled = scheduleServiceRestartLocked(sr, true);
   10443 
   10444                     // Should the service remain running?  Note that in the
   10445                     // extreme case of so many attempts to deliver a command
   10446                     // that it failed, that we also will stop it here.
   10447                     if (sr.startRequested && (sr.stopIfKilled || canceled)) {
   10448                         if (sr.pendingStarts.size() == 0) {
   10449                             sr.startRequested = false;
   10450                             if (!hasClients) {
   10451                                 // Whoops, no reason to restart!
   10452                                 bringDownServiceLocked(sr, true);
   10453                             }
   10454                         }
   10455                     }
   10456                 }
   10457             }
   10458 
   10459             if (!allowRestart) {
   10460                 app.services.clear();
   10461             }
   10462         }
   10463 
   10464         // Make sure we have no more records on the stopping list.
   10465         int i = mStoppingServices.size();
   10466         while (i > 0) {
   10467             i--;
   10468             ServiceRecord sr = mStoppingServices.get(i);
   10469             if (sr.app == app) {
   10470                 mStoppingServices.remove(i);
   10471             }
   10472         }
   10473 
   10474         app.executingServices.clear();
   10475     }
   10476 
   10477     private final void removeDyingProviderLocked(ProcessRecord proc,
   10478             ContentProviderRecord cpr) {
   10479         synchronized (cpr) {
   10480             cpr.launchingApp = null;
   10481             cpr.notifyAll();
   10482         }
   10483 
   10484         mProvidersByClass.remove(cpr.info.name);
   10485         String names[] = cpr.info.authority.split(";");
   10486         for (int j = 0; j < names.length; j++) {
   10487             mProvidersByName.remove(names[j]);
   10488         }
   10489 
   10490         Iterator<ProcessRecord> cit = cpr.clients.iterator();
   10491         while (cit.hasNext()) {
   10492             ProcessRecord capp = cit.next();
   10493             if (!capp.persistent && capp.thread != null
   10494                     && capp.pid != 0
   10495                     && capp.pid != MY_PID) {
   10496                 Slog.i(TAG, "Kill " + capp.processName
   10497                         + " (pid " + capp.pid + "): provider " + cpr.info.name
   10498                         + " in dying process " + proc.processName);
   10499                 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
   10500                         capp.processName, capp.setAdj, "dying provider " + proc.processName);
   10501                 Process.killProcess(capp.pid);
   10502             }
   10503         }
   10504 
   10505         mLaunchingProviders.remove(cpr);
   10506     }
   10507 
   10508     /**
   10509      * Main code for cleaning up a process when it has gone away.  This is
   10510      * called both as a result of the process dying, or directly when stopping
   10511      * a process when running in single process mode.
   10512      */
   10513     private final void cleanUpApplicationRecordLocked(ProcessRecord app,
   10514             boolean restarting, int index) {
   10515         if (index >= 0) {
   10516             mLruProcesses.remove(index);
   10517         }
   10518 
   10519         mProcessesToGc.remove(app);
   10520 
   10521         // Dismiss any open dialogs.
   10522         if (app.crashDialog != null) {
   10523             app.crashDialog.dismiss();
   10524             app.crashDialog = null;
   10525         }
   10526         if (app.anrDialog != null) {
   10527             app.anrDialog.dismiss();
   10528             app.anrDialog = null;
   10529         }
   10530         if (app.waitDialog != null) {
   10531             app.waitDialog.dismiss();
   10532             app.waitDialog = null;
   10533         }
   10534 
   10535         app.crashing = false;
   10536         app.notResponding = false;
   10537 
   10538         app.resetPackageList();
   10539         app.thread = null;
   10540         app.forcingToForeground = null;
   10541         app.foregroundServices = false;
   10542 
   10543         killServicesLocked(app, true);
   10544 
   10545         boolean restart = false;
   10546 
   10547         int NL = mLaunchingProviders.size();
   10548 
   10549         // Remove published content providers.
   10550         if (!app.pubProviders.isEmpty()) {
   10551             Iterator it = app.pubProviders.values().iterator();
   10552             while (it.hasNext()) {
   10553                 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
   10554                 cpr.provider = null;
   10555                 cpr.app = null;
   10556 
   10557                 // See if someone is waiting for this provider...  in which
   10558                 // case we don't remove it, but just let it restart.
   10559                 int i = 0;
   10560                 if (!app.bad) {
   10561                     for (; i<NL; i++) {
   10562                         if (mLaunchingProviders.get(i) == cpr) {
   10563                             restart = true;
   10564                             break;
   10565                         }
   10566                     }
   10567                 } else {
   10568                     i = NL;
   10569                 }
   10570 
   10571                 if (i >= NL) {
   10572                     removeDyingProviderLocked(app, cpr);
   10573                     NL = mLaunchingProviders.size();
   10574                 }
   10575             }
   10576             app.pubProviders.clear();
   10577         }
   10578 
   10579         // Take care of any launching providers waiting for this process.
   10580         if (checkAppInLaunchingProvidersLocked(app, false)) {
   10581             restart = true;
   10582         }
   10583 
   10584         // Unregister from connected content providers.
   10585         if (!app.conProviders.isEmpty()) {
   10586             Iterator it = app.conProviders.keySet().iterator();
   10587             while (it.hasNext()) {
   10588                 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
   10589                 cpr.clients.remove(app);
   10590             }
   10591             app.conProviders.clear();
   10592         }
   10593 
   10594         // At this point there may be remaining entries in mLaunchingProviders
   10595         // where we were the only one waiting, so they are no longer of use.
   10596         // Look for these and clean up if found.
   10597         // XXX Commented out for now.  Trying to figure out a way to reproduce
   10598         // the actual situation to identify what is actually going on.
   10599         if (false) {
   10600             for (int i=0; i<NL; i++) {
   10601                 ContentProviderRecord cpr = (ContentProviderRecord)
   10602                         mLaunchingProviders.get(i);
   10603                 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
   10604                     synchronized (cpr) {
   10605                         cpr.launchingApp = null;
   10606                         cpr.notifyAll();
   10607                     }
   10608                 }
   10609             }
   10610         }
   10611 
   10612         skipCurrentReceiverLocked(app);
   10613 
   10614         // Unregister any receivers.
   10615         if (app.receivers.size() > 0) {
   10616             Iterator<ReceiverList> it = app.receivers.iterator();
   10617             while (it.hasNext()) {
   10618                 removeReceiverLocked(it.next());
   10619             }
   10620             app.receivers.clear();
   10621         }
   10622 
   10623         // If the app is undergoing backup, tell the backup manager about it
   10624         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
   10625             if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
   10626             try {
   10627                 IBackupManager bm = IBackupManager.Stub.asInterface(
   10628                         ServiceManager.getService(Context.BACKUP_SERVICE));
   10629                 bm.agentDisconnected(app.info.packageName);
   10630             } catch (RemoteException e) {
   10631                 // can't happen; backup manager is local
   10632             }
   10633         }
   10634 
   10635         // If the caller is restarting this app, then leave it in its
   10636         // current lists and let the caller take care of it.
   10637         if (restarting) {
   10638             return;
   10639         }
   10640 
   10641         if (!app.persistent) {
   10642             if (DEBUG_PROCESSES) Slog.v(TAG,
   10643                     "Removing non-persistent process during cleanup: " + app);
   10644             mProcessNames.remove(app.processName, app.info.uid);
   10645         } else if (!app.removed) {
   10646             // This app is persistent, so we need to keep its record around.
   10647             // If it is not already on the pending app list, add it there
   10648             // and start a new process for it.
   10649             app.thread = null;
   10650             app.forcingToForeground = null;
   10651             app.foregroundServices = false;
   10652             if (mPersistentStartingProcesses.indexOf(app) < 0) {
   10653                 mPersistentStartingProcesses.add(app);
   10654                 restart = true;
   10655             }
   10656         }
   10657         mProcessesOnHold.remove(app);
   10658 
   10659         if (app == mHomeProcess) {
   10660             mHomeProcess = null;
   10661         }
   10662 
   10663         if (restart) {
   10664             // We have components that still need to be running in the
   10665             // process, so re-launch it.
   10666             mProcessNames.put(app.processName, app.info.uid, app);
   10667             startProcessLocked(app, "restart", app.processName);
   10668         } else if (app.pid > 0 && app.pid != MY_PID) {
   10669             // Goodbye!
   10670             synchronized (mPidsSelfLocked) {
   10671                 mPidsSelfLocked.remove(app.pid);
   10672                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   10673             }
   10674             app.setPid(0);
   10675         }
   10676     }
   10677 
   10678     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
   10679         // Look through the content providers we are waiting to have launched,
   10680         // and if any run in this process then either schedule a restart of
   10681         // the process or kill the client waiting for it if this process has
   10682         // gone bad.
   10683         int NL = mLaunchingProviders.size();
   10684         boolean restart = false;
   10685         for (int i=0; i<NL; i++) {
   10686             ContentProviderRecord cpr = (ContentProviderRecord)
   10687                     mLaunchingProviders.get(i);
   10688             if (cpr.launchingApp == app) {
   10689                 if (!alwaysBad && !app.bad) {
   10690                     restart = true;
   10691                 } else {
   10692                     removeDyingProviderLocked(app, cpr);
   10693                     NL = mLaunchingProviders.size();
   10694                 }
   10695             }
   10696         }
   10697         return restart;
   10698     }
   10699 
   10700     // =========================================================
   10701     // SERVICES
   10702     // =========================================================
   10703 
   10704     ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
   10705         ActivityManager.RunningServiceInfo info =
   10706             new ActivityManager.RunningServiceInfo();
   10707         info.service = r.name;
   10708         if (r.app != null) {
   10709             info.pid = r.app.pid;
   10710         }
   10711         info.uid = r.appInfo.uid;
   10712         info.process = r.processName;
   10713         info.foreground = r.isForeground;
   10714         info.activeSince = r.createTime;
   10715         info.started = r.startRequested;
   10716         info.clientCount = r.connections.size();
   10717         info.crashCount = r.crashCount;
   10718         info.lastActivityTime = r.lastActivity;
   10719         if (r.isForeground) {
   10720             info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
   10721         }
   10722         if (r.startRequested) {
   10723             info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
   10724         }
   10725         if (r.app != null && r.app.pid == MY_PID) {
   10726             info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
   10727         }
   10728         if (r.app != null && r.app.persistent) {
   10729             info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
   10730         }
   10731         for (ConnectionRecord conn : r.connections.values()) {
   10732             if (conn.clientLabel != 0) {
   10733                 info.clientPackage = conn.binding.client.info.packageName;
   10734                 info.clientLabel = conn.clientLabel;
   10735                 break;
   10736             }
   10737         }
   10738         return info;
   10739     }
   10740 
   10741     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
   10742             int flags) {
   10743         synchronized (this) {
   10744             ArrayList<ActivityManager.RunningServiceInfo> res
   10745                     = new ArrayList<ActivityManager.RunningServiceInfo>();
   10746 
   10747             if (mServices.size() > 0) {
   10748                 Iterator<ServiceRecord> it = mServices.values().iterator();
   10749                 while (it.hasNext() && res.size() < maxNum) {
   10750                     res.add(makeRunningServiceInfoLocked(it.next()));
   10751                 }
   10752             }
   10753 
   10754             for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
   10755                 ServiceRecord r = mRestartingServices.get(i);
   10756                 ActivityManager.RunningServiceInfo info =
   10757                         makeRunningServiceInfoLocked(r);
   10758                 info.restarting = r.nextRestartTime;
   10759                 res.add(info);
   10760             }
   10761 
   10762             return res;
   10763         }
   10764     }
   10765 
   10766     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
   10767         synchronized (this) {
   10768             ServiceRecord r = mServices.get(name);
   10769             if (r != null) {
   10770                 for (ConnectionRecord conn : r.connections.values()) {
   10771                     if (conn.clientIntent != null) {
   10772                         return conn.clientIntent;
   10773                     }
   10774                 }
   10775             }
   10776         }
   10777         return null;
   10778     }
   10779 
   10780     private final ServiceRecord findServiceLocked(ComponentName name,
   10781             IBinder token) {
   10782         ServiceRecord r = mServices.get(name);
   10783         return r == token ? r : null;
   10784     }
   10785 
   10786     private final class ServiceLookupResult {
   10787         final ServiceRecord record;
   10788         final String permission;
   10789 
   10790         ServiceLookupResult(ServiceRecord _record, String _permission) {
   10791             record = _record;
   10792             permission = _permission;
   10793         }
   10794     };
   10795 
   10796     private ServiceLookupResult findServiceLocked(Intent service,
   10797             String resolvedType) {
   10798         ServiceRecord r = null;
   10799         if (service.getComponent() != null) {
   10800             r = mServices.get(service.getComponent());
   10801         }
   10802         if (r == null) {
   10803             Intent.FilterComparison filter = new Intent.FilterComparison(service);
   10804             r = mServicesByIntent.get(filter);
   10805         }
   10806 
   10807         if (r == null) {
   10808             try {
   10809                 ResolveInfo rInfo =
   10810                     ActivityThread.getPackageManager().resolveService(
   10811                             service, resolvedType, 0);
   10812                 ServiceInfo sInfo =
   10813                     rInfo != null ? rInfo.serviceInfo : null;
   10814                 if (sInfo == null) {
   10815                     return null;
   10816                 }
   10817 
   10818                 ComponentName name = new ComponentName(
   10819                         sInfo.applicationInfo.packageName, sInfo.name);
   10820                 r = mServices.get(name);
   10821             } catch (RemoteException ex) {
   10822                 // pm is in same process, this will never happen.
   10823             }
   10824         }
   10825         if (r != null) {
   10826             int callingPid = Binder.getCallingPid();
   10827             int callingUid = Binder.getCallingUid();
   10828             if (checkComponentPermission(r.permission,
   10829                     callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
   10830                     != PackageManager.PERMISSION_GRANTED) {
   10831                 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
   10832                         + " from pid=" + callingPid
   10833                         + ", uid=" + callingUid
   10834                         + " requires " + r.permission);
   10835                 return new ServiceLookupResult(null, r.permission);
   10836             }
   10837             return new ServiceLookupResult(r, null);
   10838         }
   10839         return null;
   10840     }
   10841 
   10842     private class ServiceRestarter implements Runnable {
   10843         private ServiceRecord mService;
   10844 
   10845         void setService(ServiceRecord service) {
   10846             mService = service;
   10847         }
   10848 
   10849         public void run() {
   10850             synchronized(ActivityManagerService.this) {
   10851                 performServiceRestartLocked(mService);
   10852             }
   10853         }
   10854     }
   10855 
   10856     private ServiceLookupResult retrieveServiceLocked(Intent service,
   10857             String resolvedType, int callingPid, int callingUid) {
   10858         ServiceRecord r = null;
   10859         if (service.getComponent() != null) {
   10860             r = mServices.get(service.getComponent());
   10861         }
   10862         Intent.FilterComparison filter = new Intent.FilterComparison(service);
   10863         r = mServicesByIntent.get(filter);
   10864         if (r == null) {
   10865             try {
   10866                 ResolveInfo rInfo =
   10867                     ActivityThread.getPackageManager().resolveService(
   10868                             service, resolvedType, STOCK_PM_FLAGS);
   10869                 ServiceInfo sInfo =
   10870                     rInfo != null ? rInfo.serviceInfo : null;
   10871                 if (sInfo == null) {
   10872                     Slog.w(TAG, "Unable to start service " + service +
   10873                           ": not found");
   10874                     return null;
   10875                 }
   10876 
   10877                 ComponentName name = new ComponentName(
   10878                         sInfo.applicationInfo.packageName, sInfo.name);
   10879                 r = mServices.get(name);
   10880                 if (r == null) {
   10881                     filter = new Intent.FilterComparison(service.cloneFilter());
   10882                     ServiceRestarter res = new ServiceRestarter();
   10883                     BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   10884                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   10885                     synchronized (stats) {
   10886                         ss = stats.getServiceStatsLocked(
   10887                                 sInfo.applicationInfo.uid, sInfo.packageName,
   10888                                 sInfo.name);
   10889                     }
   10890                     r = new ServiceRecord(this, ss, name, filter, sInfo, res);
   10891                     res.setService(r);
   10892                     mServices.put(name, r);
   10893                     mServicesByIntent.put(filter, r);
   10894 
   10895                     // Make sure this component isn't in the pending list.
   10896                     int N = mPendingServices.size();
   10897                     for (int i=0; i<N; i++) {
   10898                         ServiceRecord pr = mPendingServices.get(i);
   10899                         if (pr.name.equals(name)) {
   10900                             mPendingServices.remove(i);
   10901                             i--;
   10902                             N--;
   10903                         }
   10904                     }
   10905                 }
   10906             } catch (RemoteException ex) {
   10907                 // pm is in same process, this will never happen.
   10908             }
   10909         }
   10910         if (r != null) {
   10911             if (checkComponentPermission(r.permission,
   10912                     callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
   10913                     != PackageManager.PERMISSION_GRANTED) {
   10914                 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
   10915                         + " from pid=" + Binder.getCallingPid()
   10916                         + ", uid=" + Binder.getCallingUid()
   10917                         + " requires " + r.permission);
   10918                 return new ServiceLookupResult(null, r.permission);
   10919             }
   10920             return new ServiceLookupResult(r, null);
   10921         }
   10922         return null;
   10923     }
   10924 
   10925     private final void bumpServiceExecutingLocked(ServiceRecord r) {
   10926         long now = SystemClock.uptimeMillis();
   10927         if (r.executeNesting == 0 && r.app != null) {
   10928             if (r.app.executingServices.size() == 0) {
   10929                 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   10930                 msg.obj = r.app;
   10931                 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
   10932             }
   10933             r.app.executingServices.add(r);
   10934         }
   10935         r.executeNesting++;
   10936         r.executingStart = now;
   10937     }
   10938 
   10939     private final void sendServiceArgsLocked(ServiceRecord r,
   10940             boolean oomAdjusted) {
   10941         final int N = r.pendingStarts.size();
   10942         if (N == 0) {
   10943             return;
   10944         }
   10945 
   10946         int i = 0;
   10947         while (i < N) {
   10948             try {
   10949                 ServiceRecord.StartItem si = r.pendingStarts.get(i);
   10950                 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to service: "
   10951                         + r.name + " " + r.intent + " args=" + si.intent);
   10952                 if (si.intent == null && N > 1) {
   10953                     // If somehow we got a dummy start at the front, then
   10954                     // just drop it here.
   10955                     i++;
   10956                     continue;
   10957                 }
   10958                 bumpServiceExecutingLocked(r);
   10959                 if (!oomAdjusted) {
   10960                     oomAdjusted = true;
   10961                     updateOomAdjLocked(r.app);
   10962                 }
   10963                 int flags = 0;
   10964                 if (si.deliveryCount > 0) {
   10965                     flags |= Service.START_FLAG_RETRY;
   10966                 }
   10967                 if (si.doneExecutingCount > 0) {
   10968                     flags |= Service.START_FLAG_REDELIVERY;
   10969                 }
   10970                 r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent);
   10971                 si.deliveredTime = SystemClock.uptimeMillis();
   10972                 r.deliveredStarts.add(si);
   10973                 si.deliveryCount++;
   10974                 i++;
   10975             } catch (RemoteException e) {
   10976                 // Remote process gone...  we'll let the normal cleanup take
   10977                 // care of this.
   10978                 break;
   10979             } catch (Exception e) {
   10980                 Slog.w(TAG, "Unexpected exception", e);
   10981                 break;
   10982             }
   10983         }
   10984         if (i == N) {
   10985             r.pendingStarts.clear();
   10986         } else {
   10987             while (i > 0) {
   10988                 i--;
   10989                 r.pendingStarts.remove(i);
   10990             }
   10991         }
   10992     }
   10993 
   10994     private final boolean requestServiceBindingLocked(ServiceRecord r,
   10995             IntentBindRecord i, boolean rebind) {
   10996         if (r.app == null || r.app.thread == null) {
   10997             // If service is not currently running, can't yet bind.
   10998             return false;
   10999         }
   11000         if ((!i.requested || rebind) && i.apps.size() > 0) {
   11001             try {
   11002                 bumpServiceExecutingLocked(r);
   11003                 if (DEBUG_SERVICE) Slog.v(TAG, "Connecting binding " + i
   11004                         + ": shouldUnbind=" + i.hasBound);
   11005                 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
   11006                 if (!rebind) {
   11007                     i.requested = true;
   11008                 }
   11009                 i.hasBound = true;
   11010                 i.doRebind = false;
   11011             } catch (RemoteException e) {
   11012                 return false;
   11013             }
   11014         }
   11015         return true;
   11016     }
   11017 
   11018     private final void requestServiceBindingsLocked(ServiceRecord r) {
   11019         Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
   11020         while (bindings.hasNext()) {
   11021             IntentBindRecord i = bindings.next();
   11022             if (!requestServiceBindingLocked(r, i, false)) {
   11023                 break;
   11024             }
   11025         }
   11026     }
   11027 
   11028     private final void realStartServiceLocked(ServiceRecord r,
   11029             ProcessRecord app) throws RemoteException {
   11030         if (app.thread == null) {
   11031             throw new RemoteException();
   11032         }
   11033 
   11034         r.app = app;
   11035         r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
   11036 
   11037         app.services.add(r);
   11038         bumpServiceExecutingLocked(r);
   11039         updateLruProcessLocked(app, true, true);
   11040 
   11041         boolean created = false;
   11042         try {
   11043             if (DEBUG_SERVICE) Slog.v(TAG, "Scheduling start service: "
   11044                     + r.name + " " + r.intent);
   11045             mStringBuilder.setLength(0);
   11046             r.intent.getIntent().toShortString(mStringBuilder, false, true);
   11047             EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
   11048                     System.identityHashCode(r), r.shortName,
   11049                     mStringBuilder.toString(), r.app.pid);
   11050             synchronized (r.stats.getBatteryStats()) {
   11051                 r.stats.startLaunchedLocked();
   11052             }
   11053             ensurePackageDexOpt(r.serviceInfo.packageName);
   11054             app.thread.scheduleCreateService(r, r.serviceInfo);
   11055             r.postNotification();
   11056             created = true;
   11057         } finally {
   11058             if (!created) {
   11059                 app.services.remove(r);
   11060                 scheduleServiceRestartLocked(r, false);
   11061             }
   11062         }
   11063 
   11064         requestServiceBindingsLocked(r);
   11065 
   11066         // If the service is in the started state, and there are no
   11067         // pending arguments, then fake up one so its onStartCommand() will
   11068         // be called.
   11069         if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
   11070             r.lastStartId++;
   11071             if (r.lastStartId < 1) {
   11072                 r.lastStartId = 1;
   11073             }
   11074             r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, null));
   11075         }
   11076 
   11077         sendServiceArgsLocked(r, true);
   11078     }
   11079 
   11080     private final boolean scheduleServiceRestartLocked(ServiceRecord r,
   11081             boolean allowCancel) {
   11082         boolean canceled = false;
   11083 
   11084         final long now = SystemClock.uptimeMillis();
   11085         long minDuration = SERVICE_RESTART_DURATION;
   11086         long resetTime = SERVICE_RESET_RUN_DURATION;
   11087 
   11088         // Any delivered but not yet finished starts should be put back
   11089         // on the pending list.
   11090         final int N = r.deliveredStarts.size();
   11091         if (N > 0) {
   11092             for (int i=N-1; i>=0; i--) {
   11093                 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
   11094                 if (si.intent == null) {
   11095                     // We'll generate this again if needed.
   11096                 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
   11097                         && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
   11098                     r.pendingStarts.add(0, si);
   11099                     long dur = SystemClock.uptimeMillis() - si.deliveredTime;
   11100                     dur *= 2;
   11101                     if (minDuration < dur) minDuration = dur;
   11102                     if (resetTime < dur) resetTime = dur;
   11103                 } else {
   11104                     Slog.w(TAG, "Canceling start item " + si.intent + " in service "
   11105                             + r.name);
   11106                     canceled = true;
   11107                 }
   11108             }
   11109             r.deliveredStarts.clear();
   11110         }
   11111 
   11112         r.totalRestartCount++;
   11113         if (r.restartDelay == 0) {
   11114             r.restartCount++;
   11115             r.restartDelay = minDuration;
   11116         } else {
   11117             // If it has been a "reasonably long time" since the service
   11118             // was started, then reset our restart duration back to
   11119             // the beginning, so we don't infinitely increase the duration
   11120             // on a service that just occasionally gets killed (which is
   11121             // a normal case, due to process being killed to reclaim memory).
   11122             if (now > (r.restartTime+resetTime)) {
   11123                 r.restartCount = 1;
   11124                 r.restartDelay = minDuration;
   11125             } else {
   11126                 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
   11127                 if (r.restartDelay < minDuration) {
   11128                     r.restartDelay = minDuration;
   11129                 }
   11130             }
   11131         }
   11132 
   11133         r.nextRestartTime = now + r.restartDelay;
   11134 
   11135         // Make sure that we don't end up restarting a bunch of services
   11136         // all at the same time.
   11137         boolean repeat;
   11138         do {
   11139             repeat = false;
   11140             for (int i=mRestartingServices.size()-1; i>=0; i--) {
   11141                 ServiceRecord r2 = mRestartingServices.get(i);
   11142                 if (r2 != r && r.nextRestartTime
   11143                         >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
   11144                         && r.nextRestartTime
   11145                         < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
   11146                     r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
   11147                     r.restartDelay = r.nextRestartTime - now;
   11148                     repeat = true;
   11149                     break;
   11150                 }
   11151             }
   11152         } while (repeat);
   11153 
   11154         if (!mRestartingServices.contains(r)) {
   11155             mRestartingServices.add(r);
   11156         }
   11157 
   11158         r.cancelNotification();
   11159 
   11160         mHandler.removeCallbacks(r.restarter);
   11161         mHandler.postAtTime(r.restarter, r.nextRestartTime);
   11162         r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
   11163         Slog.w(TAG, "Scheduling restart of crashed service "
   11164                 + r.shortName + " in " + r.restartDelay + "ms");
   11165         EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
   11166                 r.shortName, r.restartDelay);
   11167 
   11168         return canceled;
   11169     }
   11170 
   11171     final void performServiceRestartLocked(ServiceRecord r) {
   11172         if (!mRestartingServices.contains(r)) {
   11173             return;
   11174         }
   11175         bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
   11176     }
   11177 
   11178     private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
   11179         if (r.restartDelay == 0) {
   11180             return false;
   11181         }
   11182         r.resetRestartCounter();
   11183         mRestartingServices.remove(r);
   11184         mHandler.removeCallbacks(r.restarter);
   11185         return true;
   11186     }
   11187 
   11188     private final boolean bringUpServiceLocked(ServiceRecord r,
   11189             int intentFlags, boolean whileRestarting) {
   11190         //Slog.i(TAG, "Bring up service:");
   11191         //r.dump("  ");
   11192 
   11193         if (r.app != null && r.app.thread != null) {
   11194             sendServiceArgsLocked(r, false);
   11195             return true;
   11196         }
   11197 
   11198         if (!whileRestarting && r.restartDelay > 0) {
   11199             // If waiting for a restart, then do nothing.
   11200             return true;
   11201         }
   11202 
   11203         if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up service " + r.name
   11204                 + " " + r.intent);
   11205 
   11206         // We are now bringing the service up, so no longer in the
   11207         // restarting state.
   11208         mRestartingServices.remove(r);
   11209 
   11210         final String appName = r.processName;
   11211         ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
   11212         if (app != null && app.thread != null) {
   11213             try {
   11214                 realStartServiceLocked(r, app);
   11215                 return true;
   11216             } catch (RemoteException e) {
   11217                 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
   11218             }
   11219 
   11220             // If a dead object exception was thrown -- fall through to
   11221             // restart the application.
   11222         }
   11223 
   11224         // Not running -- get it started, and enqueue this service record
   11225         // to be executed when the app comes up.
   11226         if (startProcessLocked(appName, r.appInfo, true, intentFlags,
   11227                 "service", r.name, false) == null) {
   11228             Slog.w(TAG, "Unable to launch app "
   11229                     + r.appInfo.packageName + "/"
   11230                     + r.appInfo.uid + " for service "
   11231                     + r.intent.getIntent() + ": process is bad");
   11232             bringDownServiceLocked(r, true);
   11233             return false;
   11234         }
   11235 
   11236         if (!mPendingServices.contains(r)) {
   11237             mPendingServices.add(r);
   11238         }
   11239 
   11240         return true;
   11241     }
   11242 
   11243     private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
   11244         //Slog.i(TAG, "Bring down service:");
   11245         //r.dump("  ");
   11246 
   11247         // Does it still need to run?
   11248         if (!force && r.startRequested) {
   11249             return;
   11250         }
   11251         if (r.connections.size() > 0) {
   11252             if (!force) {
   11253                 // XXX should probably keep a count of the number of auto-create
   11254                 // connections directly in the service.
   11255                 Iterator<ConnectionRecord> it = r.connections.values().iterator();
   11256                 while (it.hasNext()) {
   11257                     ConnectionRecord cr = it.next();
   11258                     if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
   11259                         return;
   11260                     }
   11261                 }
   11262             }
   11263 
   11264             // Report to all of the connections that the service is no longer
   11265             // available.
   11266             Iterator<ConnectionRecord> it = r.connections.values().iterator();
   11267             while (it.hasNext()) {
   11268                 ConnectionRecord c = it.next();
   11269                 try {
   11270                     // todo: shouldn't be a synchronous call!
   11271                     c.conn.connected(r.name, null);
   11272                 } catch (Exception e) {
   11273                     Slog.w(TAG, "Failure disconnecting service " + r.name +
   11274                           " to connection " + c.conn.asBinder() +
   11275                           " (in " + c.binding.client.processName + ")", e);
   11276                 }
   11277             }
   11278         }
   11279 
   11280         // Tell the service that it has been unbound.
   11281         if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
   11282             Iterator<IntentBindRecord> it = r.bindings.values().iterator();
   11283             while (it.hasNext()) {
   11284                 IntentBindRecord ibr = it.next();
   11285                 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
   11286                         + ": hasBound=" + ibr.hasBound);
   11287                 if (r.app != null && r.app.thread != null && ibr.hasBound) {
   11288                     try {
   11289                         bumpServiceExecutingLocked(r);
   11290                         updateOomAdjLocked(r.app);
   11291                         ibr.hasBound = false;
   11292                         r.app.thread.scheduleUnbindService(r,
   11293                                 ibr.intent.getIntent());
   11294                     } catch (Exception e) {
   11295                         Slog.w(TAG, "Exception when unbinding service "
   11296                                 + r.shortName, e);
   11297                         serviceDoneExecutingLocked(r, true);
   11298                     }
   11299                 }
   11300             }
   11301         }
   11302 
   11303         if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down service " + r.name
   11304                  + " " + r.intent);
   11305         EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
   11306                 System.identityHashCode(r), r.shortName,
   11307                 (r.app != null) ? r.app.pid : -1);
   11308 
   11309         mServices.remove(r.name);
   11310         mServicesByIntent.remove(r.intent);
   11311         if (localLOGV) Slog.v(TAG, "BRING DOWN SERVICE: " + r.shortName);
   11312         r.totalRestartCount = 0;
   11313         unscheduleServiceRestartLocked(r);
   11314 
   11315         // Also make sure it is not on the pending list.
   11316         int N = mPendingServices.size();
   11317         for (int i=0; i<N; i++) {
   11318             if (mPendingServices.get(i) == r) {
   11319                 mPendingServices.remove(i);
   11320                 if (DEBUG_SERVICE) Slog.v(
   11321                     TAG, "Removed pending service: " + r.shortName);
   11322                 i--;
   11323                 N--;
   11324             }
   11325         }
   11326 
   11327         r.cancelNotification();
   11328         r.isForeground = false;
   11329         r.foregroundId = 0;
   11330         r.foregroundNoti = null;
   11331 
   11332         // Clear start entries.
   11333         r.deliveredStarts.clear();
   11334         r.pendingStarts.clear();
   11335 
   11336         if (r.app != null) {
   11337             synchronized (r.stats.getBatteryStats()) {
   11338                 r.stats.stopLaunchedLocked();
   11339             }
   11340             r.app.services.remove(r);
   11341             if (r.app.thread != null) {
   11342                 try {
   11343                     if (DEBUG_SERVICE) Slog.v(TAG,
   11344                             "Stopping service: " + r.shortName);
   11345                     bumpServiceExecutingLocked(r);
   11346                     mStoppingServices.add(r);
   11347                     updateOomAdjLocked(r.app);
   11348                     r.app.thread.scheduleStopService(r);
   11349                 } catch (Exception e) {
   11350                     Slog.w(TAG, "Exception when stopping service "
   11351                             + r.shortName, e);
   11352                     serviceDoneExecutingLocked(r, true);
   11353                 }
   11354                 updateServiceForegroundLocked(r.app, false);
   11355             } else {
   11356                 if (DEBUG_SERVICE) Slog.v(
   11357                     TAG, "Removed service that has no process: " + r.shortName);
   11358             }
   11359         } else {
   11360             if (DEBUG_SERVICE) Slog.v(
   11361                 TAG, "Removed service that is not running: " + r.shortName);
   11362         }
   11363     }
   11364 
   11365     ComponentName startServiceLocked(IApplicationThread caller,
   11366             Intent service, String resolvedType,
   11367             int callingPid, int callingUid) {
   11368         synchronized(this) {
   11369             if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
   11370                     + " type=" + resolvedType + " args=" + service.getExtras());
   11371 
   11372             if (caller != null) {
   11373                 final ProcessRecord callerApp = getRecordForAppLocked(caller);
   11374                 if (callerApp == null) {
   11375                     throw new SecurityException(
   11376                             "Unable to find app for caller " + caller
   11377                             + " (pid=" + Binder.getCallingPid()
   11378                             + ") when starting service " + service);
   11379                 }
   11380             }
   11381 
   11382             ServiceLookupResult res =
   11383                 retrieveServiceLocked(service, resolvedType,
   11384                         callingPid, callingUid);
   11385             if (res == null) {
   11386                 return null;
   11387             }
   11388             if (res.record == null) {
   11389                 return new ComponentName("!", res.permission != null
   11390                         ? res.permission : "private to package");
   11391             }
   11392             ServiceRecord r = res.record;
   11393             if (unscheduleServiceRestartLocked(r)) {
   11394                 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: "
   11395                         + r.shortName);
   11396             }
   11397             r.startRequested = true;
   11398             r.callStart = false;
   11399             r.lastStartId++;
   11400             if (r.lastStartId < 1) {
   11401                 r.lastStartId = 1;
   11402             }
   11403             r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, service));
   11404             r.lastActivity = SystemClock.uptimeMillis();
   11405             synchronized (r.stats.getBatteryStats()) {
   11406                 r.stats.startRunningLocked();
   11407             }
   11408             if (!bringUpServiceLocked(r, service.getFlags(), false)) {
   11409                 return new ComponentName("!", "Service process is bad");
   11410             }
   11411             return r.name;
   11412         }
   11413     }
   11414 
   11415     public ComponentName startService(IApplicationThread caller, Intent service,
   11416             String resolvedType) {
   11417         // Refuse possible leaked file descriptors
   11418         if (service != null && service.hasFileDescriptors() == true) {
   11419             throw new IllegalArgumentException("File descriptors passed in Intent");
   11420         }
   11421 
   11422         synchronized(this) {
   11423             final int callingPid = Binder.getCallingPid();
   11424             final int callingUid = Binder.getCallingUid();
   11425             final long origId = Binder.clearCallingIdentity();
   11426             ComponentName res = startServiceLocked(caller, service,
   11427                     resolvedType, callingPid, callingUid);
   11428             Binder.restoreCallingIdentity(origId);
   11429             return res;
   11430         }
   11431     }
   11432 
   11433     ComponentName startServiceInPackage(int uid,
   11434             Intent service, String resolvedType) {
   11435         synchronized(this) {
   11436             final long origId = Binder.clearCallingIdentity();
   11437             ComponentName res = startServiceLocked(null, service,
   11438                     resolvedType, -1, uid);
   11439             Binder.restoreCallingIdentity(origId);
   11440             return res;
   11441         }
   11442     }
   11443 
   11444     public int stopService(IApplicationThread caller, Intent service,
   11445             String resolvedType) {
   11446         // Refuse possible leaked file descriptors
   11447         if (service != null && service.hasFileDescriptors() == true) {
   11448             throw new IllegalArgumentException("File descriptors passed in Intent");
   11449         }
   11450 
   11451         synchronized(this) {
   11452             if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
   11453                     + " type=" + resolvedType);
   11454 
   11455             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   11456             if (caller != null && callerApp == null) {
   11457                 throw new SecurityException(
   11458                         "Unable to find app for caller " + caller
   11459                         + " (pid=" + Binder.getCallingPid()
   11460                         + ") when stopping service " + service);
   11461             }
   11462 
   11463             // If this service is active, make sure it is stopped.
   11464             ServiceLookupResult r = findServiceLocked(service, resolvedType);
   11465             if (r != null) {
   11466                 if (r.record != null) {
   11467                     synchronized (r.record.stats.getBatteryStats()) {
   11468                         r.record.stats.stopRunningLocked();
   11469                     }
   11470                     r.record.startRequested = false;
   11471                     r.record.callStart = false;
   11472                     final long origId = Binder.clearCallingIdentity();
   11473                     bringDownServiceLocked(r.record, false);
   11474                     Binder.restoreCallingIdentity(origId);
   11475                     return 1;
   11476                 }
   11477                 return -1;
   11478             }
   11479         }
   11480 
   11481         return 0;
   11482     }
   11483 
   11484     public IBinder peekService(Intent service, String resolvedType) {
   11485         // Refuse possible leaked file descriptors
   11486         if (service != null && service.hasFileDescriptors() == true) {
   11487             throw new IllegalArgumentException("File descriptors passed in Intent");
   11488         }
   11489 
   11490         IBinder ret = null;
   11491 
   11492         synchronized(this) {
   11493             ServiceLookupResult r = findServiceLocked(service, resolvedType);
   11494 
   11495             if (r != null) {
   11496                 // r.record is null if findServiceLocked() failed the caller permission check
   11497                 if (r.record == null) {
   11498                     throw new SecurityException(
   11499                             "Permission Denial: Accessing service " + r.record.name
   11500                             + " from pid=" + Binder.getCallingPid()
   11501                             + ", uid=" + Binder.getCallingUid()
   11502                             + " requires " + r.permission);
   11503                 }
   11504                 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
   11505                 if (ib != null) {
   11506                     ret = ib.binder;
   11507                 }
   11508             }
   11509         }
   11510 
   11511         return ret;
   11512     }
   11513 
   11514     public boolean stopServiceToken(ComponentName className, IBinder token,
   11515             int startId) {
   11516         synchronized(this) {
   11517             if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
   11518                     + " " + token + " startId=" + startId);
   11519             ServiceRecord r = findServiceLocked(className, token);
   11520             if (r != null) {
   11521                 if (startId >= 0) {
   11522                     // Asked to only stop if done with all work.  Note that
   11523                     // to avoid leaks, we will take this as dropping all
   11524                     // start items up to and including this one.
   11525                     ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
   11526                     if (si != null) {
   11527                         while (r.deliveredStarts.size() > 0) {
   11528                             if (r.deliveredStarts.remove(0) == si) {
   11529                                 break;
   11530                             }
   11531                         }
   11532                     }
   11533 
   11534                     if (r.lastStartId != startId) {
   11535                         return false;
   11536                     }
   11537 
   11538                     if (r.deliveredStarts.size() > 0) {
   11539                         Slog.w(TAG, "stopServiceToken startId " + startId
   11540                                 + " is last, but have " + r.deliveredStarts.size()
   11541                                 + " remaining args");
   11542                     }
   11543                 }
   11544 
   11545                 synchronized (r.stats.getBatteryStats()) {
   11546                     r.stats.stopRunningLocked();
   11547                     r.startRequested = false;
   11548                     r.callStart = false;
   11549                 }
   11550                 final long origId = Binder.clearCallingIdentity();
   11551                 bringDownServiceLocked(r, false);
   11552                 Binder.restoreCallingIdentity(origId);
   11553                 return true;
   11554             }
   11555         }
   11556         return false;
   11557     }
   11558 
   11559     public void setServiceForeground(ComponentName className, IBinder token,
   11560             int id, Notification notification, boolean removeNotification) {
   11561         final long origId = Binder.clearCallingIdentity();
   11562         try {
   11563         synchronized(this) {
   11564             ServiceRecord r = findServiceLocked(className, token);
   11565             if (r != null) {
   11566                 if (id != 0) {
   11567                     if (notification == null) {
   11568                         throw new IllegalArgumentException("null notification");
   11569                     }
   11570                     if (r.foregroundId != id) {
   11571                         r.cancelNotification();
   11572                         r.foregroundId = id;
   11573                     }
   11574                     notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
   11575                     r.foregroundNoti = notification;
   11576                     r.isForeground = true;
   11577                     r.postNotification();
   11578                     if (r.app != null) {
   11579                         updateServiceForegroundLocked(r.app, true);
   11580                     }
   11581                 } else {
   11582                     if (r.isForeground) {
   11583                         r.isForeground = false;
   11584                         if (r.app != null) {
   11585                             updateLruProcessLocked(r.app, false, true);
   11586                             updateServiceForegroundLocked(r.app, true);
   11587                         }
   11588                     }
   11589                     if (removeNotification) {
   11590                         r.cancelNotification();
   11591                         r.foregroundId = 0;
   11592                         r.foregroundNoti = null;
   11593                     }
   11594                 }
   11595             }
   11596         }
   11597         } finally {
   11598             Binder.restoreCallingIdentity(origId);
   11599         }
   11600     }
   11601 
   11602     public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
   11603         boolean anyForeground = false;
   11604         for (ServiceRecord sr : (HashSet<ServiceRecord>)proc.services) {
   11605             if (sr.isForeground) {
   11606                 anyForeground = true;
   11607                 break;
   11608             }
   11609         }
   11610         if (anyForeground != proc.foregroundServices) {
   11611             proc.foregroundServices = anyForeground;
   11612             if (oomAdj) {
   11613                 updateOomAdjLocked();
   11614             }
   11615         }
   11616     }
   11617 
   11618     public int bindService(IApplicationThread caller, IBinder token,
   11619             Intent service, String resolvedType,
   11620             IServiceConnection connection, int flags) {
   11621         // Refuse possible leaked file descriptors
   11622         if (service != null && service.hasFileDescriptors() == true) {
   11623             throw new IllegalArgumentException("File descriptors passed in Intent");
   11624         }
   11625 
   11626         synchronized(this) {
   11627             if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
   11628                     + " type=" + resolvedType + " conn=" + connection.asBinder()
   11629                     + " flags=0x" + Integer.toHexString(flags));
   11630             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   11631             if (callerApp == null) {
   11632                 throw new SecurityException(
   11633                         "Unable to find app for caller " + caller
   11634                         + " (pid=" + Binder.getCallingPid()
   11635                         + ") when binding service " + service);
   11636             }
   11637 
   11638             HistoryRecord activity = null;
   11639             if (token != null) {
   11640                 int aindex = indexOfTokenLocked(token);
   11641                 if (aindex < 0) {
   11642                     Slog.w(TAG, "Binding with unknown activity: " + token);
   11643                     return 0;
   11644                 }
   11645                 activity = (HistoryRecord)mHistory.get(aindex);
   11646             }
   11647 
   11648             int clientLabel = 0;
   11649             PendingIntent clientIntent = null;
   11650 
   11651             if (callerApp.info.uid == Process.SYSTEM_UID) {
   11652                 // Hacky kind of thing -- allow system stuff to tell us
   11653                 // what they are, so we can report this elsewhere for
   11654                 // others to know why certain services are running.
   11655                 try {
   11656                     clientIntent = (PendingIntent)service.getParcelableExtra(
   11657                             Intent.EXTRA_CLIENT_INTENT);
   11658                 } catch (RuntimeException e) {
   11659                 }
   11660                 if (clientIntent != null) {
   11661                     clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
   11662                     if (clientLabel != 0) {
   11663                         // There are no useful extras in the intent, trash them.
   11664                         // System code calling with this stuff just needs to know
   11665                         // this will happen.
   11666                         service = service.cloneFilter();
   11667                     }
   11668                 }
   11669             }
   11670 
   11671             ServiceLookupResult res =
   11672                 retrieveServiceLocked(service, resolvedType,
   11673                         Binder.getCallingPid(), Binder.getCallingUid());
   11674             if (res == null) {
   11675                 return 0;
   11676             }
   11677             if (res.record == null) {
   11678                 return -1;
   11679             }
   11680             ServiceRecord s = res.record;
   11681 
   11682             final long origId = Binder.clearCallingIdentity();
   11683 
   11684             if (unscheduleServiceRestartLocked(s)) {
   11685                 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
   11686                         + s.shortName);
   11687             }
   11688 
   11689             AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
   11690             ConnectionRecord c = new ConnectionRecord(b, activity,
   11691                     connection, flags, clientLabel, clientIntent);
   11692 
   11693             IBinder binder = connection.asBinder();
   11694             s.connections.put(binder, c);
   11695             b.connections.add(c);
   11696             if (activity != null) {
   11697                 if (activity.connections == null) {
   11698                     activity.connections = new HashSet<ConnectionRecord>();
   11699                 }
   11700                 activity.connections.add(c);
   11701             }
   11702             b.client.connections.add(c);
   11703             mServiceConnections.put(binder, c);
   11704 
   11705             if ((flags&Context.BIND_AUTO_CREATE) != 0) {
   11706                 s.lastActivity = SystemClock.uptimeMillis();
   11707                 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
   11708                     return 0;
   11709                 }
   11710             }
   11711 
   11712             if (s.app != null) {
   11713                 // This could have made the service more important.
   11714                 updateOomAdjLocked(s.app);
   11715             }
   11716 
   11717             if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
   11718                     + ": received=" + b.intent.received
   11719                     + " apps=" + b.intent.apps.size()
   11720                     + " doRebind=" + b.intent.doRebind);
   11721 
   11722             if (s.app != null && b.intent.received) {
   11723                 // Service is already running, so we can immediately
   11724                 // publish the connection.
   11725                 try {
   11726                     c.conn.connected(s.name, b.intent.binder);
   11727                 } catch (Exception e) {
   11728                     Slog.w(TAG, "Failure sending service " + s.shortName
   11729                             + " to connection " + c.conn.asBinder()
   11730                             + " (in " + c.binding.client.processName + ")", e);
   11731                 }
   11732 
   11733                 // If this is the first app connected back to this binding,
   11734                 // and the service had previously asked to be told when
   11735                 // rebound, then do so.
   11736                 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
   11737                     requestServiceBindingLocked(s, b.intent, true);
   11738                 }
   11739             } else if (!b.intent.requested) {
   11740                 requestServiceBindingLocked(s, b.intent, false);
   11741             }
   11742 
   11743             Binder.restoreCallingIdentity(origId);
   11744         }
   11745 
   11746         return 1;
   11747     }
   11748 
   11749     private void removeConnectionLocked(
   11750         ConnectionRecord c, ProcessRecord skipApp, HistoryRecord skipAct) {
   11751         IBinder binder = c.conn.asBinder();
   11752         AppBindRecord b = c.binding;
   11753         ServiceRecord s = b.service;
   11754         s.connections.remove(binder);
   11755         b.connections.remove(c);
   11756         if (c.activity != null && c.activity != skipAct) {
   11757             if (c.activity.connections != null) {
   11758                 c.activity.connections.remove(c);
   11759             }
   11760         }
   11761         if (b.client != skipApp) {
   11762             b.client.connections.remove(c);
   11763         }
   11764         mServiceConnections.remove(binder);
   11765 
   11766         if (b.connections.size() == 0) {
   11767             b.intent.apps.remove(b.client);
   11768         }
   11769 
   11770         if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
   11771                 + ": shouldUnbind=" + b.intent.hasBound);
   11772         if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
   11773                 && b.intent.hasBound) {
   11774             try {
   11775                 bumpServiceExecutingLocked(s);
   11776                 updateOomAdjLocked(s.app);
   11777                 b.intent.hasBound = false;
   11778                 // Assume the client doesn't want to know about a rebind;
   11779                 // we will deal with that later if it asks for one.
   11780                 b.intent.doRebind = false;
   11781                 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
   11782             } catch (Exception e) {
   11783                 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
   11784                 serviceDoneExecutingLocked(s, true);
   11785             }
   11786         }
   11787 
   11788         if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
   11789             bringDownServiceLocked(s, false);
   11790         }
   11791     }
   11792 
   11793     public boolean unbindService(IServiceConnection connection) {
   11794         synchronized (this) {
   11795             IBinder binder = connection.asBinder();
   11796             if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
   11797             ConnectionRecord r = mServiceConnections.get(binder);
   11798             if (r == null) {
   11799                 Slog.w(TAG, "Unbind failed: could not find connection for "
   11800                       + connection.asBinder());
   11801                 return false;
   11802             }
   11803 
   11804             final long origId = Binder.clearCallingIdentity();
   11805 
   11806             removeConnectionLocked(r, null, null);
   11807 
   11808             if (r.binding.service.app != null) {
   11809                 // This could have made the service less important.
   11810                 updateOomAdjLocked(r.binding.service.app);
   11811             }
   11812 
   11813             Binder.restoreCallingIdentity(origId);
   11814         }
   11815 
   11816         return true;
   11817     }
   11818 
   11819     public void publishService(IBinder token, Intent intent, IBinder service) {
   11820         // Refuse possible leaked file descriptors
   11821         if (intent != null && intent.hasFileDescriptors() == true) {
   11822             throw new IllegalArgumentException("File descriptors passed in Intent");
   11823         }
   11824 
   11825         synchronized(this) {
   11826             if (!(token instanceof ServiceRecord)) {
   11827                 throw new IllegalArgumentException("Invalid service token");
   11828             }
   11829             ServiceRecord r = (ServiceRecord)token;
   11830 
   11831             final long origId = Binder.clearCallingIdentity();
   11832 
   11833             if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING SERVICE " + r.name
   11834                     + " " + intent + ": " + service);
   11835             if (r != null) {
   11836                 Intent.FilterComparison filter
   11837                         = new Intent.FilterComparison(intent);
   11838                 IntentBindRecord b = r.bindings.get(filter);
   11839                 if (b != null && !b.received) {
   11840                     b.binder = service;
   11841                     b.requested = true;
   11842                     b.received = true;
   11843                     if (r.connections.size() > 0) {
   11844                         Iterator<ConnectionRecord> it
   11845                                 = r.connections.values().iterator();
   11846                         while (it.hasNext()) {
   11847                             ConnectionRecord c = it.next();
   11848                             if (!filter.equals(c.binding.intent.intent)) {
   11849                                 if (DEBUG_SERVICE) Slog.v(
   11850                                         TAG, "Not publishing to: " + c);
   11851                                 if (DEBUG_SERVICE) Slog.v(
   11852                                         TAG, "Bound intent: " + c.binding.intent.intent);
   11853                                 if (DEBUG_SERVICE) Slog.v(
   11854                                         TAG, "Published intent: " + intent);
   11855                                 continue;
   11856                             }
   11857                             if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
   11858                             try {
   11859                                 c.conn.connected(r.name, service);
   11860                             } catch (Exception e) {
   11861                                 Slog.w(TAG, "Failure sending service " + r.name +
   11862                                       " to connection " + c.conn.asBinder() +
   11863                                       " (in " + c.binding.client.processName + ")", e);
   11864                             }
   11865                         }
   11866                     }
   11867                 }
   11868 
   11869                 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
   11870 
   11871                 Binder.restoreCallingIdentity(origId);
   11872             }
   11873         }
   11874     }
   11875 
   11876     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
   11877         // Refuse possible leaked file descriptors
   11878         if (intent != null && intent.hasFileDescriptors() == true) {
   11879             throw new IllegalArgumentException("File descriptors passed in Intent");
   11880         }
   11881 
   11882         synchronized(this) {
   11883             if (!(token instanceof ServiceRecord)) {
   11884                 throw new IllegalArgumentException("Invalid service token");
   11885             }
   11886             ServiceRecord r = (ServiceRecord)token;
   11887 
   11888             final long origId = Binder.clearCallingIdentity();
   11889 
   11890             if (r != null) {
   11891                 Intent.FilterComparison filter
   11892                         = new Intent.FilterComparison(intent);
   11893                 IntentBindRecord b = r.bindings.get(filter);
   11894                 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
   11895                         + " at " + b + ": apps="
   11896                         + (b != null ? b.apps.size() : 0));
   11897                 if (b != null) {
   11898                     if (b.apps.size() > 0) {
   11899                         // Applications have already bound since the last
   11900                         // unbind, so just rebind right here.
   11901                         requestServiceBindingLocked(r, b, true);
   11902                     } else {
   11903                         // Note to tell the service the next time there is
   11904                         // a new client.
   11905                         b.doRebind = true;
   11906                     }
   11907                 }
   11908 
   11909                 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
   11910 
   11911                 Binder.restoreCallingIdentity(origId);
   11912             }
   11913         }
   11914     }
   11915 
   11916     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
   11917         synchronized(this) {
   11918             if (!(token instanceof ServiceRecord)) {
   11919                 throw new IllegalArgumentException("Invalid service token");
   11920             }
   11921             ServiceRecord r = (ServiceRecord)token;
   11922             boolean inStopping = mStoppingServices.contains(token);
   11923             if (r != null) {
   11924                 if (DEBUG_SERVICE) Slog.v(TAG, "DONE EXECUTING SERVICE " + r.name
   11925                         + ": nesting=" + r.executeNesting
   11926                         + ", inStopping=" + inStopping);
   11927                 if (r != token) {
   11928                     Slog.w(TAG, "Done executing service " + r.name
   11929                           + " with incorrect token: given " + token
   11930                           + ", expected " + r);
   11931                     return;
   11932                 }
   11933 
   11934                 if (type == 1) {
   11935                     // This is a call from a service start...  take care of
   11936                     // book-keeping.
   11937                     r.callStart = true;
   11938                     switch (res) {
   11939                         case Service.START_STICKY_COMPATIBILITY:
   11940                         case Service.START_STICKY: {
   11941                             // We are done with the associated start arguments.
   11942                             r.findDeliveredStart(startId, true);
   11943                             // Don't stop if killed.
   11944                             r.stopIfKilled = false;
   11945                             break;
   11946                         }
   11947                         case Service.START_NOT_STICKY: {
   11948                             // We are done with the associated start arguments.
   11949                             r.findDeliveredStart(startId, true);
   11950                             if (r.lastStartId == startId) {
   11951                                 // There is no more work, and this service
   11952                                 // doesn't want to hang around if killed.
   11953                                 r.stopIfKilled = true;
   11954                             }
   11955                             break;
   11956                         }
   11957                         case Service.START_REDELIVER_INTENT: {
   11958                             // We'll keep this item until they explicitly
   11959                             // call stop for it, but keep track of the fact
   11960                             // that it was delivered.
   11961                             ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
   11962                             if (si != null) {
   11963                                 si.deliveryCount = 0;
   11964                                 si.doneExecutingCount++;
   11965                                 // Don't stop if killed.
   11966                                 r.stopIfKilled = true;
   11967                             }
   11968                             break;
   11969                         }
   11970                         default:
   11971                             throw new IllegalArgumentException(
   11972                                     "Unknown service start result: " + res);
   11973                     }
   11974                     if (res == Service.START_STICKY_COMPATIBILITY) {
   11975                         r.callStart = false;
   11976                     }
   11977                 }
   11978 
   11979                 final long origId = Binder.clearCallingIdentity();
   11980                 serviceDoneExecutingLocked(r, inStopping);
   11981                 Binder.restoreCallingIdentity(origId);
   11982             } else {
   11983                 Slog.w(TAG, "Done executing unknown service " + r.name
   11984                         + " with token " + token);
   11985             }
   11986         }
   11987     }
   11988 
   11989     public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
   11990         r.executeNesting--;
   11991         if (r.executeNesting <= 0 && r.app != null) {
   11992             r.app.executingServices.remove(r);
   11993             if (r.app.executingServices.size() == 0) {
   11994                 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
   11995             }
   11996             if (inStopping) {
   11997                 mStoppingServices.remove(r);
   11998             }
   11999             updateOomAdjLocked(r.app);
   12000         }
   12001     }
   12002 
   12003     void serviceTimeout(ProcessRecord proc) {
   12004         String anrMessage = null;
   12005 
   12006         synchronized(this) {
   12007             if (proc.executingServices.size() == 0 || proc.thread == null) {
   12008                 return;
   12009             }
   12010             long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
   12011             Iterator<ServiceRecord> it = proc.executingServices.iterator();
   12012             ServiceRecord timeout = null;
   12013             long nextTime = 0;
   12014             while (it.hasNext()) {
   12015                 ServiceRecord sr = it.next();
   12016                 if (sr.executingStart < maxTime) {
   12017                     timeout = sr;
   12018                     break;
   12019                 }
   12020                 if (sr.executingStart > nextTime) {
   12021                     nextTime = sr.executingStart;
   12022                 }
   12023             }
   12024             if (timeout != null && mLruProcesses.contains(proc)) {
   12025                 Slog.w(TAG, "Timeout executing service: " + timeout);
   12026                 anrMessage = "Executing service " + timeout.shortName;
   12027             } else {
   12028                 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   12029                 msg.obj = proc;
   12030                 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
   12031             }
   12032         }
   12033 
   12034         if (anrMessage != null) {
   12035             appNotResponding(proc, null, null, anrMessage);
   12036         }
   12037     }
   12038 
   12039     // =========================================================
   12040     // BACKUP AND RESTORE
   12041     // =========================================================
   12042 
   12043     // Cause the target app to be launched if necessary and its backup agent
   12044     // instantiated.  The backup agent will invoke backupAgentCreated() on the
   12045     // activity manager to announce its creation.
   12046     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
   12047         if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
   12048         enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
   12049 
   12050         synchronized(this) {
   12051             // !!! TODO: currently no check here that we're already bound
   12052             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   12053             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   12054             synchronized (stats) {
   12055                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
   12056             }
   12057 
   12058             BackupRecord r = new BackupRecord(ss, app, backupMode);
   12059             ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName);
   12060             // startProcessLocked() returns existing proc's record if it's already running
   12061             ProcessRecord proc = startProcessLocked(app.processName, app,
   12062                     false, 0, "backup", hostingName, false);
   12063             if (proc == null) {
   12064                 Slog.e(TAG, "Unable to start backup agent process " + r);
   12065                 return false;
   12066             }
   12067 
   12068             r.app = proc;
   12069             mBackupTarget = r;
   12070             mBackupAppName = app.packageName;
   12071 
   12072             // Try not to kill the process during backup
   12073             updateOomAdjLocked(proc);
   12074 
   12075             // If the process is already attached, schedule the creation of the backup agent now.
   12076             // If it is not yet live, this will be done when it attaches to the framework.
   12077             if (proc.thread != null) {
   12078                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
   12079                 try {
   12080                     proc.thread.scheduleCreateBackupAgent(app, backupMode);
   12081                 } catch (RemoteException e) {
   12082                     // Will time out on the backup manager side
   12083                 }
   12084             } else {
   12085                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
   12086             }
   12087             // Invariants: at this point, the target app process exists and the application
   12088             // is either already running or in the process of coming up.  mBackupTarget and
   12089             // mBackupAppName describe the app, so that when it binds back to the AM we
   12090             // know that it's scheduled for a backup-agent operation.
   12091         }
   12092 
   12093         return true;
   12094     }
   12095 
   12096     // A backup agent has just come up
   12097     public void backupAgentCreated(String agentPackageName, IBinder agent) {
   12098         if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
   12099                 + " = " + agent);
   12100 
   12101         synchronized(this) {
   12102             if (!agentPackageName.equals(mBackupAppName)) {
   12103                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
   12104                 return;
   12105             }
   12106 
   12107             long oldIdent = Binder.clearCallingIdentity();
   12108             try {
   12109                 IBackupManager bm = IBackupManager.Stub.asInterface(
   12110                         ServiceManager.getService(Context.BACKUP_SERVICE));
   12111                 bm.agentConnected(agentPackageName, agent);
   12112             } catch (RemoteException e) {
   12113                 // can't happen; the backup manager service is local
   12114             } catch (Exception e) {
   12115                 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
   12116                 e.printStackTrace();
   12117             } finally {
   12118                 Binder.restoreCallingIdentity(oldIdent);
   12119             }
   12120         }
   12121     }
   12122 
   12123     // done with this agent
   12124     public void unbindBackupAgent(ApplicationInfo appInfo) {
   12125         if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
   12126         if (appInfo == null) {
   12127             Slog.w(TAG, "unbind backup agent for null app");
   12128             return;
   12129         }
   12130 
   12131         synchronized(this) {
   12132             if (mBackupAppName == null) {
   12133                 Slog.w(TAG, "Unbinding backup agent with no active backup");
   12134                 return;
   12135             }
   12136 
   12137             if (!mBackupAppName.equals(appInfo.packageName)) {
   12138                 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
   12139                 return;
   12140             }
   12141 
   12142             ProcessRecord proc = mBackupTarget.app;
   12143             mBackupTarget = null;
   12144             mBackupAppName = null;
   12145 
   12146             // Not backing this app up any more; reset its OOM adjustment
   12147             updateOomAdjLocked(proc);
   12148 
   12149             // If the app crashed during backup, 'thread' will be null here
   12150             if (proc.thread != null) {
   12151                 try {
   12152                     proc.thread.scheduleDestroyBackupAgent(appInfo);
   12153                 } catch (Exception e) {
   12154                     Slog.e(TAG, "Exception when unbinding backup agent:");
   12155                     e.printStackTrace();
   12156                 }
   12157             }
   12158         }
   12159     }
   12160     // =========================================================
   12161     // BROADCASTS
   12162     // =========================================================
   12163 
   12164     private final List getStickiesLocked(String action, IntentFilter filter,
   12165             List cur) {
   12166         final ContentResolver resolver = mContext.getContentResolver();
   12167         final ArrayList<Intent> list = mStickyBroadcasts.get(action);
   12168         if (list == null) {
   12169             return cur;
   12170         }
   12171         int N = list.size();
   12172         for (int i=0; i<N; i++) {
   12173             Intent intent = list.get(i);
   12174             if (filter.match(resolver, intent, true, TAG) >= 0) {
   12175                 if (cur == null) {
   12176                     cur = new ArrayList<Intent>();
   12177                 }
   12178                 cur.add(intent);
   12179             }
   12180         }
   12181         return cur;
   12182     }
   12183 
   12184     private final void scheduleBroadcastsLocked() {
   12185         if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
   12186                 + mBroadcastsScheduled);
   12187 
   12188         if (mBroadcastsScheduled) {
   12189             return;
   12190         }
   12191         mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
   12192         mBroadcastsScheduled = true;
   12193     }
   12194 
   12195     public Intent registerReceiver(IApplicationThread caller,
   12196             IIntentReceiver receiver, IntentFilter filter, String permission) {
   12197         synchronized(this) {
   12198             ProcessRecord callerApp = null;
   12199             if (caller != null) {
   12200                 callerApp = getRecordForAppLocked(caller);
   12201                 if (callerApp == null) {
   12202                     throw new SecurityException(
   12203                             "Unable to find app for caller " + caller
   12204                             + " (pid=" + Binder.getCallingPid()
   12205                             + ") when registering receiver " + receiver);
   12206                 }
   12207             }
   12208 
   12209             List allSticky = null;
   12210 
   12211             // Look for any matching sticky broadcasts...
   12212             Iterator actions = filter.actionsIterator();
   12213             if (actions != null) {
   12214                 while (actions.hasNext()) {
   12215                     String action = (String)actions.next();
   12216                     allSticky = getStickiesLocked(action, filter, allSticky);
   12217                 }
   12218             } else {
   12219                 allSticky = getStickiesLocked(null, filter, allSticky);
   12220             }
   12221 
   12222             // The first sticky in the list is returned directly back to
   12223             // the client.
   12224             Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
   12225 
   12226             if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
   12227                     + ": " + sticky);
   12228 
   12229             if (receiver == null) {
   12230                 return sticky;
   12231             }
   12232 
   12233             ReceiverList rl
   12234                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   12235             if (rl == null) {
   12236                 rl = new ReceiverList(this, callerApp,
   12237                         Binder.getCallingPid(),
   12238                         Binder.getCallingUid(), receiver);
   12239                 if (rl.app != null) {
   12240                     rl.app.receivers.add(rl);
   12241                 } else {
   12242                     try {
   12243                         receiver.asBinder().linkToDeath(rl, 0);
   12244                     } catch (RemoteException e) {
   12245                         return sticky;
   12246                     }
   12247                     rl.linkedToDeath = true;
   12248                 }
   12249                 mRegisteredReceivers.put(receiver.asBinder(), rl);
   12250             }
   12251             BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
   12252             rl.add(bf);
   12253             if (!bf.debugCheck()) {
   12254                 Slog.w(TAG, "==> For Dynamic broadast");
   12255             }
   12256             mReceiverResolver.addFilter(bf);
   12257 
   12258             // Enqueue broadcasts for all existing stickies that match
   12259             // this filter.
   12260             if (allSticky != null) {
   12261                 ArrayList receivers = new ArrayList();
   12262                 receivers.add(bf);
   12263 
   12264                 int N = allSticky.size();
   12265                 for (int i=0; i<N; i++) {
   12266                     Intent intent = (Intent)allSticky.get(i);
   12267                     BroadcastRecord r = new BroadcastRecord(intent, null,
   12268                             null, -1, -1, null, receivers, null, 0, null, null,
   12269                             false, true, true);
   12270                     if (mParallelBroadcasts.size() == 0) {
   12271                         scheduleBroadcastsLocked();
   12272                     }
   12273                     mParallelBroadcasts.add(r);
   12274                 }
   12275             }
   12276 
   12277             return sticky;
   12278         }
   12279     }
   12280 
   12281     public void unregisterReceiver(IIntentReceiver receiver) {
   12282         if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
   12283 
   12284         boolean doNext = false;
   12285 
   12286         synchronized(this) {
   12287             ReceiverList rl
   12288                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   12289             if (rl != null) {
   12290                 if (rl.curBroadcast != null) {
   12291                     BroadcastRecord r = rl.curBroadcast;
   12292                     doNext = finishReceiverLocked(
   12293                         receiver.asBinder(), r.resultCode, r.resultData,
   12294                         r.resultExtras, r.resultAbort, true);
   12295                 }
   12296 
   12297                 if (rl.app != null) {
   12298                     rl.app.receivers.remove(rl);
   12299                 }
   12300                 removeReceiverLocked(rl);
   12301                 if (rl.linkedToDeath) {
   12302                     rl.linkedToDeath = false;
   12303                     rl.receiver.asBinder().unlinkToDeath(rl, 0);
   12304                 }
   12305             }
   12306         }
   12307 
   12308         if (!doNext) {
   12309             return;
   12310         }
   12311 
   12312         final long origId = Binder.clearCallingIdentity();
   12313         processNextBroadcast(false);
   12314         trimApplications();
   12315         Binder.restoreCallingIdentity(origId);
   12316     }
   12317 
   12318     void removeReceiverLocked(ReceiverList rl) {
   12319         mRegisteredReceivers.remove(rl.receiver.asBinder());
   12320         int N = rl.size();
   12321         for (int i=0; i<N; i++) {
   12322             mReceiverResolver.removeFilter(rl.get(i));
   12323         }
   12324     }
   12325 
   12326     private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
   12327         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   12328             ProcessRecord r = mLruProcesses.get(i);
   12329             if (r.thread != null) {
   12330                 try {
   12331                     r.thread.dispatchPackageBroadcast(cmd, packages);
   12332                 } catch (RemoteException ex) {
   12333                 }
   12334             }
   12335         }
   12336     }
   12337 
   12338     private final int broadcastIntentLocked(ProcessRecord callerApp,
   12339             String callerPackage, Intent intent, String resolvedType,
   12340             IIntentReceiver resultTo, int resultCode, String resultData,
   12341             Bundle map, String requiredPermission,
   12342             boolean ordered, boolean sticky, int callingPid, int callingUid) {
   12343         intent = new Intent(intent);
   12344 
   12345         if (DEBUG_BROADCAST_LIGHT) Slog.v(
   12346             TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
   12347             + " ordered=" + ordered);
   12348         if ((resultTo != null) && !ordered) {
   12349             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
   12350         }
   12351 
   12352         // Handle special intents: if this broadcast is from the package
   12353         // manager about a package being removed, we need to remove all of
   12354         // its activities from the history stack.
   12355         final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals(
   12356                 intent.getAction());
   12357         if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
   12358                 || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
   12359                 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
   12360                 || uidRemoved) {
   12361             if (checkComponentPermission(
   12362                     android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
   12363                     callingPid, callingUid, -1)
   12364                     == PackageManager.PERMISSION_GRANTED) {
   12365                 if (uidRemoved) {
   12366                     final Bundle intentExtras = intent.getExtras();
   12367                     final int uid = intentExtras != null
   12368                             ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
   12369                     if (uid >= 0) {
   12370                         BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
   12371                         synchronized (bs) {
   12372                             bs.removeUidStatsLocked(uid);
   12373                         }
   12374                     }
   12375                 } else {
   12376                     // If resources are unvailble just force stop all
   12377                     // those packages and flush the attribute cache as well.
   12378                     if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
   12379                         String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   12380                         if (list != null && (list.length > 0)) {
   12381                             for (String pkg : list) {
   12382                                 forceStopPackageLocked(pkg, -1, false, true, true);
   12383                             }
   12384                             sendPackageBroadcastLocked(
   12385                                     IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
   12386                         }
   12387                     } else {
   12388                         Uri data = intent.getData();
   12389                         String ssp;
   12390                         if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   12391                             if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
   12392                                 forceStopPackageLocked(ssp,
   12393                                         intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
   12394                             }
   12395                             if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
   12396                                 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
   12397                                         new String[] {ssp});
   12398                             }
   12399                         }
   12400                     }
   12401                 }
   12402             } else {
   12403                 String msg = "Permission Denial: " + intent.getAction()
   12404                         + " broadcast from " + callerPackage + " (pid=" + callingPid
   12405                         + ", uid=" + callingUid + ")"
   12406                         + " requires "
   12407                         + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
   12408                 Slog.w(TAG, msg);
   12409                 throw new SecurityException(msg);
   12410             }
   12411         }
   12412 
   12413         /*
   12414          * If this is the time zone changed action, queue up a message that will reset the timezone
   12415          * of all currently running processes. This message will get queued up before the broadcast
   12416          * happens.
   12417          */
   12418         if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
   12419             mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
   12420         }
   12421 
   12422         /*
   12423          * Prevent non-system code (defined here to be non-persistent
   12424          * processes) from sending protected broadcasts.
   12425          */
   12426         if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
   12427                 || callingUid == Process.SHELL_UID || callingUid == 0) {
   12428             // Always okay.
   12429         } else if (callerApp == null || !callerApp.persistent) {
   12430             try {
   12431                 if (ActivityThread.getPackageManager().isProtectedBroadcast(
   12432                         intent.getAction())) {
   12433                     String msg = "Permission Denial: not allowed to send broadcast "
   12434                             + intent.getAction() + " from pid="
   12435                             + callingPid + ", uid=" + callingUid;
   12436                     Slog.w(TAG, msg);
   12437                     throw new SecurityException(msg);
   12438                 }
   12439             } catch (RemoteException e) {
   12440                 Slog.w(TAG, "Remote exception", e);
   12441                 return BROADCAST_SUCCESS;
   12442             }
   12443         }
   12444 
   12445         // Add to the sticky list if requested.
   12446         if (sticky) {
   12447             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
   12448                     callingPid, callingUid)
   12449                     != PackageManager.PERMISSION_GRANTED) {
   12450                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
   12451                         + callingPid + ", uid=" + callingUid
   12452                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   12453                 Slog.w(TAG, msg);
   12454                 throw new SecurityException(msg);
   12455             }
   12456             if (requiredPermission != null) {
   12457                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
   12458                         + " and enforce permission " + requiredPermission);
   12459                 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
   12460             }
   12461             if (intent.getComponent() != null) {
   12462                 throw new SecurityException(
   12463                         "Sticky broadcasts can't target a specific component");
   12464             }
   12465             ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
   12466             if (list == null) {
   12467                 list = new ArrayList<Intent>();
   12468                 mStickyBroadcasts.put(intent.getAction(), list);
   12469             }
   12470             int N = list.size();
   12471             int i;
   12472             for (i=0; i<N; i++) {
   12473                 if (intent.filterEquals(list.get(i))) {
   12474                     // This sticky already exists, replace it.
   12475                     list.set(i, new Intent(intent));
   12476                     break;
   12477                 }
   12478             }
   12479             if (i >= N) {
   12480                 list.add(new Intent(intent));
   12481             }
   12482         }
   12483 
   12484         // Figure out who all will receive this broadcast.
   12485         List receivers = null;
   12486         List<BroadcastFilter> registeredReceivers = null;
   12487         try {
   12488             if (intent.getComponent() != null) {
   12489                 // Broadcast is going to one specific receiver class...
   12490                 ActivityInfo ai = ActivityThread.getPackageManager().
   12491                     getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
   12492                 if (ai != null) {
   12493                     receivers = new ArrayList();
   12494                     ResolveInfo ri = new ResolveInfo();
   12495                     ri.activityInfo = ai;
   12496                     receivers.add(ri);
   12497                 }
   12498             } else {
   12499                 // Need to resolve the intent to interested receivers...
   12500                 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
   12501                          == 0) {
   12502                     receivers =
   12503                         ActivityThread.getPackageManager().queryIntentReceivers(
   12504                                 intent, resolvedType, STOCK_PM_FLAGS);
   12505                 }
   12506                 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
   12507             }
   12508         } catch (RemoteException ex) {
   12509             // pm is in same process, this will never happen.
   12510         }
   12511 
   12512         final boolean replacePending =
   12513                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
   12514 
   12515         if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
   12516                 + " replacePending=" + replacePending);
   12517 
   12518         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
   12519         if (!ordered && NR > 0) {
   12520             // If we are not serializing this broadcast, then send the
   12521             // registered receivers separately so they don't wait for the
   12522             // components to be launched.
   12523             BroadcastRecord r = new BroadcastRecord(intent, callerApp,
   12524                     callerPackage, callingPid, callingUid, requiredPermission,
   12525                     registeredReceivers, resultTo, resultCode, resultData, map,
   12526                     ordered, sticky, false);
   12527             if (DEBUG_BROADCAST) Slog.v(
   12528                     TAG, "Enqueueing parallel broadcast " + r
   12529                     + ": prev had " + mParallelBroadcasts.size());
   12530             boolean replaced = false;
   12531             if (replacePending) {
   12532                 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
   12533                     if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
   12534                         if (DEBUG_BROADCAST) Slog.v(TAG,
   12535                                 "***** DROPPING PARALLEL: " + intent);
   12536                         mParallelBroadcasts.set(i, r);
   12537                         replaced = true;
   12538                         break;
   12539                     }
   12540                 }
   12541             }
   12542             if (!replaced) {
   12543                 mParallelBroadcasts.add(r);
   12544                 scheduleBroadcastsLocked();
   12545             }
   12546             registeredReceivers = null;
   12547             NR = 0;
   12548         }
   12549 
   12550         // Merge into one list.
   12551         int ir = 0;
   12552         if (receivers != null) {
   12553             // A special case for PACKAGE_ADDED: do not allow the package
   12554             // being added to see this broadcast.  This prevents them from
   12555             // using this as a back door to get run as soon as they are
   12556             // installed.  Maybe in the future we want to have a special install
   12557             // broadcast or such for apps, but we'd like to deliberately make
   12558             // this decision.
   12559             String skipPackages[] = null;
   12560             if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
   12561                     || intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
   12562                     || intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
   12563                 Uri data = intent.getData();
   12564                 if (data != null) {
   12565                     String pkgName = data.getSchemeSpecificPart();
   12566                     if (pkgName != null) {
   12567                         skipPackages = new String[] { pkgName };
   12568                     }
   12569                 }
   12570             } else if (intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
   12571                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   12572             }
   12573             if (skipPackages != null && (skipPackages.length > 0)) {
   12574                 for (String skipPackage : skipPackages) {
   12575                     if (skipPackage != null) {
   12576                         int NT = receivers.size();
   12577                         for (int it=0; it<NT; it++) {
   12578                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
   12579                             if (curt.activityInfo.packageName.equals(skipPackage)) {
   12580                                 receivers.remove(it);
   12581                                 it--;
   12582                                 NT--;
   12583                             }
   12584                         }
   12585                     }
   12586                 }
   12587             }
   12588 
   12589             int NT = receivers != null ? receivers.size() : 0;
   12590             int it = 0;
   12591             ResolveInfo curt = null;
   12592             BroadcastFilter curr = null;
   12593             while (it < NT && ir < NR) {
   12594                 if (curt == null) {
   12595                     curt = (ResolveInfo)receivers.get(it);
   12596                 }
   12597                 if (curr == null) {
   12598                     curr = registeredReceivers.get(ir);
   12599                 }
   12600                 if (curr.getPriority() >= curt.priority) {
   12601                     // Insert this broadcast record into the final list.
   12602                     receivers.add(it, curr);
   12603                     ir++;
   12604                     curr = null;
   12605                     it++;
   12606                     NT++;
   12607                 } else {
   12608                     // Skip to the next ResolveInfo in the final list.
   12609                     it++;
   12610                     curt = null;
   12611                 }
   12612             }
   12613         }
   12614         while (ir < NR) {
   12615             if (receivers == null) {
   12616                 receivers = new ArrayList();
   12617             }
   12618             receivers.add(registeredReceivers.get(ir));
   12619             ir++;
   12620         }
   12621 
   12622         if ((receivers != null && receivers.size() > 0)
   12623                 || resultTo != null) {
   12624             BroadcastRecord r = new BroadcastRecord(intent, callerApp,
   12625                     callerPackage, callingPid, callingUid, requiredPermission,
   12626                     receivers, resultTo, resultCode, resultData, map, ordered,
   12627                     sticky, false);
   12628             if (DEBUG_BROADCAST) Slog.v(
   12629                     TAG, "Enqueueing ordered broadcast " + r
   12630                     + ": prev had " + mOrderedBroadcasts.size());
   12631             if (DEBUG_BROADCAST) {
   12632                 int seq = r.intent.getIntExtra("seq", -1);
   12633                 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
   12634             }
   12635             boolean replaced = false;
   12636             if (replacePending) {
   12637                 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
   12638                     if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
   12639                         if (DEBUG_BROADCAST) Slog.v(TAG,
   12640                                 "***** DROPPING ORDERED: " + intent);
   12641                         mOrderedBroadcasts.set(i, r);
   12642                         replaced = true;
   12643                         break;
   12644                     }
   12645                 }
   12646             }
   12647             if (!replaced) {
   12648                 mOrderedBroadcasts.add(r);
   12649                 scheduleBroadcastsLocked();
   12650             }
   12651         }
   12652 
   12653         return BROADCAST_SUCCESS;
   12654     }
   12655 
   12656     public final int broadcastIntent(IApplicationThread caller,
   12657             Intent intent, String resolvedType, IIntentReceiver resultTo,
   12658             int resultCode, String resultData, Bundle map,
   12659             String requiredPermission, boolean serialized, boolean sticky) {
   12660         // Refuse possible leaked file descriptors
   12661         if (intent != null && intent.hasFileDescriptors() == true) {
   12662             throw new IllegalArgumentException("File descriptors passed in Intent");
   12663         }
   12664 
   12665         synchronized(this) {
   12666             int flags = intent.getFlags();
   12667 
   12668             if (!mSystemReady) {
   12669                 // if the caller really truly claims to know what they're doing, go
   12670                 // ahead and allow the broadcast without launching any receivers
   12671                 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
   12672                     intent = new Intent(intent);
   12673                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   12674                 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0){
   12675                     Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
   12676                             + " before boot completion");
   12677                     throw new IllegalStateException("Cannot broadcast before boot completed");
   12678                 }
   12679             }
   12680 
   12681             if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   12682                 throw new IllegalArgumentException(
   12683                         "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   12684             }
   12685 
   12686             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   12687             final int callingPid = Binder.getCallingPid();
   12688             final int callingUid = Binder.getCallingUid();
   12689             final long origId = Binder.clearCallingIdentity();
   12690             int res = broadcastIntentLocked(callerApp,
   12691                     callerApp != null ? callerApp.info.packageName : null,
   12692                     intent, resolvedType, resultTo,
   12693                     resultCode, resultData, map, requiredPermission, serialized,
   12694                     sticky, callingPid, callingUid);
   12695             Binder.restoreCallingIdentity(origId);
   12696             return res;
   12697         }
   12698     }
   12699 
   12700     int broadcastIntentInPackage(String packageName, int uid,
   12701             Intent intent, String resolvedType, IIntentReceiver resultTo,
   12702             int resultCode, String resultData, Bundle map,
   12703             String requiredPermission, boolean serialized, boolean sticky) {
   12704         synchronized(this) {
   12705             final long origId = Binder.clearCallingIdentity();
   12706             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
   12707                     resultTo, resultCode, resultData, map, requiredPermission,
   12708                     serialized, sticky, -1, uid);
   12709             Binder.restoreCallingIdentity(origId);
   12710             return res;
   12711         }
   12712     }
   12713 
   12714     public final void unbroadcastIntent(IApplicationThread caller,
   12715             Intent intent) {
   12716         // Refuse possible leaked file descriptors
   12717         if (intent != null && intent.hasFileDescriptors() == true) {
   12718             throw new IllegalArgumentException("File descriptors passed in Intent");
   12719         }
   12720 
   12721         synchronized(this) {
   12722             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
   12723                     != PackageManager.PERMISSION_GRANTED) {
   12724                 String msg = "Permission Denial: unbroadcastIntent() from pid="
   12725                         + Binder.getCallingPid()
   12726                         + ", uid=" + Binder.getCallingUid()
   12727                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   12728                 Slog.w(TAG, msg);
   12729                 throw new SecurityException(msg);
   12730             }
   12731             ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
   12732             if (list != null) {
   12733                 int N = list.size();
   12734                 int i;
   12735                 for (i=0; i<N; i++) {
   12736                     if (intent.filterEquals(list.get(i))) {
   12737                         list.remove(i);
   12738                         break;
   12739                     }
   12740                 }
   12741             }
   12742         }
   12743     }
   12744 
   12745     private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
   12746             String resultData, Bundle resultExtras, boolean resultAbort,
   12747             boolean explicit) {
   12748         if (mOrderedBroadcasts.size() == 0) {
   12749             if (explicit) {
   12750                 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
   12751             }
   12752             return false;
   12753         }
   12754         BroadcastRecord r = mOrderedBroadcasts.get(0);
   12755         if (r.receiver == null) {
   12756             if (explicit) {
   12757                 Slog.w(TAG, "finishReceiver called but none active");
   12758             }
   12759             return false;
   12760         }
   12761         if (r.receiver != receiver) {
   12762             Slog.w(TAG, "finishReceiver called but active receiver is different");
   12763             return false;
   12764         }
   12765         int state = r.state;
   12766         r.state = r.IDLE;
   12767         if (state == r.IDLE) {
   12768             if (explicit) {
   12769                 Slog.w(TAG, "finishReceiver called but state is IDLE");
   12770             }
   12771         }
   12772         r.receiver = null;
   12773         r.intent.setComponent(null);
   12774         if (r.curApp != null) {
   12775             r.curApp.curReceiver = null;
   12776         }
   12777         if (r.curFilter != null) {
   12778             r.curFilter.receiverList.curBroadcast = null;
   12779         }
   12780         r.curFilter = null;
   12781         r.curApp = null;
   12782         r.curComponent = null;
   12783         r.curReceiver = null;
   12784         mPendingBroadcast = null;
   12785 
   12786         r.resultCode = resultCode;
   12787         r.resultData = resultData;
   12788         r.resultExtras = resultExtras;
   12789         r.resultAbort = resultAbort;
   12790 
   12791         // We will process the next receiver right now if this is finishing
   12792         // an app receiver (which is always asynchronous) or after we have
   12793         // come back from calling a receiver.
   12794         return state == BroadcastRecord.APP_RECEIVE
   12795                 || state == BroadcastRecord.CALL_DONE_RECEIVE;
   12796     }
   12797 
   12798     public void finishReceiver(IBinder who, int resultCode, String resultData,
   12799             Bundle resultExtras, boolean resultAbort) {
   12800         if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
   12801 
   12802         // Refuse possible leaked file descriptors
   12803         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
   12804             throw new IllegalArgumentException("File descriptors passed in Bundle");
   12805         }
   12806 
   12807         boolean doNext;
   12808 
   12809         final long origId = Binder.clearCallingIdentity();
   12810 
   12811         synchronized(this) {
   12812             doNext = finishReceiverLocked(
   12813                 who, resultCode, resultData, resultExtras, resultAbort, true);
   12814         }
   12815 
   12816         if (doNext) {
   12817             processNextBroadcast(false);
   12818         }
   12819         trimApplications();
   12820 
   12821         Binder.restoreCallingIdentity(origId);
   12822     }
   12823 
   12824     private final void logBroadcastReceiverDiscard(BroadcastRecord r) {
   12825         if (r.nextReceiver > 0) {
   12826             Object curReceiver = r.receivers.get(r.nextReceiver-1);
   12827             if (curReceiver instanceof BroadcastFilter) {
   12828                 BroadcastFilter bf = (BroadcastFilter) curReceiver;
   12829                 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
   12830                         System.identityHashCode(r),
   12831                         r.intent.getAction(),
   12832                         r.nextReceiver - 1,
   12833                         System.identityHashCode(bf));
   12834             } else {
   12835                 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
   12836                         System.identityHashCode(r),
   12837                         r.intent.getAction(),
   12838                         r.nextReceiver - 1,
   12839                         ((ResolveInfo)curReceiver).toString());
   12840             }
   12841         } else {
   12842             Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
   12843                     + r);
   12844             EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
   12845                     System.identityHashCode(r),
   12846                     r.intent.getAction(),
   12847                     r.nextReceiver,
   12848                     "NONE");
   12849         }
   12850     }
   12851 
   12852     private final void broadcastTimeout() {
   12853         ProcessRecord app = null;
   12854         String anrMessage = null;
   12855 
   12856         synchronized (this) {
   12857             if (mOrderedBroadcasts.size() == 0) {
   12858                 return;
   12859             }
   12860             long now = SystemClock.uptimeMillis();
   12861             BroadcastRecord r = mOrderedBroadcasts.get(0);
   12862             if ((r.receiverTime+BROADCAST_TIMEOUT) > now) {
   12863                 if (DEBUG_BROADCAST) Slog.v(TAG,
   12864                         "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
   12865                         + (r.receiverTime + BROADCAST_TIMEOUT));
   12866                 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
   12867                 mHandler.sendMessageAtTime(msg, r.receiverTime+BROADCAST_TIMEOUT);
   12868                 return;
   12869             }
   12870 
   12871             Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver);
   12872             r.receiverTime = now;
   12873             r.anrCount++;
   12874 
   12875             // Current receiver has passed its expiration date.
   12876             if (r.nextReceiver <= 0) {
   12877                 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
   12878                 return;
   12879             }
   12880 
   12881             Object curReceiver = r.receivers.get(r.nextReceiver-1);
   12882             Slog.w(TAG, "Receiver during timeout: " + curReceiver);
   12883             logBroadcastReceiverDiscard(r);
   12884             if (curReceiver instanceof BroadcastFilter) {
   12885                 BroadcastFilter bf = (BroadcastFilter)curReceiver;
   12886                 if (bf.receiverList.pid != 0
   12887                         && bf.receiverList.pid != MY_PID) {
   12888                     synchronized (this.mPidsSelfLocked) {
   12889                         app = this.mPidsSelfLocked.get(
   12890                                 bf.receiverList.pid);
   12891                     }
   12892                 }
   12893             } else {
   12894                 app = r.curApp;
   12895             }
   12896 
   12897             if (app != null) {
   12898                 anrMessage = "Broadcast of " + r.intent.toString();
   12899             }
   12900 
   12901             if (mPendingBroadcast == r) {
   12902                 mPendingBroadcast = null;
   12903             }
   12904 
   12905             // Move on to the next receiver.
   12906             finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
   12907                     r.resultExtras, r.resultAbort, true);
   12908             scheduleBroadcastsLocked();
   12909         }
   12910 
   12911         if (anrMessage != null) {
   12912             appNotResponding(app, null, null, anrMessage);
   12913         }
   12914     }
   12915 
   12916     private final void processCurBroadcastLocked(BroadcastRecord r,
   12917             ProcessRecord app) throws RemoteException {
   12918         if (app.thread == null) {
   12919             throw new RemoteException();
   12920         }
   12921         r.receiver = app.thread.asBinder();
   12922         r.curApp = app;
   12923         app.curReceiver = r;
   12924         updateLruProcessLocked(app, true, true);
   12925 
   12926         // Tell the application to launch this receiver.
   12927         r.intent.setComponent(r.curComponent);
   12928 
   12929         boolean started = false;
   12930         try {
   12931             if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
   12932                     "Delivering to component " + r.curComponent
   12933                     + ": " + r);
   12934             ensurePackageDexOpt(r.intent.getComponent().getPackageName());
   12935             app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
   12936                     r.resultCode, r.resultData, r.resultExtras, r.ordered);
   12937             started = true;
   12938         } finally {
   12939             if (!started) {
   12940                 r.receiver = null;
   12941                 r.curApp = null;
   12942                 app.curReceiver = null;
   12943             }
   12944         }
   12945 
   12946     }
   12947 
   12948     static void performReceive(ProcessRecord app, IIntentReceiver receiver,
   12949             Intent intent, int resultCode, String data, Bundle extras,
   12950             boolean ordered, boolean sticky) throws RemoteException {
   12951         if (app != null && app.thread != null) {
   12952             // If we have an app thread, do the call through that so it is
   12953             // correctly ordered with other one-way calls.
   12954             app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
   12955                     data, extras, ordered, sticky);
   12956         } else {
   12957             receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
   12958         }
   12959     }
   12960 
   12961     private final void deliverToRegisteredReceiver(BroadcastRecord r,
   12962             BroadcastFilter filter, boolean ordered) {
   12963         boolean skip = false;
   12964         if (filter.requiredPermission != null) {
   12965             int perm = checkComponentPermission(filter.requiredPermission,
   12966                     r.callingPid, r.callingUid, -1);
   12967             if (perm != PackageManager.PERMISSION_GRANTED) {
   12968                 Slog.w(TAG, "Permission Denial: broadcasting "
   12969                         + r.intent.toString()
   12970                         + " from " + r.callerPackage + " (pid="
   12971                         + r.callingPid + ", uid=" + r.callingUid + ")"
   12972                         + " requires " + filter.requiredPermission
   12973                         + " due to registered receiver " + filter);
   12974                 skip = true;
   12975             }
   12976         }
   12977         if (r.requiredPermission != null) {
   12978             int perm = checkComponentPermission(r.requiredPermission,
   12979                     filter.receiverList.pid, filter.receiverList.uid, -1);
   12980             if (perm != PackageManager.PERMISSION_GRANTED) {
   12981                 Slog.w(TAG, "Permission Denial: receiving "
   12982                         + r.intent.toString()
   12983                         + " to " + filter.receiverList.app
   12984                         + " (pid=" + filter.receiverList.pid
   12985                         + ", uid=" + filter.receiverList.uid + ")"
   12986                         + " requires " + r.requiredPermission
   12987                         + " due to sender " + r.callerPackage
   12988                         + " (uid " + r.callingUid + ")");
   12989                 skip = true;
   12990             }
   12991         }
   12992 
   12993         if (!skip) {
   12994             // If this is not being sent as an ordered broadcast, then we
   12995             // don't want to touch the fields that keep track of the current
   12996             // state of ordered broadcasts.
   12997             if (ordered) {
   12998                 r.receiver = filter.receiverList.receiver.asBinder();
   12999                 r.curFilter = filter;
   13000                 filter.receiverList.curBroadcast = r;
   13001                 r.state = BroadcastRecord.CALL_IN_RECEIVE;
   13002                 if (filter.receiverList.app != null) {
   13003                     // Bump hosting application to no longer be in background
   13004                     // scheduling class.  Note that we can't do that if there
   13005                     // isn't an app...  but we can only be in that case for
   13006                     // things that directly call the IActivityManager API, which
   13007                     // are already core system stuff so don't matter for this.
   13008                     r.curApp = filter.receiverList.app;
   13009                     filter.receiverList.app.curReceiver = r;
   13010                     updateOomAdjLocked();
   13011                 }
   13012             }
   13013             try {
   13014                 if (DEBUG_BROADCAST_LIGHT) {
   13015                     int seq = r.intent.getIntExtra("seq", -1);
   13016                     Slog.i(TAG, "Delivering to " + filter
   13017                             + " (seq=" + seq + "): " + r);
   13018                 }
   13019                 performReceive(filter.receiverList.app, filter.receiverList.receiver,
   13020                     new Intent(r.intent), r.resultCode,
   13021                     r.resultData, r.resultExtras, r.ordered, r.initialSticky);
   13022                 if (ordered) {
   13023                     r.state = BroadcastRecord.CALL_DONE_RECEIVE;
   13024                 }
   13025             } catch (RemoteException e) {
   13026                 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
   13027                 if (ordered) {
   13028                     r.receiver = null;
   13029                     r.curFilter = null;
   13030                     filter.receiverList.curBroadcast = null;
   13031                     if (filter.receiverList.app != null) {
   13032                         filter.receiverList.app.curReceiver = null;
   13033                     }
   13034                 }
   13035             }
   13036         }
   13037     }
   13038 
   13039     private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
   13040         if (r.callingUid < 0) {
   13041             // This was from a registerReceiver() call; ignore it.
   13042             return;
   13043         }
   13044         System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
   13045                 MAX_BROADCAST_HISTORY-1);
   13046         r.finishTime = SystemClock.uptimeMillis();
   13047         mBroadcastHistory[0] = r;
   13048     }
   13049 
   13050     private final void processNextBroadcast(boolean fromMsg) {
   13051         synchronized(this) {
   13052             BroadcastRecord r;
   13053 
   13054             if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
   13055                     + mParallelBroadcasts.size() + " broadcasts, "
   13056                     + mOrderedBroadcasts.size() + " ordered broadcasts");
   13057 
   13058             updateCpuStats();
   13059 
   13060             if (fromMsg) {
   13061                 mBroadcastsScheduled = false;
   13062             }
   13063 
   13064             // First, deliver any non-serialized broadcasts right away.
   13065             while (mParallelBroadcasts.size() > 0) {
   13066                 r = mParallelBroadcasts.remove(0);
   13067                 r.dispatchTime = SystemClock.uptimeMillis();
   13068                 final int N = r.receivers.size();
   13069                 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
   13070                         + r);
   13071                 for (int i=0; i<N; i++) {
   13072                     Object target = r.receivers.get(i);
   13073                     if (DEBUG_BROADCAST)  Slog.v(TAG,
   13074                             "Delivering non-ordered to registered "
   13075                             + target + ": " + r);
   13076                     deliverToRegisteredReceiver(r, (BroadcastFilter)target, false);
   13077                 }
   13078                 addBroadcastToHistoryLocked(r);
   13079                 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
   13080                         + r);
   13081             }
   13082 
   13083             // Now take care of the next serialized one...
   13084 
   13085             // If we are waiting for a process to come up to handle the next
   13086             // broadcast, then do nothing at this point.  Just in case, we
   13087             // check that the process we're waiting for still exists.
   13088             if (mPendingBroadcast != null) {
   13089                 if (DEBUG_BROADCAST_LIGHT) {
   13090                     Slog.v(TAG, "processNextBroadcast: waiting for "
   13091                             + mPendingBroadcast.curApp);
   13092                 }
   13093 
   13094                 boolean isDead;
   13095                 synchronized (mPidsSelfLocked) {
   13096                     isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
   13097                 }
   13098                 if (!isDead) {
   13099                     // It's still alive, so keep waiting
   13100                     return;
   13101                 } else {
   13102                     Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
   13103                             + " died before responding to broadcast");
   13104                     mPendingBroadcast = null;
   13105                 }
   13106             }
   13107 
   13108             boolean looped = false;
   13109 
   13110             do {
   13111                 if (mOrderedBroadcasts.size() == 0) {
   13112                     // No more broadcasts pending, so all done!
   13113                     scheduleAppGcsLocked();
   13114                     if (looped) {
   13115                         // If we had finished the last ordered broadcast, then
   13116                         // make sure all processes have correct oom and sched
   13117                         // adjustments.
   13118                         updateOomAdjLocked();
   13119                     }
   13120                     return;
   13121                 }
   13122                 r = mOrderedBroadcasts.get(0);
   13123                 boolean forceReceive = false;
   13124 
   13125                 // Ensure that even if something goes awry with the timeout
   13126                 // detection, we catch "hung" broadcasts here, discard them,
   13127                 // and continue to make progress.
   13128                 //
   13129                 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
   13130                 // receivers don't get executed with with timeouts. They're intended for
   13131                 // one time heavy lifting after system upgrades and can take
   13132                 // significant amounts of time.
   13133                 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
   13134                 if (mSystemReady && r.dispatchTime > 0) {
   13135                     long now = SystemClock.uptimeMillis();
   13136                     if ((numReceivers > 0) &&
   13137                             (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
   13138                         Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
   13139                                 + " now=" + now
   13140                                 + " dispatchTime=" + r.dispatchTime
   13141                                 + " startTime=" + r.receiverTime
   13142                                 + " intent=" + r.intent
   13143                                 + " numReceivers=" + numReceivers
   13144                                 + " nextReceiver=" + r.nextReceiver
   13145                                 + " state=" + r.state);
   13146                         broadcastTimeout(); // forcibly finish this broadcast
   13147                         forceReceive = true;
   13148                         r.state = BroadcastRecord.IDLE;
   13149                     }
   13150                 }
   13151 
   13152                 if (r.state != BroadcastRecord.IDLE) {
   13153                     if (DEBUG_BROADCAST) Slog.d(TAG,
   13154                             "processNextBroadcast() called when not idle (state="
   13155                             + r.state + ")");
   13156                     return;
   13157                 }
   13158 
   13159                 if (r.receivers == null || r.nextReceiver >= numReceivers
   13160                         || r.resultAbort || forceReceive) {
   13161                     // No more receivers for this broadcast!  Send the final
   13162                     // result if requested...
   13163                     if (r.resultTo != null) {
   13164                         try {
   13165                             if (DEBUG_BROADCAST) {
   13166                                 int seq = r.intent.getIntExtra("seq", -1);
   13167                                 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
   13168                                         + " seq=" + seq + " app=" + r.callerApp);
   13169                             }
   13170                             performReceive(r.callerApp, r.resultTo,
   13171                                 new Intent(r.intent), r.resultCode,
   13172                                 r.resultData, r.resultExtras, false, false);
   13173                         } catch (RemoteException e) {
   13174                             Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
   13175                         }
   13176                     }
   13177 
   13178                     if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
   13179                     mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
   13180 
   13181                     if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
   13182                             + r);
   13183 
   13184                     // ... and on to the next...
   13185                     addBroadcastToHistoryLocked(r);
   13186                     mOrderedBroadcasts.remove(0);
   13187                     r = null;
   13188                     looped = true;
   13189                     continue;
   13190                 }
   13191             } while (r == null);
   13192 
   13193             // Get the next receiver...
   13194             int recIdx = r.nextReceiver++;
   13195 
   13196             // Keep track of when this receiver started, and make sure there
   13197             // is a timeout message pending to kill it if need be.
   13198             r.receiverTime = SystemClock.uptimeMillis();
   13199             if (recIdx == 0) {
   13200                 r.dispatchTime = r.receiverTime;
   13201 
   13202                 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
   13203                         + r);
   13204                 if (DEBUG_BROADCAST) Slog.v(TAG,
   13205                         "Submitting BROADCAST_TIMEOUT_MSG for "
   13206                         + (r.receiverTime + BROADCAST_TIMEOUT));
   13207                 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
   13208                 mHandler.sendMessageAtTime(msg, r.receiverTime+BROADCAST_TIMEOUT);
   13209             }
   13210 
   13211             Object nextReceiver = r.receivers.get(recIdx);
   13212             if (nextReceiver instanceof BroadcastFilter) {
   13213                 // Simple case: this is a registered receiver who gets
   13214                 // a direct call.
   13215                 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
   13216                 if (DEBUG_BROADCAST)  Slog.v(TAG,
   13217                         "Delivering ordered to registered "
   13218                         + filter + ": " + r);
   13219                 deliverToRegisteredReceiver(r, filter, r.ordered);
   13220                 if (r.receiver == null || !r.ordered) {
   13221                     // The receiver has already finished, so schedule to
   13222                     // process the next one.
   13223                     if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
   13224                             + r.ordered + " receiver=" + r.receiver);
   13225                     r.state = BroadcastRecord.IDLE;
   13226                     scheduleBroadcastsLocked();
   13227                 }
   13228                 return;
   13229             }
   13230 
   13231             // Hard case: need to instantiate the receiver, possibly
   13232             // starting its application process to host it.
   13233 
   13234             ResolveInfo info =
   13235                 (ResolveInfo)nextReceiver;
   13236 
   13237             boolean skip = false;
   13238             int perm = checkComponentPermission(info.activityInfo.permission,
   13239                     r.callingPid, r.callingUid,
   13240                     info.activityInfo.exported
   13241                             ? -1 : info.activityInfo.applicationInfo.uid);
   13242             if (perm != PackageManager.PERMISSION_GRANTED) {
   13243                 Slog.w(TAG, "Permission Denial: broadcasting "
   13244                         + r.intent.toString()
   13245                         + " from " + r.callerPackage + " (pid=" + r.callingPid
   13246                         + ", uid=" + r.callingUid + ")"
   13247                         + " requires " + info.activityInfo.permission
   13248                         + " due to receiver " + info.activityInfo.packageName
   13249                         + "/" + info.activityInfo.name);
   13250                 skip = true;
   13251             }
   13252             if (r.callingUid != Process.SYSTEM_UID &&
   13253                 r.requiredPermission != null) {
   13254                 try {
   13255                     perm = ActivityThread.getPackageManager().
   13256                             checkPermission(r.requiredPermission,
   13257                                     info.activityInfo.applicationInfo.packageName);
   13258                 } catch (RemoteException e) {
   13259                     perm = PackageManager.PERMISSION_DENIED;
   13260                 }
   13261                 if (perm != PackageManager.PERMISSION_GRANTED) {
   13262                     Slog.w(TAG, "Permission Denial: receiving "
   13263                             + r.intent + " to "
   13264                             + info.activityInfo.applicationInfo.packageName
   13265                             + " requires " + r.requiredPermission
   13266                             + " due to sender " + r.callerPackage
   13267                             + " (uid " + r.callingUid + ")");
   13268                     skip = true;
   13269                 }
   13270             }
   13271             if (r.curApp != null && r.curApp.crashing) {
   13272                 // If the target process is crashing, just skip it.
   13273                 skip = true;
   13274             }
   13275 
   13276             if (skip) {
   13277                 r.receiver = null;
   13278                 r.curFilter = null;
   13279                 r.state = BroadcastRecord.IDLE;
   13280                 scheduleBroadcastsLocked();
   13281                 return;
   13282             }
   13283 
   13284             r.state = BroadcastRecord.APP_RECEIVE;
   13285             String targetProcess = info.activityInfo.processName;
   13286             r.curComponent = new ComponentName(
   13287                     info.activityInfo.applicationInfo.packageName,
   13288                     info.activityInfo.name);
   13289             r.curReceiver = info.activityInfo;
   13290 
   13291             // Is this receiver's application already running?
   13292             ProcessRecord app = getProcessRecordLocked(targetProcess,
   13293                     info.activityInfo.applicationInfo.uid);
   13294             if (app != null && app.thread != null) {
   13295                 try {
   13296                     processCurBroadcastLocked(r, app);
   13297                     return;
   13298                 } catch (RemoteException e) {
   13299                     Slog.w(TAG, "Exception when sending broadcast to "
   13300                           + r.curComponent, e);
   13301                 }
   13302 
   13303                 // If a dead object exception was thrown -- fall through to
   13304                 // restart the application.
   13305             }
   13306 
   13307             // Not running -- get it started, to be executed when the app comes up.
   13308             if ((r.curApp=startProcessLocked(targetProcess,
   13309                     info.activityInfo.applicationInfo, true,
   13310                     r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
   13311                     "broadcast", r.curComponent,
   13312                     (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
   13313                             == null) {
   13314                 // Ah, this recipient is unavailable.  Finish it if necessary,
   13315                 // and mark the broadcast record as ready for the next.
   13316                 Slog.w(TAG, "Unable to launch app "
   13317                         + info.activityInfo.applicationInfo.packageName + "/"
   13318                         + info.activityInfo.applicationInfo.uid + " for broadcast "
   13319                         + r.intent + ": process is bad");
   13320                 logBroadcastReceiverDiscard(r);
   13321                 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
   13322                         r.resultExtras, r.resultAbort, true);
   13323                 scheduleBroadcastsLocked();
   13324                 r.state = BroadcastRecord.IDLE;
   13325                 return;
   13326             }
   13327 
   13328             mPendingBroadcast = r;
   13329         }
   13330     }
   13331 
   13332     // =========================================================
   13333     // INSTRUMENTATION
   13334     // =========================================================
   13335 
   13336     public boolean startInstrumentation(ComponentName className,
   13337             String profileFile, int flags, Bundle arguments,
   13338             IInstrumentationWatcher watcher) {
   13339         // Refuse possible leaked file descriptors
   13340         if (arguments != null && arguments.hasFileDescriptors()) {
   13341             throw new IllegalArgumentException("File descriptors passed in Bundle");
   13342         }
   13343 
   13344         synchronized(this) {
   13345             InstrumentationInfo ii = null;
   13346             ApplicationInfo ai = null;
   13347             try {
   13348                 ii = mContext.getPackageManager().getInstrumentationInfo(
   13349                     className, STOCK_PM_FLAGS);
   13350                 ai = mContext.getPackageManager().getApplicationInfo(
   13351                     ii.targetPackage, STOCK_PM_FLAGS);
   13352             } catch (PackageManager.NameNotFoundException e) {
   13353             }
   13354             if (ii == null) {
   13355                 reportStartInstrumentationFailure(watcher, className,
   13356                         "Unable to find instrumentation info for: " + className);
   13357                 return false;
   13358             }
   13359             if (ai == null) {
   13360                 reportStartInstrumentationFailure(watcher, className,
   13361                         "Unable to find instrumentation target package: " + ii.targetPackage);
   13362                 return false;
   13363             }
   13364 
   13365             int match = mContext.getPackageManager().checkSignatures(
   13366                     ii.targetPackage, ii.packageName);
   13367             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
   13368                 String msg = "Permission Denial: starting instrumentation "
   13369                         + className + " from pid="
   13370                         + Binder.getCallingPid()
   13371                         + ", uid=" + Binder.getCallingPid()
   13372                         + " not allowed because package " + ii.packageName
   13373                         + " does not have a signature matching the target "
   13374                         + ii.targetPackage;
   13375                 reportStartInstrumentationFailure(watcher, className, msg);
   13376                 throw new SecurityException(msg);
   13377             }
   13378 
   13379             final long origId = Binder.clearCallingIdentity();
   13380             forceStopPackageLocked(ii.targetPackage, -1, true, false, true);
   13381             ProcessRecord app = addAppLocked(ai);
   13382             app.instrumentationClass = className;
   13383             app.instrumentationInfo = ai;
   13384             app.instrumentationProfileFile = profileFile;
   13385             app.instrumentationArguments = arguments;
   13386             app.instrumentationWatcher = watcher;
   13387             app.instrumentationResultClass = className;
   13388             Binder.restoreCallingIdentity(origId);
   13389         }
   13390 
   13391         return true;
   13392     }
   13393 
   13394     /**
   13395      * Report errors that occur while attempting to start Instrumentation.  Always writes the
   13396      * error to the logs, but if somebody is watching, send the report there too.  This enables
   13397      * the "am" command to report errors with more information.
   13398      *
   13399      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
   13400      * @param cn The component name of the instrumentation.
   13401      * @param report The error report.
   13402      */
   13403     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
   13404             ComponentName cn, String report) {
   13405         Slog.w(TAG, report);
   13406         try {
   13407             if (watcher != null) {
   13408                 Bundle results = new Bundle();
   13409                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
   13410                 results.putString("Error", report);
   13411                 watcher.instrumentationStatus(cn, -1, results);
   13412             }
   13413         } catch (RemoteException e) {
   13414             Slog.w(TAG, e);
   13415         }
   13416     }
   13417 
   13418     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
   13419         if (app.instrumentationWatcher != null) {
   13420             try {
   13421                 // NOTE:  IInstrumentationWatcher *must* be oneway here
   13422                 app.instrumentationWatcher.instrumentationFinished(
   13423                     app.instrumentationClass,
   13424                     resultCode,
   13425                     results);
   13426             } catch (RemoteException e) {
   13427             }
   13428         }
   13429         app.instrumentationWatcher = null;
   13430         app.instrumentationClass = null;
   13431         app.instrumentationInfo = null;
   13432         app.instrumentationProfileFile = null;
   13433         app.instrumentationArguments = null;
   13434 
   13435         forceStopPackageLocked(app.processName, -1, false, false, true);
   13436     }
   13437 
   13438     public void finishInstrumentation(IApplicationThread target,
   13439             int resultCode, Bundle results) {
   13440         // Refuse possible leaked file descriptors
   13441         if (results != null && results.hasFileDescriptors()) {
   13442             throw new IllegalArgumentException("File descriptors passed in Intent");
   13443         }
   13444 
   13445         synchronized(this) {
   13446             ProcessRecord app = getRecordForAppLocked(target);
   13447             if (app == null) {
   13448                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
   13449                 return;
   13450             }
   13451             final long origId = Binder.clearCallingIdentity();
   13452             finishInstrumentationLocked(app, resultCode, results);
   13453             Binder.restoreCallingIdentity(origId);
   13454         }
   13455     }
   13456 
   13457     // =========================================================
   13458     // CONFIGURATION
   13459     // =========================================================
   13460 
   13461     public ConfigurationInfo getDeviceConfigurationInfo() {
   13462         ConfigurationInfo config = new ConfigurationInfo();
   13463         synchronized (this) {
   13464             config.reqTouchScreen = mConfiguration.touchscreen;
   13465             config.reqKeyboardType = mConfiguration.keyboard;
   13466             config.reqNavigation = mConfiguration.navigation;
   13467             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
   13468                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
   13469                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
   13470             }
   13471             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
   13472                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
   13473                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
   13474             }
   13475             config.reqGlEsVersion = GL_ES_VERSION;
   13476         }
   13477         return config;
   13478     }
   13479 
   13480     public Configuration getConfiguration() {
   13481         Configuration ci;
   13482         synchronized(this) {
   13483             ci = new Configuration(mConfiguration);
   13484         }
   13485         return ci;
   13486     }
   13487 
   13488     public void updateConfiguration(Configuration values) {
   13489         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   13490                 "updateConfiguration()");
   13491 
   13492         synchronized(this) {
   13493             if (values == null && mWindowManager != null) {
   13494                 // sentinel: fetch the current configuration from the window manager
   13495                 values = mWindowManager.computeNewConfiguration();
   13496             }
   13497 
   13498             final long origId = Binder.clearCallingIdentity();
   13499             updateConfigurationLocked(values, null);
   13500             Binder.restoreCallingIdentity(origId);
   13501         }
   13502     }
   13503 
   13504     /**
   13505      * Do either or both things: (1) change the current configuration, and (2)
   13506      * make sure the given activity is running with the (now) current
   13507      * configuration.  Returns true if the activity has been left running, or
   13508      * false if <var>starting</var> is being destroyed to match the new
   13509      * configuration.
   13510      */
   13511     public boolean updateConfigurationLocked(Configuration values,
   13512             HistoryRecord starting) {
   13513         int changes = 0;
   13514 
   13515         boolean kept = true;
   13516 
   13517         if (values != null) {
   13518             Configuration newConfig = new Configuration(mConfiguration);
   13519             changes = newConfig.updateFrom(values);
   13520             if (changes != 0) {
   13521                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
   13522                     Slog.i(TAG, "Updating configuration to: " + values);
   13523                 }
   13524 
   13525                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
   13526 
   13527                 if (values.locale != null) {
   13528                     saveLocaleLocked(values.locale,
   13529                                      !values.locale.equals(mConfiguration.locale),
   13530                                      values.userSetLocale);
   13531                 }
   13532 
   13533                 mConfigurationSeq++;
   13534                 if (mConfigurationSeq <= 0) {
   13535                     mConfigurationSeq = 1;
   13536                 }
   13537                 newConfig.seq = mConfigurationSeq;
   13538                 mConfiguration = newConfig;
   13539                 Slog.i(TAG, "Config changed: " + newConfig);
   13540 
   13541                 AttributeCache ac = AttributeCache.instance();
   13542                 if (ac != null) {
   13543                     ac.updateConfiguration(mConfiguration);
   13544                 }
   13545 
   13546                 if (Settings.System.hasInterestingConfigurationChanges(changes)) {
   13547                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
   13548                     msg.obj = new Configuration(mConfiguration);
   13549                     mHandler.sendMessage(msg);
   13550                 }
   13551 
   13552                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   13553                     ProcessRecord app = mLruProcesses.get(i);
   13554                     try {
   13555                         if (app.thread != null) {
   13556                             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
   13557                                     + app.processName + " new config " + mConfiguration);
   13558                             app.thread.scheduleConfigurationChanged(mConfiguration);
   13559                         }
   13560                     } catch (Exception e) {
   13561                     }
   13562                 }
   13563                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
   13564                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   13565                         | Intent.FLAG_RECEIVER_REPLACE_PENDING);
   13566                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
   13567                         null, false, false, MY_PID, Process.SYSTEM_UID);
   13568                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
   13569                     broadcastIntentLocked(null, null,
   13570                             new Intent(Intent.ACTION_LOCALE_CHANGED),
   13571                             null, null, 0, null, null,
   13572                             null, false, false, MY_PID, Process.SYSTEM_UID);
   13573                 }
   13574             }
   13575         }
   13576 
   13577         if (changes != 0 && starting == null) {
   13578             // If the configuration changed, and the caller is not already
   13579             // in the process of starting an activity, then find the top
   13580             // activity to check if its configuration needs to change.
   13581             starting = topRunningActivityLocked(null);
   13582         }
   13583 
   13584         if (starting != null) {
   13585             kept = ensureActivityConfigurationLocked(starting, changes);
   13586             if (kept) {
   13587                 // If this didn't result in the starting activity being
   13588                 // destroyed, then we need to make sure at this point that all
   13589                 // other activities are made visible.
   13590                 if (DEBUG_SWITCH) Slog.i(TAG, "Config didn't destroy " + starting
   13591                         + ", ensuring others are correct.");
   13592                 ensureActivitiesVisibleLocked(starting, changes);
   13593             }
   13594         }
   13595 
   13596         if (values != null && mWindowManager != null) {
   13597             mWindowManager.setNewConfiguration(mConfiguration);
   13598         }
   13599 
   13600         return kept;
   13601     }
   13602 
   13603     private final boolean relaunchActivityLocked(HistoryRecord r,
   13604             int changes, boolean andResume) {
   13605         List<ResultInfo> results = null;
   13606         List<Intent> newIntents = null;
   13607         if (andResume) {
   13608             results = r.results;
   13609             newIntents = r.newIntents;
   13610         }
   13611         if (DEBUG_SWITCH) Slog.v(TAG, "Relaunching: " + r
   13612                 + " with results=" + results + " newIntents=" + newIntents
   13613                 + " andResume=" + andResume);
   13614         EventLog.writeEvent(andResume ? EventLogTags.AM_RELAUNCH_RESUME_ACTIVITY
   13615                 : EventLogTags.AM_RELAUNCH_ACTIVITY, System.identityHashCode(r),
   13616                 r.task.taskId, r.shortComponentName);
   13617 
   13618         r.startFreezingScreenLocked(r.app, 0);
   13619 
   13620         try {
   13621             if (DEBUG_SWITCH) Slog.i(TAG, "Switch is restarting resumed " + r);
   13622             r.app.thread.scheduleRelaunchActivity(r, results, newIntents,
   13623                     changes, !andResume, mConfiguration);
   13624             // Note: don't need to call pauseIfSleepingLocked() here, because
   13625             // the caller will only pass in 'andResume' if this activity is
   13626             // currently resumed, which implies we aren't sleeping.
   13627         } catch (RemoteException e) {
   13628             return false;
   13629         }
   13630 
   13631         if (andResume) {
   13632             r.results = null;
   13633             r.newIntents = null;
   13634             reportResumedActivityLocked(r);
   13635         }
   13636 
   13637         return true;
   13638     }
   13639 
   13640     /**
   13641      * Make sure the given activity matches the current configuration.  Returns
   13642      * false if the activity had to be destroyed.  Returns true if the
   13643      * configuration is the same, or the activity will remain running as-is
   13644      * for whatever reason.  Ensures the HistoryRecord is updated with the
   13645      * correct configuration and all other bookkeeping is handled.
   13646      */
   13647     private final boolean ensureActivityConfigurationLocked(HistoryRecord r,
   13648             int globalChanges) {
   13649         if (mConfigWillChange) {
   13650             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
   13651                     "Skipping config check (will change): " + r);
   13652             return true;
   13653         }
   13654 
   13655         if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
   13656                 "Ensuring correct configuration: " + r);
   13657 
   13658         // Short circuit: if the two configurations are the exact same
   13659         // object (the common case), then there is nothing to do.
   13660         Configuration newConfig = mConfiguration;
   13661         if (r.configuration == newConfig) {
   13662             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
   13663                     "Configuration unchanged in " + r);
   13664             return true;
   13665         }
   13666 
   13667         // We don't worry about activities that are finishing.
   13668         if (r.finishing) {
   13669             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
   13670                     "Configuration doesn't matter in finishing " + r);
   13671             r.stopFreezingScreenLocked(false);
   13672             return true;
   13673         }
   13674 
   13675         // Okay we now are going to make this activity have the new config.
   13676         // But then we need to figure out how it needs to deal with that.
   13677         Configuration oldConfig = r.configuration;
   13678         r.configuration = newConfig;
   13679 
   13680         // If the activity isn't currently running, just leave the new
   13681         // configuration and it will pick that up next time it starts.
   13682         if (r.app == null || r.app.thread == null) {
   13683             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
   13684                     "Configuration doesn't matter not running " + r);
   13685             r.stopFreezingScreenLocked(false);
   13686             return true;
   13687         }
   13688 
   13689         // If the activity isn't persistent, there is a chance we will
   13690         // need to restart it.
   13691         if (!r.persistent) {
   13692 
   13693             // Figure out what has changed between the two configurations.
   13694             int changes = oldConfig.diff(newConfig);
   13695             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
   13696                 Slog.v(TAG, "Checking to restart " + r.info.name + ": changed=0x"
   13697                         + Integer.toHexString(changes) + ", handles=0x"
   13698                         + Integer.toHexString(r.info.configChanges)
   13699                         + ", newConfig=" + newConfig);
   13700             }
   13701             if ((changes&(~r.info.configChanges)) != 0) {
   13702                 // Aha, the activity isn't handling the change, so DIE DIE DIE.
   13703                 r.configChangeFlags |= changes;
   13704                 r.startFreezingScreenLocked(r.app, globalChanges);
   13705                 if (r.app == null || r.app.thread == null) {
   13706                     if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
   13707                             "Switch is destroying non-running " + r);
   13708                     destroyActivityLocked(r, true);
   13709                 } else if (r.state == ActivityState.PAUSING) {
   13710                     // A little annoying: we are waiting for this activity to
   13711                     // finish pausing.  Let's not do anything now, but just
   13712                     // flag that it needs to be restarted when done pausing.
   13713                     if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
   13714                             "Switch is skipping already pausing " + r);
   13715                     r.configDestroy = true;
   13716                     return true;
   13717                 } else if (r.state == ActivityState.RESUMED) {
   13718                     // Try to optimize this case: the configuration is changing
   13719                     // and we need to restart the top, resumed activity.
   13720                     // Instead of doing the normal handshaking, just say
   13721                     // "restart!".
   13722                     if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
   13723                             "Switch is restarting resumed " + r);
   13724                     relaunchActivityLocked(r, r.configChangeFlags, true);
   13725                     r.configChangeFlags = 0;
   13726                 } else {
   13727                     if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
   13728                             "Switch is restarting non-resumed " + r);
   13729                     relaunchActivityLocked(r, r.configChangeFlags, false);
   13730                     r.configChangeFlags = 0;
   13731                 }
   13732 
   13733                 // All done...  tell the caller we weren't able to keep this
   13734                 // activity around.
   13735                 return false;
   13736             }
   13737         }
   13738 
   13739         // Default case: the activity can handle this new configuration, so
   13740         // hand it over.  Note that we don't need to give it the new
   13741         // configuration, since we always send configuration changes to all
   13742         // process when they happen so it can just use whatever configuration
   13743         // it last got.
   13744         if (r.app != null && r.app.thread != null) {
   13745             try {
   13746                 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending new config to " + r);
   13747                 r.app.thread.scheduleActivityConfigurationChanged(r);
   13748             } catch (RemoteException e) {
   13749                 // If process died, whatever.
   13750             }
   13751         }
   13752         r.stopFreezingScreenLocked(false);
   13753 
   13754         return true;
   13755     }
   13756 
   13757     /**
   13758      * Save the locale.  You must be inside a synchronized (this) block.
   13759      */
   13760     private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
   13761         if(isDiff) {
   13762             SystemProperties.set("user.language", l.getLanguage());
   13763             SystemProperties.set("user.region", l.getCountry());
   13764         }
   13765 
   13766         if(isPersist) {
   13767             SystemProperties.set("persist.sys.language", l.getLanguage());
   13768             SystemProperties.set("persist.sys.country", l.getCountry());
   13769             SystemProperties.set("persist.sys.localevar", l.getVariant());
   13770         }
   13771     }
   13772 
   13773     // =========================================================
   13774     // LIFETIME MANAGEMENT
   13775     // =========================================================
   13776 
   13777     private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
   13778             ProcessRecord TOP_APP, boolean recursed) {
   13779         if (mAdjSeq == app.adjSeq) {
   13780             // This adjustment has already been computed.  If we are calling
   13781             // from the top, we may have already computed our adjustment with
   13782             // an earlier hidden adjustment that isn't really for us... if
   13783             // so, use the new hidden adjustment.
   13784             if (!recursed && app.hidden) {
   13785                 app.curAdj = hiddenAdj;
   13786             }
   13787             return app.curAdj;
   13788         }
   13789 
   13790         if (app.thread == null) {
   13791             app.adjSeq = mAdjSeq;
   13792             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13793             return (app.curAdj=EMPTY_APP_ADJ);
   13794         }
   13795 
   13796         if (app.maxAdj <= FOREGROUND_APP_ADJ) {
   13797             // The max adjustment doesn't allow this app to be anything
   13798             // below foreground, so it is not worth doing work for it.
   13799             app.adjType = "fixed";
   13800             app.adjSeq = mAdjSeq;
   13801             app.curRawAdj = app.maxAdj;
   13802             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
   13803             return (app.curAdj=app.maxAdj);
   13804        }
   13805 
   13806         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
   13807         app.adjSource = null;
   13808         app.adjTarget = null;
   13809         app.empty = false;
   13810         app.hidden = false;
   13811 
   13812         // Determine the importance of the process, starting with most
   13813         // important to least, and assign an appropriate OOM adjustment.
   13814         int adj;
   13815         int schedGroup;
   13816         int N;
   13817         if (app == TOP_APP) {
   13818             // The last app on the list is the foreground app.
   13819             adj = FOREGROUND_APP_ADJ;
   13820             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13821             app.adjType = "top-activity";
   13822         } else if (app.instrumentationClass != null) {
   13823             // Don't want to kill running instrumentation.
   13824             adj = FOREGROUND_APP_ADJ;
   13825             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13826             app.adjType = "instrumentation";
   13827         } else if (app.persistentActivities > 0) {
   13828             // Special persistent activities...  shouldn't be used these days.
   13829             adj = FOREGROUND_APP_ADJ;
   13830             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13831             app.adjType = "persistent";
   13832         } else if (app.curReceiver != null ||
   13833                 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
   13834             // An app that is currently receiving a broadcast also
   13835             // counts as being in the foreground.
   13836             adj = FOREGROUND_APP_ADJ;
   13837             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13838             app.adjType = "broadcast";
   13839         } else if (app.executingServices.size() > 0) {
   13840             // An app that is currently executing a service callback also
   13841             // counts as being in the foreground.
   13842             adj = FOREGROUND_APP_ADJ;
   13843             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13844             app.adjType = "exec-service";
   13845         } else if (app.foregroundServices) {
   13846             // The user is aware of this app, so make it visible.
   13847             adj = VISIBLE_APP_ADJ;
   13848             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13849             app.adjType = "foreground-service";
   13850         } else if (app.forcingToForeground != null) {
   13851             // The user is aware of this app, so make it visible.
   13852             adj = VISIBLE_APP_ADJ;
   13853             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13854             app.adjType = "force-foreground";
   13855             app.adjSource = app.forcingToForeground;
   13856         } else if (app == mHomeProcess) {
   13857             // This process is hosting what we currently consider to be the
   13858             // home app, so we don't want to let it go into the background.
   13859             adj = HOME_APP_ADJ;
   13860             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13861             app.adjType = "home";
   13862         } else if ((N=app.activities.size()) != 0) {
   13863             // This app is in the background with paused activities.
   13864             app.hidden = true;
   13865             adj = hiddenAdj;
   13866             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13867             app.adjType = "bg-activities";
   13868             N = app.activities.size();
   13869             for (int j=0; j<N; j++) {
   13870                 if (((HistoryRecord)app.activities.get(j)).visible) {
   13871                     // This app has a visible activity!
   13872                     app.hidden = false;
   13873                     adj = VISIBLE_APP_ADJ;
   13874                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   13875                     app.adjType = "visible";
   13876                     break;
   13877                 }
   13878             }
   13879         } else {
   13880             // A very not-needed process.  If this is lower in the lru list,
   13881             // we will push it in to the empty bucket.
   13882             app.hidden = true;
   13883             app.empty = true;
   13884             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13885             adj = hiddenAdj;
   13886             app.adjType = "bg-empty";
   13887         }
   13888 
   13889         //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
   13890 
   13891         // By default, we use the computed adjustment.  It may be changed if
   13892         // there are applications dependent on our services or providers, but
   13893         // this gives us a baseline and makes sure we don't get into an
   13894         // infinite recursion.
   13895         app.adjSeq = mAdjSeq;
   13896         app.curRawAdj = adj;
   13897 
   13898         if (mBackupTarget != null && app == mBackupTarget.app) {
   13899             // If possible we want to avoid killing apps while they're being backed up
   13900             if (adj > BACKUP_APP_ADJ) {
   13901                 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
   13902                 adj = BACKUP_APP_ADJ;
   13903                 app.adjType = "backup";
   13904                 app.hidden = false;
   13905             }
   13906         }
   13907 
   13908         if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
   13909                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   13910             final long now = SystemClock.uptimeMillis();
   13911             // This process is more important if the top activity is
   13912             // bound to the service.
   13913             Iterator jt = app.services.iterator();
   13914             while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
   13915                 ServiceRecord s = (ServiceRecord)jt.next();
   13916                 if (s.startRequested) {
   13917                     if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
   13918                         // This service has seen some activity within
   13919                         // recent memory, so we will keep its process ahead
   13920                         // of the background processes.
   13921                         if (adj > SECONDARY_SERVER_ADJ) {
   13922                             adj = SECONDARY_SERVER_ADJ;
   13923                             app.adjType = "started-services";
   13924                             app.hidden = false;
   13925                         }
   13926                     }
   13927                     // If we have let the service slide into the background
   13928                     // state, still have some text describing what it is doing
   13929                     // even though the service no longer has an impact.
   13930                     if (adj > SECONDARY_SERVER_ADJ) {
   13931                         app.adjType = "started-bg-services";
   13932                     }
   13933                 }
   13934                 if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
   13935                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   13936                     Iterator<ConnectionRecord> kt
   13937                             = s.connections.values().iterator();
   13938                     while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
   13939                         // XXX should compute this based on the max of
   13940                         // all connected clients.
   13941                         ConnectionRecord cr = kt.next();
   13942                         if (cr.binding.client == app) {
   13943                             // Binding to ourself is not interesting.
   13944                             continue;
   13945                         }
   13946                         if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
   13947                             ProcessRecord client = cr.binding.client;
   13948                             int myHiddenAdj = hiddenAdj;
   13949                             if (myHiddenAdj > client.hiddenAdj) {
   13950                                 if (client.hiddenAdj > VISIBLE_APP_ADJ) {
   13951                                     myHiddenAdj = client.hiddenAdj;
   13952                                 } else {
   13953                                     myHiddenAdj = VISIBLE_APP_ADJ;
   13954                                 }
   13955                             }
   13956                             int clientAdj = computeOomAdjLocked(
   13957                                 client, myHiddenAdj, TOP_APP, true);
   13958                             if (adj > clientAdj) {
   13959                                 adj = clientAdj > VISIBLE_APP_ADJ
   13960                                         ? clientAdj : VISIBLE_APP_ADJ;
   13961                                 if (!client.hidden) {
   13962                                     app.hidden = false;
   13963                                 }
   13964                                 app.adjType = "service";
   13965                                 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   13966                                         .REASON_SERVICE_IN_USE;
   13967                                 app.adjSource = cr.binding.client;
   13968                                 app.adjTarget = s.serviceInfo.name;
   13969                             }
   13970                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   13971                                 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   13972                                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   13973                                 }
   13974                             }
   13975                         }
   13976                         HistoryRecord a = cr.activity;
   13977                         //if (a != null) {
   13978                         //    Slog.i(TAG, "Connection to " + a ": state=" + a.state);
   13979                         //}
   13980                         if (a != null && adj > FOREGROUND_APP_ADJ &&
   13981                                 (a.state == ActivityState.RESUMED
   13982                                  || a.state == ActivityState.PAUSING)) {
   13983                             adj = FOREGROUND_APP_ADJ;
   13984                             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13985                             app.hidden = false;
   13986                             app.adjType = "service";
   13987                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   13988                                     .REASON_SERVICE_IN_USE;
   13989                             app.adjSource = a;
   13990                             app.adjTarget = s.serviceInfo.name;
   13991                         }
   13992                     }
   13993                 }
   13994             }
   13995 
   13996             // Finally, f this process has active services running in it, we
   13997             // would like to avoid killing it unless it would prevent the current
   13998             // application from running.  By default we put the process in
   13999             // with the rest of the background processes; as we scan through
   14000             // its services we may bump it up from there.
   14001             if (adj > hiddenAdj) {
   14002                 adj = hiddenAdj;
   14003                 app.hidden = false;
   14004                 app.adjType = "bg-services";
   14005             }
   14006         }
   14007 
   14008         if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ
   14009                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   14010             Iterator jt = app.pubProviders.values().iterator();
   14011             while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ
   14012                     || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   14013                 ContentProviderRecord cpr = (ContentProviderRecord)jt.next();
   14014                 if (cpr.clients.size() != 0) {
   14015                     Iterator<ProcessRecord> kt = cpr.clients.iterator();
   14016                     while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
   14017                         ProcessRecord client = kt.next();
   14018                         if (client == app) {
   14019                             // Being our own client is not interesting.
   14020                             continue;
   14021                         }
   14022                         int myHiddenAdj = hiddenAdj;
   14023                         if (myHiddenAdj > client.hiddenAdj) {
   14024                             if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
   14025                                 myHiddenAdj = client.hiddenAdj;
   14026                             } else {
   14027                                 myHiddenAdj = FOREGROUND_APP_ADJ;
   14028                             }
   14029                         }
   14030                         int clientAdj = computeOomAdjLocked(
   14031                             client, myHiddenAdj, TOP_APP, true);
   14032                         if (adj > clientAdj) {
   14033                             adj = clientAdj > FOREGROUND_APP_ADJ
   14034                                     ? clientAdj : FOREGROUND_APP_ADJ;
   14035                             if (!client.hidden) {
   14036                                 app.hidden = false;
   14037                             }
   14038                             app.adjType = "provider";
   14039                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   14040                                     .REASON_PROVIDER_IN_USE;
   14041                             app.adjSource = client;
   14042                             app.adjTarget = cpr.info.name;
   14043                         }
   14044                         if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   14045                             schedGroup = Process.THREAD_GROUP_DEFAULT;
   14046                         }
   14047                     }
   14048                 }
   14049                 // If the provider has external (non-framework) process
   14050                 // dependencies, ensure that its adjustment is at least
   14051                 // FOREGROUND_APP_ADJ.
   14052                 if (cpr.externals != 0) {
   14053                     if (adj > FOREGROUND_APP_ADJ) {
   14054                         adj = FOREGROUND_APP_ADJ;
   14055                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   14056                         app.hidden = false;
   14057                         app.adjType = "provider";
   14058                         app.adjTarget = cpr.info.name;
   14059                     }
   14060                 }
   14061             }
   14062         }
   14063 
   14064         app.curRawAdj = adj;
   14065 
   14066         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
   14067         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
   14068         if (adj > app.maxAdj) {
   14069             adj = app.maxAdj;
   14070             if (app.maxAdj <= VISIBLE_APP_ADJ) {
   14071                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   14072             }
   14073         }
   14074 
   14075         app.curAdj = adj;
   14076         app.curSchedGroup = schedGroup;
   14077 
   14078         return adj;
   14079     }
   14080 
   14081     /**
   14082      * Ask a given process to GC right now.
   14083      */
   14084     final void performAppGcLocked(ProcessRecord app) {
   14085         try {
   14086             app.lastRequestedGc = SystemClock.uptimeMillis();
   14087             if (app.thread != null) {
   14088                 if (app.reportLowMemory) {
   14089                     app.reportLowMemory = false;
   14090                     app.thread.scheduleLowMemory();
   14091                 } else {
   14092                     app.thread.processInBackground();
   14093                 }
   14094             }
   14095         } catch (Exception e) {
   14096             // whatever.
   14097         }
   14098     }
   14099 
   14100     /**
   14101      * Returns true if things are idle enough to perform GCs.
   14102      */
   14103     private final boolean canGcNowLocked() {
   14104         return mParallelBroadcasts.size() == 0
   14105                 && mOrderedBroadcasts.size() == 0
   14106                 && (mSleeping || (mResumedActivity != null &&
   14107                         mResumedActivity.idle));
   14108     }
   14109 
   14110     /**
   14111      * Perform GCs on all processes that are waiting for it, but only
   14112      * if things are idle.
   14113      */
   14114     final void performAppGcsLocked() {
   14115         final int N = mProcessesToGc.size();
   14116         if (N <= 0) {
   14117             return;
   14118         }
   14119         if (canGcNowLocked()) {
   14120             while (mProcessesToGc.size() > 0) {
   14121                 ProcessRecord proc = mProcessesToGc.remove(0);
   14122                 if (proc.curRawAdj > VISIBLE_APP_ADJ || proc.reportLowMemory) {
   14123                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
   14124                             <= SystemClock.uptimeMillis()) {
   14125                         // To avoid spamming the system, we will GC processes one
   14126                         // at a time, waiting a few seconds between each.
   14127                         performAppGcLocked(proc);
   14128                         scheduleAppGcsLocked();
   14129                         return;
   14130                     } else {
   14131                         // It hasn't been long enough since we last GCed this
   14132                         // process...  put it in the list to wait for its time.
   14133                         addProcessToGcListLocked(proc);
   14134                         break;
   14135                     }
   14136                 }
   14137             }
   14138 
   14139             scheduleAppGcsLocked();
   14140         }
   14141     }
   14142 
   14143     /**
   14144      * If all looks good, perform GCs on all processes waiting for them.
   14145      */
   14146     final void performAppGcsIfAppropriateLocked() {
   14147         if (canGcNowLocked()) {
   14148             performAppGcsLocked();
   14149             return;
   14150         }
   14151         // Still not idle, wait some more.
   14152         scheduleAppGcsLocked();
   14153     }
   14154 
   14155     /**
   14156      * Schedule the execution of all pending app GCs.
   14157      */
   14158     final void scheduleAppGcsLocked() {
   14159         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
   14160 
   14161         if (mProcessesToGc.size() > 0) {
   14162             // Schedule a GC for the time to the next process.
   14163             ProcessRecord proc = mProcessesToGc.get(0);
   14164             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
   14165 
   14166             long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL;
   14167             long now = SystemClock.uptimeMillis();
   14168             if (when < (now+GC_TIMEOUT)) {
   14169                 when = now + GC_TIMEOUT;
   14170             }
   14171             mHandler.sendMessageAtTime(msg, when);
   14172         }
   14173     }
   14174 
   14175     /**
   14176      * Add a process to the array of processes waiting to be GCed.  Keeps the
   14177      * list in sorted order by the last GC time.  The process can't already be
   14178      * on the list.
   14179      */
   14180     final void addProcessToGcListLocked(ProcessRecord proc) {
   14181         boolean added = false;
   14182         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
   14183             if (mProcessesToGc.get(i).lastRequestedGc <
   14184                     proc.lastRequestedGc) {
   14185                 added = true;
   14186                 mProcessesToGc.add(i+1, proc);
   14187                 break;
   14188             }
   14189         }
   14190         if (!added) {
   14191             mProcessesToGc.add(0, proc);
   14192         }
   14193     }
   14194 
   14195     /**
   14196      * Set up to ask a process to GC itself.  This will either do it
   14197      * immediately, or put it on the list of processes to gc the next
   14198      * time things are idle.
   14199      */
   14200     final void scheduleAppGcLocked(ProcessRecord app) {
   14201         long now = SystemClock.uptimeMillis();
   14202         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
   14203             return;
   14204         }
   14205         if (!mProcessesToGc.contains(app)) {
   14206             addProcessToGcListLocked(app);
   14207             scheduleAppGcsLocked();
   14208         }
   14209     }
   14210 
   14211     private final boolean updateOomAdjLocked(
   14212         ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
   14213         app.hiddenAdj = hiddenAdj;
   14214 
   14215         if (app.thread == null) {
   14216             return true;
   14217         }
   14218 
   14219         int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
   14220 
   14221         if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) {
   14222             if (app.curRawAdj != app.setRawAdj) {
   14223                 if (app.curRawAdj > FOREGROUND_APP_ADJ
   14224                         && app.setRawAdj <= FOREGROUND_APP_ADJ) {
   14225                     // If this app is transitioning from foreground to
   14226                     // non-foreground, have it do a gc.
   14227                     scheduleAppGcLocked(app);
   14228                 } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
   14229                         && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
   14230                     // Likewise do a gc when an app is moving in to the
   14231                     // background (such as a service stopping).
   14232                     scheduleAppGcLocked(app);
   14233                 }
   14234                 app.setRawAdj = app.curRawAdj;
   14235             }
   14236             if (adj != app.setAdj) {
   14237                 if (Process.setOomAdj(app.pid, adj)) {
   14238                     if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
   14239                         TAG, "Set app " + app.processName +
   14240                         " oom adj to " + adj);
   14241                     app.setAdj = adj;
   14242                 } else {
   14243                     return false;
   14244                 }
   14245             }
   14246             if (app.setSchedGroup != app.curSchedGroup) {
   14247                 app.setSchedGroup = app.curSchedGroup;
   14248                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   14249                         "Setting process group of " + app.processName
   14250                         + " to " + app.curSchedGroup);
   14251                 if (true) {
   14252                     long oldId = Binder.clearCallingIdentity();
   14253                     try {
   14254                         Process.setProcessGroup(app.pid, app.curSchedGroup);
   14255                     } catch (Exception e) {
   14256                         Slog.w(TAG, "Failed setting process group of " + app.pid
   14257                                 + " to " + app.curSchedGroup);
   14258                         e.printStackTrace();
   14259                     } finally {
   14260                         Binder.restoreCallingIdentity(oldId);
   14261                     }
   14262                 }
   14263                 if (false) {
   14264                     if (app.thread != null) {
   14265                         try {
   14266                             app.thread.setSchedulingGroup(app.curSchedGroup);
   14267                         } catch (RemoteException e) {
   14268                         }
   14269                     }
   14270                 }
   14271             }
   14272         }
   14273 
   14274         return true;
   14275     }
   14276 
   14277     private final HistoryRecord resumedAppLocked() {
   14278         HistoryRecord resumedActivity = mResumedActivity;
   14279         if (resumedActivity == null || resumedActivity.app == null) {
   14280             resumedActivity = mPausingActivity;
   14281             if (resumedActivity == null || resumedActivity.app == null) {
   14282                 resumedActivity = topRunningActivityLocked(null);
   14283             }
   14284         }
   14285         return resumedActivity;
   14286     }
   14287 
   14288     private final boolean updateOomAdjLocked(ProcessRecord app) {
   14289         final HistoryRecord TOP_ACT = resumedAppLocked();
   14290         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   14291         int curAdj = app.curAdj;
   14292         final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
   14293             && app.curAdj <= HIDDEN_APP_MAX_ADJ;
   14294 
   14295         mAdjSeq++;
   14296 
   14297         final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
   14298         if (res) {
   14299             final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
   14300                 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
   14301             if (nowHidden != wasHidden) {
   14302                 // Changed to/from hidden state, so apps after it in the LRU
   14303                 // list may also be changed.
   14304                 updateOomAdjLocked();
   14305             }
   14306         }
   14307         return res;
   14308     }
   14309 
   14310     private final boolean updateOomAdjLocked() {
   14311         boolean didOomAdj = true;
   14312         final HistoryRecord TOP_ACT = resumedAppLocked();
   14313         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   14314 
   14315         if (false) {
   14316             RuntimeException e = new RuntimeException();
   14317             e.fillInStackTrace();
   14318             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
   14319         }
   14320 
   14321         mAdjSeq++;
   14322 
   14323         // Let's determine how many processes we have running vs.
   14324         // how many slots we have for background processes; we may want
   14325         // to put multiple processes in a slot of there are enough of
   14326         // them.
   14327         int numSlots = HIDDEN_APP_MAX_ADJ - HIDDEN_APP_MIN_ADJ + 1;
   14328         int factor = (mLruProcesses.size()-4)/numSlots;
   14329         if (factor < 1) factor = 1;
   14330         int step = 0;
   14331         int numHidden = 0;
   14332 
   14333         // First try updating the OOM adjustment for each of the
   14334         // application processes based on their current state.
   14335         int i = mLruProcesses.size();
   14336         int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
   14337         while (i > 0) {
   14338             i--;
   14339             ProcessRecord app = mLruProcesses.get(i);
   14340             //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
   14341             if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
   14342                 if (curHiddenAdj < EMPTY_APP_ADJ
   14343                     && app.curAdj == curHiddenAdj) {
   14344                     step++;
   14345                     if (step >= factor) {
   14346                         step = 0;
   14347                         curHiddenAdj++;
   14348                     }
   14349                 }
   14350                 if (app.curAdj >= HIDDEN_APP_MIN_ADJ) {
   14351                     if (!app.killedBackground) {
   14352                         numHidden++;
   14353                         if (numHidden > MAX_HIDDEN_APPS) {
   14354                             Slog.i(TAG, "No longer want " + app.processName
   14355                                     + " (pid " + app.pid + "): hidden #" + numHidden);
   14356                             EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   14357                                     app.processName, app.setAdj, "too many background");
   14358                             app.killedBackground = true;
   14359                             Process.killProcessQuiet(app.pid);
   14360                         }
   14361                     }
   14362                 }
   14363             } else {
   14364                 didOomAdj = false;
   14365             }
   14366         }
   14367 
   14368         // If we return false, we will fall back on killing processes to
   14369         // have a fixed limit.  Do this if a limit has been requested; else
   14370         // only return false if one of the adjustments failed.
   14371         return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
   14372     }
   14373 
   14374     private final void trimApplications() {
   14375         synchronized (this) {
   14376             int i;
   14377 
   14378             // First remove any unused application processes whose package
   14379             // has been removed.
   14380             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
   14381                 final ProcessRecord app = mRemovedProcesses.get(i);
   14382                 if (app.activities.size() == 0
   14383                         && app.curReceiver == null && app.services.size() == 0) {
   14384                     Slog.i(
   14385                         TAG, "Exiting empty application process "
   14386                         + app.processName + " ("
   14387                         + (app.thread != null ? app.thread.asBinder() : null)
   14388                         + ")\n");
   14389                     if (app.pid > 0 && app.pid != MY_PID) {
   14390                         Process.killProcess(app.pid);
   14391                     } else {
   14392                         try {
   14393                             app.thread.scheduleExit();
   14394                         } catch (Exception e) {
   14395                             // Ignore exceptions.
   14396                         }
   14397                     }
   14398                     cleanUpApplicationRecordLocked(app, false, -1);
   14399                     mRemovedProcesses.remove(i);
   14400 
   14401                     if (app.persistent) {
   14402                         if (app.persistent) {
   14403                             addAppLocked(app.info);
   14404                         }
   14405                     }
   14406                 }
   14407             }
   14408 
   14409             // Now try updating the OOM adjustment for each of the
   14410             // application processes based on their current state.
   14411             // If the setOomAdj() API is not supported, then go with our
   14412             // back-up plan...
   14413             if (!updateOomAdjLocked()) {
   14414 
   14415                 // Count how many processes are running services.
   14416                 int numServiceProcs = 0;
   14417                 for (i=mLruProcesses.size()-1; i>=0; i--) {
   14418                     final ProcessRecord app = mLruProcesses.get(i);
   14419 
   14420                     if (app.persistent || app.services.size() != 0
   14421                             || app.curReceiver != null
   14422                             || app.persistentActivities > 0) {
   14423                         // Don't count processes holding services against our
   14424                         // maximum process count.
   14425                         if (localLOGV) Slog.v(
   14426                             TAG, "Not trimming app " + app + " with services: "
   14427                             + app.services);
   14428                         numServiceProcs++;
   14429                     }
   14430                 }
   14431 
   14432                 int curMaxProcs = mProcessLimit;
   14433                 if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
   14434                 if (mAlwaysFinishActivities) {
   14435                     curMaxProcs = 1;
   14436                 }
   14437                 curMaxProcs += numServiceProcs;
   14438 
   14439                 // Quit as many processes as we can to get down to the desired
   14440                 // process count.  First remove any processes that no longer
   14441                 // have activites running in them.
   14442                 for (   i=0;
   14443                         i<mLruProcesses.size()
   14444                             && mLruProcesses.size() > curMaxProcs;
   14445                         i++) {
   14446                     final ProcessRecord app = mLruProcesses.get(i);
   14447                     // Quit an application only if it is not currently
   14448                     // running any activities.
   14449                     if (!app.persistent && app.activities.size() == 0
   14450                             && app.curReceiver == null && app.services.size() == 0) {
   14451                         Slog.i(
   14452                             TAG, "Exiting empty application process "
   14453                             + app.processName + " ("
   14454                             + (app.thread != null ? app.thread.asBinder() : null)
   14455                             + ")\n");
   14456                         if (app.pid > 0 && app.pid != MY_PID) {
   14457                             Process.killProcess(app.pid);
   14458                         } else {
   14459                             try {
   14460                                 app.thread.scheduleExit();
   14461                             } catch (Exception e) {
   14462                                 // Ignore exceptions.
   14463                             }
   14464                         }
   14465                         // todo: For now we assume the application is not buggy
   14466                         // or evil, and will quit as a result of our request.
   14467                         // Eventually we need to drive this off of the death
   14468                         // notification, and kill the process if it takes too long.
   14469                         cleanUpApplicationRecordLocked(app, false, i);
   14470                         i--;
   14471                     }
   14472                 }
   14473 
   14474                 // If we still have too many processes, now from the least
   14475                 // recently used process we start finishing activities.
   14476                 if (Config.LOGV) Slog.v(
   14477                     TAG, "*** NOW HAVE " + mLruProcesses.size() +
   14478                     " of " + curMaxProcs + " processes");
   14479                 for (   i=0;
   14480                         i<mLruProcesses.size()
   14481                             && mLruProcesses.size() > curMaxProcs;
   14482                         i++) {
   14483                     final ProcessRecord app = mLruProcesses.get(i);
   14484                     // Quit the application only if we have a state saved for
   14485                     // all of its activities.
   14486                     boolean canQuit = !app.persistent && app.curReceiver == null
   14487                         && app.services.size() == 0
   14488                         && app.persistentActivities == 0;
   14489                     int NUMA = app.activities.size();
   14490                     int j;
   14491                     if (Config.LOGV) Slog.v(
   14492                         TAG, "Looking to quit " + app.processName);
   14493                     for (j=0; j<NUMA && canQuit; j++) {
   14494                         HistoryRecord r = (HistoryRecord)app.activities.get(j);
   14495                         if (Config.LOGV) Slog.v(
   14496                             TAG, "  " + r.intent.getComponent().flattenToShortString()
   14497                             + ": frozen=" + r.haveState + ", visible=" + r.visible);
   14498                         canQuit = (r.haveState || !r.stateNotNeeded)
   14499                                 && !r.visible && r.stopped;
   14500                     }
   14501                     if (canQuit) {
   14502                         // Finish all of the activities, and then the app itself.
   14503                         for (j=0; j<NUMA; j++) {
   14504                             HistoryRecord r = (HistoryRecord)app.activities.get(j);
   14505                             if (!r.finishing) {
   14506                                 destroyActivityLocked(r, false);
   14507                             }
   14508                             r.resultTo = null;
   14509                         }
   14510                         Slog.i(TAG, "Exiting application process "
   14511                               + app.processName + " ("
   14512                               + (app.thread != null ? app.thread.asBinder() : null)
   14513                               + ")\n");
   14514                         if (app.pid > 0 && app.pid != MY_PID) {
   14515                             Process.killProcess(app.pid);
   14516                         } else {
   14517                             try {
   14518                                 app.thread.scheduleExit();
   14519                             } catch (Exception e) {
   14520                                 // Ignore exceptions.
   14521                             }
   14522                         }
   14523                         // todo: For now we assume the application is not buggy
   14524                         // or evil, and will quit as a result of our request.
   14525                         // Eventually we need to drive this off of the death
   14526                         // notification, and kill the process if it takes too long.
   14527                         cleanUpApplicationRecordLocked(app, false, i);
   14528                         i--;
   14529                         //dump();
   14530                     }
   14531                 }
   14532 
   14533             }
   14534 
   14535             int curMaxActivities = MAX_ACTIVITIES;
   14536             if (mAlwaysFinishActivities) {
   14537                 curMaxActivities = 1;
   14538             }
   14539 
   14540             // Finally, if there are too many activities now running, try to
   14541             // finish as many as we can to get back down to the limit.
   14542             for (   i=0;
   14543                     i<mLRUActivities.size()
   14544                         && mLRUActivities.size() > curMaxActivities;
   14545                     i++) {
   14546                 final HistoryRecord r
   14547                     = (HistoryRecord)mLRUActivities.get(i);
   14548 
   14549                 // We can finish this one if we have its icicle saved and
   14550                 // it is not persistent.
   14551                 if ((r.haveState || !r.stateNotNeeded) && !r.visible
   14552                         && r.stopped && !r.persistent && !r.finishing) {
   14553                     final int origSize = mLRUActivities.size();
   14554                     destroyActivityLocked(r, true);
   14555 
   14556                     // This will remove it from the LRU list, so keep
   14557                     // our index at the same value.  Note that this check to
   14558                     // see if the size changes is just paranoia -- if
   14559                     // something unexpected happens, we don't want to end up
   14560                     // in an infinite loop.
   14561                     if (origSize > mLRUActivities.size()) {
   14562                         i--;
   14563                     }
   14564                 }
   14565             }
   14566         }
   14567     }
   14568 
   14569     /** This method sends the specified signal to each of the persistent apps */
   14570     public void signalPersistentProcesses(int sig) throws RemoteException {
   14571         if (sig != Process.SIGNAL_USR1) {
   14572             throw new SecurityException("Only SIGNAL_USR1 is allowed");
   14573         }
   14574 
   14575         synchronized (this) {
   14576             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
   14577                     != PackageManager.PERMISSION_GRANTED) {
   14578                 throw new SecurityException("Requires permission "
   14579                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
   14580             }
   14581 
   14582             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   14583                 ProcessRecord r = mLruProcesses.get(i);
   14584                 if (r.thread != null && r.persistent) {
   14585                     Process.sendSignal(r.pid, sig);
   14586                 }
   14587             }
   14588         }
   14589     }
   14590 
   14591     public boolean profileControl(String process, boolean start,
   14592             String path, ParcelFileDescriptor fd) throws RemoteException {
   14593 
   14594         try {
   14595             synchronized (this) {
   14596                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   14597                 // its own permission.
   14598                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   14599                         != PackageManager.PERMISSION_GRANTED) {
   14600                     throw new SecurityException("Requires permission "
   14601                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   14602                 }
   14603 
   14604                 if (start && fd == null) {
   14605                     throw new IllegalArgumentException("null fd");
   14606                 }
   14607 
   14608                 ProcessRecord proc = null;
   14609                 try {
   14610                     int pid = Integer.parseInt(process);
   14611                     synchronized (mPidsSelfLocked) {
   14612                         proc = mPidsSelfLocked.get(pid);
   14613                     }
   14614                 } catch (NumberFormatException e) {
   14615                 }
   14616 
   14617                 if (proc == null) {
   14618                     HashMap<String, SparseArray<ProcessRecord>> all
   14619                             = mProcessNames.getMap();
   14620                     SparseArray<ProcessRecord> procs = all.get(process);
   14621                     if (procs != null && procs.size() > 0) {
   14622                         proc = procs.valueAt(0);
   14623                     }
   14624                 }
   14625 
   14626                 if (proc == null || proc.thread == null) {
   14627                     throw new IllegalArgumentException("Unknown process: " + process);
   14628                 }
   14629 
   14630                 boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
   14631                 if (isSecure) {
   14632                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   14633                         throw new SecurityException("Process not debuggable: " + proc);
   14634                     }
   14635                 }
   14636 
   14637                 proc.thread.profilerControl(start, path, fd);
   14638                 fd = null;
   14639                 return true;
   14640             }
   14641         } catch (RemoteException e) {
   14642             throw new IllegalStateException("Process disappeared");
   14643         } finally {
   14644             if (fd != null) {
   14645                 try {
   14646                     fd.close();
   14647                 } catch (IOException e) {
   14648                 }
   14649             }
   14650         }
   14651     }
   14652 
   14653     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
   14654     public void monitor() {
   14655         synchronized (this) { }
   14656     }
   14657 }
   14658