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