Home | History | Annotate | Download | only in am
      1 /*
      2  * Copyright (C) 2006-2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.server.am;
     18 
     19 import com.android.internal.R;
     20 import com.android.internal.os.BatteryStatsImpl;
     21 import com.android.internal.os.ProcessStats;
     22 import com.android.server.AttributeCache;
     23 import com.android.server.IntentResolver;
     24 import com.android.server.ProcessMap;
     25 import com.android.server.SystemServer;
     26 import com.android.server.Watchdog;
     27 import com.android.server.am.ActivityStack.ActivityState;
     28 import com.android.server.wm.WindowManagerService;
     29 
     30 import dalvik.system.Zygote;
     31 
     32 import android.app.Activity;
     33 import android.app.ActivityManager;
     34 import android.app.ActivityManagerNative;
     35 import android.app.ActivityThread;
     36 import android.app.AlertDialog;
     37 import android.app.AppGlobals;
     38 import android.app.ApplicationErrorReport;
     39 import android.app.Dialog;
     40 import android.app.IActivityController;
     41 import android.app.IActivityWatcher;
     42 import android.app.IApplicationThread;
     43 import android.app.IInstrumentationWatcher;
     44 import android.app.INotificationManager;
     45 import android.app.IProcessObserver;
     46 import android.app.IServiceConnection;
     47 import android.app.IThumbnailReceiver;
     48 import android.app.Instrumentation;
     49 import android.app.Notification;
     50 import android.app.NotificationManager;
     51 import android.app.PendingIntent;
     52 import android.app.Service;
     53 import android.app.backup.IBackupManager;
     54 import android.content.ActivityNotFoundException;
     55 import android.content.BroadcastReceiver;
     56 import android.content.ComponentCallbacks2;
     57 import android.content.ComponentName;
     58 import android.content.ContentResolver;
     59 import android.content.Context;
     60 import android.content.DialogInterface;
     61 import android.content.Intent;
     62 import android.content.IntentFilter;
     63 import android.content.IIntentReceiver;
     64 import android.content.IIntentSender;
     65 import android.content.IntentSender;
     66 import android.content.pm.ActivityInfo;
     67 import android.content.pm.ApplicationInfo;
     68 import android.content.pm.ConfigurationInfo;
     69 import android.content.pm.IPackageDataObserver;
     70 import android.content.pm.IPackageManager;
     71 import android.content.pm.InstrumentationInfo;
     72 import android.content.pm.PackageInfo;
     73 import android.content.pm.PackageManager;
     74 import android.content.pm.PathPermission;
     75 import android.content.pm.ProviderInfo;
     76 import android.content.pm.ResolveInfo;
     77 import android.content.pm.ServiceInfo;
     78 import android.content.pm.PackageManager.NameNotFoundException;
     79 import android.content.res.CompatibilityInfo;
     80 import android.content.res.Configuration;
     81 import android.graphics.Bitmap;
     82 import android.net.Proxy;
     83 import android.net.ProxyProperties;
     84 import android.net.Uri;
     85 import android.os.Binder;
     86 import android.os.Build;
     87 import android.os.Bundle;
     88 import android.os.Debug;
     89 import android.os.DropBoxManager;
     90 import android.os.Environment;
     91 import android.os.FileObserver;
     92 import android.os.FileUtils;
     93 import android.os.Handler;
     94 import android.os.IBinder;
     95 import android.os.IPermissionController;
     96 import android.os.Looper;
     97 import android.os.Message;
     98 import android.os.Parcel;
     99 import android.os.ParcelFileDescriptor;
    100 import android.os.Process;
    101 import android.os.RemoteCallbackList;
    102 import android.os.RemoteException;
    103 import android.os.ServiceManager;
    104 import android.os.StrictMode;
    105 import android.os.SystemClock;
    106 import android.os.SystemProperties;
    107 import android.provider.Settings;
    108 import android.util.EventLog;
    109 import android.util.Pair;
    110 import android.util.Slog;
    111 import android.util.Log;
    112 import android.util.PrintWriterPrinter;
    113 import android.util.SparseArray;
    114 import android.util.TimeUtils;
    115 import android.view.Gravity;
    116 import android.view.LayoutInflater;
    117 import android.view.View;
    118 import android.view.WindowManager;
    119 import android.view.WindowManagerPolicy;
    120 
    121 import java.io.BufferedInputStream;
    122 import java.io.BufferedOutputStream;
    123 import java.io.DataInputStream;
    124 import java.io.DataOutputStream;
    125 import java.io.File;
    126 import java.io.FileDescriptor;
    127 import java.io.FileInputStream;
    128 import java.io.FileNotFoundException;
    129 import java.io.FileOutputStream;
    130 import java.io.IOException;
    131 import java.io.InputStreamReader;
    132 import java.io.PrintWriter;
    133 import java.lang.IllegalStateException;
    134 import java.lang.ref.WeakReference;
    135 import java.util.ArrayList;
    136 import java.util.Collections;
    137 import java.util.Comparator;
    138 import java.util.HashMap;
    139 import java.util.HashSet;
    140 import java.util.Iterator;
    141 import java.util.List;
    142 import java.util.Locale;
    143 import java.util.Map;
    144 import java.util.Set;
    145 import java.util.concurrent.atomic.AtomicBoolean;
    146 import java.util.concurrent.atomic.AtomicLong;
    147 
    148 public final class ActivityManagerService extends ActivityManagerNative
    149         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    150     static final String TAG = "ActivityManager";
    151     static final boolean DEBUG = false;
    152     static final boolean localLOGV = DEBUG;
    153     static final boolean DEBUG_SWITCH = localLOGV || false;
    154     static final boolean DEBUG_TASKS = localLOGV || false;
    155     static final boolean DEBUG_PAUSE = localLOGV || false;
    156     static final boolean DEBUG_OOM_ADJ = localLOGV || false;
    157     static final boolean DEBUG_TRANSITION = localLOGV || false;
    158     static final boolean DEBUG_BROADCAST = localLOGV || false;
    159     static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
    160     static final boolean DEBUG_SERVICE = localLOGV || false;
    161     static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
    162     static final boolean DEBUG_VISBILITY = localLOGV || false;
    163     static final boolean DEBUG_PROCESSES = localLOGV || false;
    164     static final boolean DEBUG_PROVIDER = localLOGV || false;
    165     static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
    166     static final boolean DEBUG_USER_LEAVING = localLOGV || false;
    167     static final boolean DEBUG_RESULTS = localLOGV || false;
    168     static final boolean DEBUG_BACKUP = localLOGV || false;
    169     static final boolean DEBUG_CONFIGURATION = localLOGV || false;
    170     static final boolean DEBUG_POWER = localLOGV || false;
    171     static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
    172     static final boolean VALIDATE_TOKENS = false;
    173     static final boolean SHOW_ACTIVITY_START_TIME = true;
    174 
    175     // Control over CPU and battery monitoring.
    176     static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
    177     static final boolean MONITOR_CPU_USAGE = true;
    178     static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
    179     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
    180     static final boolean MONITOR_THREAD_CPU_USAGE = false;
    181 
    182     // The flags that are set for all calls we make to the package manager.
    183     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
    184 
    185     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
    186 
    187     // Maximum number of recent tasks that we can remember.
    188     static final int MAX_RECENT_TASKS = 20;
    189 
    190     // Amount of time after a call to stopAppSwitches() during which we will
    191     // prevent further untrusted switches from happening.
    192     static final long APP_SWITCH_DELAY_TIME = 5*1000;
    193 
    194     // How long we wait for a launched process to attach to the activity manager
    195     // before we decide it's never going to come up for real.
    196     static final int PROC_START_TIMEOUT = 10*1000;
    197 
    198     // How long we wait for a launched process to attach to the activity manager
    199     // before we decide it's never going to come up for real, when the process was
    200     // started with a wrapper for instrumentation (such as Valgrind) because it
    201     // could take much longer than usual.
    202     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
    203 
    204     // How long to wait after going idle before forcing apps to GC.
    205     static final int GC_TIMEOUT = 5*1000;
    206 
    207     // The minimum amount of time between successive GC requests for a process.
    208     static final int GC_MIN_INTERVAL = 60*1000;
    209 
    210     // The rate at which we check for apps using excessive power -- 15 mins.
    211     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
    212 
    213     // The minimum sample duration we will allow before deciding we have
    214     // enough data on wake locks to start killing things.
    215     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    216 
    217     // The minimum sample duration we will allow before deciding we have
    218     // enough data on CPU usage to start killing things.
    219     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    220 
    221     // How long we allow a receiver to run before giving up on it.
    222     static final int BROADCAST_TIMEOUT = 10*1000;
    223 
    224     // How long we wait for a service to finish executing.
    225     static final int SERVICE_TIMEOUT = 20*1000;
    226 
    227     // How long a service needs to be running until restarting its process
    228     // is no longer considered to be a relaunch of the service.
    229     static final int SERVICE_RESTART_DURATION = 5*1000;
    230 
    231     // How long a service needs to be running until it will start back at
    232     // SERVICE_RESTART_DURATION after being killed.
    233     static final int SERVICE_RESET_RUN_DURATION = 60*1000;
    234 
    235     // Multiplying factor to increase restart duration time by, for each time
    236     // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
    237     static final int SERVICE_RESTART_DURATION_FACTOR = 4;
    238 
    239     // The minimum amount of time between restarting services that we allow.
    240     // That is, when multiple services are restarting, we won't allow each
    241     // to restart less than this amount of time from the last one.
    242     static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
    243 
    244     // Maximum amount of time for there to be no activity on a service before
    245     // we consider it non-essential and allow its process to go on the
    246     // LRU background list.
    247     static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
    248 
    249     // How long we wait until we timeout on key dispatching.
    250     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
    251 
    252     // How long we wait until we timeout on key dispatching during instrumentation.
    253     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
    254 
    255     static final int MY_PID = Process.myPid();
    256 
    257     static final String[] EMPTY_STRING_ARRAY = new String[0];
    258 
    259     public ActivityStack mMainStack;
    260 
    261     /**
    262      * Description of a request to start a new activity, which has been held
    263      * due to app switches being disabled.
    264      */
    265     static class PendingActivityLaunch {
    266         ActivityRecord r;
    267         ActivityRecord sourceRecord;
    268         Uri[] grantedUriPermissions;
    269         int grantedMode;
    270         boolean onlyIfNeeded;
    271     }
    272 
    273     final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
    274             = new ArrayList<PendingActivityLaunch>();
    275 
    276     /**
    277      * List of all active broadcasts that are to be executed immediately
    278      * (without waiting for another broadcast to finish).  Currently this only
    279      * contains broadcasts to registered receivers, to avoid spinning up
    280      * a bunch of processes to execute IntentReceiver components.
    281      */
    282     final ArrayList<BroadcastRecord> mParallelBroadcasts
    283             = new ArrayList<BroadcastRecord>();
    284 
    285     /**
    286      * List of all active broadcasts that are to be executed one at a time.
    287      * The object at the top of the list is the currently activity broadcasts;
    288      * those after it are waiting for the top to finish..
    289      */
    290     final ArrayList<BroadcastRecord> mOrderedBroadcasts
    291             = new ArrayList<BroadcastRecord>();
    292 
    293     /**
    294      * Historical data of past broadcasts, for debugging.
    295      */
    296     static final int MAX_BROADCAST_HISTORY = 100;
    297     final BroadcastRecord[] mBroadcastHistory
    298             = new BroadcastRecord[MAX_BROADCAST_HISTORY];
    299 
    300     /**
    301      * Set when we current have a BROADCAST_INTENT_MSG in flight.
    302      */
    303     boolean mBroadcastsScheduled = false;
    304 
    305     /**
    306      * Activity we have told the window manager to have key focus.
    307      */
    308     ActivityRecord mFocusedActivity = null;
    309     /**
    310      * List of intents that were used to start the most recent tasks.
    311      */
    312     final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
    313 
    314     /**
    315      * Process management.
    316      */
    317     final ProcessList mProcessList = new ProcessList();
    318 
    319     /**
    320      * All of the applications we currently have running organized by name.
    321      * The keys are strings of the application package name (as
    322      * returned by the package manager), and the keys are ApplicationRecord
    323      * objects.
    324      */
    325     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
    326 
    327     /**
    328      * The currently running heavy-weight process, if any.
    329      */
    330     ProcessRecord mHeavyWeightProcess = null;
    331 
    332     /**
    333      * The last time that various processes have crashed.
    334      */
    335     final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
    336 
    337     /**
    338      * Set of applications that we consider to be bad, and will reject
    339      * incoming broadcasts from (which the user has no control over).
    340      * Processes are added to this set when they have crashed twice within
    341      * a minimum amount of time; they are removed from it when they are
    342      * later restarted (hopefully due to some user action).  The value is the
    343      * time it was added to the list.
    344      */
    345     final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
    346 
    347     /**
    348      * All of the processes we currently have running organized by pid.
    349      * The keys are the pid running the application.
    350      *
    351      * <p>NOTE: This object is protected by its own lock, NOT the global
    352      * activity manager lock!
    353      */
    354     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
    355 
    356     /**
    357      * All of the processes that have been forced to be foreground.  The key
    358      * is the pid of the caller who requested it (we hold a death
    359      * link on it).
    360      */
    361     abstract class ForegroundToken implements IBinder.DeathRecipient {
    362         int pid;
    363         IBinder token;
    364     }
    365     final SparseArray<ForegroundToken> mForegroundProcesses
    366             = new SparseArray<ForegroundToken>();
    367 
    368     /**
    369      * List of records for processes that someone had tried to start before the
    370      * system was ready.  We don't start them at that point, but ensure they
    371      * are started by the time booting is complete.
    372      */
    373     final ArrayList<ProcessRecord> mProcessesOnHold
    374             = new ArrayList<ProcessRecord>();
    375 
    376     /**
    377      * List of persistent applications that are in the process
    378      * of being started.
    379      */
    380     final ArrayList<ProcessRecord> mPersistentStartingProcesses
    381             = new ArrayList<ProcessRecord>();
    382 
    383     /**
    384      * Processes that are being forcibly torn down.
    385      */
    386     final ArrayList<ProcessRecord> mRemovedProcesses
    387             = new ArrayList<ProcessRecord>();
    388 
    389     /**
    390      * List of running applications, sorted by recent usage.
    391      * The first entry in the list is the least recently used.
    392      * It contains ApplicationRecord objects.  This list does NOT include
    393      * any persistent application records (since we never want to exit them).
    394      */
    395     final ArrayList<ProcessRecord> mLruProcesses
    396             = new ArrayList<ProcessRecord>();
    397 
    398     /**
    399      * List of processes that should gc as soon as things are idle.
    400      */
    401     final ArrayList<ProcessRecord> mProcessesToGc
    402             = new ArrayList<ProcessRecord>();
    403 
    404     /**
    405      * This is the process holding what we currently consider to be
    406      * the "home" activity.
    407      */
    408     ProcessRecord mHomeProcess;
    409 
    410     /**
    411      * Packages that the user has asked to have run in screen size
    412      * compatibility mode instead of filling the screen.
    413      */
    414     final CompatModePackages mCompatModePackages;
    415 
    416     /**
    417      * Set of PendingResultRecord objects that are currently active.
    418      */
    419     final HashSet mPendingResultRecords = new HashSet();
    420 
    421     /**
    422      * Set of IntentSenderRecord objects that are currently active.
    423      */
    424     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
    425             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
    426 
    427     /**
    428      * Fingerprints (hashCode()) of stack traces that we've
    429      * already logged DropBox entries for.  Guarded by itself.  If
    430      * something (rogue user app) forces this over
    431      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
    432      */
    433     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
    434     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
    435 
    436     /**
    437      * Strict Mode background batched logging state.
    438      *
    439      * The string buffer is guarded by itself, and its lock is also
    440      * used to determine if another batched write is already
    441      * in-flight.
    442      */
    443     private final StringBuilder mStrictModeBuffer = new StringBuilder();
    444 
    445     /**
    446      * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
    447      */
    448     private boolean mPendingBroadcastTimeoutMessage;
    449 
    450     /**
    451      * Intent broadcast that we have tried to start, but are
    452      * waiting for its application's process to be created.  We only
    453      * need one (instead of a list) because we always process broadcasts
    454      * one at a time, so no others can be started while waiting for this
    455      * one.
    456      */
    457     BroadcastRecord mPendingBroadcast = null;
    458 
    459     /**
    460      * The receiver index that is pending, to restart the broadcast if needed.
    461      */
    462     int mPendingBroadcastRecvIndex;
    463 
    464     /**
    465      * Keeps track of all IIntentReceivers that have been registered for
    466      * broadcasts.  Hash keys are the receiver IBinder, hash value is
    467      * a ReceiverList.
    468      */
    469     final HashMap mRegisteredReceivers = new HashMap();
    470 
    471     /**
    472      * Resolver for broadcast intents to registered receivers.
    473      * Holds BroadcastFilter (subclass of IntentFilter).
    474      */
    475     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
    476             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
    477         @Override
    478         protected boolean allowFilterResult(
    479                 BroadcastFilter filter, List<BroadcastFilter> dest) {
    480             IBinder target = filter.receiverList.receiver.asBinder();
    481             for (int i=dest.size()-1; i>=0; i--) {
    482                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
    483                     return false;
    484                 }
    485             }
    486             return true;
    487         }
    488 
    489         @Override
    490         protected String packageForFilter(BroadcastFilter filter) {
    491             return filter.packageName;
    492         }
    493     };
    494 
    495     /**
    496      * State of all active sticky broadcasts.  Keys are the action of the
    497      * sticky Intent, values are an ArrayList of all broadcasted intents with
    498      * that action (which should usually be one).
    499      */
    500     final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
    501             new HashMap<String, ArrayList<Intent>>();
    502 
    503     /**
    504      * All currently running services.
    505      */
    506     final HashMap<ComponentName, ServiceRecord> mServices =
    507         new HashMap<ComponentName, ServiceRecord>();
    508 
    509     /**
    510      * All currently running services indexed by the Intent used to start them.
    511      */
    512     final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
    513         new HashMap<Intent.FilterComparison, ServiceRecord>();
    514 
    515     /**
    516      * All currently bound service connections.  Keys are the IBinder of
    517      * the client's IServiceConnection.
    518      */
    519     final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
    520             = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
    521 
    522     /**
    523      * List of services that we have been asked to start,
    524      * but haven't yet been able to.  It is used to hold start requests
    525      * while waiting for their corresponding application thread to get
    526      * going.
    527      */
    528     final ArrayList<ServiceRecord> mPendingServices
    529             = new ArrayList<ServiceRecord>();
    530 
    531     /**
    532      * List of services that are scheduled to restart following a crash.
    533      */
    534     final ArrayList<ServiceRecord> mRestartingServices
    535             = new ArrayList<ServiceRecord>();
    536 
    537     /**
    538      * List of services that are in the process of being stopped.
    539      */
    540     final ArrayList<ServiceRecord> mStoppingServices
    541             = new ArrayList<ServiceRecord>();
    542 
    543     /**
    544      * Backup/restore process management
    545      */
    546     String mBackupAppName = null;
    547     BackupRecord mBackupTarget = null;
    548 
    549     /**
    550      * List of PendingThumbnailsRecord objects of clients who are still
    551      * waiting to receive all of the thumbnails for a task.
    552      */
    553     final ArrayList mPendingThumbnails = new ArrayList();
    554 
    555     /**
    556      * List of HistoryRecord objects that have been finished and must
    557      * still report back to a pending thumbnail receiver.
    558      */
    559     final ArrayList mCancelledThumbnails = new ArrayList();
    560 
    561     /**
    562      * All of the currently running global content providers.  Keys are a
    563      * string containing the provider name and values are a
    564      * ContentProviderRecord object containing the data about it.  Note
    565      * that a single provider may be published under multiple names, so
    566      * there may be multiple entries here for a single one in mProvidersByClass.
    567      */
    568     final HashMap<String, ContentProviderRecord> mProvidersByName
    569             = new HashMap<String, ContentProviderRecord>();
    570 
    571     /**
    572      * All of the currently running global content providers.  Keys are a
    573      * string containing the provider's implementation class and values are a
    574      * ContentProviderRecord object containing the data about it.
    575      */
    576     final HashMap<ComponentName, ContentProviderRecord> mProvidersByClass
    577             = new HashMap<ComponentName, ContentProviderRecord>();
    578 
    579     /**
    580      * List of content providers who have clients waiting for them.  The
    581      * application is currently being launched and the provider will be
    582      * removed from this list once it is published.
    583      */
    584     final ArrayList<ContentProviderRecord> mLaunchingProviders
    585             = new ArrayList<ContentProviderRecord>();
    586 
    587     /**
    588      * Global set of specific Uri permissions that have been granted.
    589      */
    590     final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
    591             = new SparseArray<HashMap<Uri, UriPermission>>();
    592 
    593     CoreSettingsObserver mCoreSettingsObserver;
    594 
    595     /**
    596      * Thread-local storage used to carry caller permissions over through
    597      * indirect content-provider access.
    598      * @see #ActivityManagerService.openContentUri()
    599      */
    600     private class Identity {
    601         public int pid;
    602         public int uid;
    603 
    604         Identity(int _pid, int _uid) {
    605             pid = _pid;
    606             uid = _uid;
    607         }
    608     }
    609     private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
    610 
    611     /**
    612      * All information we have collected about the runtime performance of
    613      * any user id that can impact battery performance.
    614      */
    615     final BatteryStatsService mBatteryStatsService;
    616 
    617     /**
    618      * information about component usage
    619      */
    620     final UsageStatsService mUsageStatsService;
    621 
    622     /**
    623      * Current configuration information.  HistoryRecord objects are given
    624      * a reference to this object to indicate which configuration they are
    625      * currently running in, so this object must be kept immutable.
    626      */
    627     Configuration mConfiguration = new Configuration();
    628 
    629     /**
    630      * Current sequencing integer of the configuration, for skipping old
    631      * configurations.
    632      */
    633     int mConfigurationSeq = 0;
    634 
    635     /**
    636      * Hardware-reported OpenGLES version.
    637      */
    638     final int GL_ES_VERSION;
    639 
    640     /**
    641      * List of initialization arguments to pass to all processes when binding applications to them.
    642      * For example, references to the commonly used services.
    643      */
    644     HashMap<String, IBinder> mAppBindArgs;
    645 
    646     /**
    647      * Temporary to avoid allocations.  Protected by main lock.
    648      */
    649     final StringBuilder mStringBuilder = new StringBuilder(256);
    650 
    651     /**
    652      * Used to control how we initialize the service.
    653      */
    654     boolean mStartRunning = false;
    655     ComponentName mTopComponent;
    656     String mTopAction;
    657     String mTopData;
    658     boolean mProcessesReady = false;
    659     boolean mSystemReady = false;
    660     boolean mBooting = false;
    661     boolean mWaitingUpdate = false;
    662     boolean mDidUpdate = false;
    663     boolean mOnBattery = false;
    664     boolean mLaunchWarningShown = false;
    665 
    666     Context mContext;
    667 
    668     int mFactoryTest;
    669 
    670     boolean mCheckedForSetup;
    671 
    672     /**
    673      * The time at which we will allow normal application switches again,
    674      * after a call to {@link #stopAppSwitches()}.
    675      */
    676     long mAppSwitchesAllowedTime;
    677 
    678     /**
    679      * This is set to true after the first switch after mAppSwitchesAllowedTime
    680      * is set; any switches after that will clear the time.
    681      */
    682     boolean mDidAppSwitch;
    683 
    684     /**
    685      * Last time (in realtime) at which we checked for power usage.
    686      */
    687     long mLastPowerCheckRealtime;
    688 
    689     /**
    690      * Last time (in uptime) at which we checked for power usage.
    691      */
    692     long mLastPowerCheckUptime;
    693 
    694     /**
    695      * Set while we are wanting to sleep, to prevent any
    696      * activities from being started/resumed.
    697      */
    698     boolean mSleeping = false;
    699 
    700     /**
    701      * Set if we are shutting down the system, similar to sleeping.
    702      */
    703     boolean mShuttingDown = false;
    704 
    705     /**
    706      * Task identifier that activities are currently being started
    707      * in.  Incremented each time a new task is created.
    708      * todo: Replace this with a TokenSpace class that generates non-repeating
    709      * integers that won't wrap.
    710      */
    711     int mCurTask = 1;
    712 
    713     /**
    714      * Current sequence id for oom_adj computation traversal.
    715      */
    716     int mAdjSeq = 0;
    717 
    718     /**
    719      * Current sequence id for process LRU updating.
    720      */
    721     int mLruSeq = 0;
    722 
    723     /**
    724      * System monitoring: number of processes that died since the last
    725      * N procs were started.
    726      */
    727     int[] mProcDeaths = new int[20];
    728 
    729     /**
    730      * This is set if we had to do a delayed dexopt of an app before launching
    731      * it, to increasing the ANR timeouts in that case.
    732      */
    733     boolean mDidDexOpt;
    734 
    735     String mDebugApp = null;
    736     boolean mWaitForDebugger = false;
    737     boolean mDebugTransient = false;
    738     String mOrigDebugApp = null;
    739     boolean mOrigWaitForDebugger = false;
    740     boolean mAlwaysFinishActivities = false;
    741     IActivityController mController = null;
    742     String mProfileApp = null;
    743     ProcessRecord mProfileProc = null;
    744     String mProfileFile;
    745     ParcelFileDescriptor mProfileFd;
    746     int mProfileType = 0;
    747     boolean mAutoStopProfiler = false;
    748 
    749     final RemoteCallbackList<IActivityWatcher> mWatchers
    750             = new RemoteCallbackList<IActivityWatcher>();
    751 
    752     final RemoteCallbackList<IProcessObserver> mProcessObservers
    753             = new RemoteCallbackList<IProcessObserver>();
    754 
    755     /**
    756      * Callback of last caller to {@link #requestPss}.
    757      */
    758     Runnable mRequestPssCallback;
    759 
    760     /**
    761      * Remaining processes for which we are waiting results from the last
    762      * call to {@link #requestPss}.
    763      */
    764     final ArrayList<ProcessRecord> mRequestPssList
    765             = new ArrayList<ProcessRecord>();
    766 
    767     /**
    768      * Runtime statistics collection thread.  This object's lock is used to
    769      * protect all related state.
    770      */
    771     final Thread mProcessStatsThread;
    772 
    773     /**
    774      * Used to collect process stats when showing not responding dialog.
    775      * Protected by mProcessStatsThread.
    776      */
    777     final ProcessStats mProcessStats = new ProcessStats(
    778             MONITOR_THREAD_CPU_USAGE);
    779     final AtomicLong mLastCpuTime = new AtomicLong(0);
    780     final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
    781 
    782     long mLastWriteTime = 0;
    783 
    784     /**
    785      * Set to true after the system has finished booting.
    786      */
    787     boolean mBooted = false;
    788 
    789     int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
    790     int mProcessLimitOverride = -1;
    791 
    792     WindowManagerService mWindowManager;
    793 
    794     static ActivityManagerService mSelf;
    795     static ActivityThread mSystemThread;
    796 
    797     private final class AppDeathRecipient implements IBinder.DeathRecipient {
    798         final ProcessRecord mApp;
    799         final int mPid;
    800         final IApplicationThread mAppThread;
    801 
    802         AppDeathRecipient(ProcessRecord app, int pid,
    803                 IApplicationThread thread) {
    804             if (localLOGV) Slog.v(
    805                 TAG, "New death recipient " + this
    806                 + " for thread " + thread.asBinder());
    807             mApp = app;
    808             mPid = pid;
    809             mAppThread = thread;
    810         }
    811 
    812         public void binderDied() {
    813             if (localLOGV) Slog.v(
    814                 TAG, "Death received in " + this
    815                 + " for thread " + mAppThread.asBinder());
    816             synchronized(ActivityManagerService.this) {
    817                 appDiedLocked(mApp, mPid, mAppThread);
    818             }
    819         }
    820     }
    821 
    822     static final int SHOW_ERROR_MSG = 1;
    823     static final int SHOW_NOT_RESPONDING_MSG = 2;
    824     static final int SHOW_FACTORY_ERROR_MSG = 3;
    825     static final int UPDATE_CONFIGURATION_MSG = 4;
    826     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
    827     static final int WAIT_FOR_DEBUGGER_MSG = 6;
    828     static final int BROADCAST_INTENT_MSG = 7;
    829     static final int BROADCAST_TIMEOUT_MSG = 8;
    830     static final int SERVICE_TIMEOUT_MSG = 12;
    831     static final int UPDATE_TIME_ZONE = 13;
    832     static final int SHOW_UID_ERROR_MSG = 14;
    833     static final int IM_FEELING_LUCKY_MSG = 15;
    834     static final int PROC_START_TIMEOUT_MSG = 20;
    835     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
    836     static final int KILL_APPLICATION_MSG = 22;
    837     static final int FINALIZE_PENDING_INTENT_MSG = 23;
    838     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
    839     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
    840     static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
    841     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
    842     static final int CLEAR_DNS_CACHE = 28;
    843     static final int UPDATE_HTTP_PROXY = 29;
    844     static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
    845     static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
    846     static final int DISPATCH_PROCESS_DIED = 32;
    847 
    848     AlertDialog mUidAlert;
    849     CompatModeDialog mCompatModeDialog;
    850 
    851     final Handler mHandler = new Handler() {
    852         //public Handler() {
    853         //    if (localLOGV) Slog.v(TAG, "Handler started!");
    854         //}
    855 
    856         public void handleMessage(Message msg) {
    857             switch (msg.what) {
    858             case SHOW_ERROR_MSG: {
    859                 HashMap data = (HashMap) msg.obj;
    860                 synchronized (ActivityManagerService.this) {
    861                     ProcessRecord proc = (ProcessRecord)data.get("app");
    862                     if (proc != null && proc.crashDialog != null) {
    863                         Slog.e(TAG, "App already has crash dialog: " + proc);
    864                         return;
    865                     }
    866                     AppErrorResult res = (AppErrorResult) data.get("result");
    867                     if (!mSleeping && !mShuttingDown) {
    868                         Dialog d = new AppErrorDialog(mContext, res, proc);
    869                         d.show();
    870                         proc.crashDialog = d;
    871                     } else {
    872                         // The device is asleep, so just pretend that the user
    873                         // saw a crash dialog and hit "force quit".
    874                         res.set(0);
    875                     }
    876                 }
    877 
    878                 ensureBootCompleted();
    879             } break;
    880             case SHOW_NOT_RESPONDING_MSG: {
    881                 synchronized (ActivityManagerService.this) {
    882                     HashMap data = (HashMap) msg.obj;
    883                     ProcessRecord proc = (ProcessRecord)data.get("app");
    884                     if (proc != null && proc.anrDialog != null) {
    885                         Slog.e(TAG, "App already has anr dialog: " + proc);
    886                         return;
    887                     }
    888 
    889                     Intent intent = new Intent("android.intent.action.ANR");
    890                     if (!mProcessesReady) {
    891                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
    892                     }
    893                     broadcastIntentLocked(null, null, intent,
    894                             null, null, 0, null, null, null,
    895                             false, false, MY_PID, Process.SYSTEM_UID);
    896 
    897                     Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
    898                             mContext, proc, (ActivityRecord)data.get("activity"));
    899                     d.show();
    900                     proc.anrDialog = d;
    901                 }
    902 
    903                 ensureBootCompleted();
    904             } break;
    905             case SHOW_STRICT_MODE_VIOLATION_MSG: {
    906                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
    907                 synchronized (ActivityManagerService.this) {
    908                     ProcessRecord proc = (ProcessRecord) data.get("app");
    909                     if (proc == null) {
    910                         Slog.e(TAG, "App not found when showing strict mode dialog.");
    911                         break;
    912                     }
    913                     if (proc.crashDialog != null) {
    914                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
    915                         return;
    916                     }
    917                     AppErrorResult res = (AppErrorResult) data.get("result");
    918                     if (!mSleeping && !mShuttingDown) {
    919                         Dialog d = new StrictModeViolationDialog(mContext, res, proc);
    920                         d.show();
    921                         proc.crashDialog = d;
    922                     } else {
    923                         // The device is asleep, so just pretend that the user
    924                         // saw a crash dialog and hit "force quit".
    925                         res.set(0);
    926                     }
    927                 }
    928                 ensureBootCompleted();
    929             } break;
    930             case SHOW_FACTORY_ERROR_MSG: {
    931                 Dialog d = new FactoryErrorDialog(
    932                     mContext, msg.getData().getCharSequence("msg"));
    933                 d.show();
    934                 ensureBootCompleted();
    935             } break;
    936             case UPDATE_CONFIGURATION_MSG: {
    937                 final ContentResolver resolver = mContext.getContentResolver();
    938                 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
    939             } break;
    940             case GC_BACKGROUND_PROCESSES_MSG: {
    941                 synchronized (ActivityManagerService.this) {
    942                     performAppGcsIfAppropriateLocked();
    943                 }
    944             } break;
    945             case WAIT_FOR_DEBUGGER_MSG: {
    946                 synchronized (ActivityManagerService.this) {
    947                     ProcessRecord app = (ProcessRecord)msg.obj;
    948                     if (msg.arg1 != 0) {
    949                         if (!app.waitedForDebugger) {
    950                             Dialog d = new AppWaitingForDebuggerDialog(
    951                                     ActivityManagerService.this,
    952                                     mContext, app);
    953                             app.waitDialog = d;
    954                             app.waitedForDebugger = true;
    955                             d.show();
    956                         }
    957                     } else {
    958                         if (app.waitDialog != null) {
    959                             app.waitDialog.dismiss();
    960                             app.waitDialog = null;
    961                         }
    962                     }
    963                 }
    964             } break;
    965             case BROADCAST_INTENT_MSG: {
    966                 if (DEBUG_BROADCAST) Slog.v(
    967                         TAG, "Received BROADCAST_INTENT_MSG");
    968                 processNextBroadcast(true);
    969             } break;
    970             case BROADCAST_TIMEOUT_MSG: {
    971                 synchronized (ActivityManagerService.this) {
    972                     broadcastTimeoutLocked(true);
    973                 }
    974             } break;
    975             case SERVICE_TIMEOUT_MSG: {
    976                 if (mDidDexOpt) {
    977                     mDidDexOpt = false;
    978                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
    979                     nmsg.obj = msg.obj;
    980                     mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
    981                     return;
    982                 }
    983                 serviceTimeout((ProcessRecord)msg.obj);
    984             } break;
    985             case UPDATE_TIME_ZONE: {
    986                 synchronized (ActivityManagerService.this) {
    987                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
    988                         ProcessRecord r = mLruProcesses.get(i);
    989                         if (r.thread != null) {
    990                             try {
    991                                 r.thread.updateTimeZone();
    992                             } catch (RemoteException ex) {
    993                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
    994                             }
    995                         }
    996                     }
    997                 }
    998             } break;
    999             case CLEAR_DNS_CACHE: {
   1000                 synchronized (ActivityManagerService.this) {
   1001                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1002                         ProcessRecord r = mLruProcesses.get(i);
   1003                         if (r.thread != null) {
   1004                             try {
   1005                                 r.thread.clearDnsCache();
   1006                             } catch (RemoteException ex) {
   1007                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
   1008                             }
   1009                         }
   1010                     }
   1011                 }
   1012             } break;
   1013             case UPDATE_HTTP_PROXY: {
   1014                 ProxyProperties proxy = (ProxyProperties)msg.obj;
   1015                 String host = "";
   1016                 String port = "";
   1017                 String exclList = "";
   1018                 if (proxy != null) {
   1019                     host = proxy.getHost();
   1020                     port = Integer.toString(proxy.getPort());
   1021                     exclList = proxy.getExclusionList();
   1022                 }
   1023                 synchronized (ActivityManagerService.this) {
   1024                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1025                         ProcessRecord r = mLruProcesses.get(i);
   1026                         if (r.thread != null) {
   1027                             try {
   1028                                 r.thread.setHttpProxy(host, port, exclList);
   1029                             } catch (RemoteException ex) {
   1030                                 Slog.w(TAG, "Failed to update http proxy for: " +
   1031                                         r.info.processName);
   1032                             }
   1033                         }
   1034                     }
   1035                 }
   1036             } break;
   1037             case SHOW_UID_ERROR_MSG: {
   1038                 // XXX This is a temporary dialog, no need to localize.
   1039                 AlertDialog d = new BaseErrorDialog(mContext);
   1040                 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
   1041                 d.setCancelable(false);
   1042                 d.setTitle("System UIDs Inconsistent");
   1043                 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
   1044                 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
   1045                         mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
   1046                 mUidAlert = d;
   1047                 d.show();
   1048             } break;
   1049             case IM_FEELING_LUCKY_MSG: {
   1050                 if (mUidAlert != null) {
   1051                     mUidAlert.dismiss();
   1052                     mUidAlert = null;
   1053                 }
   1054             } break;
   1055             case PROC_START_TIMEOUT_MSG: {
   1056                 if (mDidDexOpt) {
   1057                     mDidDexOpt = false;
   1058                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   1059                     nmsg.obj = msg.obj;
   1060                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
   1061                     return;
   1062                 }
   1063                 ProcessRecord app = (ProcessRecord)msg.obj;
   1064                 synchronized (ActivityManagerService.this) {
   1065                     processStartTimedOutLocked(app);
   1066                 }
   1067             } break;
   1068             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
   1069                 synchronized (ActivityManagerService.this) {
   1070                     doPendingActivityLaunchesLocked(true);
   1071                 }
   1072             } break;
   1073             case KILL_APPLICATION_MSG: {
   1074                 synchronized (ActivityManagerService.this) {
   1075                     int uid = msg.arg1;
   1076                     boolean restart = (msg.arg2 == 1);
   1077                     String pkg = (String) msg.obj;
   1078                     forceStopPackageLocked(pkg, uid, restart, false, true, false);
   1079                 }
   1080             } break;
   1081             case FINALIZE_PENDING_INTENT_MSG: {
   1082                 ((PendingIntentRecord)msg.obj).completeFinalize();
   1083             } break;
   1084             case POST_HEAVY_NOTIFICATION_MSG: {
   1085                 INotificationManager inm = NotificationManager.getService();
   1086                 if (inm == null) {
   1087                     return;
   1088                 }
   1089 
   1090                 ActivityRecord root = (ActivityRecord)msg.obj;
   1091                 ProcessRecord process = root.app;
   1092                 if (process == null) {
   1093                     return;
   1094                 }
   1095 
   1096                 try {
   1097                     Context context = mContext.createPackageContext(process.info.packageName, 0);
   1098                     String text = mContext.getString(R.string.heavy_weight_notification,
   1099                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
   1100                     Notification notification = new Notification();
   1101                     notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
   1102                     notification.when = 0;
   1103                     notification.flags = Notification.FLAG_ONGOING_EVENT;
   1104                     notification.tickerText = text;
   1105                     notification.defaults = 0; // please be quiet
   1106                     notification.sound = null;
   1107                     notification.vibrate = null;
   1108                     notification.setLatestEventInfo(context, text,
   1109                             mContext.getText(R.string.heavy_weight_notification_detail),
   1110                             PendingIntent.getActivity(mContext, 0, root.intent,
   1111                                     PendingIntent.FLAG_CANCEL_CURRENT));
   1112 
   1113                     try {
   1114                         int[] outId = new int[1];
   1115                         inm.enqueueNotification("android", R.string.heavy_weight_notification,
   1116                                 notification, outId);
   1117                     } catch (RuntimeException e) {
   1118                         Slog.w(ActivityManagerService.TAG,
   1119                                 "Error showing notification for heavy-weight app", e);
   1120                     } catch (RemoteException e) {
   1121                     }
   1122                 } catch (NameNotFoundException e) {
   1123                     Slog.w(TAG, "Unable to create context for heavy notification", e);
   1124                 }
   1125             } break;
   1126             case CANCEL_HEAVY_NOTIFICATION_MSG: {
   1127                 INotificationManager inm = NotificationManager.getService();
   1128                 if (inm == null) {
   1129                     return;
   1130                 }
   1131                 try {
   1132                     inm.cancelNotification("android",
   1133                             R.string.heavy_weight_notification);
   1134                 } catch (RuntimeException e) {
   1135                     Slog.w(ActivityManagerService.TAG,
   1136                             "Error canceling notification for service", e);
   1137                 } catch (RemoteException e) {
   1138                 }
   1139             } break;
   1140             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
   1141                 synchronized (ActivityManagerService.this) {
   1142                     checkExcessivePowerUsageLocked(true);
   1143                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1144                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1145                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   1146                 }
   1147             } break;
   1148             case SHOW_COMPAT_MODE_DIALOG_MSG: {
   1149                 synchronized (ActivityManagerService.this) {
   1150                     ActivityRecord ar = (ActivityRecord)msg.obj;
   1151                     if (mCompatModeDialog != null) {
   1152                         if (mCompatModeDialog.mAppInfo.packageName.equals(
   1153                                 ar.info.applicationInfo.packageName)) {
   1154                             return;
   1155                         }
   1156                         mCompatModeDialog.dismiss();
   1157                         mCompatModeDialog = null;
   1158                     }
   1159                     if (ar != null && false) {
   1160                         if (mCompatModePackages.getPackageAskCompatModeLocked(
   1161                                 ar.packageName)) {
   1162                             int mode = mCompatModePackages.computeCompatModeLocked(
   1163                                     ar.info.applicationInfo);
   1164                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
   1165                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
   1166                                 mCompatModeDialog = new CompatModeDialog(
   1167                                         ActivityManagerService.this, mContext,
   1168                                         ar.info.applicationInfo);
   1169                                 mCompatModeDialog.show();
   1170                             }
   1171                         }
   1172                     }
   1173                 }
   1174                 break;
   1175             }
   1176             case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
   1177                 final int pid = msg.arg1;
   1178                 final int uid = msg.arg2;
   1179                 final boolean foregroundActivities = (Boolean) msg.obj;
   1180                 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
   1181                 break;
   1182             }
   1183             case DISPATCH_PROCESS_DIED: {
   1184                 final int pid = msg.arg1;
   1185                 final int uid = msg.arg2;
   1186                 dispatchProcessDied(pid, uid);
   1187                 break;
   1188             }
   1189             }
   1190         }
   1191     };
   1192 
   1193     public static void setSystemProcess() {
   1194         try {
   1195             ActivityManagerService m = mSelf;
   1196 
   1197             ServiceManager.addService("activity", m);
   1198             ServiceManager.addService("meminfo", new MemBinder(m));
   1199             ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
   1200             if (MONITOR_CPU_USAGE) {
   1201                 ServiceManager.addService("cpuinfo", new CpuBinder(m));
   1202             }
   1203             ServiceManager.addService("permission", new PermissionController(m));
   1204 
   1205             ApplicationInfo info =
   1206                 mSelf.mContext.getPackageManager().getApplicationInfo(
   1207                         "android", STOCK_PM_FLAGS);
   1208             mSystemThread.installSystemApplicationInfo(info);
   1209 
   1210             synchronized (mSelf) {
   1211                 ProcessRecord app = mSelf.newProcessRecordLocked(
   1212                         mSystemThread.getApplicationThread(), info,
   1213                         info.processName);
   1214                 app.persistent = true;
   1215                 app.pid = MY_PID;
   1216                 app.maxAdj = ProcessList.SYSTEM_ADJ;
   1217                 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
   1218                 synchronized (mSelf.mPidsSelfLocked) {
   1219                     mSelf.mPidsSelfLocked.put(app.pid, app);
   1220                 }
   1221                 mSelf.updateLruProcessLocked(app, true, true);
   1222             }
   1223         } catch (PackageManager.NameNotFoundException e) {
   1224             throw new RuntimeException(
   1225                     "Unable to find android system package", e);
   1226         }
   1227     }
   1228 
   1229     public void setWindowManager(WindowManagerService wm) {
   1230         mWindowManager = wm;
   1231     }
   1232 
   1233     public static final Context main(int factoryTest) {
   1234         AThread thr = new AThread();
   1235         thr.start();
   1236 
   1237         synchronized (thr) {
   1238             while (thr.mService == null) {
   1239                 try {
   1240                     thr.wait();
   1241                 } catch (InterruptedException e) {
   1242                 }
   1243             }
   1244         }
   1245 
   1246         ActivityManagerService m = thr.mService;
   1247         mSelf = m;
   1248         ActivityThread at = ActivityThread.systemMain();
   1249         mSystemThread = at;
   1250         Context context = at.getSystemContext();
   1251         context.setTheme(android.R.style.Theme_Holo);
   1252         m.mContext = context;
   1253         m.mFactoryTest = factoryTest;
   1254         m.mMainStack = new ActivityStack(m, context, true);
   1255 
   1256         m.mBatteryStatsService.publish(context);
   1257         m.mUsageStatsService.publish(context);
   1258 
   1259         synchronized (thr) {
   1260             thr.mReady = true;
   1261             thr.notifyAll();
   1262         }
   1263 
   1264         m.startRunning(null, null, null, null);
   1265 
   1266         return context;
   1267     }
   1268 
   1269     public static ActivityManagerService self() {
   1270         return mSelf;
   1271     }
   1272 
   1273     static class AThread extends Thread {
   1274         ActivityManagerService mService;
   1275         boolean mReady = false;
   1276 
   1277         public AThread() {
   1278             super("ActivityManager");
   1279         }
   1280 
   1281         public void run() {
   1282             Looper.prepare();
   1283 
   1284             android.os.Process.setThreadPriority(
   1285                     android.os.Process.THREAD_PRIORITY_FOREGROUND);
   1286             android.os.Process.setCanSelfBackground(false);
   1287 
   1288             ActivityManagerService m = new ActivityManagerService();
   1289 
   1290             synchronized (this) {
   1291                 mService = m;
   1292                 notifyAll();
   1293             }
   1294 
   1295             synchronized (this) {
   1296                 while (!mReady) {
   1297                     try {
   1298                         wait();
   1299                     } catch (InterruptedException e) {
   1300                     }
   1301                 }
   1302             }
   1303 
   1304             // For debug builds, log event loop stalls to dropbox for analysis.
   1305             if (StrictMode.conditionallyEnableDebugLogging()) {
   1306                 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
   1307             }
   1308 
   1309             Looper.loop();
   1310         }
   1311     }
   1312 
   1313     static class MemBinder extends Binder {
   1314         ActivityManagerService mActivityManagerService;
   1315         MemBinder(ActivityManagerService activityManagerService) {
   1316             mActivityManagerService = activityManagerService;
   1317         }
   1318 
   1319         @Override
   1320         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1321             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1322                     != PackageManager.PERMISSION_GRANTED) {
   1323                 pw.println("Permission Denial: can't dump meminfo from from pid="
   1324                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1325                         + " without permission " + android.Manifest.permission.DUMP);
   1326                 return;
   1327             }
   1328 
   1329             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args);
   1330         }
   1331     }
   1332 
   1333     static class GraphicsBinder extends Binder {
   1334         ActivityManagerService mActivityManagerService;
   1335         GraphicsBinder(ActivityManagerService activityManagerService) {
   1336             mActivityManagerService = activityManagerService;
   1337         }
   1338 
   1339         @Override
   1340         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1341             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1342                     != PackageManager.PERMISSION_GRANTED) {
   1343                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
   1344                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1345                         + " without permission " + android.Manifest.permission.DUMP);
   1346                 return;
   1347             }
   1348 
   1349             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
   1350         }
   1351     }
   1352 
   1353     static class CpuBinder extends Binder {
   1354         ActivityManagerService mActivityManagerService;
   1355         CpuBinder(ActivityManagerService activityManagerService) {
   1356             mActivityManagerService = activityManagerService;
   1357         }
   1358 
   1359         @Override
   1360         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1361             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1362                     != PackageManager.PERMISSION_GRANTED) {
   1363                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
   1364                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1365                         + " without permission " + android.Manifest.permission.DUMP);
   1366                 return;
   1367             }
   1368 
   1369             synchronized (mActivityManagerService.mProcessStatsThread) {
   1370                 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
   1371                 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
   1372                         SystemClock.uptimeMillis()));
   1373             }
   1374         }
   1375     }
   1376 
   1377     private ActivityManagerService() {
   1378         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
   1379 
   1380         File dataDir = Environment.getDataDirectory();
   1381         File systemDir = new File(dataDir, "system");
   1382         systemDir.mkdirs();
   1383         mBatteryStatsService = new BatteryStatsService(new File(
   1384                 systemDir, "batterystats.bin").toString());
   1385         mBatteryStatsService.getActiveStatistics().readLocked();
   1386         mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
   1387         mOnBattery = DEBUG_POWER ? true
   1388                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
   1389         mBatteryStatsService.getActiveStatistics().setCallback(this);
   1390 
   1391         mUsageStatsService = new UsageStatsService(new File(
   1392                 systemDir, "usagestats").toString());
   1393 
   1394         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
   1395             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
   1396 
   1397         mConfiguration.setToDefaults();
   1398         mConfiguration.locale = Locale.getDefault();
   1399         mProcessStats.init();
   1400 
   1401         mCompatModePackages = new CompatModePackages(this, systemDir);
   1402 
   1403         // Add ourself to the Watchdog monitors.
   1404         Watchdog.getInstance().addMonitor(this);
   1405 
   1406         mProcessStatsThread = new Thread("ProcessStats") {
   1407             public void run() {
   1408                 while (true) {
   1409                     try {
   1410                         try {
   1411                             synchronized(this) {
   1412                                 final long now = SystemClock.uptimeMillis();
   1413                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
   1414                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
   1415                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
   1416                                 //        + ", write delay=" + nextWriteDelay);
   1417                                 if (nextWriteDelay < nextCpuDelay) {
   1418                                     nextCpuDelay = nextWriteDelay;
   1419                                 }
   1420                                 if (nextCpuDelay > 0) {
   1421                                     mProcessStatsMutexFree.set(true);
   1422                                     this.wait(nextCpuDelay);
   1423                                 }
   1424                             }
   1425                         } catch (InterruptedException e) {
   1426                         }
   1427                         updateCpuStatsNow();
   1428                     } catch (Exception e) {
   1429                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
   1430                     }
   1431                 }
   1432             }
   1433         };
   1434         mProcessStatsThread.start();
   1435     }
   1436 
   1437     @Override
   1438     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   1439             throws RemoteException {
   1440         try {
   1441             return super.onTransact(code, data, reply, flags);
   1442         } catch (RuntimeException e) {
   1443             // The activity manager only throws security exceptions, so let's
   1444             // log all others.
   1445             if (!(e instanceof SecurityException)) {
   1446                 Slog.e(TAG, "Activity Manager Crash", e);
   1447             }
   1448             throw e;
   1449         }
   1450     }
   1451 
   1452     void updateCpuStats() {
   1453         final long now = SystemClock.uptimeMillis();
   1454         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
   1455             return;
   1456         }
   1457         if (mProcessStatsMutexFree.compareAndSet(true, false)) {
   1458             synchronized (mProcessStatsThread) {
   1459                 mProcessStatsThread.notify();
   1460             }
   1461         }
   1462     }
   1463 
   1464     void updateCpuStatsNow() {
   1465         synchronized (mProcessStatsThread) {
   1466             mProcessStatsMutexFree.set(false);
   1467             final long now = SystemClock.uptimeMillis();
   1468             boolean haveNewCpuStats = false;
   1469 
   1470             if (MONITOR_CPU_USAGE &&
   1471                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
   1472                 mLastCpuTime.set(now);
   1473                 haveNewCpuStats = true;
   1474                 mProcessStats.update();
   1475                 //Slog.i(TAG, mProcessStats.printCurrentState());
   1476                 //Slog.i(TAG, "Total CPU usage: "
   1477                 //        + mProcessStats.getTotalCpuPercent() + "%");
   1478 
   1479                 // Slog the cpu usage if the property is set.
   1480                 if ("true".equals(SystemProperties.get("events.cpu"))) {
   1481                     int user = mProcessStats.getLastUserTime();
   1482                     int system = mProcessStats.getLastSystemTime();
   1483                     int iowait = mProcessStats.getLastIoWaitTime();
   1484                     int irq = mProcessStats.getLastIrqTime();
   1485                     int softIrq = mProcessStats.getLastSoftIrqTime();
   1486                     int idle = mProcessStats.getLastIdleTime();
   1487 
   1488                     int total = user + system + iowait + irq + softIrq + idle;
   1489                     if (total == 0) total = 1;
   1490 
   1491                     EventLog.writeEvent(EventLogTags.CPU,
   1492                             ((user+system+iowait+irq+softIrq) * 100) / total,
   1493                             (user * 100) / total,
   1494                             (system * 100) / total,
   1495                             (iowait * 100) / total,
   1496                             (irq * 100) / total,
   1497                             (softIrq * 100) / total);
   1498                 }
   1499             }
   1500 
   1501             long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
   1502             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
   1503             synchronized(bstats) {
   1504                 synchronized(mPidsSelfLocked) {
   1505                     if (haveNewCpuStats) {
   1506                         if (mOnBattery) {
   1507                             int perc = bstats.startAddingCpuLocked();
   1508                             int totalUTime = 0;
   1509                             int totalSTime = 0;
   1510                             final int N = mProcessStats.countStats();
   1511                             for (int i=0; i<N; i++) {
   1512                                 ProcessStats.Stats st = mProcessStats.getStats(i);
   1513                                 if (!st.working) {
   1514                                     continue;
   1515                                 }
   1516                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
   1517                                 int otherUTime = (st.rel_utime*perc)/100;
   1518                                 int otherSTime = (st.rel_stime*perc)/100;
   1519                                 totalUTime += otherUTime;
   1520                                 totalSTime += otherSTime;
   1521                                 if (pr != null) {
   1522                                     BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
   1523                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
   1524                                             st.rel_stime-otherSTime);
   1525                                     ps.addSpeedStepTimes(cpuSpeedTimes);
   1526                                     pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
   1527                                 } else {
   1528                                     BatteryStatsImpl.Uid.Proc ps =
   1529                                             bstats.getProcessStatsLocked(st.name, st.pid);
   1530                                     if (ps != null) {
   1531                                         ps.addCpuTimeLocked(st.rel_utime-otherUTime,
   1532                                                 st.rel_stime-otherSTime);
   1533                                         ps.addSpeedStepTimes(cpuSpeedTimes);
   1534                                     }
   1535                                 }
   1536                             }
   1537                             bstats.finishAddingCpuLocked(perc, totalUTime,
   1538                                     totalSTime, cpuSpeedTimes);
   1539                         }
   1540                     }
   1541                 }
   1542 
   1543                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
   1544                     mLastWriteTime = now;
   1545                     mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
   1546                 }
   1547             }
   1548         }
   1549     }
   1550 
   1551     @Override
   1552     public void batteryNeedsCpuUpdate() {
   1553         updateCpuStatsNow();
   1554     }
   1555 
   1556     @Override
   1557     public void batteryPowerChanged(boolean onBattery) {
   1558         // When plugging in, update the CPU stats first before changing
   1559         // the plug state.
   1560         updateCpuStatsNow();
   1561         synchronized (this) {
   1562             synchronized(mPidsSelfLocked) {
   1563                 mOnBattery = DEBUG_POWER ? true : onBattery;
   1564             }
   1565         }
   1566     }
   1567 
   1568     /**
   1569      * Initialize the application bind args. These are passed to each
   1570      * process when the bindApplication() IPC is sent to the process. They're
   1571      * lazily setup to make sure the services are running when they're asked for.
   1572      */
   1573     private HashMap<String, IBinder> getCommonServicesLocked() {
   1574         if (mAppBindArgs == null) {
   1575             mAppBindArgs = new HashMap<String, IBinder>();
   1576 
   1577             // Setup the application init args
   1578             mAppBindArgs.put("package", ServiceManager.getService("package"));
   1579             mAppBindArgs.put("window", ServiceManager.getService("window"));
   1580             mAppBindArgs.put(Context.ALARM_SERVICE,
   1581                     ServiceManager.getService(Context.ALARM_SERVICE));
   1582         }
   1583         return mAppBindArgs;
   1584     }
   1585 
   1586     final void setFocusedActivityLocked(ActivityRecord r) {
   1587         if (mFocusedActivity != r) {
   1588             mFocusedActivity = r;
   1589             mWindowManager.setFocusedApp(r, true);
   1590         }
   1591     }
   1592 
   1593     private final void updateLruProcessInternalLocked(ProcessRecord app,
   1594             boolean oomAdj, boolean updateActivityTime, int bestPos) {
   1595         // put it on the LRU to keep track of when it should be exited.
   1596         int lrui = mLruProcesses.indexOf(app);
   1597         if (lrui >= 0) mLruProcesses.remove(lrui);
   1598 
   1599         int i = mLruProcesses.size()-1;
   1600         int skipTop = 0;
   1601 
   1602         app.lruSeq = mLruSeq;
   1603 
   1604         // compute the new weight for this process.
   1605         if (updateActivityTime) {
   1606             app.lastActivityTime = SystemClock.uptimeMillis();
   1607         }
   1608         if (app.activities.size() > 0) {
   1609             // If this process has activities, we more strongly want to keep
   1610             // it around.
   1611             app.lruWeight = app.lastActivityTime;
   1612         } else if (app.pubProviders.size() > 0) {
   1613             // If this process contains content providers, we want to keep
   1614             // it a little more strongly.
   1615             app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
   1616             // Also don't let it kick out the first few "real" hidden processes.
   1617             skipTop = ProcessList.MIN_HIDDEN_APPS;
   1618         } else {
   1619             // If this process doesn't have activities, we less strongly
   1620             // want to keep it around, and generally want to avoid getting
   1621             // in front of any very recently used activities.
   1622             app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
   1623             // Also don't let it kick out the first few "real" hidden processes.
   1624             skipTop = ProcessList.MIN_HIDDEN_APPS;
   1625         }
   1626 
   1627         while (i >= 0) {
   1628             ProcessRecord p = mLruProcesses.get(i);
   1629             // If this app shouldn't be in front of the first N background
   1630             // apps, then skip over that many that are currently hidden.
   1631             if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   1632                 skipTop--;
   1633             }
   1634             if (p.lruWeight <= app.lruWeight || i < bestPos) {
   1635                 mLruProcesses.add(i+1, app);
   1636                 break;
   1637             }
   1638             i--;
   1639         }
   1640         if (i < 0) {
   1641             mLruProcesses.add(0, app);
   1642         }
   1643 
   1644         // If the app is currently using a content provider or service,
   1645         // bump those processes as well.
   1646         if (app.connections.size() > 0) {
   1647             for (ConnectionRecord cr : app.connections) {
   1648                 if (cr.binding != null && cr.binding.service != null
   1649                         && cr.binding.service.app != null
   1650                         && cr.binding.service.app.lruSeq != mLruSeq) {
   1651                     updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
   1652                             updateActivityTime, i+1);
   1653                 }
   1654             }
   1655         }
   1656         if (app.conProviders.size() > 0) {
   1657             for (ContentProviderRecord cpr : app.conProviders.keySet()) {
   1658                 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
   1659                     updateLruProcessInternalLocked(cpr.proc, oomAdj,
   1660                             updateActivityTime, i+1);
   1661                 }
   1662             }
   1663         }
   1664 
   1665         //Slog.i(TAG, "Putting proc to front: " + app.processName);
   1666         if (oomAdj) {
   1667             updateOomAdjLocked();
   1668         }
   1669     }
   1670 
   1671     final void updateLruProcessLocked(ProcessRecord app,
   1672             boolean oomAdj, boolean updateActivityTime) {
   1673         mLruSeq++;
   1674         updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
   1675     }
   1676 
   1677     final ProcessRecord getProcessRecordLocked(
   1678             String processName, int uid) {
   1679         if (uid == Process.SYSTEM_UID) {
   1680             // The system gets to run in any process.  If there are multiple
   1681             // processes with the same uid, just pick the first (this
   1682             // should never happen).
   1683             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
   1684                     processName);
   1685             return procs != null ? procs.valueAt(0) : null;
   1686         }
   1687         ProcessRecord proc = mProcessNames.get(processName, uid);
   1688         return proc;
   1689     }
   1690 
   1691     void ensurePackageDexOpt(String packageName) {
   1692         IPackageManager pm = AppGlobals.getPackageManager();
   1693         try {
   1694             if (pm.performDexOpt(packageName)) {
   1695                 mDidDexOpt = true;
   1696             }
   1697         } catch (RemoteException e) {
   1698         }
   1699     }
   1700 
   1701     boolean isNextTransitionForward() {
   1702         int transit = mWindowManager.getPendingAppTransition();
   1703         return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
   1704                 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
   1705                 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
   1706     }
   1707 
   1708     final ProcessRecord startProcessLocked(String processName,
   1709             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
   1710             String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
   1711         ProcessRecord app = getProcessRecordLocked(processName, info.uid);
   1712         // We don't have to do anything more if:
   1713         // (1) There is an existing application record; and
   1714         // (2) The caller doesn't think it is dead, OR there is no thread
   1715         //     object attached to it so we know it couldn't have crashed; and
   1716         // (3) There is a pid assigned to it, so it is either starting or
   1717         //     already running.
   1718         if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
   1719                 + " app=" + app + " knownToBeDead=" + knownToBeDead
   1720                 + " thread=" + (app != null ? app.thread : null)
   1721                 + " pid=" + (app != null ? app.pid : -1));
   1722         if (app != null && app.pid > 0) {
   1723             if (!knownToBeDead || app.thread == null) {
   1724                 // We already have the app running, or are waiting for it to
   1725                 // come up (we have a pid but not yet its thread), so keep it.
   1726                 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
   1727                 // If this is a new package in the process, add the package to the list
   1728                 app.addPackage(info.packageName);
   1729                 return app;
   1730             } else {
   1731                 // An application record is attached to a previous process,
   1732                 // clean it up now.
   1733                 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
   1734                 handleAppDiedLocked(app, true, true);
   1735             }
   1736         }
   1737 
   1738         String hostingNameStr = hostingName != null
   1739                 ? hostingName.flattenToShortString() : null;
   1740 
   1741         if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
   1742             // If we are in the background, then check to see if this process
   1743             // is bad.  If so, we will just silently fail.
   1744             if (mBadProcesses.get(info.processName, info.uid) != null) {
   1745                 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
   1746                         + "/" + info.processName);
   1747                 return null;
   1748             }
   1749         } else {
   1750             // When the user is explicitly starting a process, then clear its
   1751             // crash count so that we won't make it bad until they see at
   1752             // least one crash dialog again, and make the process good again
   1753             // if it had been bad.
   1754             if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
   1755                     + "/" + info.processName);
   1756             mProcessCrashTimes.remove(info.processName, info.uid);
   1757             if (mBadProcesses.get(info.processName, info.uid) != null) {
   1758                 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
   1759                         info.processName);
   1760                 mBadProcesses.remove(info.processName, info.uid);
   1761                 if (app != null) {
   1762                     app.bad = false;
   1763                 }
   1764             }
   1765         }
   1766 
   1767         if (app == null) {
   1768             app = newProcessRecordLocked(null, info, processName);
   1769             mProcessNames.put(processName, info.uid, app);
   1770         } else {
   1771             // If this is a new package in the process, add the package to the list
   1772             app.addPackage(info.packageName);
   1773         }
   1774 
   1775         // If the system is not ready yet, then hold off on starting this
   1776         // process until it is.
   1777         if (!mProcessesReady
   1778                 && !isAllowedWhileBooting(info)
   1779                 && !allowWhileBooting) {
   1780             if (!mProcessesOnHold.contains(app)) {
   1781                 mProcessesOnHold.add(app);
   1782             }
   1783             if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
   1784             return app;
   1785         }
   1786 
   1787         startProcessLocked(app, hostingType, hostingNameStr);
   1788         return (app.pid != 0) ? app : null;
   1789     }
   1790 
   1791     boolean isAllowedWhileBooting(ApplicationInfo ai) {
   1792         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
   1793     }
   1794 
   1795     private final void startProcessLocked(ProcessRecord app,
   1796             String hostingType, String hostingNameStr) {
   1797         if (app.pid > 0 && app.pid != MY_PID) {
   1798             synchronized (mPidsSelfLocked) {
   1799                 mPidsSelfLocked.remove(app.pid);
   1800                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   1801             }
   1802             app.pid = 0;
   1803         }
   1804 
   1805         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   1806                 "startProcessLocked removing on hold: " + app);
   1807         mProcessesOnHold.remove(app);
   1808 
   1809         updateCpuStats();
   1810 
   1811         System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
   1812         mProcDeaths[0] = 0;
   1813 
   1814         try {
   1815             int uid = app.info.uid;
   1816             int[] gids = null;
   1817             try {
   1818                 gids = mContext.getPackageManager().getPackageGids(
   1819                         app.info.packageName);
   1820             } catch (PackageManager.NameNotFoundException e) {
   1821                 Slog.w(TAG, "Unable to retrieve gids", e);
   1822             }
   1823             if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
   1824                 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
   1825                         && mTopComponent != null
   1826                         && app.processName.equals(mTopComponent.getPackageName())) {
   1827                     uid = 0;
   1828                 }
   1829                 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
   1830                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
   1831                     uid = 0;
   1832                 }
   1833             }
   1834             int debugFlags = 0;
   1835             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   1836                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
   1837                 // Also turn on CheckJNI for debuggable apps. It's quite
   1838                 // awkward to turn on otherwise.
   1839                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   1840             }
   1841             // Run the app in safe mode if its manifest requests so or the
   1842             // system is booted in safe mode.
   1843             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
   1844                 Zygote.systemInSafeMode == true) {
   1845                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
   1846             }
   1847             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
   1848                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   1849             }
   1850             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
   1851                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
   1852             }
   1853             if ("1".equals(SystemProperties.get("debug.assert"))) {
   1854                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
   1855             }
   1856 
   1857             // Start the process.  It will either succeed and return a result containing
   1858             // the PID of the new process, or else throw a RuntimeException.
   1859             Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
   1860                     app.processName, uid, uid, gids, debugFlags,
   1861                     app.info.targetSdkVersion, null);
   1862 
   1863             BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
   1864             synchronized (bs) {
   1865                 if (bs.isOnBattery()) {
   1866                     app.batteryStats.incStartsLocked();
   1867                 }
   1868             }
   1869 
   1870             EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
   1871                     app.processName, hostingType,
   1872                     hostingNameStr != null ? hostingNameStr : "");
   1873 
   1874             if (app.persistent) {
   1875                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
   1876             }
   1877 
   1878             StringBuilder buf = mStringBuilder;
   1879             buf.setLength(0);
   1880             buf.append("Start proc ");
   1881             buf.append(app.processName);
   1882             buf.append(" for ");
   1883             buf.append(hostingType);
   1884             if (hostingNameStr != null) {
   1885                 buf.append(" ");
   1886                 buf.append(hostingNameStr);
   1887             }
   1888             buf.append(": pid=");
   1889             buf.append(startResult.pid);
   1890             buf.append(" uid=");
   1891             buf.append(uid);
   1892             buf.append(" gids={");
   1893             if (gids != null) {
   1894                 for (int gi=0; gi<gids.length; gi++) {
   1895                     if (gi != 0) buf.append(", ");
   1896                     buf.append(gids[gi]);
   1897 
   1898                 }
   1899             }
   1900             buf.append("}");
   1901             Slog.i(TAG, buf.toString());
   1902             app.pid = startResult.pid;
   1903             app.usingWrapper = startResult.usingWrapper;
   1904             app.removed = false;
   1905             synchronized (mPidsSelfLocked) {
   1906                 this.mPidsSelfLocked.put(startResult.pid, app);
   1907                 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   1908                 msg.obj = app;
   1909                 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
   1910                         ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
   1911             }
   1912         } catch (RuntimeException e) {
   1913             // XXX do better error recovery.
   1914             app.pid = 0;
   1915             Slog.e(TAG, "Failure starting process " + app.processName, e);
   1916         }
   1917     }
   1918 
   1919     void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
   1920         if (resumed) {
   1921             mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
   1922         } else {
   1923             mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
   1924         }
   1925     }
   1926 
   1927     boolean startHomeActivityLocked() {
   1928         if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
   1929                 && mTopAction == null) {
   1930             // We are running in factory test mode, but unable to find
   1931             // the factory test app, so just sit around displaying the
   1932             // error message and don't try to start anything.
   1933             return false;
   1934         }
   1935         Intent intent = new Intent(
   1936             mTopAction,
   1937             mTopData != null ? Uri.parse(mTopData) : null);
   1938         intent.setComponent(mTopComponent);
   1939         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   1940             intent.addCategory(Intent.CATEGORY_HOME);
   1941         }
   1942         ActivityInfo aInfo =
   1943             intent.resolveActivityInfo(mContext.getPackageManager(),
   1944                     STOCK_PM_FLAGS);
   1945         if (aInfo != null) {
   1946             intent.setComponent(new ComponentName(
   1947                     aInfo.applicationInfo.packageName, aInfo.name));
   1948             // Don't do this if the home app is currently being
   1949             // instrumented.
   1950             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
   1951                     aInfo.applicationInfo.uid);
   1952             if (app == null || app.instrumentationClass == null) {
   1953                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
   1954                 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
   1955                         null, null, 0, 0, 0, false, false, null);
   1956             }
   1957         }
   1958 
   1959 
   1960         return true;
   1961     }
   1962 
   1963     /**
   1964      * Starts the "new version setup screen" if appropriate.
   1965      */
   1966     void startSetupActivityLocked() {
   1967         // Only do this once per boot.
   1968         if (mCheckedForSetup) {
   1969             return;
   1970         }
   1971 
   1972         // We will show this screen if the current one is a different
   1973         // version than the last one shown, and we are not running in
   1974         // low-level factory test mode.
   1975         final ContentResolver resolver = mContext.getContentResolver();
   1976         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
   1977                 Settings.Secure.getInt(resolver,
   1978                         Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
   1979             mCheckedForSetup = true;
   1980 
   1981             // See if we should be showing the platform update setup UI.
   1982             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
   1983             List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
   1984                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
   1985 
   1986             // We don't allow third party apps to replace this.
   1987             ResolveInfo ri = null;
   1988             for (int i=0; ris != null && i<ris.size(); i++) {
   1989                 if ((ris.get(i).activityInfo.applicationInfo.flags
   1990                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
   1991                     ri = ris.get(i);
   1992                     break;
   1993                 }
   1994             }
   1995 
   1996             if (ri != null) {
   1997                 String vers = ri.activityInfo.metaData != null
   1998                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
   1999                         : null;
   2000                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
   2001                     vers = ri.activityInfo.applicationInfo.metaData.getString(
   2002                             Intent.METADATA_SETUP_VERSION);
   2003                 }
   2004                 String lastVers = Settings.Secure.getString(
   2005                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
   2006                 if (vers != null && !vers.equals(lastVers)) {
   2007                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   2008                     intent.setComponent(new ComponentName(
   2009                             ri.activityInfo.packageName, ri.activityInfo.name));
   2010                     mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
   2011                             null, null, 0, 0, 0, false, false, null);
   2012                 }
   2013             }
   2014         }
   2015     }
   2016 
   2017     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
   2018         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
   2019     }
   2020 
   2021     public int getFrontActivityScreenCompatMode() {
   2022         synchronized (this) {
   2023             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
   2024         }
   2025     }
   2026 
   2027     public void setFrontActivityScreenCompatMode(int mode) {
   2028         synchronized (this) {
   2029             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
   2030         }
   2031     }
   2032 
   2033     public int getPackageScreenCompatMode(String packageName) {
   2034         synchronized (this) {
   2035             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
   2036         }
   2037     }
   2038 
   2039     public void setPackageScreenCompatMode(String packageName, int mode) {
   2040         synchronized (this) {
   2041             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
   2042         }
   2043     }
   2044 
   2045     public boolean getPackageAskScreenCompat(String packageName) {
   2046         synchronized (this) {
   2047             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
   2048         }
   2049     }
   2050 
   2051     public void setPackageAskScreenCompat(String packageName, boolean ask) {
   2052         synchronized (this) {
   2053             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
   2054         }
   2055     }
   2056 
   2057     void reportResumedActivityLocked(ActivityRecord r) {
   2058         //Slog.i(TAG, "**** REPORT RESUME: " + r);
   2059 
   2060         final int identHash = System.identityHashCode(r);
   2061         updateUsageStats(r, true);
   2062 
   2063         int i = mWatchers.beginBroadcast();
   2064         while (i > 0) {
   2065             i--;
   2066             IActivityWatcher w = mWatchers.getBroadcastItem(i);
   2067             if (w != null) {
   2068                 try {
   2069                     w.activityResuming(identHash);
   2070                 } catch (RemoteException e) {
   2071                 }
   2072             }
   2073         }
   2074         mWatchers.finishBroadcast();
   2075     }
   2076 
   2077     private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
   2078         int i = mProcessObservers.beginBroadcast();
   2079         while (i > 0) {
   2080             i--;
   2081             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   2082             if (observer != null) {
   2083                 try {
   2084                     observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
   2085                 } catch (RemoteException e) {
   2086                 }
   2087             }
   2088         }
   2089         mProcessObservers.finishBroadcast();
   2090     }
   2091 
   2092     private void dispatchProcessDied(int pid, int uid) {
   2093         int i = mProcessObservers.beginBroadcast();
   2094         while (i > 0) {
   2095             i--;
   2096             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   2097             if (observer != null) {
   2098                 try {
   2099                     observer.onProcessDied(pid, uid);
   2100                 } catch (RemoteException e) {
   2101                 }
   2102             }
   2103         }
   2104         mProcessObservers.finishBroadcast();
   2105     }
   2106 
   2107     final void doPendingActivityLaunchesLocked(boolean doResume) {
   2108         final int N = mPendingActivityLaunches.size();
   2109         if (N <= 0) {
   2110             return;
   2111         }
   2112         for (int i=0; i<N; i++) {
   2113             PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
   2114             mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
   2115                     pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
   2116                     doResume && i == (N-1));
   2117         }
   2118         mPendingActivityLaunches.clear();
   2119     }
   2120 
   2121     public final int startActivity(IApplicationThread caller,
   2122             Intent intent, String resolvedType, Uri[] grantedUriPermissions,
   2123             int grantedMode, IBinder resultTo,
   2124             String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
   2125             String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
   2126         return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
   2127                 grantedUriPermissions, grantedMode, resultTo, resultWho,
   2128                 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
   2129                 null, null);
   2130     }
   2131 
   2132     public final WaitResult startActivityAndWait(IApplicationThread caller,
   2133             Intent intent, String resolvedType, Uri[] grantedUriPermissions,
   2134             int grantedMode, IBinder resultTo,
   2135             String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
   2136             String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
   2137         WaitResult res = new WaitResult();
   2138         mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
   2139                 grantedUriPermissions, grantedMode, resultTo, resultWho,
   2140                 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
   2141                 res, null);
   2142         return res;
   2143     }
   2144 
   2145     public final int startActivityWithConfig(IApplicationThread caller,
   2146             Intent intent, String resolvedType, Uri[] grantedUriPermissions,
   2147             int grantedMode, IBinder resultTo,
   2148             String resultWho, int requestCode, boolean onlyIfNeeded,
   2149             boolean debug, Configuration config) {
   2150         return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
   2151                 grantedUriPermissions, grantedMode, resultTo, resultWho,
   2152                 requestCode, onlyIfNeeded, debug, null, null, false, null, config);
   2153     }
   2154 
   2155     public int startActivityIntentSender(IApplicationThread caller,
   2156             IntentSender intent, Intent fillInIntent, String resolvedType,
   2157             IBinder resultTo, String resultWho, int requestCode,
   2158             int flagsMask, int flagsValues) {
   2159         // Refuse possible leaked file descriptors
   2160         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
   2161             throw new IllegalArgumentException("File descriptors passed in Intent");
   2162         }
   2163 
   2164         IIntentSender sender = intent.getTarget();
   2165         if (!(sender instanceof PendingIntentRecord)) {
   2166             throw new IllegalArgumentException("Bad PendingIntent object");
   2167         }
   2168 
   2169         PendingIntentRecord pir = (PendingIntentRecord)sender;
   2170 
   2171         synchronized (this) {
   2172             // If this is coming from the currently resumed activity, it is
   2173             // effectively saying that app switches are allowed at this point.
   2174             if (mMainStack.mResumedActivity != null
   2175                     && mMainStack.mResumedActivity.info.applicationInfo.uid ==
   2176                             Binder.getCallingUid()) {
   2177                 mAppSwitchesAllowedTime = 0;
   2178             }
   2179         }
   2180 
   2181         return pir.sendInner(0, fillInIntent, resolvedType, null,
   2182                 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
   2183     }
   2184 
   2185     public boolean startNextMatchingActivity(IBinder callingActivity,
   2186             Intent intent) {
   2187         // Refuse possible leaked file descriptors
   2188         if (intent != null && intent.hasFileDescriptors() == true) {
   2189             throw new IllegalArgumentException("File descriptors passed in Intent");
   2190         }
   2191 
   2192         synchronized (this) {
   2193             ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
   2194             if (r == null) {
   2195                 return false;
   2196             }
   2197             if (r.app == null || r.app.thread == null) {
   2198                 // The caller is not running...  d'oh!
   2199                 return false;
   2200             }
   2201             intent = new Intent(intent);
   2202             // The caller is not allowed to change the data.
   2203             intent.setDataAndType(r.intent.getData(), r.intent.getType());
   2204             // And we are resetting to find the next component...
   2205             intent.setComponent(null);
   2206 
   2207             ActivityInfo aInfo = null;
   2208             try {
   2209                 List<ResolveInfo> resolves =
   2210                     AppGlobals.getPackageManager().queryIntentActivities(
   2211                             intent, r.resolvedType,
   2212                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
   2213 
   2214                 // Look for the original activity in the list...
   2215                 final int N = resolves != null ? resolves.size() : 0;
   2216                 for (int i=0; i<N; i++) {
   2217                     ResolveInfo rInfo = resolves.get(i);
   2218                     if (rInfo.activityInfo.packageName.equals(r.packageName)
   2219                             && rInfo.activityInfo.name.equals(r.info.name)) {
   2220                         // We found the current one...  the next matching is
   2221                         // after it.
   2222                         i++;
   2223                         if (i<N) {
   2224                             aInfo = resolves.get(i).activityInfo;
   2225                         }
   2226                         break;
   2227                     }
   2228                 }
   2229             } catch (RemoteException e) {
   2230             }
   2231 
   2232             if (aInfo == null) {
   2233                 // Nobody who is next!
   2234                 return false;
   2235             }
   2236 
   2237             intent.setComponent(new ComponentName(
   2238                     aInfo.applicationInfo.packageName, aInfo.name));
   2239             intent.setFlags(intent.getFlags()&~(
   2240                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
   2241                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
   2242                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
   2243                     Intent.FLAG_ACTIVITY_NEW_TASK));
   2244 
   2245             // Okay now we need to start the new activity, replacing the
   2246             // currently running activity.  This is a little tricky because
   2247             // we want to start the new one as if the current one is finished,
   2248             // but not finish the current one first so that there is no flicker.
   2249             // And thus...
   2250             final boolean wasFinishing = r.finishing;
   2251             r.finishing = true;
   2252 
   2253             // Propagate reply information over to the new activity.
   2254             final ActivityRecord resultTo = r.resultTo;
   2255             final String resultWho = r.resultWho;
   2256             final int requestCode = r.requestCode;
   2257             r.resultTo = null;
   2258             if (resultTo != null) {
   2259                 resultTo.removeResultsLocked(r, resultWho, requestCode);
   2260             }
   2261 
   2262             final long origId = Binder.clearCallingIdentity();
   2263             // XXX we are not dealing with propagating grantedUriPermissions...
   2264             // those are not yet exposed to user code, so there is no need.
   2265             int res = mMainStack.startActivityLocked(r.app.thread, intent,
   2266                     r.resolvedType, null, 0, aInfo, resultTo, resultWho,
   2267                     requestCode, -1, r.launchedFromUid, false, false, null);
   2268             Binder.restoreCallingIdentity(origId);
   2269 
   2270             r.finishing = wasFinishing;
   2271             if (res != START_SUCCESS) {
   2272                 return false;
   2273             }
   2274             return true;
   2275         }
   2276     }
   2277 
   2278     public final int startActivityInPackage(int uid,
   2279             Intent intent, String resolvedType, IBinder resultTo,
   2280             String resultWho, int requestCode, boolean onlyIfNeeded) {
   2281 
   2282         // This is so super not safe, that only the system (or okay root)
   2283         // can do it.
   2284         final int callingUid = Binder.getCallingUid();
   2285         if (callingUid != 0 && callingUid != Process.myUid()) {
   2286             throw new SecurityException(
   2287                     "startActivityInPackage only available to the system");
   2288         }
   2289 
   2290         return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
   2291                 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
   2292                 null, null, false, null, null);
   2293     }
   2294 
   2295     public final int startActivities(IApplicationThread caller,
   2296             Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
   2297         return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
   2298     }
   2299 
   2300     public final int startActivitiesInPackage(int uid,
   2301             Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
   2302 
   2303         // This is so super not safe, that only the system (or okay root)
   2304         // can do it.
   2305         final int callingUid = Binder.getCallingUid();
   2306         if (callingUid != 0 && callingUid != Process.myUid()) {
   2307             throw new SecurityException(
   2308                     "startActivityInPackage only available to the system");
   2309         }
   2310 
   2311         return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
   2312     }
   2313 
   2314     final void addRecentTaskLocked(TaskRecord task) {
   2315         int N = mRecentTasks.size();
   2316         // Quick case: check if the top-most recent task is the same.
   2317         if (N > 0 && mRecentTasks.get(0) == task) {
   2318             return;
   2319         }
   2320         // Remove any existing entries that are the same kind of task.
   2321         for (int i=0; i<N; i++) {
   2322             TaskRecord tr = mRecentTasks.get(i);
   2323             if ((task.affinity != null && task.affinity.equals(tr.affinity))
   2324                     || (task.intent != null && task.intent.filterEquals(tr.intent))) {
   2325                 mRecentTasks.remove(i);
   2326                 i--;
   2327                 N--;
   2328                 if (task.intent == null) {
   2329                     // If the new recent task we are adding is not fully
   2330                     // specified, then replace it with the existing recent task.
   2331                     task = tr;
   2332                 }
   2333             }
   2334         }
   2335         if (N >= MAX_RECENT_TASKS) {
   2336             mRecentTasks.remove(N-1);
   2337         }
   2338         mRecentTasks.add(0, task);
   2339     }
   2340 
   2341     public void setRequestedOrientation(IBinder token,
   2342             int requestedOrientation) {
   2343         synchronized (this) {
   2344             ActivityRecord r = mMainStack.isInStackLocked(token);
   2345             if (r == null) {
   2346                 return;
   2347             }
   2348             final long origId = Binder.clearCallingIdentity();
   2349             mWindowManager.setAppOrientation(r, requestedOrientation);
   2350             Configuration config = mWindowManager.updateOrientationFromAppTokens(
   2351                     mConfiguration,
   2352                     r.mayFreezeScreenLocked(r.app) ? r : null);
   2353             if (config != null) {
   2354                 r.frozenBeforeDestroy = true;
   2355                 if (!updateConfigurationLocked(config, r, false)) {
   2356                     mMainStack.resumeTopActivityLocked(null);
   2357                 }
   2358             }
   2359             Binder.restoreCallingIdentity(origId);
   2360         }
   2361     }
   2362 
   2363     public int getRequestedOrientation(IBinder token) {
   2364         synchronized (this) {
   2365             ActivityRecord r = mMainStack.isInStackLocked(token);
   2366             if (r == null) {
   2367                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
   2368             }
   2369             return mWindowManager.getAppOrientation(r);
   2370         }
   2371     }
   2372 
   2373     /**
   2374      * This is the internal entry point for handling Activity.finish().
   2375      *
   2376      * @param token The Binder token referencing the Activity we want to finish.
   2377      * @param resultCode Result code, if any, from this Activity.
   2378      * @param resultData Result data (Intent), if any, from this Activity.
   2379      *
   2380      * @return Returns true if the activity successfully finished, or false if it is still running.
   2381      */
   2382     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
   2383         // Refuse possible leaked file descriptors
   2384         if (resultData != null && resultData.hasFileDescriptors() == true) {
   2385             throw new IllegalArgumentException("File descriptors passed in Intent");
   2386         }
   2387 
   2388         synchronized(this) {
   2389             if (mController != null) {
   2390                 // Find the first activity that is not finishing.
   2391                 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
   2392                 if (next != null) {
   2393                     // ask watcher if this is allowed
   2394                     boolean resumeOK = true;
   2395                     try {
   2396                         resumeOK = mController.activityResuming(next.packageName);
   2397                     } catch (RemoteException e) {
   2398                         mController = null;
   2399                     }
   2400 
   2401                     if (!resumeOK) {
   2402                         return false;
   2403                     }
   2404                 }
   2405             }
   2406             final long origId = Binder.clearCallingIdentity();
   2407             boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
   2408                     resultData, "app-request");
   2409             Binder.restoreCallingIdentity(origId);
   2410             return res;
   2411         }
   2412     }
   2413 
   2414     public final void finishHeavyWeightApp() {
   2415         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   2416                 != PackageManager.PERMISSION_GRANTED) {
   2417             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
   2418                     + Binder.getCallingPid()
   2419                     + ", uid=" + Binder.getCallingUid()
   2420                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   2421             Slog.w(TAG, msg);
   2422             throw new SecurityException(msg);
   2423         }
   2424 
   2425         synchronized(this) {
   2426             if (mHeavyWeightProcess == null) {
   2427                 return;
   2428             }
   2429 
   2430             ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
   2431                     mHeavyWeightProcess.activities);
   2432             for (int i=0; i<activities.size(); i++) {
   2433                 ActivityRecord r = activities.get(i);
   2434                 if (!r.finishing) {
   2435                     int index = mMainStack.indexOfTokenLocked(r);
   2436                     if (index >= 0) {
   2437                         mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
   2438                                 null, "finish-heavy");
   2439                     }
   2440                 }
   2441             }
   2442 
   2443             mHeavyWeightProcess = null;
   2444             mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
   2445         }
   2446     }
   2447 
   2448     public void crashApplication(int uid, int initialPid, String packageName,
   2449             String message) {
   2450         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   2451                 != PackageManager.PERMISSION_GRANTED) {
   2452             String msg = "Permission Denial: crashApplication() from pid="
   2453                     + Binder.getCallingPid()
   2454                     + ", uid=" + Binder.getCallingUid()
   2455                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   2456             Slog.w(TAG, msg);
   2457             throw new SecurityException(msg);
   2458         }
   2459 
   2460         synchronized(this) {
   2461             ProcessRecord proc = null;
   2462 
   2463             // Figure out which process to kill.  We don't trust that initialPid
   2464             // still has any relation to current pids, so must scan through the
   2465             // list.
   2466             synchronized (mPidsSelfLocked) {
   2467                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   2468                     ProcessRecord p = mPidsSelfLocked.valueAt(i);
   2469                     if (p.info.uid != uid) {
   2470                         continue;
   2471                     }
   2472                     if (p.pid == initialPid) {
   2473                         proc = p;
   2474                         break;
   2475                     }
   2476                     for (String str : p.pkgList) {
   2477                         if (str.equals(packageName)) {
   2478                             proc = p;
   2479                         }
   2480                     }
   2481                 }
   2482             }
   2483 
   2484             if (proc == null) {
   2485                 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
   2486                         + " initialPid=" + initialPid
   2487                         + " packageName=" + packageName);
   2488                 return;
   2489             }
   2490 
   2491             if (proc.thread != null) {
   2492                 if (proc.pid == Process.myPid()) {
   2493                     Log.w(TAG, "crashApplication: trying to crash self!");
   2494                     return;
   2495                 }
   2496                 long ident = Binder.clearCallingIdentity();
   2497                 try {
   2498                     proc.thread.scheduleCrash(message);
   2499                 } catch (RemoteException e) {
   2500                 }
   2501                 Binder.restoreCallingIdentity(ident);
   2502             }
   2503         }
   2504     }
   2505 
   2506     public final void finishSubActivity(IBinder token, String resultWho,
   2507             int requestCode) {
   2508         synchronized(this) {
   2509             ActivityRecord self = mMainStack.isInStackLocked(token);
   2510             if (self == null) {
   2511                 return;
   2512             }
   2513 
   2514             final long origId = Binder.clearCallingIdentity();
   2515 
   2516             int i;
   2517             for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
   2518                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   2519                 if (r.resultTo == self && r.requestCode == requestCode) {
   2520                     if ((r.resultWho == null && resultWho == null) ||
   2521                         (r.resultWho != null && r.resultWho.equals(resultWho))) {
   2522                         mMainStack.finishActivityLocked(r, i,
   2523                                 Activity.RESULT_CANCELED, null, "request-sub");
   2524                     }
   2525                 }
   2526             }
   2527 
   2528             Binder.restoreCallingIdentity(origId);
   2529         }
   2530     }
   2531 
   2532     public boolean willActivityBeVisible(IBinder token) {
   2533         synchronized(this) {
   2534             int i;
   2535             for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
   2536                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   2537                 if (r == token) {
   2538                     return true;
   2539                 }
   2540                 if (r.fullscreen && !r.finishing) {
   2541                     return false;
   2542                 }
   2543             }
   2544             return true;
   2545         }
   2546     }
   2547 
   2548     public void overridePendingTransition(IBinder token, String packageName,
   2549             int enterAnim, int exitAnim) {
   2550         synchronized(this) {
   2551             ActivityRecord self = mMainStack.isInStackLocked(token);
   2552             if (self == null) {
   2553                 return;
   2554             }
   2555 
   2556             final long origId = Binder.clearCallingIdentity();
   2557 
   2558             if (self.state == ActivityState.RESUMED
   2559                     || self.state == ActivityState.PAUSING) {
   2560                 mWindowManager.overridePendingAppTransition(packageName,
   2561                         enterAnim, exitAnim);
   2562             }
   2563 
   2564             Binder.restoreCallingIdentity(origId);
   2565         }
   2566     }
   2567 
   2568     /**
   2569      * Main function for removing an existing process from the activity manager
   2570      * as a result of that process going away.  Clears out all connections
   2571      * to the process.
   2572      */
   2573     private final void handleAppDiedLocked(ProcessRecord app,
   2574             boolean restarting, boolean allowRestart) {
   2575         cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
   2576         if (!restarting) {
   2577             mLruProcesses.remove(app);
   2578         }
   2579 
   2580         if (mProfileProc == app) {
   2581             clearProfilerLocked();
   2582         }
   2583 
   2584         // Just in case...
   2585         if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
   2586             if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
   2587             mMainStack.mPausingActivity = null;
   2588         }
   2589         if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
   2590             mMainStack.mLastPausedActivity = null;
   2591         }
   2592 
   2593         // Remove this application's activities from active lists.
   2594         mMainStack.removeHistoryRecordsForAppLocked(app);
   2595 
   2596         boolean atTop = true;
   2597         boolean hasVisibleActivities = false;
   2598 
   2599         // Clean out the history list.
   2600         int i = mMainStack.mHistory.size();
   2601         if (localLOGV) Slog.v(
   2602             TAG, "Removing app " + app + " from history with " + i + " entries");
   2603         while (i > 0) {
   2604             i--;
   2605             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   2606             if (localLOGV) Slog.v(
   2607                 TAG, "Record #" + i + " " + r + ": app=" + r.app);
   2608             if (r.app == app) {
   2609                 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
   2610                     if (ActivityStack.DEBUG_ADD_REMOVE) {
   2611                         RuntimeException here = new RuntimeException("here");
   2612                         here.fillInStackTrace();
   2613                         Slog.i(TAG, "Removing activity " + r + " from stack at " + i
   2614                                 + ": haveState=" + r.haveState
   2615                                 + " stateNotNeeded=" + r.stateNotNeeded
   2616                                 + " finishing=" + r.finishing
   2617                                 + " state=" + r.state, here);
   2618                     }
   2619                     if (!r.finishing) {
   2620                         Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
   2621                     }
   2622                     r.makeFinishing();
   2623                     mMainStack.mHistory.remove(i);
   2624                     r.takeFromHistory();
   2625                     mWindowManager.removeAppToken(r);
   2626                     if (VALIDATE_TOKENS) {
   2627                         mWindowManager.validateAppTokens(mMainStack.mHistory);
   2628                     }
   2629                     r.removeUriPermissionsLocked();
   2630 
   2631                 } else {
   2632                     // We have the current state for this activity, so
   2633                     // it can be restarted later when needed.
   2634                     if (localLOGV) Slog.v(
   2635                         TAG, "Keeping entry, setting app to null");
   2636                     if (r.visible) {
   2637                         hasVisibleActivities = true;
   2638                     }
   2639                     r.app = null;
   2640                     r.nowVisible = false;
   2641                     if (!r.haveState) {
   2642                         if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
   2643                                 "App died, clearing saved state of " + r);
   2644                         r.icicle = null;
   2645                     }
   2646                 }
   2647 
   2648                 r.stack.cleanUpActivityLocked(r, true, true);
   2649             }
   2650             atTop = false;
   2651         }
   2652 
   2653         app.activities.clear();
   2654 
   2655         if (app.instrumentationClass != null) {
   2656             Slog.w(TAG, "Crash of app " + app.processName
   2657                   + " running instrumentation " + app.instrumentationClass);
   2658             Bundle info = new Bundle();
   2659             info.putString("shortMsg", "Process crashed.");
   2660             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
   2661         }
   2662 
   2663         if (!restarting) {
   2664             if (!mMainStack.resumeTopActivityLocked(null)) {
   2665                 // If there was nothing to resume, and we are not already
   2666                 // restarting this process, but there is a visible activity that
   2667                 // is hosted by the process...  then make sure all visible
   2668                 // activities are running, taking care of restarting this
   2669                 // process.
   2670                 if (hasVisibleActivities) {
   2671                     mMainStack.ensureActivitiesVisibleLocked(null, 0);
   2672                 }
   2673             }
   2674         }
   2675     }
   2676 
   2677     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
   2678         IBinder threadBinder = thread.asBinder();
   2679 
   2680         // Find the application record.
   2681         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   2682             ProcessRecord rec = mLruProcesses.get(i);
   2683             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
   2684                 return i;
   2685             }
   2686         }
   2687         return -1;
   2688     }
   2689 
   2690     final ProcessRecord getRecordForAppLocked(
   2691             IApplicationThread thread) {
   2692         if (thread == null) {
   2693             return null;
   2694         }
   2695 
   2696         int appIndex = getLRURecordIndexForAppLocked(thread);
   2697         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
   2698     }
   2699 
   2700     final void appDiedLocked(ProcessRecord app, int pid,
   2701             IApplicationThread thread) {
   2702 
   2703         mProcDeaths[0]++;
   2704 
   2705         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   2706         synchronized (stats) {
   2707             stats.noteProcessDiedLocked(app.info.uid, pid);
   2708         }
   2709 
   2710         // Clean up already done if the process has been re-started.
   2711         if (app.pid == pid && app.thread != null &&
   2712                 app.thread.asBinder() == thread.asBinder()) {
   2713             if (!app.killedBackground) {
   2714                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   2715                         + ") has died.");
   2716             }
   2717             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
   2718             if (localLOGV) Slog.v(
   2719                 TAG, "Dying app: " + app + ", pid: " + pid
   2720                 + ", thread: " + thread.asBinder());
   2721             boolean doLowMem = app.instrumentationClass == null;
   2722             handleAppDiedLocked(app, false, true);
   2723 
   2724             if (doLowMem) {
   2725                 // If there are no longer any background processes running,
   2726                 // and the app that died was not running instrumentation,
   2727                 // then tell everyone we are now low on memory.
   2728                 boolean haveBg = false;
   2729                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   2730                     ProcessRecord rec = mLruProcesses.get(i);
   2731                     if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   2732                         haveBg = true;
   2733                         break;
   2734                     }
   2735                 }
   2736 
   2737                 if (!haveBg) {
   2738                     EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
   2739                     long now = SystemClock.uptimeMillis();
   2740                     for (int i=mLruProcesses.size()-1; i>=0; i--) {
   2741                         ProcessRecord rec = mLruProcesses.get(i);
   2742                         if (rec != app && rec.thread != null &&
   2743                                 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
   2744                             // The low memory report is overriding any current
   2745                             // state for a GC request.  Make sure to do
   2746                             // heavy/important/visible/foreground processes first.
   2747                             if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   2748                                 rec.lastRequestedGc = 0;
   2749                             } else {
   2750                                 rec.lastRequestedGc = rec.lastLowMemory;
   2751                             }
   2752                             rec.reportLowMemory = true;
   2753                             rec.lastLowMemory = now;
   2754                             mProcessesToGc.remove(rec);
   2755                             addProcessToGcListLocked(rec);
   2756                         }
   2757                     }
   2758                     scheduleAppGcsLocked();
   2759                 }
   2760             }
   2761         } else if (app.pid != pid) {
   2762             // A new process has already been started.
   2763             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   2764                     + ") has died and restarted (pid " + app.pid + ").");
   2765             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
   2766         } else if (DEBUG_PROCESSES) {
   2767             Slog.d(TAG, "Received spurious death notification for thread "
   2768                     + thread.asBinder());
   2769         }
   2770     }
   2771 
   2772     /**
   2773      * If a stack trace dump file is configured, dump process stack traces.
   2774      * @param clearTraces causes the dump file to be erased prior to the new
   2775      *    traces being written, if true; when false, the new traces will be
   2776      *    appended to any existing file content.
   2777      * @param firstPids of dalvik VM processes to dump stack traces for first
   2778      * @param lastPids of dalvik VM processes to dump stack traces for last
   2779      * @return file containing stack traces, or null if no dump file is configured
   2780      */
   2781     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
   2782             ProcessStats processStats, SparseArray<Boolean> lastPids) {
   2783         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   2784         if (tracesPath == null || tracesPath.length() == 0) {
   2785             return null;
   2786         }
   2787 
   2788         File tracesFile = new File(tracesPath);
   2789         try {
   2790             File tracesDir = tracesFile.getParentFile();
   2791             if (!tracesDir.exists()) tracesFile.mkdirs();
   2792             FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
   2793 
   2794             if (clearTraces && tracesFile.exists()) tracesFile.delete();
   2795             tracesFile.createNewFile();
   2796             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   2797         } catch (IOException e) {
   2798             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
   2799             return null;
   2800         }
   2801 
   2802         // Use a FileObserver to detect when traces finish writing.
   2803         // The order of traces is considered important to maintain for legibility.
   2804         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
   2805             public synchronized void onEvent(int event, String path) { notify(); }
   2806         };
   2807 
   2808         try {
   2809             observer.startWatching();
   2810 
   2811             // First collect all of the stacks of the most important pids.
   2812             try {
   2813                 int num = firstPids.size();
   2814                 for (int i = 0; i < num; i++) {
   2815                     synchronized (observer) {
   2816                         Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
   2817                         observer.wait(200);  // Wait for write-close, give up after 200msec
   2818                     }
   2819                 }
   2820             } catch (InterruptedException e) {
   2821                 Log.wtf(TAG, e);
   2822             }
   2823 
   2824             // Next measure CPU usage.
   2825             if (processStats != null) {
   2826                 processStats.init();
   2827                 System.gc();
   2828                 processStats.update();
   2829                 try {
   2830                     synchronized (processStats) {
   2831                         processStats.wait(500); // measure over 1/2 second.
   2832                     }
   2833                 } catch (InterruptedException e) {
   2834                 }
   2835                 processStats.update();
   2836 
   2837                 // We'll take the stack crawls of just the top apps using CPU.
   2838                 final int N = processStats.countWorkingStats();
   2839                 int numProcs = 0;
   2840                 for (int i=0; i<N && numProcs<5; i++) {
   2841                     ProcessStats.Stats stats = processStats.getWorkingStats(i);
   2842                     if (lastPids.indexOfKey(stats.pid) >= 0) {
   2843                         numProcs++;
   2844                         try {
   2845                             synchronized (observer) {
   2846                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
   2847                                 observer.wait(200);  // Wait for write-close, give up after 200msec
   2848                             }
   2849                         } catch (InterruptedException e) {
   2850                             Log.wtf(TAG, e);
   2851                         }
   2852 
   2853                     }
   2854                 }
   2855             }
   2856 
   2857             return tracesFile;
   2858 
   2859         } finally {
   2860             observer.stopWatching();
   2861         }
   2862     }
   2863 
   2864     private final class AppNotResponding implements Runnable {
   2865         private final ProcessRecord mApp;
   2866         private final String mAnnotation;
   2867 
   2868         public AppNotResponding(ProcessRecord app, String annotation) {
   2869             mApp = app;
   2870             mAnnotation = annotation;
   2871         }
   2872 
   2873         @Override
   2874         public void run() {
   2875             appNotResponding(mApp, null, null, mAnnotation);
   2876         }
   2877     }
   2878 
   2879     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
   2880             ActivityRecord parent, final String annotation) {
   2881         ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
   2882         SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
   2883 
   2884         if (mController != null) {
   2885             try {
   2886                 // 0 == continue, -1 = kill process immediately
   2887                 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
   2888                 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
   2889             } catch (RemoteException e) {
   2890                 mController = null;
   2891             }
   2892         }
   2893 
   2894         long anrTime = SystemClock.uptimeMillis();
   2895         if (MONITOR_CPU_USAGE) {
   2896             updateCpuStatsNow();
   2897         }
   2898 
   2899         synchronized (this) {
   2900             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
   2901             if (mShuttingDown) {
   2902                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
   2903                 return;
   2904             } else if (app.notResponding) {
   2905                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
   2906                 return;
   2907             } else if (app.crashing) {
   2908                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
   2909                 return;
   2910             }
   2911 
   2912             // In case we come through here for the same app before completing
   2913             // this one, mark as anring now so we will bail out.
   2914             app.notResponding = true;
   2915 
   2916             // Log the ANR to the event log.
   2917             EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
   2918                     annotation);
   2919 
   2920             // Dump thread traces as quickly as we can, starting with "interesting" processes.
   2921             firstPids.add(app.pid);
   2922 
   2923             int parentPid = app.pid;
   2924             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
   2925             if (parentPid != app.pid) firstPids.add(parentPid);
   2926 
   2927             if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
   2928 
   2929             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   2930                 ProcessRecord r = mLruProcesses.get(i);
   2931                 if (r != null && r.thread != null) {
   2932                     int pid = r.pid;
   2933                     if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
   2934                         if (r.persistent) {
   2935                             firstPids.add(pid);
   2936                         } else {
   2937                             lastPids.put(pid, Boolean.TRUE);
   2938                         }
   2939                     }
   2940                 }
   2941             }
   2942         }
   2943 
   2944         // Log the ANR to the main log.
   2945         StringBuilder info = mStringBuilder;
   2946         info.setLength(0);
   2947         info.append("ANR in ").append(app.processName);
   2948         if (activity != null && activity.shortComponentName != null) {
   2949             info.append(" (").append(activity.shortComponentName).append(")");
   2950         }
   2951         info.append("\n");
   2952         if (annotation != null) {
   2953             info.append("Reason: ").append(annotation).append("\n");
   2954         }
   2955         if (parent != null && parent != activity) {
   2956             info.append("Parent: ").append(parent.shortComponentName).append("\n");
   2957         }
   2958 
   2959         final ProcessStats processStats = new ProcessStats(true);
   2960 
   2961         File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
   2962 
   2963         String cpuInfo = null;
   2964         if (MONITOR_CPU_USAGE) {
   2965             updateCpuStatsNow();
   2966             synchronized (mProcessStatsThread) {
   2967                 cpuInfo = mProcessStats.printCurrentState(anrTime);
   2968             }
   2969             info.append(processStats.printCurrentLoad());
   2970             info.append(cpuInfo);
   2971         }
   2972 
   2973         info.append(processStats.printCurrentState(anrTime));
   2974 
   2975         Slog.e(TAG, info.toString());
   2976         if (tracesFile == null) {
   2977             // There is no trace file, so dump (only) the alleged culprit's threads to the log
   2978             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
   2979         }
   2980 
   2981         addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
   2982 
   2983         if (mController != null) {
   2984             try {
   2985                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
   2986                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
   2987                 if (res != 0) {
   2988                     if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
   2989                     return;
   2990                 }
   2991             } catch (RemoteException e) {
   2992                 mController = null;
   2993             }
   2994         }
   2995 
   2996         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
   2997         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
   2998                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
   2999 
   3000         synchronized (this) {
   3001             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
   3002                 Slog.w(TAG, "Killing " + app + ": background ANR");
   3003                 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   3004                         app.processName, app.setAdj, "background ANR");
   3005                 Process.killProcessQuiet(app.pid);
   3006                 return;
   3007             }
   3008 
   3009             // Set the app's notResponding state, and look up the errorReportReceiver
   3010             makeAppNotRespondingLocked(app,
   3011                     activity != null ? activity.shortComponentName : null,
   3012                     annotation != null ? "ANR " + annotation : "ANR",
   3013                     info.toString());
   3014 
   3015             // Bring up the infamous App Not Responding dialog
   3016             Message msg = Message.obtain();
   3017             HashMap map = new HashMap();
   3018             msg.what = SHOW_NOT_RESPONDING_MSG;
   3019             msg.obj = map;
   3020             map.put("app", app);
   3021             if (activity != null) {
   3022                 map.put("activity", activity);
   3023             }
   3024 
   3025             mHandler.sendMessage(msg);
   3026         }
   3027     }
   3028 
   3029     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
   3030         if (!mLaunchWarningShown) {
   3031             mLaunchWarningShown = true;
   3032             mHandler.post(new Runnable() {
   3033                 @Override
   3034                 public void run() {
   3035                     synchronized (ActivityManagerService.this) {
   3036                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
   3037                         d.show();
   3038                         mHandler.postDelayed(new Runnable() {
   3039                             @Override
   3040                             public void run() {
   3041                                 synchronized (ActivityManagerService.this) {
   3042                                     d.dismiss();
   3043                                     mLaunchWarningShown = false;
   3044                                 }
   3045                             }
   3046                         }, 4000);
   3047                     }
   3048                 }
   3049             });
   3050         }
   3051     }
   3052 
   3053     public boolean clearApplicationUserData(final String packageName,
   3054             final IPackageDataObserver observer) {
   3055         int uid = Binder.getCallingUid();
   3056         int pid = Binder.getCallingPid();
   3057         long callingId = Binder.clearCallingIdentity();
   3058         try {
   3059             IPackageManager pm = AppGlobals.getPackageManager();
   3060             int pkgUid = -1;
   3061             synchronized(this) {
   3062                 try {
   3063                     pkgUid = pm.getPackageUid(packageName);
   3064                 } catch (RemoteException e) {
   3065                 }
   3066                 if (pkgUid == -1) {
   3067                     Slog.w(TAG, "Invalid packageName:" + packageName);
   3068                     return false;
   3069                 }
   3070                 if (uid == pkgUid || checkComponentPermission(
   3071                         android.Manifest.permission.CLEAR_APP_USER_DATA,
   3072                         pid, uid, -1, true)
   3073                         == PackageManager.PERMISSION_GRANTED) {
   3074                     forceStopPackageLocked(packageName, pkgUid);
   3075                 } else {
   3076                     throw new SecurityException(pid+" does not have permission:"+
   3077                             android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
   3078                                     "for process:"+packageName);
   3079                 }
   3080             }
   3081 
   3082             try {
   3083                 //clear application user data
   3084                 pm.clearApplicationUserData(packageName, observer);
   3085                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
   3086                         Uri.fromParts("package", packageName, null));
   3087                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
   3088                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
   3089                         null, null, 0, null, null, null, false, false);
   3090             } catch (RemoteException e) {
   3091             }
   3092         } finally {
   3093             Binder.restoreCallingIdentity(callingId);
   3094         }
   3095         return true;
   3096     }
   3097 
   3098     public void killBackgroundProcesses(final String packageName) {
   3099         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   3100                 != PackageManager.PERMISSION_GRANTED &&
   3101                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
   3102                         != PackageManager.PERMISSION_GRANTED) {
   3103             String msg = "Permission Denial: killBackgroundProcesses() from pid="
   3104                     + Binder.getCallingPid()
   3105                     + ", uid=" + Binder.getCallingUid()
   3106                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   3107             Slog.w(TAG, msg);
   3108             throw new SecurityException(msg);
   3109         }
   3110 
   3111         long callingId = Binder.clearCallingIdentity();
   3112         try {
   3113             IPackageManager pm = AppGlobals.getPackageManager();
   3114             int pkgUid = -1;
   3115             synchronized(this) {
   3116                 try {
   3117                     pkgUid = pm.getPackageUid(packageName);
   3118                 } catch (RemoteException e) {
   3119                 }
   3120                 if (pkgUid == -1) {
   3121                     Slog.w(TAG, "Invalid packageName: " + packageName);
   3122                     return;
   3123                 }
   3124                 killPackageProcessesLocked(packageName, pkgUid,
   3125                         ProcessList.SECONDARY_SERVER_ADJ, false, true, true, false);
   3126             }
   3127         } finally {
   3128             Binder.restoreCallingIdentity(callingId);
   3129         }
   3130     }
   3131 
   3132     public void forceStopPackage(final String packageName) {
   3133         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   3134                 != PackageManager.PERMISSION_GRANTED) {
   3135             String msg = "Permission Denial: forceStopPackage() from pid="
   3136                     + Binder.getCallingPid()
   3137                     + ", uid=" + Binder.getCallingUid()
   3138                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   3139             Slog.w(TAG, msg);
   3140             throw new SecurityException(msg);
   3141         }
   3142 
   3143         long callingId = Binder.clearCallingIdentity();
   3144         try {
   3145             IPackageManager pm = AppGlobals.getPackageManager();
   3146             int pkgUid = -1;
   3147             synchronized(this) {
   3148                 try {
   3149                     pkgUid = pm.getPackageUid(packageName);
   3150                 } catch (RemoteException e) {
   3151                 }
   3152                 if (pkgUid == -1) {
   3153                     Slog.w(TAG, "Invalid packageName: " + packageName);
   3154                     return;
   3155                 }
   3156                 forceStopPackageLocked(packageName, pkgUid);
   3157                 try {
   3158                     pm.setPackageStoppedState(packageName, true);
   3159                 } catch (RemoteException e) {
   3160                 } catch (IllegalArgumentException e) {
   3161                     Slog.w(TAG, "Failed trying to unstop package "
   3162                             + packageName + ": " + e);
   3163                 }
   3164             }
   3165         } finally {
   3166             Binder.restoreCallingIdentity(callingId);
   3167         }
   3168     }
   3169 
   3170     /*
   3171      * The pkg name and uid have to be specified.
   3172      * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
   3173      */
   3174     public void killApplicationWithUid(String pkg, int uid) {
   3175         if (pkg == null) {
   3176             return;
   3177         }
   3178         // Make sure the uid is valid.
   3179         if (uid < 0) {
   3180             Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
   3181             return;
   3182         }
   3183         int callerUid = Binder.getCallingUid();
   3184         // Only the system server can kill an application
   3185         if (callerUid == Process.SYSTEM_UID) {
   3186             // Post an aysnc message to kill the application
   3187             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
   3188             msg.arg1 = uid;
   3189             msg.arg2 = 0;
   3190             msg.obj = pkg;
   3191             mHandler.sendMessage(msg);
   3192         } else {
   3193             throw new SecurityException(callerUid + " cannot kill pkg: " +
   3194                     pkg);
   3195         }
   3196     }
   3197 
   3198     public void closeSystemDialogs(String reason) {
   3199         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
   3200         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   3201         if (reason != null) {
   3202             intent.putExtra("reason", reason);
   3203         }
   3204 
   3205         final int uid = Binder.getCallingUid();
   3206         final long origId = Binder.clearCallingIdentity();
   3207         synchronized (this) {
   3208             int i = mWatchers.beginBroadcast();
   3209             while (i > 0) {
   3210                 i--;
   3211                 IActivityWatcher w = mWatchers.getBroadcastItem(i);
   3212                 if (w != null) {
   3213                     try {
   3214                         w.closingSystemDialogs(reason);
   3215                     } catch (RemoteException e) {
   3216                     }
   3217                 }
   3218             }
   3219             mWatchers.finishBroadcast();
   3220 
   3221             mWindowManager.closeSystemDialogs(reason);
   3222 
   3223             for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
   3224                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   3225                 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
   3226                     r.stack.finishActivityLocked(r, i,
   3227                             Activity.RESULT_CANCELED, null, "close-sys");
   3228                 }
   3229             }
   3230 
   3231             broadcastIntentLocked(null, null, intent, null,
   3232                     null, 0, null, null, null, false, false, -1, uid);
   3233         }
   3234         Binder.restoreCallingIdentity(origId);
   3235     }
   3236 
   3237     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
   3238             throws RemoteException {
   3239         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
   3240         for (int i=pids.length-1; i>=0; i--) {
   3241             infos[i] = new Debug.MemoryInfo();
   3242             Debug.getMemoryInfo(pids[i], infos[i]);
   3243         }
   3244         return infos;
   3245     }
   3246 
   3247     public long[] getProcessPss(int[] pids) throws RemoteException {
   3248         long[] pss = new long[pids.length];
   3249         for (int i=pids.length-1; i>=0; i--) {
   3250             pss[i] = Debug.getPss(pids[i]);
   3251         }
   3252         return pss;
   3253     }
   3254 
   3255     public void killApplicationProcess(String processName, int uid) {
   3256         if (processName == null) {
   3257             return;
   3258         }
   3259 
   3260         int callerUid = Binder.getCallingUid();
   3261         // Only the system server can kill an application
   3262         if (callerUid == Process.SYSTEM_UID) {
   3263             synchronized (this) {
   3264                 ProcessRecord app = getProcessRecordLocked(processName, uid);
   3265                 if (app != null && app.thread != null) {
   3266                     try {
   3267                         app.thread.scheduleSuicide();
   3268                     } catch (RemoteException e) {
   3269                         // If the other end already died, then our work here is done.
   3270                     }
   3271                 } else {
   3272                     Slog.w(TAG, "Process/uid not found attempting kill of "
   3273                             + processName + " / " + uid);
   3274                 }
   3275             }
   3276         } else {
   3277             throw new SecurityException(callerUid + " cannot kill app process: " +
   3278                     processName);
   3279         }
   3280     }
   3281 
   3282     private void forceStopPackageLocked(final String packageName, int uid) {
   3283         forceStopPackageLocked(packageName, uid, false, false, true, false);
   3284         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
   3285                 Uri.fromParts("package", packageName, null));
   3286         if (!mProcessesReady) {
   3287             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   3288         }
   3289         intent.putExtra(Intent.EXTRA_UID, uid);
   3290         broadcastIntentLocked(null, null, intent,
   3291                 null, null, 0, null, null, null,
   3292                 false, false, MY_PID, Process.SYSTEM_UID);
   3293     }
   3294 
   3295     private final boolean killPackageProcessesLocked(String packageName, int uid,
   3296             int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
   3297             boolean evenPersistent) {
   3298         ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   3299 
   3300         // Remove all processes this package may have touched: all with the
   3301         // same UID (except for the system or root user), and all whose name
   3302         // matches the package name.
   3303         final String procNamePrefix = packageName + ":";
   3304         for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   3305             final int NA = apps.size();
   3306             for (int ia=0; ia<NA; ia++) {
   3307                 ProcessRecord app = apps.valueAt(ia);
   3308                 if (app.persistent && !evenPersistent) {
   3309                     // we don't kill persistent processes
   3310                     continue;
   3311                 }
   3312                 if (app.removed) {
   3313                     if (doit) {
   3314                         procs.add(app);
   3315                     }
   3316                 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
   3317                         || app.processName.equals(packageName)
   3318                         || app.processName.startsWith(procNamePrefix)) {
   3319                     if (app.setAdj >= minOomAdj) {
   3320                         if (!doit) {
   3321                             return true;
   3322                         }
   3323                         app.removed = true;
   3324                         procs.add(app);
   3325                     }
   3326                 }
   3327             }
   3328         }
   3329 
   3330         int N = procs.size();
   3331         for (int i=0; i<N; i++) {
   3332             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart);
   3333         }
   3334         return N > 0;
   3335     }
   3336 
   3337     private final boolean forceStopPackageLocked(String name, int uid,
   3338             boolean callerWillRestart, boolean purgeCache, boolean doit,
   3339             boolean evenPersistent) {
   3340         int i;
   3341         int N;
   3342 
   3343         if (uid < 0) {
   3344             try {
   3345                 uid = AppGlobals.getPackageManager().getPackageUid(name);
   3346             } catch (RemoteException e) {
   3347             }
   3348         }
   3349 
   3350         if (doit) {
   3351             Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
   3352 
   3353             Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
   3354             while (badApps.hasNext()) {
   3355                 SparseArray<Long> ba = badApps.next();
   3356                 if (ba.get(uid) != null) {
   3357                     badApps.remove();
   3358                 }
   3359             }
   3360         }
   3361 
   3362         boolean didSomething = killPackageProcessesLocked(name, uid, -100,
   3363                 callerWillRestart, false, doit, evenPersistent);
   3364 
   3365         TaskRecord lastTask = null;
   3366         for (i=0; i<mMainStack.mHistory.size(); i++) {
   3367             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   3368             final boolean samePackage = r.packageName.equals(name);
   3369             if ((samePackage || r.task == lastTask)
   3370                     && (r.app == null || evenPersistent || !r.app.persistent)) {
   3371                 if (!doit) {
   3372                     if (r.finishing) {
   3373                         // If this activity is just finishing, then it is not
   3374                         // interesting as far as something to stop.
   3375                         continue;
   3376                     }
   3377                     return true;
   3378                 }
   3379                 didSomething = true;
   3380                 Slog.i(TAG, "  Force finishing activity " + r);
   3381                 if (samePackage) {
   3382                     if (r.app != null) {
   3383                         r.app.removed = true;
   3384                     }
   3385                     r.app = null;
   3386                 }
   3387                 lastTask = r.task;
   3388                 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
   3389                         null, "force-stop")) {
   3390                     i--;
   3391                 }
   3392             }
   3393         }
   3394 
   3395         ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
   3396         for (ServiceRecord service : mServices.values()) {
   3397             if (service.packageName.equals(name)
   3398                     && (service.app == null || evenPersistent || !service.app.persistent)) {
   3399                 if (!doit) {
   3400                     return true;
   3401                 }
   3402                 didSomething = true;
   3403                 Slog.i(TAG, "  Force stopping service " + service);
   3404                 if (service.app != null) {
   3405                     service.app.removed = true;
   3406                 }
   3407                 service.app = null;
   3408                 services.add(service);
   3409             }
   3410         }
   3411 
   3412         N = services.size();
   3413         for (i=0; i<N; i++) {
   3414             bringDownServiceLocked(services.get(i), true);
   3415         }
   3416 
   3417         ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
   3418         for (ContentProviderRecord provider : mProvidersByClass.values()) {
   3419             if (provider.info.packageName.equals(name)
   3420                     && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
   3421                 if (!doit) {
   3422                     return true;
   3423                 }
   3424                 didSomething = true;
   3425                 providers.add(provider);
   3426             }
   3427         }
   3428 
   3429         N = providers.size();
   3430         for (i=0; i<N; i++) {
   3431             removeDyingProviderLocked(null, providers.get(i));
   3432         }
   3433 
   3434         if (doit) {
   3435             if (purgeCache) {
   3436                 AttributeCache ac = AttributeCache.instance();
   3437                 if (ac != null) {
   3438                     ac.removePackage(name);
   3439                 }
   3440             }
   3441             if (mBooted) {
   3442                 mMainStack.resumeTopActivityLocked(null);
   3443                 mMainStack.scheduleIdleLocked();
   3444             }
   3445         }
   3446 
   3447         return didSomething;
   3448     }
   3449 
   3450     private final boolean removeProcessLocked(ProcessRecord app,
   3451             boolean callerWillRestart, boolean allowRestart) {
   3452         final String name = app.processName;
   3453         final int uid = app.info.uid;
   3454         if (DEBUG_PROCESSES) Slog.d(
   3455             TAG, "Force removing process " + app + " (" + name
   3456             + "/" + uid + ")");
   3457 
   3458         mProcessNames.remove(name, uid);
   3459         if (mHeavyWeightProcess == app) {
   3460             mHeavyWeightProcess = null;
   3461             mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
   3462         }
   3463         boolean needRestart = false;
   3464         if (app.pid > 0 && app.pid != MY_PID) {
   3465             int pid = app.pid;
   3466             synchronized (mPidsSelfLocked) {
   3467                 mPidsSelfLocked.remove(pid);
   3468                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   3469             }
   3470             handleAppDiedLocked(app, true, allowRestart);
   3471             mLruProcesses.remove(app);
   3472             Process.killProcess(pid);
   3473 
   3474             if (app.persistent) {
   3475                 if (!callerWillRestart) {
   3476                     addAppLocked(app.info);
   3477                 } else {
   3478                     needRestart = true;
   3479                 }
   3480             }
   3481         } else {
   3482             mRemovedProcesses.add(app);
   3483         }
   3484 
   3485         return needRestart;
   3486     }
   3487 
   3488     private final void processStartTimedOutLocked(ProcessRecord app) {
   3489         final int pid = app.pid;
   3490         boolean gone = false;
   3491         synchronized (mPidsSelfLocked) {
   3492             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
   3493             if (knownApp != null && knownApp.thread == null) {
   3494                 mPidsSelfLocked.remove(pid);
   3495                 gone = true;
   3496             }
   3497         }
   3498 
   3499         if (gone) {
   3500             Slog.w(TAG, "Process " + app + " failed to attach");
   3501             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
   3502                     app.processName);
   3503             mProcessNames.remove(app.processName, app.info.uid);
   3504             if (mHeavyWeightProcess == app) {
   3505                 mHeavyWeightProcess = null;
   3506                 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
   3507             }
   3508             // Take care of any launching providers waiting for this process.
   3509             checkAppInLaunchingProvidersLocked(app, true);
   3510             // Take care of any services that are waiting for the process.
   3511             for (int i=0; i<mPendingServices.size(); i++) {
   3512                 ServiceRecord sr = mPendingServices.get(i);
   3513                 if (app.info.uid == sr.appInfo.uid
   3514                         && app.processName.equals(sr.processName)) {
   3515                     Slog.w(TAG, "Forcing bringing down service: " + sr);
   3516                     mPendingServices.remove(i);
   3517                     i--;
   3518                     bringDownServiceLocked(sr, true);
   3519                 }
   3520             }
   3521             EventLog.writeEvent(EventLogTags.AM_KILL, pid,
   3522                     app.processName, app.setAdj, "start timeout");
   3523             Process.killProcessQuiet(pid);
   3524             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
   3525                 Slog.w(TAG, "Unattached app died before backup, skipping");
   3526                 try {
   3527                     IBackupManager bm = IBackupManager.Stub.asInterface(
   3528                             ServiceManager.getService(Context.BACKUP_SERVICE));
   3529                     bm.agentDisconnected(app.info.packageName);
   3530                 } catch (RemoteException e) {
   3531                     // Can't happen; the backup manager is local
   3532                 }
   3533             }
   3534             if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
   3535                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   3536                 mPendingBroadcast.state = BroadcastRecord.IDLE;
   3537                 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
   3538                 mPendingBroadcast = null;
   3539                 scheduleBroadcastsLocked();
   3540             }
   3541         } else {
   3542             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
   3543         }
   3544     }
   3545 
   3546     private final boolean attachApplicationLocked(IApplicationThread thread,
   3547             int pid) {
   3548 
   3549         // Find the application record that is being attached...  either via
   3550         // the pid if we are running in multiple processes, or just pull the
   3551         // next app record if we are emulating process with anonymous threads.
   3552         ProcessRecord app;
   3553         if (pid != MY_PID && pid >= 0) {
   3554             synchronized (mPidsSelfLocked) {
   3555                 app = mPidsSelfLocked.get(pid);
   3556             }
   3557         } else {
   3558             app = null;
   3559         }
   3560 
   3561         if (app == null) {
   3562             Slog.w(TAG, "No pending application record for pid " + pid
   3563                     + " (IApplicationThread " + thread + "); dropping process");
   3564             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
   3565             if (pid > 0 && pid != MY_PID) {
   3566                 Process.killProcessQuiet(pid);
   3567             } else {
   3568                 try {
   3569                     thread.scheduleExit();
   3570                 } catch (Exception e) {
   3571                     // Ignore exceptions.
   3572                 }
   3573             }
   3574             return false;
   3575         }
   3576 
   3577         // If this application record is still attached to a previous
   3578         // process, clean it up now.
   3579         if (app.thread != null) {
   3580             handleAppDiedLocked(app, true, true);
   3581         }
   3582 
   3583         // Tell the process all about itself.
   3584 
   3585         if (localLOGV) Slog.v(
   3586                 TAG, "Binding process pid " + pid + " to record " + app);
   3587 
   3588         String processName = app.processName;
   3589         try {
   3590             AppDeathRecipient adr = new AppDeathRecipient(
   3591                     app, pid, thread);
   3592             thread.asBinder().linkToDeath(adr, 0);
   3593             app.deathRecipient = adr;
   3594         } catch (RemoteException e) {
   3595             app.resetPackageList();
   3596             startProcessLocked(app, "link fail", processName);
   3597             return false;
   3598         }
   3599 
   3600         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
   3601 
   3602         app.thread = thread;
   3603         app.curAdj = app.setAdj = -100;
   3604         app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
   3605         app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   3606         app.forcingToForeground = null;
   3607         app.foregroundServices = false;
   3608         app.hasShownUi = false;
   3609         app.debugging = false;
   3610 
   3611         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   3612 
   3613         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
   3614         List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
   3615 
   3616         if (!normalMode) {
   3617             Slog.i(TAG, "Launching preboot mode app: " + app);
   3618         }
   3619 
   3620         if (localLOGV) Slog.v(
   3621             TAG, "New app record " + app
   3622             + " thread=" + thread.asBinder() + " pid=" + pid);
   3623         try {
   3624             int testMode = IApplicationThread.DEBUG_OFF;
   3625             if (mDebugApp != null && mDebugApp.equals(processName)) {
   3626                 testMode = mWaitForDebugger
   3627                     ? IApplicationThread.DEBUG_WAIT
   3628                     : IApplicationThread.DEBUG_ON;
   3629                 app.debugging = true;
   3630                 if (mDebugTransient) {
   3631                     mDebugApp = mOrigDebugApp;
   3632                     mWaitForDebugger = mOrigWaitForDebugger;
   3633                 }
   3634             }
   3635             String profileFile = app.instrumentationProfileFile;
   3636             ParcelFileDescriptor profileFd = null;
   3637             boolean profileAutoStop = false;
   3638             if (mProfileApp != null && mProfileApp.equals(processName)) {
   3639                 mProfileProc = app;
   3640                 profileFile = mProfileFile;
   3641                 profileFd = mProfileFd;
   3642                 profileAutoStop = mAutoStopProfiler;
   3643             }
   3644 
   3645             // If the app is being launched for restore or full backup, set it up specially
   3646             boolean isRestrictedBackupMode = false;
   3647             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
   3648                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
   3649                         || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
   3650                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
   3651             }
   3652 
   3653             ensurePackageDexOpt(app.instrumentationInfo != null
   3654                     ? app.instrumentationInfo.packageName
   3655                     : app.info.packageName);
   3656             if (app.instrumentationClass != null) {
   3657                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
   3658             }
   3659             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
   3660                     + processName + " with config " + mConfiguration);
   3661             ApplicationInfo appInfo = app.instrumentationInfo != null
   3662                     ? app.instrumentationInfo : app.info;
   3663             app.compat = compatibilityInfoForPackageLocked(appInfo);
   3664             if (profileFd != null) {
   3665                 profileFd = profileFd.dup();
   3666             }
   3667             thread.bindApplication(processName, appInfo, providers,
   3668                     app.instrumentationClass, profileFile, profileFd, profileAutoStop,
   3669                     app.instrumentationArguments, app.instrumentationWatcher, testMode,
   3670                     isRestrictedBackupMode || !normalMode, app.persistent,
   3671                     mConfiguration, app.compat, getCommonServicesLocked(),
   3672                     mCoreSettingsObserver.getCoreSettingsLocked());
   3673             updateLruProcessLocked(app, false, true);
   3674             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
   3675         } catch (Exception e) {
   3676             // todo: Yikes!  What should we do?  For now we will try to
   3677             // start another process, but that could easily get us in
   3678             // an infinite loop of restarting processes...
   3679             Slog.w(TAG, "Exception thrown during bind!", e);
   3680 
   3681             app.resetPackageList();
   3682             app.unlinkDeathRecipient();
   3683             startProcessLocked(app, "bind fail", processName);
   3684             return false;
   3685         }
   3686 
   3687         // Remove this record from the list of starting applications.
   3688         mPersistentStartingProcesses.remove(app);
   3689         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   3690                 "Attach application locked removing on hold: " + app);
   3691         mProcessesOnHold.remove(app);
   3692 
   3693         boolean badApp = false;
   3694         boolean didSomething = false;
   3695 
   3696         // See if the top visible activity is waiting to run in this process...
   3697         ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
   3698         if (hr != null && normalMode) {
   3699             if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
   3700                     && processName.equals(hr.processName)) {
   3701                 try {
   3702                     if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
   3703                         didSomething = true;
   3704                     }
   3705                 } catch (Exception e) {
   3706                     Slog.w(TAG, "Exception in new application when starting activity "
   3707                           + hr.intent.getComponent().flattenToShortString(), e);
   3708                     badApp = true;
   3709                 }
   3710             } else {
   3711                 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
   3712             }
   3713         }
   3714 
   3715         // Find any services that should be running in this process...
   3716         if (!badApp && mPendingServices.size() > 0) {
   3717             ServiceRecord sr = null;
   3718             try {
   3719                 for (int i=0; i<mPendingServices.size(); i++) {
   3720                     sr = mPendingServices.get(i);
   3721                     if (app.info.uid != sr.appInfo.uid
   3722                             || !processName.equals(sr.processName)) {
   3723                         continue;
   3724                     }
   3725 
   3726                     mPendingServices.remove(i);
   3727                     i--;
   3728                     realStartServiceLocked(sr, app);
   3729                     didSomething = true;
   3730                 }
   3731             } catch (Exception e) {
   3732                 Slog.w(TAG, "Exception in new application when starting service "
   3733                       + sr.shortName, e);
   3734                 badApp = true;
   3735             }
   3736         }
   3737 
   3738         // Check if the next broadcast receiver is in this process...
   3739         BroadcastRecord br = mPendingBroadcast;
   3740         if (!badApp && br != null && br.curApp == app) {
   3741             try {
   3742                 mPendingBroadcast = null;
   3743                 processCurBroadcastLocked(br, app);
   3744                 didSomething = true;
   3745             } catch (Exception e) {
   3746                 Slog.w(TAG, "Exception in new application when starting receiver "
   3747                       + br.curComponent.flattenToShortString(), e);
   3748                 badApp = true;
   3749                 logBroadcastReceiverDiscardLocked(br);
   3750                 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
   3751                         br.resultExtras, br.resultAbort, true);
   3752                 scheduleBroadcastsLocked();
   3753                 // We need to reset the state if we fails to start the receiver.
   3754                 br.state = BroadcastRecord.IDLE;
   3755             }
   3756         }
   3757 
   3758         // Check whether the next backup agent is in this process...
   3759         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
   3760             if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
   3761             ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
   3762             try {
   3763                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
   3764                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
   3765                         mBackupTarget.backupMode);
   3766             } catch (Exception e) {
   3767                 Slog.w(TAG, "Exception scheduling backup agent creation: ");
   3768                 e.printStackTrace();
   3769             }
   3770         }
   3771 
   3772         if (badApp) {
   3773             // todo: Also need to kill application to deal with all
   3774             // kinds of exceptions.
   3775             handleAppDiedLocked(app, false, true);
   3776             return false;
   3777         }
   3778 
   3779         if (!didSomething) {
   3780             updateOomAdjLocked();
   3781         }
   3782 
   3783         return true;
   3784     }
   3785 
   3786     public final void attachApplication(IApplicationThread thread) {
   3787         synchronized (this) {
   3788             int callingPid = Binder.getCallingPid();
   3789             final long origId = Binder.clearCallingIdentity();
   3790             attachApplicationLocked(thread, callingPid);
   3791             Binder.restoreCallingIdentity(origId);
   3792         }
   3793     }
   3794 
   3795     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
   3796         final long origId = Binder.clearCallingIdentity();
   3797         ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
   3798         if (stopProfiling) {
   3799             synchronized (this) {
   3800                 if (mProfileProc == r.app) {
   3801                     if (mProfileFd != null) {
   3802                         try {
   3803                             mProfileFd.close();
   3804                         } catch (IOException e) {
   3805                         }
   3806                         clearProfilerLocked();
   3807                     }
   3808                 }
   3809             }
   3810         }
   3811         Binder.restoreCallingIdentity(origId);
   3812     }
   3813 
   3814     void enableScreenAfterBoot() {
   3815         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
   3816                 SystemClock.uptimeMillis());
   3817         mWindowManager.enableScreenAfterBoot();
   3818     }
   3819 
   3820     public void showBootMessage(final CharSequence msg, final boolean always) {
   3821         mWindowManager.showBootMessage(msg, always);
   3822     }
   3823 
   3824     public void dismissKeyguardOnNextActivity() {
   3825         synchronized (this) {
   3826             mMainStack.dismissKeyguardOnNextActivityLocked();
   3827         }
   3828     }
   3829 
   3830     final void finishBooting() {
   3831         IntentFilter pkgFilter = new IntentFilter();
   3832         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
   3833         pkgFilter.addDataScheme("package");
   3834         mContext.registerReceiver(new BroadcastReceiver() {
   3835             @Override
   3836             public void onReceive(Context context, Intent intent) {
   3837                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
   3838                 if (pkgs != null) {
   3839                     for (String pkg : pkgs) {
   3840                         synchronized (ActivityManagerService.this) {
   3841                           if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
   3842                               setResultCode(Activity.RESULT_OK);
   3843                               return;
   3844                           }
   3845                        }
   3846                     }
   3847                 }
   3848             }
   3849         }, pkgFilter);
   3850 
   3851         synchronized (this) {
   3852             // Ensure that any processes we had put on hold are now started
   3853             // up.
   3854             final int NP = mProcessesOnHold.size();
   3855             if (NP > 0) {
   3856                 ArrayList<ProcessRecord> procs =
   3857                     new ArrayList<ProcessRecord>(mProcessesOnHold);
   3858                 for (int ip=0; ip<NP; ip++) {
   3859                     if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
   3860                             + procs.get(ip));
   3861                     startProcessLocked(procs.get(ip), "on-hold", null);
   3862                 }
   3863             }
   3864 
   3865             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   3866                 // Start looking for apps that are abusing wake locks.
   3867                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   3868                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   3869                 // Tell anyone interested that we are done booting!
   3870                 SystemProperties.set("sys.boot_completed", "1");
   3871                 broadcastIntentLocked(null, null,
   3872                         new Intent(Intent.ACTION_BOOT_COMPLETED, null),
   3873                         null, null, 0, null, null,
   3874                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
   3875                         false, false, MY_PID, Process.SYSTEM_UID);
   3876             }
   3877         }
   3878     }
   3879 
   3880     final void ensureBootCompleted() {
   3881         boolean booting;
   3882         boolean enableScreen;
   3883         synchronized (this) {
   3884             booting = mBooting;
   3885             mBooting = false;
   3886             enableScreen = !mBooted;
   3887             mBooted = true;
   3888         }
   3889 
   3890         if (booting) {
   3891             finishBooting();
   3892         }
   3893 
   3894         if (enableScreen) {
   3895             enableScreenAfterBoot();
   3896         }
   3897     }
   3898 
   3899     public final void activityPaused(IBinder token) {
   3900         final long origId = Binder.clearCallingIdentity();
   3901         mMainStack.activityPaused(token, false);
   3902         Binder.restoreCallingIdentity(origId);
   3903     }
   3904 
   3905     public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
   3906             CharSequence description) {
   3907         if (localLOGV) Slog.v(
   3908             TAG, "Activity stopped: token=" + token);
   3909 
   3910         // Refuse possible leaked file descriptors
   3911         if (icicle != null && icicle.hasFileDescriptors()) {
   3912             throw new IllegalArgumentException("File descriptors passed in Bundle");
   3913         }
   3914 
   3915         ActivityRecord r = null;
   3916 
   3917         final long origId = Binder.clearCallingIdentity();
   3918 
   3919         synchronized (this) {
   3920             r = mMainStack.isInStackLocked(token);
   3921             if (r != null) {
   3922                 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
   3923             }
   3924         }
   3925 
   3926         if (r != null) {
   3927             sendPendingThumbnail(r, null, null, null, false);
   3928         }
   3929 
   3930         trimApplications();
   3931 
   3932         Binder.restoreCallingIdentity(origId);
   3933     }
   3934 
   3935     public final void activityDestroyed(IBinder token) {
   3936         if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
   3937         mMainStack.activityDestroyed(token);
   3938     }
   3939 
   3940     public String getCallingPackage(IBinder token) {
   3941         synchronized (this) {
   3942             ActivityRecord r = getCallingRecordLocked(token);
   3943             return r != null && r.app != null ? r.info.packageName : null;
   3944         }
   3945     }
   3946 
   3947     public ComponentName getCallingActivity(IBinder token) {
   3948         synchronized (this) {
   3949             ActivityRecord r = getCallingRecordLocked(token);
   3950             return r != null ? r.intent.getComponent() : null;
   3951         }
   3952     }
   3953 
   3954     private ActivityRecord getCallingRecordLocked(IBinder token) {
   3955         ActivityRecord r = mMainStack.isInStackLocked(token);
   3956         if (r == null) {
   3957             return null;
   3958         }
   3959         return r.resultTo;
   3960     }
   3961 
   3962     public ComponentName getActivityClassForToken(IBinder token) {
   3963         synchronized(this) {
   3964             ActivityRecord r = mMainStack.isInStackLocked(token);
   3965             if (r == null) {
   3966                 return null;
   3967             }
   3968             return r.intent.getComponent();
   3969         }
   3970     }
   3971 
   3972     public String getPackageForToken(IBinder token) {
   3973         synchronized(this) {
   3974             ActivityRecord r = mMainStack.isInStackLocked(token);
   3975             if (r == null) {
   3976                 return null;
   3977             }
   3978             return r.packageName;
   3979         }
   3980     }
   3981 
   3982     public IIntentSender getIntentSender(int type,
   3983             String packageName, IBinder token, String resultWho,
   3984             int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
   3985         // Refuse possible leaked file descriptors
   3986         if (intents != null) {
   3987             if (intents.length < 1) {
   3988                 throw new IllegalArgumentException("Intents array length must be >= 1");
   3989             }
   3990             for (int i=0; i<intents.length; i++) {
   3991                 Intent intent = intents[i];
   3992                 if (intent != null) {
   3993                     if (intent.hasFileDescriptors()) {
   3994                         throw new IllegalArgumentException("File descriptors passed in Intent");
   3995                     }
   3996                     if (type == INTENT_SENDER_BROADCAST &&
   3997                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   3998                         throw new IllegalArgumentException(
   3999                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   4000                     }
   4001                     intents[i] = new Intent(intent);
   4002                 }
   4003             }
   4004             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
   4005                 throw new IllegalArgumentException(
   4006                         "Intent array length does not match resolvedTypes length");
   4007             }
   4008         }
   4009 
   4010         synchronized(this) {
   4011             int callingUid = Binder.getCallingUid();
   4012             try {
   4013                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   4014                     int uid = AppGlobals.getPackageManager()
   4015                             .getPackageUid(packageName);
   4016                     if (uid != Binder.getCallingUid()) {
   4017                         String msg = "Permission Denial: getIntentSender() from pid="
   4018                             + Binder.getCallingPid()
   4019                             + ", uid=" + Binder.getCallingUid()
   4020                             + ", (need uid=" + uid + ")"
   4021                             + " is not allowed to send as package " + packageName;
   4022                         Slog.w(TAG, msg);
   4023                         throw new SecurityException(msg);
   4024                     }
   4025                 }
   4026 
   4027                 return getIntentSenderLocked(type, packageName, callingUid,
   4028                         token, resultWho, requestCode, intents, resolvedTypes, flags);
   4029 
   4030             } catch (RemoteException e) {
   4031                 throw new SecurityException(e);
   4032             }
   4033         }
   4034     }
   4035 
   4036     IIntentSender getIntentSenderLocked(int type,
   4037             String packageName, int callingUid, IBinder token, String resultWho,
   4038             int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
   4039         ActivityRecord activity = null;
   4040         if (type == INTENT_SENDER_ACTIVITY_RESULT) {
   4041             activity = mMainStack.isInStackLocked(token);
   4042             if (activity == null) {
   4043                 return null;
   4044             }
   4045             if (activity.finishing) {
   4046                 return null;
   4047             }
   4048         }
   4049 
   4050         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
   4051         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
   4052         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
   4053         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
   4054                 |PendingIntent.FLAG_UPDATE_CURRENT);
   4055 
   4056         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
   4057                 type, packageName, activity, resultWho,
   4058                 requestCode, intents, resolvedTypes, flags);
   4059         WeakReference<PendingIntentRecord> ref;
   4060         ref = mIntentSenderRecords.get(key);
   4061         PendingIntentRecord rec = ref != null ? ref.get() : null;
   4062         if (rec != null) {
   4063             if (!cancelCurrent) {
   4064                 if (updateCurrent) {
   4065                     if (rec.key.requestIntent != null) {
   4066                         rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
   4067                     }
   4068                     if (intents != null) {
   4069                         intents[intents.length-1] = rec.key.requestIntent;
   4070                         rec.key.allIntents = intents;
   4071                         rec.key.allResolvedTypes = resolvedTypes;
   4072                     } else {
   4073                         rec.key.allIntents = null;
   4074                         rec.key.allResolvedTypes = null;
   4075                     }
   4076                 }
   4077                 return rec;
   4078             }
   4079             rec.canceled = true;
   4080             mIntentSenderRecords.remove(key);
   4081         }
   4082         if (noCreate) {
   4083             return rec;
   4084         }
   4085         rec = new PendingIntentRecord(this, key, callingUid);
   4086         mIntentSenderRecords.put(key, rec.ref);
   4087         if (type == INTENT_SENDER_ACTIVITY_RESULT) {
   4088             if (activity.pendingResults == null) {
   4089                 activity.pendingResults
   4090                         = new HashSet<WeakReference<PendingIntentRecord>>();
   4091             }
   4092             activity.pendingResults.add(rec.ref);
   4093         }
   4094         return rec;
   4095     }
   4096 
   4097     public void cancelIntentSender(IIntentSender sender) {
   4098         if (!(sender instanceof PendingIntentRecord)) {
   4099             return;
   4100         }
   4101         synchronized(this) {
   4102             PendingIntentRecord rec = (PendingIntentRecord)sender;
   4103             try {
   4104                 int uid = AppGlobals.getPackageManager()
   4105                         .getPackageUid(rec.key.packageName);
   4106                 if (uid != Binder.getCallingUid()) {
   4107                     String msg = "Permission Denial: cancelIntentSender() from pid="
   4108                         + Binder.getCallingPid()
   4109                         + ", uid=" + Binder.getCallingUid()
   4110                         + " is not allowed to cancel packges "
   4111                         + rec.key.packageName;
   4112                     Slog.w(TAG, msg);
   4113                     throw new SecurityException(msg);
   4114                 }
   4115             } catch (RemoteException e) {
   4116                 throw new SecurityException(e);
   4117             }
   4118             cancelIntentSenderLocked(rec, true);
   4119         }
   4120     }
   4121 
   4122     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
   4123         rec.canceled = true;
   4124         mIntentSenderRecords.remove(rec.key);
   4125         if (cleanActivity && rec.key.activity != null) {
   4126             rec.key.activity.pendingResults.remove(rec.ref);
   4127         }
   4128     }
   4129 
   4130     public String getPackageForIntentSender(IIntentSender pendingResult) {
   4131         if (!(pendingResult instanceof PendingIntentRecord)) {
   4132             return null;
   4133         }
   4134         try {
   4135             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   4136             return res.key.packageName;
   4137         } catch (ClassCastException e) {
   4138         }
   4139         return null;
   4140     }
   4141 
   4142     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
   4143         if (!(pendingResult instanceof PendingIntentRecord)) {
   4144             return false;
   4145         }
   4146         try {
   4147             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   4148             if (res.key.allIntents == null) {
   4149                 return false;
   4150             }
   4151             for (int i=0; i<res.key.allIntents.length; i++) {
   4152                 Intent intent = res.key.allIntents[i];
   4153                 if (intent.getPackage() != null && intent.getComponent() != null) {
   4154                     return false;
   4155                 }
   4156             }
   4157             return true;
   4158         } catch (ClassCastException e) {
   4159         }
   4160         return false;
   4161     }
   4162 
   4163     public void setProcessLimit(int max) {
   4164         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   4165                 "setProcessLimit()");
   4166         synchronized (this) {
   4167             mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
   4168             mProcessLimitOverride = max;
   4169         }
   4170         trimApplications();
   4171     }
   4172 
   4173     public int getProcessLimit() {
   4174         synchronized (this) {
   4175             return mProcessLimitOverride;
   4176         }
   4177     }
   4178 
   4179     void foregroundTokenDied(ForegroundToken token) {
   4180         synchronized (ActivityManagerService.this) {
   4181             synchronized (mPidsSelfLocked) {
   4182                 ForegroundToken cur
   4183                     = mForegroundProcesses.get(token.pid);
   4184                 if (cur != token) {
   4185                     return;
   4186                 }
   4187                 mForegroundProcesses.remove(token.pid);
   4188                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
   4189                 if (pr == null) {
   4190                     return;
   4191                 }
   4192                 pr.forcingToForeground = null;
   4193                 pr.foregroundServices = false;
   4194             }
   4195             updateOomAdjLocked();
   4196         }
   4197     }
   4198 
   4199     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
   4200         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   4201                 "setProcessForeground()");
   4202         synchronized(this) {
   4203             boolean changed = false;
   4204 
   4205             synchronized (mPidsSelfLocked) {
   4206                 ProcessRecord pr = mPidsSelfLocked.get(pid);
   4207                 if (pr == null) {
   4208                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
   4209                     return;
   4210                 }
   4211                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
   4212                 if (oldToken != null) {
   4213                     oldToken.token.unlinkToDeath(oldToken, 0);
   4214                     mForegroundProcesses.remove(pid);
   4215                     pr.forcingToForeground = null;
   4216                     changed = true;
   4217                 }
   4218                 if (isForeground && token != null) {
   4219                     ForegroundToken newToken = new ForegroundToken() {
   4220                         public void binderDied() {
   4221                             foregroundTokenDied(this);
   4222                         }
   4223                     };
   4224                     newToken.pid = pid;
   4225                     newToken.token = token;
   4226                     try {
   4227                         token.linkToDeath(newToken, 0);
   4228                         mForegroundProcesses.put(pid, newToken);
   4229                         pr.forcingToForeground = token;
   4230                         changed = true;
   4231                     } catch (RemoteException e) {
   4232                         // If the process died while doing this, we will later
   4233                         // do the cleanup with the process death link.
   4234                     }
   4235                 }
   4236             }
   4237 
   4238             if (changed) {
   4239                 updateOomAdjLocked();
   4240             }
   4241         }
   4242     }
   4243 
   4244     // =========================================================
   4245     // PERMISSIONS
   4246     // =========================================================
   4247 
   4248     static class PermissionController extends IPermissionController.Stub {
   4249         ActivityManagerService mActivityManagerService;
   4250         PermissionController(ActivityManagerService activityManagerService) {
   4251             mActivityManagerService = activityManagerService;
   4252         }
   4253 
   4254         public boolean checkPermission(String permission, int pid, int uid) {
   4255             return mActivityManagerService.checkPermission(permission, pid,
   4256                     uid) == PackageManager.PERMISSION_GRANTED;
   4257         }
   4258     }
   4259 
   4260     /**
   4261      * This can be called with or without the global lock held.
   4262      */
   4263     int checkComponentPermission(String permission, int pid, int uid,
   4264             int owningUid, boolean exported) {
   4265         // We might be performing an operation on behalf of an indirect binder
   4266         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
   4267         // client identity accordingly before proceeding.
   4268         Identity tlsIdentity = sCallerIdentity.get();
   4269         if (tlsIdentity != null) {
   4270             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
   4271                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
   4272             uid = tlsIdentity.uid;
   4273             pid = tlsIdentity.pid;
   4274         }
   4275 
   4276         // Root, system server and our own process get to do everything.
   4277         if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
   4278             return PackageManager.PERMISSION_GRANTED;
   4279         }
   4280         // If there is a uid that owns whatever is being accessed, it has
   4281         // blanket access to it regardless of the permissions it requires.
   4282         if (owningUid >= 0 && uid == owningUid) {
   4283             return PackageManager.PERMISSION_GRANTED;
   4284         }
   4285         // If the target is not exported, then nobody else can get to it.
   4286         if (!exported) {
   4287             Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
   4288             return PackageManager.PERMISSION_DENIED;
   4289         }
   4290         if (permission == null) {
   4291             return PackageManager.PERMISSION_GRANTED;
   4292         }
   4293         try {
   4294             return AppGlobals.getPackageManager()
   4295                     .checkUidPermission(permission, uid);
   4296         } catch (RemoteException e) {
   4297             // Should never happen, but if it does... deny!
   4298             Slog.e(TAG, "PackageManager is dead?!?", e);
   4299         }
   4300         return PackageManager.PERMISSION_DENIED;
   4301     }
   4302 
   4303     /**
   4304      * As the only public entry point for permissions checking, this method
   4305      * can enforce the semantic that requesting a check on a null global
   4306      * permission is automatically denied.  (Internally a null permission
   4307      * string is used when calling {@link #checkComponentPermission} in cases
   4308      * when only uid-based security is needed.)
   4309      *
   4310      * This can be called with or without the global lock held.
   4311      */
   4312     public int checkPermission(String permission, int pid, int uid) {
   4313         if (permission == null) {
   4314             return PackageManager.PERMISSION_DENIED;
   4315         }
   4316         return checkComponentPermission(permission, pid, uid, -1, true);
   4317     }
   4318 
   4319     /**
   4320      * Binder IPC calls go through the public entry point.
   4321      * This can be called with or without the global lock held.
   4322      */
   4323     int checkCallingPermission(String permission) {
   4324         return checkPermission(permission,
   4325                 Binder.getCallingPid(),
   4326                 Binder.getCallingUid());
   4327     }
   4328 
   4329     /**
   4330      * This can be called with or without the global lock held.
   4331      */
   4332     void enforceCallingPermission(String permission, String func) {
   4333         if (checkCallingPermission(permission)
   4334                 == PackageManager.PERMISSION_GRANTED) {
   4335             return;
   4336         }
   4337 
   4338         String msg = "Permission Denial: " + func + " from pid="
   4339                 + Binder.getCallingPid()
   4340                 + ", uid=" + Binder.getCallingUid()
   4341                 + " requires " + permission;
   4342         Slog.w(TAG, msg);
   4343         throw new SecurityException(msg);
   4344     }
   4345 
   4346     private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
   4347             ProviderInfo pi, Uri uri, int uid, int modeFlags) {
   4348         boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
   4349         boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
   4350         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4351                 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
   4352         try {
   4353             // Is the component private from the target uid?
   4354             final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
   4355 
   4356             // Acceptable if the there is no read permission needed from the
   4357             // target or the target is holding the read permission.
   4358             if (!readPerm) {
   4359                 if ((!prv && pi.readPermission == null) ||
   4360                         (pm.checkUidPermission(pi.readPermission, uid)
   4361                                 == PackageManager.PERMISSION_GRANTED)) {
   4362                     readPerm = true;
   4363                 }
   4364             }
   4365 
   4366             // Acceptable if the there is no write permission needed from the
   4367             // target or the target is holding the read permission.
   4368             if (!writePerm) {
   4369                 if (!prv && (pi.writePermission == null) ||
   4370                         (pm.checkUidPermission(pi.writePermission, uid)
   4371                                 == PackageManager.PERMISSION_GRANTED)) {
   4372                     writePerm = true;
   4373                 }
   4374             }
   4375 
   4376             // Acceptable if there is a path permission matching the URI that
   4377             // the target holds the permission on.
   4378             PathPermission[] pps = pi.pathPermissions;
   4379             if (pps != null && (!readPerm || !writePerm)) {
   4380                 final String path = uri.getPath();
   4381                 int i = pps.length;
   4382                 while (i > 0 && (!readPerm || !writePerm)) {
   4383                     i--;
   4384                     PathPermission pp = pps[i];
   4385                     if (!readPerm) {
   4386                         final String pprperm = pp.getReadPermission();
   4387                         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
   4388                                 + pprperm + " for " + pp.getPath()
   4389                                 + ": match=" + pp.match(path)
   4390                                 + " check=" + pm.checkUidPermission(pprperm, uid));
   4391                         if (pprperm != null && pp.match(path) &&
   4392                                 (pm.checkUidPermission(pprperm, uid)
   4393                                         == PackageManager.PERMISSION_GRANTED)) {
   4394                             readPerm = true;
   4395                         }
   4396                     }
   4397                     if (!writePerm) {
   4398                         final String ppwperm = pp.getWritePermission();
   4399                         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
   4400                                 + ppwperm + " for " + pp.getPath()
   4401                                 + ": match=" + pp.match(path)
   4402                                 + " check=" + pm.checkUidPermission(ppwperm, uid));
   4403                         if (ppwperm != null && pp.match(path) &&
   4404                                 (pm.checkUidPermission(ppwperm, uid)
   4405                                         == PackageManager.PERMISSION_GRANTED)) {
   4406                             writePerm = true;
   4407                         }
   4408                     }
   4409                 }
   4410             }
   4411         } catch (RemoteException e) {
   4412             return false;
   4413         }
   4414 
   4415         return readPerm && writePerm;
   4416     }
   4417 
   4418     private final boolean checkUriPermissionLocked(Uri uri, int uid,
   4419             int modeFlags) {
   4420         // Root gets to do everything.
   4421         if (uid == 0) {
   4422             return true;
   4423         }
   4424         HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   4425         if (perms == null) return false;
   4426         UriPermission perm = perms.get(uri);
   4427         if (perm == null) return false;
   4428         return (modeFlags&perm.modeFlags) == modeFlags;
   4429     }
   4430 
   4431     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
   4432         // Another redirected-binder-call permissions check as in
   4433         // {@link checkComponentPermission}.
   4434         Identity tlsIdentity = sCallerIdentity.get();
   4435         if (tlsIdentity != null) {
   4436             uid = tlsIdentity.uid;
   4437             pid = tlsIdentity.pid;
   4438         }
   4439 
   4440         // Our own process gets to do everything.
   4441         if (pid == MY_PID) {
   4442             return PackageManager.PERMISSION_GRANTED;
   4443         }
   4444         synchronized(this) {
   4445             return checkUriPermissionLocked(uri, uid, modeFlags)
   4446                     ? PackageManager.PERMISSION_GRANTED
   4447                     : PackageManager.PERMISSION_DENIED;
   4448         }
   4449     }
   4450 
   4451     /**
   4452      * Check if the targetPkg can be granted permission to access uri by
   4453      * the callingUid using the given modeFlags.  Throws a security exception
   4454      * if callingUid is not allowed to do this.  Returns the uid of the target
   4455      * if the URI permission grant should be performed; returns -1 if it is not
   4456      * needed (for example targetPkg already has permission to access the URI).
   4457      */
   4458     int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
   4459             Uri uri, int modeFlags) {
   4460         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   4461                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   4462         if (modeFlags == 0) {
   4463             return -1;
   4464         }
   4465 
   4466         if (targetPkg != null) {
   4467             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4468                     "Checking grant " + targetPkg + " permission to " + uri);
   4469         }
   4470 
   4471         final IPackageManager pm = AppGlobals.getPackageManager();
   4472 
   4473         // If this is not a content: uri, we can't do anything with it.
   4474         if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
   4475             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4476                     "Can't grant URI permission for non-content URI: " + uri);
   4477             return -1;
   4478         }
   4479 
   4480         String name = uri.getAuthority();
   4481         ProviderInfo pi = null;
   4482         ContentProviderRecord cpr = mProvidersByName.get(name);
   4483         if (cpr != null) {
   4484             pi = cpr.info;
   4485         } else {
   4486             try {
   4487                 pi = pm.resolveContentProvider(name,
   4488                         PackageManager.GET_URI_PERMISSION_PATTERNS);
   4489             } catch (RemoteException ex) {
   4490             }
   4491         }
   4492         if (pi == null) {
   4493             Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
   4494             return -1;
   4495         }
   4496 
   4497         int targetUid;
   4498         if (targetPkg != null) {
   4499             try {
   4500                 targetUid = pm.getPackageUid(targetPkg);
   4501                 if (targetUid < 0) {
   4502                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4503                             "Can't grant URI permission no uid for: " + targetPkg);
   4504                     return -1;
   4505                 }
   4506             } catch (RemoteException ex) {
   4507                 return -1;
   4508             }
   4509         } else {
   4510             targetUid = -1;
   4511         }
   4512 
   4513         if (targetUid >= 0) {
   4514             // First...  does the target actually need this permission?
   4515             if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
   4516                 // No need to grant the target this permission.
   4517                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4518                         "Target " + targetPkg + " already has full permission to " + uri);
   4519                 return -1;
   4520             }
   4521         } else {
   4522             // First...  there is no target package, so can anyone access it?
   4523             boolean allowed = pi.exported;
   4524             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   4525                 if (pi.readPermission != null) {
   4526                     allowed = false;
   4527                 }
   4528             }
   4529             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   4530                 if (pi.writePermission != null) {
   4531                     allowed = false;
   4532                 }
   4533             }
   4534             if (allowed) {
   4535                 return -1;
   4536             }
   4537         }
   4538 
   4539         // Second...  is the provider allowing granting of URI permissions?
   4540         if (!pi.grantUriPermissions) {
   4541             throw new SecurityException("Provider " + pi.packageName
   4542                     + "/" + pi.name
   4543                     + " does not allow granting of Uri permissions (uri "
   4544                     + uri + ")");
   4545         }
   4546         if (pi.uriPermissionPatterns != null) {
   4547             final int N = pi.uriPermissionPatterns.length;
   4548             boolean allowed = false;
   4549             for (int i=0; i<N; i++) {
   4550                 if (pi.uriPermissionPatterns[i] != null
   4551                         && pi.uriPermissionPatterns[i].match(uri.getPath())) {
   4552                     allowed = true;
   4553                     break;
   4554                 }
   4555             }
   4556             if (!allowed) {
   4557                 throw new SecurityException("Provider " + pi.packageName
   4558                         + "/" + pi.name
   4559                         + " does not allow granting of permission to path of Uri "
   4560                         + uri);
   4561             }
   4562         }
   4563 
   4564         // Third...  does the caller itself have permission to access
   4565         // this uri?
   4566         if (callingUid != Process.myUid()) {
   4567             if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
   4568                 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
   4569                     throw new SecurityException("Uid " + callingUid
   4570                             + " does not have permission to uri " + uri);
   4571                 }
   4572             }
   4573         }
   4574 
   4575         return targetUid;
   4576     }
   4577 
   4578     public int checkGrantUriPermission(int callingUid, String targetPkg,
   4579             Uri uri, int modeFlags) {
   4580         synchronized(this) {
   4581             return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
   4582         }
   4583     }
   4584 
   4585     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
   4586             Uri uri, int modeFlags, UriPermissionOwner owner) {
   4587         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   4588                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   4589         if (modeFlags == 0) {
   4590             return;
   4591         }
   4592 
   4593         // So here we are: the caller has the assumed permission
   4594         // to the uri, and the target doesn't.  Let's now give this to
   4595         // the target.
   4596 
   4597         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4598                 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
   4599 
   4600         HashMap<Uri, UriPermission> targetUris
   4601                 = mGrantedUriPermissions.get(targetUid);
   4602         if (targetUris == null) {
   4603             targetUris = new HashMap<Uri, UriPermission>();
   4604             mGrantedUriPermissions.put(targetUid, targetUris);
   4605         }
   4606 
   4607         UriPermission perm = targetUris.get(uri);
   4608         if (perm == null) {
   4609             perm = new UriPermission(targetUid, uri);
   4610             targetUris.put(uri, perm);
   4611         }
   4612 
   4613         perm.modeFlags |= modeFlags;
   4614         if (owner == null) {
   4615             perm.globalModeFlags |= modeFlags;
   4616         } else {
   4617             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   4618                  perm.readOwners.add(owner);
   4619                  owner.addReadPermission(perm);
   4620             }
   4621             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   4622                  perm.writeOwners.add(owner);
   4623                  owner.addWritePermission(perm);
   4624             }
   4625         }
   4626     }
   4627 
   4628     void grantUriPermissionLocked(int callingUid,
   4629             String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
   4630         if (targetPkg == null) {
   4631             throw new NullPointerException("targetPkg");
   4632         }
   4633 
   4634         int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
   4635         if (targetUid < 0) {
   4636             return;
   4637         }
   4638 
   4639         grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
   4640     }
   4641 
   4642     /**
   4643      * Like checkGrantUriPermissionLocked, but takes an Intent.
   4644      */
   4645     int checkGrantUriPermissionFromIntentLocked(int callingUid,
   4646             String targetPkg, Intent intent) {
   4647         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4648                 "Checking URI perm to " + (intent != null ? intent.getData() : null)
   4649                 + " from " + intent + "; flags=0x"
   4650                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
   4651 
   4652         if (targetPkg == null) {
   4653             throw new NullPointerException("targetPkg");
   4654         }
   4655 
   4656         if (intent == null) {
   4657             return -1;
   4658         }
   4659         Uri data = intent.getData();
   4660         if (data == null) {
   4661             return -1;
   4662         }
   4663         return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
   4664                 intent.getFlags());
   4665     }
   4666 
   4667     /**
   4668      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
   4669      */
   4670     void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
   4671             String targetPkg, Intent intent, UriPermissionOwner owner) {
   4672         grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
   4673                 intent.getFlags(), owner);
   4674     }
   4675 
   4676     void grantUriPermissionFromIntentLocked(int callingUid,
   4677             String targetPkg, Intent intent, UriPermissionOwner owner) {
   4678         int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
   4679         if (targetUid < 0) {
   4680             return;
   4681         }
   4682 
   4683         grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
   4684     }
   4685 
   4686     public void grantUriPermission(IApplicationThread caller, String targetPkg,
   4687             Uri uri, int modeFlags) {
   4688         synchronized(this) {
   4689             final ProcessRecord r = getRecordForAppLocked(caller);
   4690             if (r == null) {
   4691                 throw new SecurityException("Unable to find app for caller "
   4692                         + caller
   4693                         + " when granting permission to uri " + uri);
   4694             }
   4695             if (targetPkg == null) {
   4696                 throw new IllegalArgumentException("null target");
   4697             }
   4698             if (uri == null) {
   4699                 throw new IllegalArgumentException("null uri");
   4700             }
   4701 
   4702             grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
   4703                     null);
   4704         }
   4705     }
   4706 
   4707     void removeUriPermissionIfNeededLocked(UriPermission perm) {
   4708         if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
   4709                 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
   4710             HashMap<Uri, UriPermission> perms
   4711                     = mGrantedUriPermissions.get(perm.uid);
   4712             if (perms != null) {
   4713                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4714                         "Removing " + perm.uid + " permission to " + perm.uri);
   4715                 perms.remove(perm.uri);
   4716                 if (perms.size() == 0) {
   4717                     mGrantedUriPermissions.remove(perm.uid);
   4718                 }
   4719             }
   4720         }
   4721     }
   4722 
   4723     private void revokeUriPermissionLocked(int callingUid, Uri uri,
   4724             int modeFlags) {
   4725         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   4726                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   4727         if (modeFlags == 0) {
   4728             return;
   4729         }
   4730 
   4731         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4732                 "Revoking all granted permissions to " + uri);
   4733 
   4734         final IPackageManager pm = AppGlobals.getPackageManager();
   4735 
   4736         final String authority = uri.getAuthority();
   4737         ProviderInfo pi = null;
   4738         ContentProviderRecord cpr = mProvidersByName.get(authority);
   4739         if (cpr != null) {
   4740             pi = cpr.info;
   4741         } else {
   4742             try {
   4743                 pi = pm.resolveContentProvider(authority,
   4744                         PackageManager.GET_URI_PERMISSION_PATTERNS);
   4745             } catch (RemoteException ex) {
   4746             }
   4747         }
   4748         if (pi == null) {
   4749             Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
   4750             return;
   4751         }
   4752 
   4753         // Does the caller have this permission on the URI?
   4754         if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
   4755             // Right now, if you are not the original owner of the permission,
   4756             // you are not allowed to revoke it.
   4757             //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
   4758                 throw new SecurityException("Uid " + callingUid
   4759                         + " does not have permission to uri " + uri);
   4760             //}
   4761         }
   4762 
   4763         // Go through all of the permissions and remove any that match.
   4764         final List<String> SEGMENTS = uri.getPathSegments();
   4765         if (SEGMENTS != null) {
   4766             final int NS = SEGMENTS.size();
   4767             int N = mGrantedUriPermissions.size();
   4768             for (int i=0; i<N; i++) {
   4769                 HashMap<Uri, UriPermission> perms
   4770                         = mGrantedUriPermissions.valueAt(i);
   4771                 Iterator<UriPermission> it = perms.values().iterator();
   4772             toploop:
   4773                 while (it.hasNext()) {
   4774                     UriPermission perm = it.next();
   4775                     Uri targetUri = perm.uri;
   4776                     if (!authority.equals(targetUri.getAuthority())) {
   4777                         continue;
   4778                     }
   4779                     List<String> targetSegments = targetUri.getPathSegments();
   4780                     if (targetSegments == null) {
   4781                         continue;
   4782                     }
   4783                     if (targetSegments.size() < NS) {
   4784                         continue;
   4785                     }
   4786                     for (int j=0; j<NS; j++) {
   4787                         if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
   4788                             continue toploop;
   4789                         }
   4790                     }
   4791                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4792                             "Revoking " + perm.uid + " permission to " + perm.uri);
   4793                     perm.clearModes(modeFlags);
   4794                     if (perm.modeFlags == 0) {
   4795                         it.remove();
   4796                     }
   4797                 }
   4798                 if (perms.size() == 0) {
   4799                     mGrantedUriPermissions.remove(
   4800                             mGrantedUriPermissions.keyAt(i));
   4801                     N--;
   4802                     i--;
   4803                 }
   4804             }
   4805         }
   4806     }
   4807 
   4808     public void revokeUriPermission(IApplicationThread caller, Uri uri,
   4809             int modeFlags) {
   4810         synchronized(this) {
   4811             final ProcessRecord r = getRecordForAppLocked(caller);
   4812             if (r == null) {
   4813                 throw new SecurityException("Unable to find app for caller "
   4814                         + caller
   4815                         + " when revoking permission to uri " + uri);
   4816             }
   4817             if (uri == null) {
   4818                 Slog.w(TAG, "revokeUriPermission: null uri");
   4819                 return;
   4820             }
   4821 
   4822             modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   4823                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   4824             if (modeFlags == 0) {
   4825                 return;
   4826             }
   4827 
   4828             final IPackageManager pm = AppGlobals.getPackageManager();
   4829 
   4830             final String authority = uri.getAuthority();
   4831             ProviderInfo pi = null;
   4832             ContentProviderRecord cpr = mProvidersByName.get(authority);
   4833             if (cpr != null) {
   4834                 pi = cpr.info;
   4835             } else {
   4836                 try {
   4837                     pi = pm.resolveContentProvider(authority,
   4838                             PackageManager.GET_URI_PERMISSION_PATTERNS);
   4839                 } catch (RemoteException ex) {
   4840                 }
   4841             }
   4842             if (pi == null) {
   4843                 Slog.w(TAG, "No content provider found for permission revoke: "
   4844                         + uri.toSafeString());
   4845                 return;
   4846             }
   4847 
   4848             revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
   4849         }
   4850     }
   4851 
   4852     @Override
   4853     public IBinder newUriPermissionOwner(String name) {
   4854         synchronized(this) {
   4855             UriPermissionOwner owner = new UriPermissionOwner(this, name);
   4856             return owner.getExternalTokenLocked();
   4857         }
   4858     }
   4859 
   4860     @Override
   4861     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
   4862             Uri uri, int modeFlags) {
   4863         synchronized(this) {
   4864             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   4865             if (owner == null) {
   4866                 throw new IllegalArgumentException("Unknown owner: " + token);
   4867             }
   4868             if (fromUid != Binder.getCallingUid()) {
   4869                 if (Binder.getCallingUid() != Process.myUid()) {
   4870                     // Only system code can grant URI permissions on behalf
   4871                     // of other users.
   4872                     throw new SecurityException("nice try");
   4873                 }
   4874             }
   4875             if (targetPkg == null) {
   4876                 throw new IllegalArgumentException("null target");
   4877             }
   4878             if (uri == null) {
   4879                 throw new IllegalArgumentException("null uri");
   4880             }
   4881 
   4882             grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
   4883         }
   4884     }
   4885 
   4886     @Override
   4887     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
   4888         synchronized(this) {
   4889             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   4890             if (owner == null) {
   4891                 throw new IllegalArgumentException("Unknown owner: " + token);
   4892             }
   4893 
   4894             if (uri == null) {
   4895                 owner.removeUriPermissionsLocked(mode);
   4896             } else {
   4897                 owner.removeUriPermissionLocked(uri, mode);
   4898             }
   4899         }
   4900     }
   4901 
   4902     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
   4903         synchronized (this) {
   4904             ProcessRecord app =
   4905                 who != null ? getRecordForAppLocked(who) : null;
   4906             if (app == null) return;
   4907 
   4908             Message msg = Message.obtain();
   4909             msg.what = WAIT_FOR_DEBUGGER_MSG;
   4910             msg.obj = app;
   4911             msg.arg1 = waiting ? 1 : 0;
   4912             mHandler.sendMessage(msg);
   4913         }
   4914     }
   4915 
   4916     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
   4917         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
   4918         final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
   4919         outInfo.availMem = Process.getFreeMemory();
   4920         outInfo.threshold = homeAppMem;
   4921         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
   4922         outInfo.hiddenAppThreshold = hiddenAppMem;
   4923         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
   4924                 ProcessList.SECONDARY_SERVER_ADJ);
   4925         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
   4926                 ProcessList.VISIBLE_APP_ADJ);
   4927         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
   4928                 ProcessList.FOREGROUND_APP_ADJ);
   4929     }
   4930 
   4931     // =========================================================
   4932     // TASK MANAGEMENT
   4933     // =========================================================
   4934 
   4935     public List getTasks(int maxNum, int flags,
   4936                          IThumbnailReceiver receiver) {
   4937         ArrayList list = new ArrayList();
   4938 
   4939         PendingThumbnailsRecord pending = null;
   4940         IApplicationThread topThumbnail = null;
   4941         ActivityRecord topRecord = null;
   4942 
   4943         synchronized(this) {
   4944             if (localLOGV) Slog.v(
   4945                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
   4946                 + ", receiver=" + receiver);
   4947 
   4948             if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
   4949                     != PackageManager.PERMISSION_GRANTED) {
   4950                 if (receiver != null) {
   4951                     // If the caller wants to wait for pending thumbnails,
   4952                     // it ain't gonna get them.
   4953                     try {
   4954                         receiver.finished();
   4955                     } catch (RemoteException ex) {
   4956                     }
   4957                 }
   4958                 String msg = "Permission Denial: getTasks() from pid="
   4959                         + Binder.getCallingPid()
   4960                         + ", uid=" + Binder.getCallingUid()
   4961                         + " requires " + android.Manifest.permission.GET_TASKS;
   4962                 Slog.w(TAG, msg);
   4963                 throw new SecurityException(msg);
   4964             }
   4965 
   4966             int pos = mMainStack.mHistory.size()-1;
   4967             ActivityRecord next =
   4968                 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
   4969             ActivityRecord top = null;
   4970             TaskRecord curTask = null;
   4971             int numActivities = 0;
   4972             int numRunning = 0;
   4973             while (pos >= 0 && maxNum > 0) {
   4974                 final ActivityRecord r = next;
   4975                 pos--;
   4976                 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
   4977 
   4978                 // Initialize state for next task if needed.
   4979                 if (top == null ||
   4980                         (top.state == ActivityState.INITIALIZING
   4981                             && top.task == r.task)) {
   4982                     top = r;
   4983                     curTask = r.task;
   4984                     numActivities = numRunning = 0;
   4985                 }
   4986 
   4987                 // Add 'r' into the current task.
   4988                 numActivities++;
   4989                 if (r.app != null && r.app.thread != null) {
   4990                     numRunning++;
   4991                 }
   4992 
   4993                 if (localLOGV) Slog.v(
   4994                     TAG, r.intent.getComponent().flattenToShortString()
   4995                     + ": task=" + r.task);
   4996 
   4997                 // If the next one is a different task, generate a new
   4998                 // TaskInfo entry for what we have.
   4999                 if (next == null || next.task != curTask) {
   5000                     ActivityManager.RunningTaskInfo ci
   5001                             = new ActivityManager.RunningTaskInfo();
   5002                     ci.id = curTask.taskId;
   5003                     ci.baseActivity = r.intent.getComponent();
   5004                     ci.topActivity = top.intent.getComponent();
   5005                     if (top.thumbHolder != null) {
   5006                         ci.description = top.thumbHolder.lastDescription;
   5007                     }
   5008                     ci.numActivities = numActivities;
   5009                     ci.numRunning = numRunning;
   5010                     //System.out.println(
   5011                     //    "#" + maxNum + ": " + " descr=" + ci.description);
   5012                     if (ci.thumbnail == null && receiver != null) {
   5013                         if (localLOGV) Slog.v(
   5014                             TAG, "State=" + top.state + "Idle=" + top.idle
   5015                             + " app=" + top.app
   5016                             + " thr=" + (top.app != null ? top.app.thread : null));
   5017                         if (top.state == ActivityState.RESUMED
   5018                                 || top.state == ActivityState.PAUSING) {
   5019                             if (top.idle && top.app != null
   5020                                 && top.app.thread != null) {
   5021                                 topRecord = top;
   5022                                 topThumbnail = top.app.thread;
   5023                             } else {
   5024                                 top.thumbnailNeeded = true;
   5025                             }
   5026                         }
   5027                         if (pending == null) {
   5028                             pending = new PendingThumbnailsRecord(receiver);
   5029                         }
   5030                         pending.pendingRecords.add(top);
   5031                     }
   5032                     list.add(ci);
   5033                     maxNum--;
   5034                     top = null;
   5035                 }
   5036             }
   5037 
   5038             if (pending != null) {
   5039                 mPendingThumbnails.add(pending);
   5040             }
   5041         }
   5042 
   5043         if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
   5044 
   5045         if (topThumbnail != null) {
   5046             if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
   5047             try {
   5048                 topThumbnail.requestThumbnail(topRecord);
   5049             } catch (Exception e) {
   5050                 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
   5051                 sendPendingThumbnail(null, topRecord, null, null, true);
   5052             }
   5053         }
   5054 
   5055         if (pending == null && receiver != null) {
   5056             // In this case all thumbnails were available and the client
   5057             // is being asked to be told when the remaining ones come in...
   5058             // which is unusually, since the top-most currently running
   5059             // activity should never have a canned thumbnail!  Oh well.
   5060             try {
   5061                 receiver.finished();
   5062             } catch (RemoteException ex) {
   5063             }
   5064         }
   5065 
   5066         return list;
   5067     }
   5068 
   5069     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
   5070             int flags) {
   5071         synchronized (this) {
   5072             enforceCallingPermission(android.Manifest.permission.GET_TASKS,
   5073                     "getRecentTasks()");
   5074 
   5075             IPackageManager pm = AppGlobals.getPackageManager();
   5076 
   5077             final int N = mRecentTasks.size();
   5078             ArrayList<ActivityManager.RecentTaskInfo> res
   5079                     = new ArrayList<ActivityManager.RecentTaskInfo>(
   5080                             maxNum < N ? maxNum : N);
   5081             for (int i=0; i<N && maxNum > 0; i++) {
   5082                 TaskRecord tr = mRecentTasks.get(i);
   5083                 // Return the entry if desired by the caller.  We always return
   5084                 // the first entry, because callers always expect this to be the
   5085                 // forground app.  We may filter others if the caller has
   5086                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
   5087                 // we should exclude the entry.
   5088                 if (i == 0
   5089                         || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
   5090                         || (tr.intent == null)
   5091                         || ((tr.intent.getFlags()
   5092                                 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
   5093                     ActivityManager.RecentTaskInfo rti
   5094                             = new ActivityManager.RecentTaskInfo();
   5095                     rti.id = tr.numActivities > 0 ? tr.taskId : -1;
   5096                     rti.persistentId = tr.taskId;
   5097                     rti.baseIntent = new Intent(
   5098                             tr.intent != null ? tr.intent : tr.affinityIntent);
   5099                     rti.origActivity = tr.origActivity;
   5100                     rti.description = tr.lastDescription;
   5101 
   5102                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
   5103                         // Check whether this activity is currently available.
   5104                         try {
   5105                             if (rti.origActivity != null) {
   5106                                 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
   5107                                     continue;
   5108                                 }
   5109                             } else if (rti.baseIntent != null) {
   5110                                 if (pm.queryIntentActivities(rti.baseIntent,
   5111                                         null, 0) == null) {
   5112                                     continue;
   5113                                 }
   5114                             }
   5115                         } catch (RemoteException e) {
   5116                             // Will never happen.
   5117                         }
   5118                     }
   5119 
   5120                     res.add(rti);
   5121                     maxNum--;
   5122                 }
   5123             }
   5124             return res;
   5125         }
   5126     }
   5127 
   5128     private TaskRecord taskForIdLocked(int id) {
   5129         final int N = mRecentTasks.size();
   5130         for (int i=0; i<N; i++) {
   5131             TaskRecord tr = mRecentTasks.get(i);
   5132             if (tr.taskId == id) {
   5133                 return tr;
   5134             }
   5135         }
   5136         return null;
   5137     }
   5138 
   5139     public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
   5140         synchronized (this) {
   5141             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
   5142                     "getTaskThumbnails()");
   5143             TaskRecord tr = taskForIdLocked(id);
   5144             if (tr != null) {
   5145                 return mMainStack.getTaskThumbnailsLocked(tr);
   5146             }
   5147         }
   5148         return null;
   5149     }
   5150 
   5151     public boolean removeSubTask(int taskId, int subTaskIndex) {
   5152         synchronized (this) {
   5153             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
   5154                     "removeSubTask()");
   5155             long ident = Binder.clearCallingIdentity();
   5156             try {
   5157                 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
   5158             } finally {
   5159                 Binder.restoreCallingIdentity(ident);
   5160             }
   5161         }
   5162     }
   5163 
   5164     private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
   5165         TaskRecord tr = root.task;
   5166         Intent baseIntent = new Intent(
   5167                 tr.intent != null ? tr.intent : tr.affinityIntent);
   5168         ComponentName component = baseIntent.getComponent();
   5169         if (component == null) {
   5170             Slog.w(TAG, "Now component for base intent of task: " + tr);
   5171             return;
   5172         }
   5173 
   5174         // Find any running services associated with this app.
   5175         ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
   5176         for (ServiceRecord sr : mServices.values()) {
   5177             if (sr.packageName.equals(component.getPackageName())) {
   5178                 services.add(sr);
   5179             }
   5180         }
   5181 
   5182         // Take care of any running services associated with the app.
   5183         for (int i=0; i<services.size(); i++) {
   5184             ServiceRecord sr = services.get(i);
   5185             if (sr.startRequested) {
   5186                 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
   5187                     Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
   5188                     stopServiceLocked(sr);
   5189                 } else {
   5190                     sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
   5191                             sr.makeNextStartId(), baseIntent, -1));
   5192                     if (sr.app != null && sr.app.thread != null) {
   5193                         sendServiceArgsLocked(sr, false);
   5194                     }
   5195                 }
   5196             }
   5197         }
   5198 
   5199         if (killProcesses) {
   5200             // Find any running processes associated with this app.
   5201             ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   5202             SparseArray<ProcessRecord> appProcs
   5203                     = mProcessNames.getMap().get(component.getPackageName());
   5204             if (appProcs != null) {
   5205                 for (int i=0; i<appProcs.size(); i++) {
   5206                     procs.add(appProcs.valueAt(i));
   5207                 }
   5208             }
   5209 
   5210             // Kill the running processes.
   5211             for (int i=0; i<procs.size(); i++) {
   5212                 ProcessRecord pr = procs.get(i);
   5213                 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
   5214                     Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
   5215                     EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
   5216                             pr.processName, pr.setAdj, "remove task");
   5217                     Process.killProcessQuiet(pr.pid);
   5218                 } else {
   5219                     pr.waitingToKill = "remove task";
   5220                 }
   5221             }
   5222         }
   5223     }
   5224 
   5225     public boolean removeTask(int taskId, int flags) {
   5226         synchronized (this) {
   5227             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
   5228                     "removeTask()");
   5229             long ident = Binder.clearCallingIdentity();
   5230             try {
   5231                 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
   5232                 if (r != null) {
   5233                     mRecentTasks.remove(r.task);
   5234                     cleanUpRemovedTaskLocked(r,
   5235                             (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
   5236                     return true;
   5237                 } else {
   5238                     TaskRecord tr = null;
   5239                     int i=0;
   5240                     while (i < mRecentTasks.size()) {
   5241                         TaskRecord t = mRecentTasks.get(i);
   5242                         if (t.taskId == taskId) {
   5243                             tr = t;
   5244                             break;
   5245                         }
   5246                         i++;
   5247                     }
   5248                     if (tr != null) {
   5249                         if (tr.numActivities <= 0) {
   5250                             // Caller is just removing a recent task that is
   5251                             // not actively running.  That is easy!
   5252                             mRecentTasks.remove(i);
   5253                         } else {
   5254                             Slog.w(TAG, "removeTask: task " + taskId
   5255                                     + " does not have activities to remove, "
   5256                                     + " but numActivities=" + tr.numActivities
   5257                                     + ": " + tr);
   5258                         }
   5259                     }
   5260                 }
   5261             } finally {
   5262                 Binder.restoreCallingIdentity(ident);
   5263             }
   5264         }
   5265         return false;
   5266     }
   5267 
   5268     private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
   5269         int j;
   5270         TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
   5271         TaskRecord jt = startTask;
   5272 
   5273         // First look backwards
   5274         for (j=startIndex-1; j>=0; j--) {
   5275             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
   5276             if (r.task != jt) {
   5277                 jt = r.task;
   5278                 if (affinity.equals(jt.affinity)) {
   5279                     return j;
   5280                 }
   5281             }
   5282         }
   5283 
   5284         // Now look forwards
   5285         final int N = mMainStack.mHistory.size();
   5286         jt = startTask;
   5287         for (j=startIndex+1; j<N; j++) {
   5288             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
   5289             if (r.task != jt) {
   5290                 if (affinity.equals(jt.affinity)) {
   5291                     return j;
   5292                 }
   5293                 jt = r.task;
   5294             }
   5295         }
   5296 
   5297         // Might it be at the top?
   5298         if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
   5299             return N-1;
   5300         }
   5301 
   5302         return -1;
   5303     }
   5304 
   5305     /**
   5306      * TODO: Add mController hook
   5307      */
   5308     public void moveTaskToFront(int task, int flags) {
   5309         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   5310                 "moveTaskToFront()");
   5311 
   5312         synchronized(this) {
   5313             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   5314                     Binder.getCallingUid(), "Task to front")) {
   5315                 return;
   5316             }
   5317             final long origId = Binder.clearCallingIdentity();
   5318             try {
   5319                 TaskRecord tr = taskForIdLocked(task);
   5320                 if (tr != null) {
   5321                     if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
   5322                         mMainStack.mUserLeaving = true;
   5323                     }
   5324                     if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
   5325                         // Caller wants the home activity moved with it.  To accomplish this,
   5326                         // we'll just move the home task to the top first.
   5327                         mMainStack.moveHomeToFrontLocked();
   5328                     }
   5329                     mMainStack.moveTaskToFrontLocked(tr, null);
   5330                     return;
   5331                 }
   5332                 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
   5333                     ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
   5334                     if (hr.task.taskId == task) {
   5335                         if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
   5336                             mMainStack.mUserLeaving = true;
   5337                         }
   5338                         if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
   5339                             // Caller wants the home activity moved with it.  To accomplish this,
   5340                             // we'll just move the home task to the top first.
   5341                             mMainStack.moveHomeToFrontLocked();
   5342                         }
   5343                         mMainStack.moveTaskToFrontLocked(hr.task, null);
   5344                         return;
   5345                     }
   5346                 }
   5347             } finally {
   5348                 Binder.restoreCallingIdentity(origId);
   5349             }
   5350         }
   5351     }
   5352 
   5353     public void moveTaskToBack(int task) {
   5354         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   5355                 "moveTaskToBack()");
   5356 
   5357         synchronized(this) {
   5358             if (mMainStack.mResumedActivity != null
   5359                     && mMainStack.mResumedActivity.task.taskId == task) {
   5360                 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   5361                         Binder.getCallingUid(), "Task to back")) {
   5362                     return;
   5363                 }
   5364             }
   5365             final long origId = Binder.clearCallingIdentity();
   5366             mMainStack.moveTaskToBackLocked(task, null);
   5367             Binder.restoreCallingIdentity(origId);
   5368         }
   5369     }
   5370 
   5371     /**
   5372      * Moves an activity, and all of the other activities within the same task, to the bottom
   5373      * of the history stack.  The activity's order within the task is unchanged.
   5374      *
   5375      * @param token A reference to the activity we wish to move
   5376      * @param nonRoot If false then this only works if the activity is the root
   5377      *                of a task; if true it will work for any activity in a task.
   5378      * @return Returns true if the move completed, false if not.
   5379      */
   5380     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
   5381         synchronized(this) {
   5382             final long origId = Binder.clearCallingIdentity();
   5383             int taskId = getTaskForActivityLocked(token, !nonRoot);
   5384             if (taskId >= 0) {
   5385                 return mMainStack.moveTaskToBackLocked(taskId, null);
   5386             }
   5387             Binder.restoreCallingIdentity(origId);
   5388         }
   5389         return false;
   5390     }
   5391 
   5392     public void moveTaskBackwards(int task) {
   5393         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   5394                 "moveTaskBackwards()");
   5395 
   5396         synchronized(this) {
   5397             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   5398                     Binder.getCallingUid(), "Task backwards")) {
   5399                 return;
   5400             }
   5401             final long origId = Binder.clearCallingIdentity();
   5402             moveTaskBackwardsLocked(task);
   5403             Binder.restoreCallingIdentity(origId);
   5404         }
   5405     }
   5406 
   5407     private final void moveTaskBackwardsLocked(int task) {
   5408         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
   5409     }
   5410 
   5411     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
   5412         synchronized(this) {
   5413             return getTaskForActivityLocked(token, onlyRoot);
   5414         }
   5415     }
   5416 
   5417     int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
   5418         final int N = mMainStack.mHistory.size();
   5419         TaskRecord lastTask = null;
   5420         for (int i=0; i<N; i++) {
   5421             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   5422             if (r == token) {
   5423                 if (!onlyRoot || lastTask != r.task) {
   5424                     return r.task.taskId;
   5425                 }
   5426                 return -1;
   5427             }
   5428             lastTask = r.task;
   5429         }
   5430 
   5431         return -1;
   5432     }
   5433 
   5434     public void finishOtherInstances(IBinder token, ComponentName className) {
   5435         synchronized(this) {
   5436             final long origId = Binder.clearCallingIdentity();
   5437 
   5438             int N = mMainStack.mHistory.size();
   5439             TaskRecord lastTask = null;
   5440             for (int i=0; i<N; i++) {
   5441                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   5442                 if (r.realActivity.equals(className)
   5443                         && r != token && lastTask != r.task) {
   5444                     if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
   5445                             null, "others")) {
   5446                         i--;
   5447                         N--;
   5448                     }
   5449                 }
   5450                 lastTask = r.task;
   5451             }
   5452 
   5453             Binder.restoreCallingIdentity(origId);
   5454         }
   5455     }
   5456 
   5457     // =========================================================
   5458     // THUMBNAILS
   5459     // =========================================================
   5460 
   5461     public void reportThumbnail(IBinder token,
   5462             Bitmap thumbnail, CharSequence description) {
   5463         //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
   5464         final long origId = Binder.clearCallingIdentity();
   5465         sendPendingThumbnail(null, token, thumbnail, description, true);
   5466         Binder.restoreCallingIdentity(origId);
   5467     }
   5468 
   5469     final void sendPendingThumbnail(ActivityRecord r, IBinder token,
   5470             Bitmap thumbnail, CharSequence description, boolean always) {
   5471         TaskRecord task = null;
   5472         ArrayList receivers = null;
   5473 
   5474         //System.out.println("Send pending thumbnail: " + r);
   5475 
   5476         synchronized(this) {
   5477             if (r == null) {
   5478                 r = mMainStack.isInStackLocked(token);
   5479                 if (r == null) {
   5480                     return;
   5481                 }
   5482             }
   5483             if (thumbnail == null && r.thumbHolder != null) {
   5484                 thumbnail = r.thumbHolder.lastThumbnail;
   5485                 description = r.thumbHolder.lastDescription;
   5486             }
   5487             if (thumbnail == null && !always) {
   5488                 // If there is no thumbnail, and this entry is not actually
   5489                 // going away, then abort for now and pick up the next
   5490                 // thumbnail we get.
   5491                 return;
   5492             }
   5493             task = r.task;
   5494 
   5495             int N = mPendingThumbnails.size();
   5496             int i=0;
   5497             while (i<N) {
   5498                 PendingThumbnailsRecord pr =
   5499                     (PendingThumbnailsRecord)mPendingThumbnails.get(i);
   5500                 //System.out.println("Looking in " + pr.pendingRecords);
   5501                 if (pr.pendingRecords.remove(r)) {
   5502                     if (receivers == null) {
   5503                         receivers = new ArrayList();
   5504                     }
   5505                     receivers.add(pr);
   5506                     if (pr.pendingRecords.size() == 0) {
   5507                         pr.finished = true;
   5508                         mPendingThumbnails.remove(i);
   5509                         N--;
   5510                         continue;
   5511                     }
   5512                 }
   5513                 i++;
   5514             }
   5515         }
   5516 
   5517         if (receivers != null) {
   5518             final int N = receivers.size();
   5519             for (int i=0; i<N; i++) {
   5520                 try {
   5521                     PendingThumbnailsRecord pr =
   5522                         (PendingThumbnailsRecord)receivers.get(i);
   5523                     pr.receiver.newThumbnail(
   5524                         task != null ? task.taskId : -1, thumbnail, description);
   5525                     if (pr.finished) {
   5526                         pr.receiver.finished();
   5527                     }
   5528                 } catch (Exception e) {
   5529                     Slog.w(TAG, "Exception thrown when sending thumbnail", e);
   5530                 }
   5531             }
   5532         }
   5533     }
   5534 
   5535     // =========================================================
   5536     // CONTENT PROVIDERS
   5537     // =========================================================
   5538 
   5539     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
   5540         List<ProviderInfo> providers = null;
   5541         try {
   5542             providers = AppGlobals.getPackageManager().
   5543                 queryContentProviders(app.processName, app.info.uid,
   5544                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
   5545         } catch (RemoteException ex) {
   5546         }
   5547         if (providers != null) {
   5548             final int N = providers.size();
   5549             for (int i=0; i<N; i++) {
   5550                 ProviderInfo cpi =
   5551                     (ProviderInfo)providers.get(i);
   5552                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   5553                 ContentProviderRecord cpr = mProvidersByClass.get(comp);
   5554                 if (cpr == null) {
   5555                     cpr = new ContentProviderRecord(cpi, app.info, comp);
   5556                     mProvidersByClass.put(comp, cpr);
   5557                 }
   5558                 app.pubProviders.put(cpi.name, cpr);
   5559                 app.addPackage(cpi.applicationInfo.packageName);
   5560                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
   5561             }
   5562         }
   5563         return providers;
   5564     }
   5565 
   5566     private final String checkContentProviderPermissionLocked(
   5567             ProviderInfo cpi, ProcessRecord r) {
   5568         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
   5569         final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
   5570         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
   5571                 cpi.applicationInfo.uid, cpi.exported)
   5572                 == PackageManager.PERMISSION_GRANTED) {
   5573             return null;
   5574         }
   5575         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
   5576                 cpi.applicationInfo.uid, cpi.exported)
   5577                 == PackageManager.PERMISSION_GRANTED) {
   5578             return null;
   5579         }
   5580 
   5581         PathPermission[] pps = cpi.pathPermissions;
   5582         if (pps != null) {
   5583             int i = pps.length;
   5584             while (i > 0) {
   5585                 i--;
   5586                 PathPermission pp = pps[i];
   5587                 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
   5588                         cpi.applicationInfo.uid, cpi.exported)
   5589                         == PackageManager.PERMISSION_GRANTED) {
   5590                     return null;
   5591                 }
   5592                 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
   5593                         cpi.applicationInfo.uid, cpi.exported)
   5594                         == PackageManager.PERMISSION_GRANTED) {
   5595                     return null;
   5596                 }
   5597             }
   5598         }
   5599 
   5600         HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   5601         if (perms != null) {
   5602             for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
   5603                 if (uri.getKey().getAuthority().equals(cpi.authority)) {
   5604                     return null;
   5605                 }
   5606             }
   5607         }
   5608 
   5609         String msg;
   5610         if (!cpi.exported) {
   5611             msg = "Permission Denial: opening provider " + cpi.name
   5612                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   5613                     + ", uid=" + callingUid + ") that is not exported from uid "
   5614                     + cpi.applicationInfo.uid;
   5615         } else {
   5616             msg = "Permission Denial: opening provider " + cpi.name
   5617                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   5618                     + ", uid=" + callingUid + ") requires "
   5619                     + cpi.readPermission + " or " + cpi.writePermission;
   5620         }
   5621         Slog.w(TAG, msg);
   5622         return msg;
   5623     }
   5624 
   5625     boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
   5626         if (r != null) {
   5627             Integer cnt = r.conProviders.get(cpr);
   5628             if (DEBUG_PROVIDER) Slog.v(TAG,
   5629                     "Adding provider requested by "
   5630                     + r.processName + " from process "
   5631                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   5632                     + " cnt=" + (cnt == null ? 1 : cnt));
   5633             if (cnt == null) {
   5634                 cpr.clients.add(r);
   5635                 r.conProviders.put(cpr, new Integer(1));
   5636                 return true;
   5637             } else {
   5638                 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
   5639             }
   5640         } else {
   5641             cpr.externals++;
   5642         }
   5643         return false;
   5644     }
   5645 
   5646     boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
   5647         if (r != null) {
   5648             Integer cnt = r.conProviders.get(cpr);
   5649             if (DEBUG_PROVIDER) Slog.v(TAG,
   5650                     "Removing provider requested by "
   5651                     + r.processName + " from process "
   5652                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   5653                     + " cnt=" + cnt);
   5654             if (cnt == null || cnt.intValue() <= 1) {
   5655                 cpr.clients.remove(r);
   5656                 r.conProviders.remove(cpr);
   5657                 return true;
   5658             } else {
   5659                 r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
   5660             }
   5661         } else {
   5662             cpr.externals++;
   5663         }
   5664         return false;
   5665     }
   5666 
   5667     private final ContentProviderHolder getContentProviderImpl(
   5668         IApplicationThread caller, String name) {
   5669         ContentProviderRecord cpr;
   5670         ProviderInfo cpi = null;
   5671 
   5672         synchronized(this) {
   5673             ProcessRecord r = null;
   5674             if (caller != null) {
   5675                 r = getRecordForAppLocked(caller);
   5676                 if (r == null) {
   5677                     throw new SecurityException(
   5678                             "Unable to find app for caller " + caller
   5679                           + " (pid=" + Binder.getCallingPid()
   5680                           + ") when getting content provider " + name);
   5681                 }
   5682             }
   5683 
   5684             // First check if this content provider has been published...
   5685             cpr = mProvidersByName.get(name);
   5686             boolean providerRunning = cpr != null;
   5687             if (providerRunning) {
   5688                 cpi = cpr.info;
   5689                 String msg;
   5690                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
   5691                     throw new SecurityException(msg);
   5692                 }
   5693 
   5694                 if (r != null && cpr.canRunHere(r)) {
   5695                     // This provider has been published or is in the process
   5696                     // of being published...  but it is also allowed to run
   5697                     // in the caller's process, so don't make a connection
   5698                     // and just let the caller instantiate its own instance.
   5699                     if (cpr.provider != null) {
   5700                         // don't give caller the provider object, it needs
   5701                         // to make its own.
   5702                         cpr = new ContentProviderRecord(cpr);
   5703                     }
   5704                     return cpr;
   5705                 }
   5706 
   5707                 final long origId = Binder.clearCallingIdentity();
   5708 
   5709                 // In this case the provider instance already exists, so we can
   5710                 // return it right away.
   5711                 final boolean countChanged = incProviderCount(r, cpr);
   5712                 if (countChanged) {
   5713                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   5714                         // If this is a perceptible app accessing the provider,
   5715                         // make sure to count it as being accessed and thus
   5716                         // back up on the LRU list.  This is good because
   5717                         // content providers are often expensive to start.
   5718                         updateLruProcessLocked(cpr.proc, false, true);
   5719                     }
   5720                 }
   5721 
   5722                 if (cpr.proc != null) {
   5723                     if (false) {
   5724                         if (cpr.name.flattenToShortString().equals(
   5725                                 "com.android.providers.calendar/.CalendarProvider2")) {
   5726                             Slog.v(TAG, "****************** KILLING "
   5727                                 + cpr.name.flattenToShortString());
   5728                             Process.killProcess(cpr.proc.pid);
   5729                         }
   5730                     }
   5731                     boolean success = updateOomAdjLocked(cpr.proc);
   5732                     if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
   5733                     // NOTE: there is still a race here where a signal could be
   5734                     // pending on the process even though we managed to update its
   5735                     // adj level.  Not sure what to do about this, but at least
   5736                     // the race is now smaller.
   5737                     if (!success) {
   5738                         // Uh oh...  it looks like the provider's process
   5739                         // has been killed on us.  We need to wait for a new
   5740                         // process to be started, and make sure its death
   5741                         // doesn't kill our process.
   5742                         Slog.i(TAG,
   5743                                 "Existing provider " + cpr.name.flattenToShortString()
   5744                                 + " is crashing; detaching " + r);
   5745                         boolean lastRef = decProviderCount(r, cpr);
   5746                         appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
   5747                         if (!lastRef) {
   5748                             // This wasn't the last ref our process had on
   5749                             // the provider...  we have now been killed, bail.
   5750                             return null;
   5751                         }
   5752                         providerRunning = false;
   5753                     }
   5754                 }
   5755 
   5756                 Binder.restoreCallingIdentity(origId);
   5757             }
   5758 
   5759             if (!providerRunning) {
   5760                 try {
   5761                     cpi = AppGlobals.getPackageManager().
   5762                         resolveContentProvider(name,
   5763                                 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
   5764                 } catch (RemoteException ex) {
   5765                 }
   5766                 if (cpi == null) {
   5767                     return null;
   5768                 }
   5769 
   5770                 String msg;
   5771                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
   5772                     throw new SecurityException(msg);
   5773                 }
   5774 
   5775                 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
   5776                         && !cpi.processName.equals("system")) {
   5777                     // If this content provider does not run in the system
   5778                     // process, and the system is not yet ready to run other
   5779                     // processes, then fail fast instead of hanging.
   5780                     throw new IllegalArgumentException(
   5781                             "Attempt to launch content provider before system ready");
   5782                 }
   5783 
   5784                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   5785                 cpr = mProvidersByClass.get(comp);
   5786                 final boolean firstClass = cpr == null;
   5787                 if (firstClass) {
   5788                     try {
   5789                         ApplicationInfo ai =
   5790                             AppGlobals.getPackageManager().
   5791                                 getApplicationInfo(
   5792                                         cpi.applicationInfo.packageName,
   5793                                         STOCK_PM_FLAGS);
   5794                         if (ai == null) {
   5795                             Slog.w(TAG, "No package info for content provider "
   5796                                     + cpi.name);
   5797                             return null;
   5798                         }
   5799                         cpr = new ContentProviderRecord(cpi, ai, comp);
   5800                     } catch (RemoteException ex) {
   5801                         // pm is in same process, this will never happen.
   5802                     }
   5803                 }
   5804 
   5805                 if (r != null && cpr.canRunHere(r)) {
   5806                     // If this is a multiprocess provider, then just return its
   5807                     // info and allow the caller to instantiate it.  Only do
   5808                     // this if the provider is the same user as the caller's
   5809                     // process, or can run as root (so can be in any process).
   5810                     return cpr;
   5811                 }
   5812 
   5813                 if (DEBUG_PROVIDER) {
   5814                     RuntimeException e = new RuntimeException("here");
   5815                     Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
   5816                           + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
   5817                 }
   5818 
   5819                 // This is single process, and our app is now connecting to it.
   5820                 // See if we are already in the process of launching this
   5821                 // provider.
   5822                 final int N = mLaunchingProviders.size();
   5823                 int i;
   5824                 for (i=0; i<N; i++) {
   5825                     if (mLaunchingProviders.get(i) == cpr) {
   5826                         break;
   5827                     }
   5828                 }
   5829 
   5830                 // If the provider is not already being launched, then get it
   5831                 // started.
   5832                 if (i >= N) {
   5833                     final long origId = Binder.clearCallingIdentity();
   5834 
   5835                     try {
   5836                         // Content provider is now in use, its package can't be stopped.
   5837                         try {
   5838                             AppGlobals.getPackageManager().setPackageStoppedState(
   5839                                     cpr.appInfo.packageName, false);
   5840                         } catch (RemoteException e) {
   5841                         } catch (IllegalArgumentException e) {
   5842                             Slog.w(TAG, "Failed trying to unstop package "
   5843                                     + cpr.appInfo.packageName + ": " + e);
   5844                         }
   5845 
   5846                         ProcessRecord proc = startProcessLocked(cpi.processName,
   5847                                 cpr.appInfo, false, 0, "content provider",
   5848                                 new ComponentName(cpi.applicationInfo.packageName,
   5849                                         cpi.name), false);
   5850                         if (proc == null) {
   5851                             Slog.w(TAG, "Unable to launch app "
   5852                                     + cpi.applicationInfo.packageName + "/"
   5853                                     + cpi.applicationInfo.uid + " for provider "
   5854                                     + name + ": process is bad");
   5855                             return null;
   5856                         }
   5857                         cpr.launchingApp = proc;
   5858                         mLaunchingProviders.add(cpr);
   5859                     } finally {
   5860                         Binder.restoreCallingIdentity(origId);
   5861                     }
   5862                 }
   5863 
   5864                 // Make sure the provider is published (the same provider class
   5865                 // may be published under multiple names).
   5866                 if (firstClass) {
   5867                     mProvidersByClass.put(comp, cpr);
   5868                 }
   5869                 mProvidersByName.put(name, cpr);
   5870                 incProviderCount(r, cpr);
   5871             }
   5872         }
   5873 
   5874         // Wait for the provider to be published...
   5875         synchronized (cpr) {
   5876             while (cpr.provider == null) {
   5877                 if (cpr.launchingApp == null) {
   5878                     Slog.w(TAG, "Unable to launch app "
   5879                             + cpi.applicationInfo.packageName + "/"
   5880                             + cpi.applicationInfo.uid + " for provider "
   5881                             + name + ": launching app became null");
   5882                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
   5883                             cpi.applicationInfo.packageName,
   5884                             cpi.applicationInfo.uid, name);
   5885                     return null;
   5886                 }
   5887                 try {
   5888                     cpr.wait();
   5889                 } catch (InterruptedException ex) {
   5890                 }
   5891             }
   5892         }
   5893         return cpr;
   5894     }
   5895 
   5896     public final ContentProviderHolder getContentProvider(
   5897             IApplicationThread caller, String name) {
   5898         if (caller == null) {
   5899             String msg = "null IApplicationThread when getting content provider "
   5900                     + name;
   5901             Slog.w(TAG, msg);
   5902             throw new SecurityException(msg);
   5903         }
   5904 
   5905         return getContentProviderImpl(caller, name);
   5906     }
   5907 
   5908     private ContentProviderHolder getContentProviderExternal(String name) {
   5909         return getContentProviderImpl(null, name);
   5910     }
   5911 
   5912     /**
   5913      * Drop a content provider from a ProcessRecord's bookkeeping
   5914      * @param cpr
   5915      */
   5916     public void removeContentProvider(IApplicationThread caller, String name) {
   5917         synchronized (this) {
   5918             ContentProviderRecord cpr = mProvidersByName.get(name);
   5919             if(cpr == null) {
   5920                 // remove from mProvidersByClass
   5921                 if (DEBUG_PROVIDER) Slog.v(TAG, name +
   5922                         " provider not found in providers list");
   5923                 return;
   5924             }
   5925             final ProcessRecord r = getRecordForAppLocked(caller);
   5926             if (r == null) {
   5927                 throw new SecurityException(
   5928                         "Unable to find app for caller " + caller +
   5929                         " when removing content provider " + name);
   5930             }
   5931             //update content provider record entry info
   5932             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
   5933             ContentProviderRecord localCpr = mProvidersByClass.get(comp);
   5934             if (localCpr.proc == r) {
   5935                 //should not happen. taken care of as a local provider
   5936                 Slog.w(TAG, "removeContentProvider called on local provider: "
   5937                         + cpr.info.name + " in process " + r.processName);
   5938                 return;
   5939             } else {
   5940                 if (decProviderCount(r, localCpr)) {
   5941                     updateOomAdjLocked();
   5942                 }
   5943             }
   5944         }
   5945     }
   5946 
   5947     private void removeContentProviderExternal(String name) {
   5948         synchronized (this) {
   5949             ContentProviderRecord cpr = mProvidersByName.get(name);
   5950             if(cpr == null) {
   5951                 //remove from mProvidersByClass
   5952                 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
   5953                 return;
   5954             }
   5955 
   5956             //update content provider record entry info
   5957             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
   5958             ContentProviderRecord localCpr = mProvidersByClass.get(comp);
   5959             localCpr.externals--;
   5960             if (localCpr.externals < 0) {
   5961                 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
   5962             }
   5963             updateOomAdjLocked();
   5964         }
   5965     }
   5966 
   5967     public final void publishContentProviders(IApplicationThread caller,
   5968             List<ContentProviderHolder> providers) {
   5969         if (providers == null) {
   5970             return;
   5971         }
   5972 
   5973         synchronized(this) {
   5974             final ProcessRecord r = getRecordForAppLocked(caller);
   5975             if (r == null) {
   5976                 throw new SecurityException(
   5977                         "Unable to find app for caller " + caller
   5978                       + " (pid=" + Binder.getCallingPid()
   5979                       + ") when publishing content providers");
   5980             }
   5981 
   5982             final long origId = Binder.clearCallingIdentity();
   5983 
   5984             final int N = providers.size();
   5985             for (int i=0; i<N; i++) {
   5986                 ContentProviderHolder src = providers.get(i);
   5987                 if (src == null || src.info == null || src.provider == null) {
   5988                     continue;
   5989                 }
   5990                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
   5991                 if (dst != null) {
   5992                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
   5993                     mProvidersByClass.put(comp, dst);
   5994                     String names[] = dst.info.authority.split(";");
   5995                     for (int j = 0; j < names.length; j++) {
   5996                         mProvidersByName.put(names[j], dst);
   5997                     }
   5998 
   5999                     int NL = mLaunchingProviders.size();
   6000                     int j;
   6001                     for (j=0; j<NL; j++) {
   6002                         if (mLaunchingProviders.get(j) == dst) {
   6003                             mLaunchingProviders.remove(j);
   6004                             j--;
   6005                             NL--;
   6006                         }
   6007                     }
   6008                     synchronized (dst) {
   6009                         dst.provider = src.provider;
   6010                         dst.proc = r;
   6011                         dst.notifyAll();
   6012                     }
   6013                     updateOomAdjLocked(r);
   6014                 }
   6015             }
   6016 
   6017             Binder.restoreCallingIdentity(origId);
   6018         }
   6019     }
   6020 
   6021     public static final void installSystemProviders() {
   6022         List<ProviderInfo> providers;
   6023         synchronized (mSelf) {
   6024             ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
   6025             providers = mSelf.generateApplicationProvidersLocked(app);
   6026             if (providers != null) {
   6027                 for (int i=providers.size()-1; i>=0; i--) {
   6028                     ProviderInfo pi = (ProviderInfo)providers.get(i);
   6029                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   6030                         Slog.w(TAG, "Not installing system proc provider " + pi.name
   6031                                 + ": not system .apk");
   6032                         providers.remove(i);
   6033                     }
   6034                 }
   6035             }
   6036         }
   6037         if (providers != null) {
   6038             mSystemThread.installSystemProviders(providers);
   6039         }
   6040 
   6041         mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
   6042 
   6043         mSelf.mUsageStatsService.monitorPackages();
   6044     }
   6045 
   6046     /**
   6047      * Allows app to retrieve the MIME type of a URI without having permission
   6048      * to access its content provider.
   6049      *
   6050      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
   6051      *
   6052      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
   6053      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
   6054      */
   6055     public String getProviderMimeType(Uri uri) {
   6056         final String name = uri.getAuthority();
   6057         final long ident = Binder.clearCallingIdentity();
   6058         ContentProviderHolder holder = null;
   6059 
   6060         try {
   6061             holder = getContentProviderExternal(name);
   6062             if (holder != null) {
   6063                 return holder.provider.getType(uri);
   6064             }
   6065         } catch (RemoteException e) {
   6066             Log.w(TAG, "Content provider dead retrieving " + uri, e);
   6067             return null;
   6068         } finally {
   6069             if (holder != null) {
   6070                 removeContentProviderExternal(name);
   6071             }
   6072             Binder.restoreCallingIdentity(ident);
   6073         }
   6074 
   6075         return null;
   6076     }
   6077 
   6078     // =========================================================
   6079     // GLOBAL MANAGEMENT
   6080     // =========================================================
   6081 
   6082     final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
   6083             ApplicationInfo info, String customProcess) {
   6084         String proc = customProcess != null ? customProcess : info.processName;
   6085         BatteryStatsImpl.Uid.Proc ps = null;
   6086         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   6087         synchronized (stats) {
   6088             ps = stats.getProcessStatsLocked(info.uid, proc);
   6089         }
   6090         return new ProcessRecord(ps, thread, info, proc);
   6091     }
   6092 
   6093     final ProcessRecord addAppLocked(ApplicationInfo info) {
   6094         ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
   6095 
   6096         if (app == null) {
   6097             app = newProcessRecordLocked(null, info, null);
   6098             mProcessNames.put(info.processName, info.uid, app);
   6099             updateLruProcessLocked(app, true, true);
   6100         }
   6101 
   6102         // This package really, really can not be stopped.
   6103         try {
   6104             AppGlobals.getPackageManager().setPackageStoppedState(
   6105                     info.packageName, false);
   6106         } catch (RemoteException e) {
   6107         } catch (IllegalArgumentException e) {
   6108             Slog.w(TAG, "Failed trying to unstop package "
   6109                     + info.packageName + ": " + e);
   6110         }
   6111 
   6112         if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
   6113                 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
   6114             app.persistent = true;
   6115             app.maxAdj = ProcessList.CORE_SERVER_ADJ;
   6116         }
   6117         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
   6118             mPersistentStartingProcesses.add(app);
   6119             startProcessLocked(app, "added application", app.processName);
   6120         }
   6121 
   6122         return app;
   6123     }
   6124 
   6125     public void unhandledBack() {
   6126         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
   6127                 "unhandledBack()");
   6128 
   6129         synchronized(this) {
   6130             int count = mMainStack.mHistory.size();
   6131             if (DEBUG_SWITCH) Slog.d(
   6132                 TAG, "Performing unhandledBack(): stack size = " + count);
   6133             if (count > 1) {
   6134                 final long origId = Binder.clearCallingIdentity();
   6135                 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
   6136                         count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
   6137                 Binder.restoreCallingIdentity(origId);
   6138             }
   6139         }
   6140     }
   6141 
   6142     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
   6143         String name = uri.getAuthority();
   6144         ContentProviderHolder cph = getContentProviderExternal(name);
   6145         ParcelFileDescriptor pfd = null;
   6146         if (cph != null) {
   6147             // We record the binder invoker's uid in thread-local storage before
   6148             // going to the content provider to open the file.  Later, in the code
   6149             // that handles all permissions checks, we look for this uid and use
   6150             // that rather than the Activity Manager's own uid.  The effect is that
   6151             // we do the check against the caller's permissions even though it looks
   6152             // to the content provider like the Activity Manager itself is making
   6153             // the request.
   6154             sCallerIdentity.set(new Identity(
   6155                     Binder.getCallingPid(), Binder.getCallingUid()));
   6156             try {
   6157                 pfd = cph.provider.openFile(uri, "r");
   6158             } catch (FileNotFoundException e) {
   6159                 // do nothing; pfd will be returned null
   6160             } finally {
   6161                 // Ensure that whatever happens, we clean up the identity state
   6162                 sCallerIdentity.remove();
   6163             }
   6164 
   6165             // We've got the fd now, so we're done with the provider.
   6166             removeContentProviderExternal(name);
   6167         } else {
   6168             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
   6169         }
   6170         return pfd;
   6171     }
   6172 
   6173     // Actually is sleeping or shutting down or whatever else in the future
   6174     // is an inactive state.
   6175     public boolean isSleeping() {
   6176         return mSleeping || mShuttingDown;
   6177     }
   6178 
   6179     public void goingToSleep() {
   6180         synchronized(this) {
   6181             mSleeping = true;
   6182             mWindowManager.setEventDispatching(false);
   6183 
   6184             mMainStack.stopIfSleepingLocked();
   6185 
   6186             // Initialize the wake times of all processes.
   6187             checkExcessivePowerUsageLocked(false);
   6188             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   6189             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   6190             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   6191         }
   6192     }
   6193 
   6194     public boolean shutdown(int timeout) {
   6195         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
   6196                 != PackageManager.PERMISSION_GRANTED) {
   6197             throw new SecurityException("Requires permission "
   6198                     + android.Manifest.permission.SHUTDOWN);
   6199         }
   6200 
   6201         boolean timedout = false;
   6202 
   6203         synchronized(this) {
   6204             mShuttingDown = true;
   6205             mWindowManager.setEventDispatching(false);
   6206 
   6207             if (mMainStack.mResumedActivity != null) {
   6208                 mMainStack.stopIfSleepingLocked();
   6209                 final long endTime = System.currentTimeMillis() + timeout;
   6210                 while (mMainStack.mResumedActivity != null
   6211                         || mMainStack.mPausingActivity != null) {
   6212                     long delay = endTime - System.currentTimeMillis();
   6213                     if (delay <= 0) {
   6214                         Slog.w(TAG, "Activity manager shutdown timed out");
   6215                         timedout = true;
   6216                         break;
   6217                     }
   6218                     try {
   6219                         this.wait();
   6220                     } catch (InterruptedException e) {
   6221                     }
   6222                 }
   6223             }
   6224         }
   6225 
   6226         mUsageStatsService.shutdown();
   6227         mBatteryStatsService.shutdown();
   6228 
   6229         return timedout;
   6230     }
   6231 
   6232     public final void activitySlept(IBinder token) {
   6233         if (localLOGV) Slog.v(
   6234             TAG, "Activity slept: token=" + token);
   6235 
   6236         ActivityRecord r = null;
   6237 
   6238         final long origId = Binder.clearCallingIdentity();
   6239 
   6240         synchronized (this) {
   6241             r = mMainStack.isInStackLocked(token);
   6242             if (r != null) {
   6243                 mMainStack.activitySleptLocked(r);
   6244             }
   6245         }
   6246 
   6247         Binder.restoreCallingIdentity(origId);
   6248     }
   6249 
   6250     public void wakingUp() {
   6251         synchronized(this) {
   6252             mWindowManager.setEventDispatching(true);
   6253             mSleeping = false;
   6254             mMainStack.awakeFromSleepingLocked();
   6255             mMainStack.resumeTopActivityLocked(null);
   6256         }
   6257     }
   6258 
   6259     public void stopAppSwitches() {
   6260         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   6261                 != PackageManager.PERMISSION_GRANTED) {
   6262             throw new SecurityException("Requires permission "
   6263                     + android.Manifest.permission.STOP_APP_SWITCHES);
   6264         }
   6265 
   6266         synchronized(this) {
   6267             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
   6268                     + APP_SWITCH_DELAY_TIME;
   6269             mDidAppSwitch = false;
   6270             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   6271             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   6272             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
   6273         }
   6274     }
   6275 
   6276     public void resumeAppSwitches() {
   6277         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   6278                 != PackageManager.PERMISSION_GRANTED) {
   6279             throw new SecurityException("Requires permission "
   6280                     + android.Manifest.permission.STOP_APP_SWITCHES);
   6281         }
   6282 
   6283         synchronized(this) {
   6284             // Note that we don't execute any pending app switches... we will
   6285             // let those wait until either the timeout, or the next start
   6286             // activity request.
   6287             mAppSwitchesAllowedTime = 0;
   6288         }
   6289     }
   6290 
   6291     boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
   6292             String name) {
   6293         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
   6294             return true;
   6295         }
   6296 
   6297         final int perm = checkComponentPermission(
   6298                 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
   6299                 callingUid, -1, true);
   6300         if (perm == PackageManager.PERMISSION_GRANTED) {
   6301             return true;
   6302         }
   6303 
   6304         Slog.w(TAG, name + " request from " + callingUid + " stopped");
   6305         return false;
   6306     }
   6307 
   6308     public void setDebugApp(String packageName, boolean waitForDebugger,
   6309             boolean persistent) {
   6310         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
   6311                 "setDebugApp()");
   6312 
   6313         // Note that this is not really thread safe if there are multiple
   6314         // callers into it at the same time, but that's not a situation we
   6315         // care about.
   6316         if (persistent) {
   6317             final ContentResolver resolver = mContext.getContentResolver();
   6318             Settings.System.putString(
   6319                 resolver, Settings.System.DEBUG_APP,
   6320                 packageName);
   6321             Settings.System.putInt(
   6322                 resolver, Settings.System.WAIT_FOR_DEBUGGER,
   6323                 waitForDebugger ? 1 : 0);
   6324         }
   6325 
   6326         synchronized (this) {
   6327             if (!persistent) {
   6328                 mOrigDebugApp = mDebugApp;
   6329                 mOrigWaitForDebugger = mWaitForDebugger;
   6330             }
   6331             mDebugApp = packageName;
   6332             mWaitForDebugger = waitForDebugger;
   6333             mDebugTransient = !persistent;
   6334             if (packageName != null) {
   6335                 final long origId = Binder.clearCallingIdentity();
   6336                 forceStopPackageLocked(packageName, -1, false, false, true, true);
   6337                 Binder.restoreCallingIdentity(origId);
   6338             }
   6339         }
   6340     }
   6341 
   6342     void setProfileApp(ApplicationInfo app, String processName, String profileFile,
   6343             ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
   6344         synchronized (this) {
   6345             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   6346             if (!isDebuggable) {
   6347                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   6348                     throw new SecurityException("Process not debuggable: " + app.packageName);
   6349                 }
   6350             }
   6351             mProfileApp = processName;
   6352             mProfileFile = profileFile;
   6353             if (mProfileFd != null) {
   6354                 try {
   6355                     mProfileFd.close();
   6356                 } catch (IOException e) {
   6357                 }
   6358                 mProfileFd = null;
   6359             }
   6360             mProfileFd = profileFd;
   6361             mProfileType = 0;
   6362             mAutoStopProfiler = autoStopProfiler;
   6363         }
   6364     }
   6365 
   6366     public void setAlwaysFinish(boolean enabled) {
   6367         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
   6368                 "setAlwaysFinish()");
   6369 
   6370         Settings.System.putInt(
   6371                 mContext.getContentResolver(),
   6372                 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
   6373 
   6374         synchronized (this) {
   6375             mAlwaysFinishActivities = enabled;
   6376         }
   6377     }
   6378 
   6379     public void setActivityController(IActivityController controller) {
   6380         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   6381                 "setActivityController()");
   6382         synchronized (this) {
   6383             mController = controller;
   6384         }
   6385     }
   6386 
   6387     public boolean isUserAMonkey() {
   6388         // For now the fact that there is a controller implies
   6389         // we have a monkey.
   6390         synchronized (this) {
   6391             return mController != null;
   6392         }
   6393     }
   6394 
   6395     public void registerActivityWatcher(IActivityWatcher watcher) {
   6396         synchronized (this) {
   6397             mWatchers.register(watcher);
   6398         }
   6399     }
   6400 
   6401     public void unregisterActivityWatcher(IActivityWatcher watcher) {
   6402         synchronized (this) {
   6403             mWatchers.unregister(watcher);
   6404         }
   6405     }
   6406 
   6407     public void registerProcessObserver(IProcessObserver observer) {
   6408         mProcessObservers.register(observer);
   6409     }
   6410 
   6411     public void unregisterProcessObserver(IProcessObserver observer) {
   6412         mProcessObservers.unregister(observer);
   6413     }
   6414 
   6415     public void setImmersive(IBinder token, boolean immersive) {
   6416         synchronized(this) {
   6417             ActivityRecord r = mMainStack.isInStackLocked(token);
   6418             if (r == null) {
   6419                 throw new IllegalArgumentException();
   6420             }
   6421             r.immersive = immersive;
   6422         }
   6423     }
   6424 
   6425     public boolean isImmersive(IBinder token) {
   6426         synchronized (this) {
   6427             ActivityRecord r = mMainStack.isInStackLocked(token);
   6428             if (r == null) {
   6429                 throw new IllegalArgumentException();
   6430             }
   6431             return r.immersive;
   6432         }
   6433     }
   6434 
   6435     public boolean isTopActivityImmersive() {
   6436         synchronized (this) {
   6437             ActivityRecord r = mMainStack.topRunningActivityLocked(null);
   6438             return (r != null) ? r.immersive : false;
   6439         }
   6440     }
   6441 
   6442     public final void enterSafeMode() {
   6443         synchronized(this) {
   6444             // It only makes sense to do this before the system is ready
   6445             // and started launching other packages.
   6446             if (!mSystemReady) {
   6447                 try {
   6448                     AppGlobals.getPackageManager().enterSafeMode();
   6449                 } catch (RemoteException e) {
   6450                 }
   6451             }
   6452         }
   6453     }
   6454 
   6455     public final void showSafeModeOverlay() {
   6456         View v = LayoutInflater.from(mContext).inflate(
   6457                 com.android.internal.R.layout.safe_mode, null);
   6458         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
   6459         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
   6460         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
   6461         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
   6462         lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
   6463         lp.format = v.getBackground().getOpacity();
   6464         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
   6465                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
   6466         ((WindowManager)mContext.getSystemService(
   6467                 Context.WINDOW_SERVICE)).addView(v, lp);
   6468     }
   6469 
   6470     public void noteWakeupAlarm(IIntentSender sender) {
   6471         if (!(sender instanceof PendingIntentRecord)) {
   6472             return;
   6473         }
   6474         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   6475         synchronized (stats) {
   6476             if (mBatteryStatsService.isOnBattery()) {
   6477                 mBatteryStatsService.enforceCallingPermission();
   6478                 PendingIntentRecord rec = (PendingIntentRecord)sender;
   6479                 int MY_UID = Binder.getCallingUid();
   6480                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
   6481                 BatteryStatsImpl.Uid.Pkg pkg =
   6482                     stats.getPackageStatsLocked(uid, rec.key.packageName);
   6483                 pkg.incWakeupsLocked();
   6484             }
   6485         }
   6486     }
   6487 
   6488     public boolean killPids(int[] pids, String pReason, boolean secure) {
   6489         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   6490             throw new SecurityException("killPids only available to the system");
   6491         }
   6492         String reason = (pReason == null) ? "Unknown" : pReason;
   6493         // XXX Note: don't acquire main activity lock here, because the window
   6494         // manager calls in with its locks held.
   6495 
   6496         boolean killed = false;
   6497         synchronized (mPidsSelfLocked) {
   6498             int[] types = new int[pids.length];
   6499             int worstType = 0;
   6500             for (int i=0; i<pids.length; i++) {
   6501                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   6502                 if (proc != null) {
   6503                     int type = proc.setAdj;
   6504                     types[i] = type;
   6505                     if (type > worstType) {
   6506                         worstType = type;
   6507                     }
   6508                 }
   6509             }
   6510 
   6511             // If the worst oom_adj is somewhere in the hidden proc LRU range,
   6512             // then constrain it so we will kill all hidden procs.
   6513             if (worstType < ProcessList.EMPTY_APP_ADJ && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
   6514                 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
   6515             }
   6516 
   6517             // If this is not a secure call, don't let it kill processes that
   6518             // are important.
   6519             if (!secure && worstType < ProcessList.SECONDARY_SERVER_ADJ) {
   6520                 worstType = ProcessList.SECONDARY_SERVER_ADJ;
   6521             }
   6522 
   6523             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
   6524             for (int i=0; i<pids.length; i++) {
   6525                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   6526                 if (proc == null) {
   6527                     continue;
   6528                 }
   6529                 int adj = proc.setAdj;
   6530                 if (adj >= worstType && !proc.killedBackground) {
   6531                     Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
   6532                     EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
   6533                             proc.processName, adj, reason);
   6534                     killed = true;
   6535                     proc.killedBackground = true;
   6536                     Process.killProcessQuiet(pids[i]);
   6537                 }
   6538             }
   6539         }
   6540         return killed;
   6541     }
   6542 
   6543     public final void startRunning(String pkg, String cls, String action,
   6544             String data) {
   6545         synchronized(this) {
   6546             if (mStartRunning) {
   6547                 return;
   6548             }
   6549             mStartRunning = true;
   6550             mTopComponent = pkg != null && cls != null
   6551                     ? new ComponentName(pkg, cls) : null;
   6552             mTopAction = action != null ? action : Intent.ACTION_MAIN;
   6553             mTopData = data;
   6554             if (!mSystemReady) {
   6555                 return;
   6556             }
   6557         }
   6558 
   6559         systemReady(null);
   6560     }
   6561 
   6562     private void retrieveSettings() {
   6563         final ContentResolver resolver = mContext.getContentResolver();
   6564         String debugApp = Settings.System.getString(
   6565             resolver, Settings.System.DEBUG_APP);
   6566         boolean waitForDebugger = Settings.System.getInt(
   6567             resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
   6568         boolean alwaysFinishActivities = Settings.System.getInt(
   6569             resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
   6570 
   6571         Configuration configuration = new Configuration();
   6572         Settings.System.getConfiguration(resolver, configuration);
   6573 
   6574         synchronized (this) {
   6575             mDebugApp = mOrigDebugApp = debugApp;
   6576             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
   6577             mAlwaysFinishActivities = alwaysFinishActivities;
   6578             // This happens before any activities are started, so we can
   6579             // change mConfiguration in-place.
   6580             mConfiguration.updateFrom(configuration);
   6581             mConfigurationSeq = mConfiguration.seq = 1;
   6582             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
   6583         }
   6584     }
   6585 
   6586     public boolean testIsSystemReady() {
   6587         // no need to synchronize(this) just to read & return the value
   6588         return mSystemReady;
   6589     }
   6590 
   6591     private static File getCalledPreBootReceiversFile() {
   6592         File dataDir = Environment.getDataDirectory();
   6593         File systemDir = new File(dataDir, "system");
   6594         File fname = new File(systemDir, "called_pre_boots.dat");
   6595         return fname;
   6596     }
   6597 
   6598     static final int LAST_DONE_VERSION = 10000;
   6599 
   6600     private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
   6601         ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
   6602         File file = getCalledPreBootReceiversFile();
   6603         FileInputStream fis = null;
   6604         try {
   6605             fis = new FileInputStream(file);
   6606             DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
   6607             int fvers = dis.readInt();
   6608             if (fvers == LAST_DONE_VERSION) {
   6609                 String vers = dis.readUTF();
   6610                 String codename = dis.readUTF();
   6611                 String build = dis.readUTF();
   6612                 if (android.os.Build.VERSION.RELEASE.equals(vers)
   6613                         && android.os.Build.VERSION.CODENAME.equals(codename)
   6614                         && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
   6615                     int num = dis.readInt();
   6616                     while (num > 0) {
   6617                         num--;
   6618                         String pkg = dis.readUTF();
   6619                         String cls = dis.readUTF();
   6620                         lastDoneReceivers.add(new ComponentName(pkg, cls));
   6621                     }
   6622                 }
   6623             }
   6624         } catch (FileNotFoundException e) {
   6625         } catch (IOException e) {
   6626             Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
   6627         } finally {
   6628             if (fis != null) {
   6629                 try {
   6630                     fis.close();
   6631                 } catch (IOException e) {
   6632                 }
   6633             }
   6634         }
   6635         return lastDoneReceivers;
   6636     }
   6637 
   6638     private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
   6639         File file = getCalledPreBootReceiversFile();
   6640         FileOutputStream fos = null;
   6641         DataOutputStream dos = null;
   6642         try {
   6643             Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
   6644             fos = new FileOutputStream(file);
   6645             dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
   6646             dos.writeInt(LAST_DONE_VERSION);
   6647             dos.writeUTF(android.os.Build.VERSION.RELEASE);
   6648             dos.writeUTF(android.os.Build.VERSION.CODENAME);
   6649             dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
   6650             dos.writeInt(list.size());
   6651             for (int i=0; i<list.size(); i++) {
   6652                 dos.writeUTF(list.get(i).getPackageName());
   6653                 dos.writeUTF(list.get(i).getClassName());
   6654             }
   6655         } catch (IOException e) {
   6656             Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
   6657             file.delete();
   6658         } finally {
   6659             FileUtils.sync(fos);
   6660             if (dos != null) {
   6661                 try {
   6662                     dos.close();
   6663                 } catch (IOException e) {
   6664                     // TODO Auto-generated catch block
   6665                     e.printStackTrace();
   6666                 }
   6667             }
   6668         }
   6669     }
   6670 
   6671     public void systemReady(final Runnable goingCallback) {
   6672         synchronized(this) {
   6673             if (mSystemReady) {
   6674                 if (goingCallback != null) goingCallback.run();
   6675                 return;
   6676             }
   6677 
   6678             // Check to see if there are any update receivers to run.
   6679             if (!mDidUpdate) {
   6680                 if (mWaitingUpdate) {
   6681                     return;
   6682                 }
   6683                 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
   6684                 List<ResolveInfo> ris = null;
   6685                 try {
   6686                     ris = AppGlobals.getPackageManager().queryIntentReceivers(
   6687                                 intent, null, 0);
   6688                 } catch (RemoteException e) {
   6689                 }
   6690                 if (ris != null) {
   6691                     for (int i=ris.size()-1; i>=0; i--) {
   6692                         if ((ris.get(i).activityInfo.applicationInfo.flags
   6693                                 &ApplicationInfo.FLAG_SYSTEM) == 0) {
   6694                             ris.remove(i);
   6695                         }
   6696                     }
   6697                     intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
   6698 
   6699                     ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
   6700 
   6701                     final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
   6702                     for (int i=0; i<ris.size(); i++) {
   6703                         ActivityInfo ai = ris.get(i).activityInfo;
   6704                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
   6705                         if (lastDoneReceivers.contains(comp)) {
   6706                             ris.remove(i);
   6707                             i--;
   6708                         }
   6709                     }
   6710 
   6711                     for (int i=0; i<ris.size(); i++) {
   6712                         ActivityInfo ai = ris.get(i).activityInfo;
   6713                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
   6714                         doneReceivers.add(comp);
   6715                         intent.setComponent(comp);
   6716                         IIntentReceiver finisher = null;
   6717                         if (i == ris.size()-1) {
   6718                             finisher = new IIntentReceiver.Stub() {
   6719                                 public void performReceive(Intent intent, int resultCode,
   6720                                         String data, Bundle extras, boolean ordered,
   6721                                         boolean sticky) {
   6722                                     // The raw IIntentReceiver interface is called
   6723                                     // with the AM lock held, so redispatch to
   6724                                     // execute our code without the lock.
   6725                                     mHandler.post(new Runnable() {
   6726                                         public void run() {
   6727                                             synchronized (ActivityManagerService.this) {
   6728                                                 mDidUpdate = true;
   6729                                             }
   6730                                             writeLastDonePreBootReceivers(doneReceivers);
   6731                                             showBootMessage(mContext.getText(
   6732                                                     R.string.android_upgrading_complete),
   6733                                                     false);
   6734                                             systemReady(goingCallback);
   6735                                         }
   6736                                     });
   6737                                 }
   6738                             };
   6739                         }
   6740                         Slog.i(TAG, "Sending system update to: " + intent.getComponent());
   6741                         broadcastIntentLocked(null, null, intent, null, finisher,
   6742                                 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
   6743                         if (finisher != null) {
   6744                             mWaitingUpdate = true;
   6745                         }
   6746                     }
   6747                 }
   6748                 if (mWaitingUpdate) {
   6749                     return;
   6750                 }
   6751                 mDidUpdate = true;
   6752             }
   6753 
   6754             mSystemReady = true;
   6755             if (!mStartRunning) {
   6756                 return;
   6757             }
   6758         }
   6759 
   6760         ArrayList<ProcessRecord> procsToKill = null;
   6761         synchronized(mPidsSelfLocked) {
   6762             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
   6763                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   6764                 if (!isAllowedWhileBooting(proc.info)){
   6765                     if (procsToKill == null) {
   6766                         procsToKill = new ArrayList<ProcessRecord>();
   6767                     }
   6768                     procsToKill.add(proc);
   6769                 }
   6770             }
   6771         }
   6772 
   6773         synchronized(this) {
   6774             if (procsToKill != null) {
   6775                 for (int i=procsToKill.size()-1; i>=0; i--) {
   6776                     ProcessRecord proc = procsToKill.get(i);
   6777                     Slog.i(TAG, "Removing system update proc: " + proc);
   6778                     removeProcessLocked(proc, true, false);
   6779                 }
   6780             }
   6781 
   6782             // Now that we have cleaned up any update processes, we
   6783             // are ready to start launching real processes and know that
   6784             // we won't trample on them any more.
   6785             mProcessesReady = true;
   6786         }
   6787 
   6788         Slog.i(TAG, "System now ready");
   6789         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
   6790             SystemClock.uptimeMillis());
   6791 
   6792         synchronized(this) {
   6793             // Make sure we have no pre-ready processes sitting around.
   6794 
   6795             if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
   6796                 ResolveInfo ri = mContext.getPackageManager()
   6797                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
   6798                                 STOCK_PM_FLAGS);
   6799                 CharSequence errorMsg = null;
   6800                 if (ri != null) {
   6801                     ActivityInfo ai = ri.activityInfo;
   6802                     ApplicationInfo app = ai.applicationInfo;
   6803                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   6804                         mTopAction = Intent.ACTION_FACTORY_TEST;
   6805                         mTopData = null;
   6806                         mTopComponent = new ComponentName(app.packageName,
   6807                                 ai.name);
   6808                     } else {
   6809                         errorMsg = mContext.getResources().getText(
   6810                                 com.android.internal.R.string.factorytest_not_system);
   6811                     }
   6812                 } else {
   6813                     errorMsg = mContext.getResources().getText(
   6814                             com.android.internal.R.string.factorytest_no_action);
   6815                 }
   6816                 if (errorMsg != null) {
   6817                     mTopAction = null;
   6818                     mTopData = null;
   6819                     mTopComponent = null;
   6820                     Message msg = Message.obtain();
   6821                     msg.what = SHOW_FACTORY_ERROR_MSG;
   6822                     msg.getData().putCharSequence("msg", errorMsg);
   6823                     mHandler.sendMessage(msg);
   6824                 }
   6825             }
   6826         }
   6827 
   6828         retrieveSettings();
   6829 
   6830         if (goingCallback != null) goingCallback.run();
   6831 
   6832         synchronized (this) {
   6833             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   6834                 try {
   6835                     List apps = AppGlobals.getPackageManager().
   6836                         getPersistentApplications(STOCK_PM_FLAGS);
   6837                     if (apps != null) {
   6838                         int N = apps.size();
   6839                         int i;
   6840                         for (i=0; i<N; i++) {
   6841                             ApplicationInfo info
   6842                                 = (ApplicationInfo)apps.get(i);
   6843                             if (info != null &&
   6844                                     !info.packageName.equals("android")) {
   6845                                 addAppLocked(info);
   6846                             }
   6847                         }
   6848                     }
   6849                 } catch (RemoteException ex) {
   6850                     // pm is in same process, this will never happen.
   6851                 }
   6852             }
   6853 
   6854             // Start up initial activity.
   6855             mBooting = true;
   6856 
   6857             try {
   6858                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
   6859                     Message msg = Message.obtain();
   6860                     msg.what = SHOW_UID_ERROR_MSG;
   6861                     mHandler.sendMessage(msg);
   6862                 }
   6863             } catch (RemoteException e) {
   6864             }
   6865 
   6866             mMainStack.resumeTopActivityLocked(null);
   6867         }
   6868     }
   6869 
   6870     private boolean makeAppCrashingLocked(ProcessRecord app,
   6871             String shortMsg, String longMsg, String stackTrace) {
   6872         app.crashing = true;
   6873         app.crashingReport = generateProcessError(app,
   6874                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
   6875         startAppProblemLocked(app);
   6876         app.stopFreezingAllLocked();
   6877         return handleAppCrashLocked(app);
   6878     }
   6879 
   6880     private void makeAppNotRespondingLocked(ProcessRecord app,
   6881             String activity, String shortMsg, String longMsg) {
   6882         app.notResponding = true;
   6883         app.notRespondingReport = generateProcessError(app,
   6884                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
   6885                 activity, shortMsg, longMsg, null);
   6886         startAppProblemLocked(app);
   6887         app.stopFreezingAllLocked();
   6888     }
   6889 
   6890     /**
   6891      * Generate a process error record, suitable for attachment to a ProcessRecord.
   6892      *
   6893      * @param app The ProcessRecord in which the error occurred.
   6894      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
   6895      *                      ActivityManager.AppErrorStateInfo
   6896      * @param activity The activity associated with the crash, if known.
   6897      * @param shortMsg Short message describing the crash.
   6898      * @param longMsg Long message describing the crash.
   6899      * @param stackTrace Full crash stack trace, may be null.
   6900      *
   6901      * @return Returns a fully-formed AppErrorStateInfo record.
   6902      */
   6903     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
   6904             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
   6905         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
   6906 
   6907         report.condition = condition;
   6908         report.processName = app.processName;
   6909         report.pid = app.pid;
   6910         report.uid = app.info.uid;
   6911         report.tag = activity;
   6912         report.shortMsg = shortMsg;
   6913         report.longMsg = longMsg;
   6914         report.stackTrace = stackTrace;
   6915 
   6916         return report;
   6917     }
   6918 
   6919     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
   6920         synchronized (this) {
   6921             app.crashing = false;
   6922             app.crashingReport = null;
   6923             app.notResponding = false;
   6924             app.notRespondingReport = null;
   6925             if (app.anrDialog == fromDialog) {
   6926                 app.anrDialog = null;
   6927             }
   6928             if (app.waitDialog == fromDialog) {
   6929                 app.waitDialog = null;
   6930             }
   6931             if (app.pid > 0 && app.pid != MY_PID) {
   6932                 handleAppCrashLocked(app);
   6933                 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
   6934                 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   6935                         app.processName, app.setAdj, "user's request after error");
   6936                 Process.killProcessQuiet(app.pid);
   6937             }
   6938         }
   6939     }
   6940 
   6941     private boolean handleAppCrashLocked(ProcessRecord app) {
   6942         long now = SystemClock.uptimeMillis();
   6943 
   6944         Long crashTime = mProcessCrashTimes.get(app.info.processName,
   6945                 app.info.uid);
   6946         if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
   6947             // This process loses!
   6948             Slog.w(TAG, "Process " + app.info.processName
   6949                     + " has crashed too many times: killing!");
   6950             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
   6951                     app.info.processName, app.info.uid);
   6952             for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
   6953                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   6954                 if (r.app == app) {
   6955                     Slog.w(TAG, "  Force finishing activity "
   6956                         + r.intent.getComponent().flattenToShortString());
   6957                     r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
   6958                 }
   6959             }
   6960             if (!app.persistent) {
   6961                 // We don't want to start this process again until the user
   6962                 // explicitly does so...  but for persistent process, we really
   6963                 // need to keep it running.  If a persistent process is actually
   6964                 // repeatedly crashing, then badness for everyone.
   6965                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
   6966                         app.info.processName);
   6967                 mBadProcesses.put(app.info.processName, app.info.uid, now);
   6968                 app.bad = true;
   6969                 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
   6970                 app.removed = true;
   6971                 // Don't let services in this process be restarted and potentially
   6972                 // annoy the user repeatedly.  Unless it is persistent, since those
   6973                 // processes run critical code.
   6974                 removeProcessLocked(app, false, false);
   6975                 mMainStack.resumeTopActivityLocked(null);
   6976                 return false;
   6977             }
   6978             mMainStack.resumeTopActivityLocked(null);
   6979         } else {
   6980             ActivityRecord r = mMainStack.topRunningActivityLocked(null);
   6981             if (r.app == app) {
   6982                 // If the top running activity is from this crashing
   6983                 // process, then terminate it to avoid getting in a loop.
   6984                 Slog.w(TAG, "  Force finishing activity "
   6985                         + r.intent.getComponent().flattenToShortString());
   6986                 int index = mMainStack.indexOfTokenLocked(r);
   6987                 r.stack.finishActivityLocked(r, index,
   6988                         Activity.RESULT_CANCELED, null, "crashed");
   6989                 // Also terminate any activities below it that aren't yet
   6990                 // stopped, to avoid a situation where one will get
   6991                 // re-start our crashing activity once it gets resumed again.
   6992                 index--;
   6993                 if (index >= 0) {
   6994                     r = (ActivityRecord)mMainStack.mHistory.get(index);
   6995                     if (r.state == ActivityState.RESUMED
   6996                             || r.state == ActivityState.PAUSING
   6997                             || r.state == ActivityState.PAUSED) {
   6998                         if (!r.isHomeActivity || mHomeProcess != r.app) {
   6999                             Slog.w(TAG, "  Force finishing activity "
   7000                                     + r.intent.getComponent().flattenToShortString());
   7001                             r.stack.finishActivityLocked(r, index,
   7002                                     Activity.RESULT_CANCELED, null, "crashed");
   7003                         }
   7004                     }
   7005                 }
   7006             }
   7007         }
   7008 
   7009         // Bump up the crash count of any services currently running in the proc.
   7010         if (app.services.size() != 0) {
   7011             // Any services running in the application need to be placed
   7012             // back in the pending list.
   7013             Iterator<ServiceRecord> it = app.services.iterator();
   7014             while (it.hasNext()) {
   7015                 ServiceRecord sr = it.next();
   7016                 sr.crashCount++;
   7017             }
   7018         }
   7019 
   7020         // If the crashing process is what we consider to be the "home process" and it has been
   7021         // replaced by a third-party app, clear the package preferred activities from packages
   7022         // with a home activity running in the process to prevent a repeatedly crashing app
   7023         // from blocking the user to manually clear the list.
   7024         if (app == mHomeProcess && mHomeProcess.activities.size() > 0
   7025                     && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
   7026             Iterator it = mHomeProcess.activities.iterator();
   7027             while (it.hasNext()) {
   7028                 ActivityRecord r = (ActivityRecord)it.next();
   7029                 if (r.isHomeActivity) {
   7030                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
   7031                     try {
   7032                         ActivityThread.getPackageManager()
   7033                                 .clearPackagePreferredActivities(r.packageName);
   7034                     } catch (RemoteException c) {
   7035                         // pm is in same process, this will never happen.
   7036                     }
   7037                 }
   7038             }
   7039         }
   7040 
   7041         mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
   7042         return true;
   7043     }
   7044 
   7045     void startAppProblemLocked(ProcessRecord app) {
   7046         app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
   7047                 mContext, app.info.packageName, app.info.flags);
   7048         skipCurrentReceiverLocked(app);
   7049     }
   7050 
   7051     void skipCurrentReceiverLocked(ProcessRecord app) {
   7052         boolean reschedule = false;
   7053         BroadcastRecord r = app.curReceiver;
   7054         if (r != null) {
   7055             // The current broadcast is waiting for this app's receiver
   7056             // to be finished.  Looks like that's not going to happen, so
   7057             // let the broadcast continue.
   7058             logBroadcastReceiverDiscardLocked(r);
   7059             finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
   7060                     r.resultExtras, r.resultAbort, true);
   7061             reschedule = true;
   7062         }
   7063         r = mPendingBroadcast;
   7064         if (r != null && r.curApp == app) {
   7065             if (DEBUG_BROADCAST) Slog.v(TAG,
   7066                     "skip & discard pending app " + r);
   7067             logBroadcastReceiverDiscardLocked(r);
   7068             finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
   7069                     r.resultExtras, r.resultAbort, true);
   7070             reschedule = true;
   7071         }
   7072         if (reschedule) {
   7073             scheduleBroadcastsLocked();
   7074         }
   7075     }
   7076 
   7077     /**
   7078      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
   7079      * The application process will exit immediately after this call returns.
   7080      * @param app object of the crashing app, null for the system server
   7081      * @param crashInfo describing the exception
   7082      */
   7083     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
   7084         ProcessRecord r = findAppProcess(app, "Crash");
   7085 
   7086         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
   7087                 app == null ? "system" : (r == null ? "unknown" : r.processName),
   7088                 r == null ? -1 : r.info.flags,
   7089                 crashInfo.exceptionClassName,
   7090                 crashInfo.exceptionMessage,
   7091                 crashInfo.throwFileName,
   7092                 crashInfo.throwLineNumber);
   7093 
   7094         addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
   7095 
   7096         crashApplication(r, crashInfo);
   7097     }
   7098 
   7099     public void handleApplicationStrictModeViolation(
   7100             IBinder app,
   7101             int violationMask,
   7102             StrictMode.ViolationInfo info) {
   7103         ProcessRecord r = findAppProcess(app, "StrictMode");
   7104         if (r == null) {
   7105             return;
   7106         }
   7107 
   7108         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
   7109             Integer stackFingerprint = info.hashCode();
   7110             boolean logIt = true;
   7111             synchronized (mAlreadyLoggedViolatedStacks) {
   7112                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
   7113                     logIt = false;
   7114                     // TODO: sub-sample into EventLog for these, with
   7115                     // the info.durationMillis?  Then we'd get
   7116                     // the relative pain numbers, without logging all
   7117                     // the stack traces repeatedly.  We'd want to do
   7118                     // likewise in the client code, which also does
   7119                     // dup suppression, before the Binder call.
   7120                 } else {
   7121                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
   7122                         mAlreadyLoggedViolatedStacks.clear();
   7123                     }
   7124                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
   7125                 }
   7126             }
   7127             if (logIt) {
   7128                 logStrictModeViolationToDropBox(r, info);
   7129             }
   7130         }
   7131 
   7132         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
   7133             AppErrorResult result = new AppErrorResult();
   7134             synchronized (this) {
   7135                 final long origId = Binder.clearCallingIdentity();
   7136 
   7137                 Message msg = Message.obtain();
   7138                 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
   7139                 HashMap<String, Object> data = new HashMap<String, Object>();
   7140                 data.put("result", result);
   7141                 data.put("app", r);
   7142                 data.put("violationMask", violationMask);
   7143                 data.put("info", info);
   7144                 msg.obj = data;
   7145                 mHandler.sendMessage(msg);
   7146 
   7147                 Binder.restoreCallingIdentity(origId);
   7148             }
   7149             int res = result.get();
   7150             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
   7151         }
   7152     }
   7153 
   7154     // Depending on the policy in effect, there could be a bunch of
   7155     // these in quick succession so we try to batch these together to
   7156     // minimize disk writes, number of dropbox entries, and maximize
   7157     // compression, by having more fewer, larger records.
   7158     private void logStrictModeViolationToDropBox(
   7159             ProcessRecord process,
   7160             StrictMode.ViolationInfo info) {
   7161         if (info == null) {
   7162             return;
   7163         }
   7164         final boolean isSystemApp = process == null ||
   7165                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
   7166                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
   7167         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
   7168         final DropBoxManager dbox = (DropBoxManager)
   7169                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   7170 
   7171         // Exit early if the dropbox isn't configured to accept this report type.
   7172         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   7173 
   7174         boolean bufferWasEmpty;
   7175         boolean needsFlush;
   7176         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
   7177         synchronized (sb) {
   7178             bufferWasEmpty = sb.length() == 0;
   7179             appendDropBoxProcessHeaders(process, sb);
   7180             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   7181             sb.append("System-App: ").append(isSystemApp).append("\n");
   7182             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
   7183             if (info.violationNumThisLoop != 0) {
   7184                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
   7185             }
   7186             if (info.numAnimationsRunning != 0) {
   7187                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
   7188             }
   7189             if (info.broadcastIntentAction != null) {
   7190                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
   7191             }
   7192             if (info.durationMillis != -1) {
   7193                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
   7194             }
   7195             if (info.numInstances != -1) {
   7196                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
   7197             }
   7198             if (info.tags != null) {
   7199                 for (String tag : info.tags) {
   7200                     sb.append("Span-Tag: ").append(tag).append("\n");
   7201                 }
   7202             }
   7203             sb.append("\n");
   7204             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
   7205                 sb.append(info.crashInfo.stackTrace);
   7206             }
   7207             sb.append("\n");
   7208 
   7209             // Only buffer up to ~64k.  Various logging bits truncate
   7210             // things at 128k.
   7211             needsFlush = (sb.length() > 64 * 1024);
   7212         }
   7213 
   7214         // Flush immediately if the buffer's grown too large, or this
   7215         // is a non-system app.  Non-system apps are isolated with a
   7216         // different tag & policy and not batched.
   7217         //
   7218         // Batching is useful during internal testing with
   7219         // StrictMode settings turned up high.  Without batching,
   7220         // thousands of separate files could be created on boot.
   7221         if (!isSystemApp || needsFlush) {
   7222             new Thread("Error dump: " + dropboxTag) {
   7223                 @Override
   7224                 public void run() {
   7225                     String report;
   7226                     synchronized (sb) {
   7227                         report = sb.toString();
   7228                         sb.delete(0, sb.length());
   7229                         sb.trimToSize();
   7230                     }
   7231                     if (report.length() != 0) {
   7232                         dbox.addText(dropboxTag, report);
   7233                     }
   7234                 }
   7235             }.start();
   7236             return;
   7237         }
   7238 
   7239         // System app batching:
   7240         if (!bufferWasEmpty) {
   7241             // An existing dropbox-writing thread is outstanding, so
   7242             // we don't need to start it up.  The existing thread will
   7243             // catch the buffer appends we just did.
   7244             return;
   7245         }
   7246 
   7247         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
   7248         // (After this point, we shouldn't access AMS internal data structures.)
   7249         new Thread("Error dump: " + dropboxTag) {
   7250             @Override
   7251             public void run() {
   7252                 // 5 second sleep to let stacks arrive and be batched together
   7253                 try {
   7254                     Thread.sleep(5000);  // 5 seconds
   7255                 } catch (InterruptedException e) {}
   7256 
   7257                 String errorReport;
   7258                 synchronized (mStrictModeBuffer) {
   7259                     errorReport = mStrictModeBuffer.toString();
   7260                     if (errorReport.length() == 0) {
   7261                         return;
   7262                     }
   7263                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
   7264                     mStrictModeBuffer.trimToSize();
   7265                 }
   7266                 dbox.addText(dropboxTag, errorReport);
   7267             }
   7268         }.start();
   7269     }
   7270 
   7271     /**
   7272      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
   7273      * @param app object of the crashing app, null for the system server
   7274      * @param tag reported by the caller
   7275      * @param crashInfo describing the context of the error
   7276      * @return true if the process should exit immediately (WTF is fatal)
   7277      */
   7278     public boolean handleApplicationWtf(IBinder app, String tag,
   7279             ApplicationErrorReport.CrashInfo crashInfo) {
   7280         ProcessRecord r = findAppProcess(app, "WTF");
   7281 
   7282         EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
   7283                 app == null ? "system" : (r == null ? "unknown" : r.processName),
   7284                 r == null ? -1 : r.info.flags,
   7285                 tag, crashInfo.exceptionMessage);
   7286 
   7287         addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
   7288 
   7289         if (r != null && r.pid != Process.myPid() &&
   7290                 Settings.Secure.getInt(mContext.getContentResolver(),
   7291                         Settings.Secure.WTF_IS_FATAL, 0) != 0) {
   7292             crashApplication(r, crashInfo);
   7293             return true;
   7294         } else {
   7295             return false;
   7296         }
   7297     }
   7298 
   7299     /**
   7300      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
   7301      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
   7302      */
   7303     private ProcessRecord findAppProcess(IBinder app, String reason) {
   7304         if (app == null) {
   7305             return null;
   7306         }
   7307 
   7308         synchronized (this) {
   7309             for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   7310                 final int NA = apps.size();
   7311                 for (int ia=0; ia<NA; ia++) {
   7312                     ProcessRecord p = apps.valueAt(ia);
   7313                     if (p.thread != null && p.thread.asBinder() == app) {
   7314                         return p;
   7315                     }
   7316                 }
   7317             }
   7318 
   7319             Slog.w(TAG, "Can't find mystery application for " + reason
   7320                     + " from pid=" + Binder.getCallingPid()
   7321                     + " uid=" + Binder.getCallingUid() + ": " + app);
   7322             return null;
   7323         }
   7324     }
   7325 
   7326     /**
   7327      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
   7328      * to append various headers to the dropbox log text.
   7329      */
   7330     private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
   7331         // Watchdog thread ends up invoking this function (with
   7332         // a null ProcessRecord) to add the stack file to dropbox.
   7333         // Do not acquire a lock on this (am) in such cases, as it
   7334         // could cause a potential deadlock, if and when watchdog
   7335         // is invoked due to unavailability of lock on am and it
   7336         // would prevent watchdog from killing system_server.
   7337         if (process == null) {
   7338             sb.append("Process: system_server\n");
   7339             return;
   7340         }
   7341         // Note: ProcessRecord 'process' is guarded by the service
   7342         // instance.  (notably process.pkgList, which could otherwise change
   7343         // concurrently during execution of this method)
   7344         synchronized (this) {
   7345             if (process.pid == MY_PID) {
   7346                 sb.append("Process: system_server\n");
   7347             } else {
   7348                 sb.append("Process: ").append(process.processName).append("\n");
   7349             }
   7350             int flags = process.info.flags;
   7351             IPackageManager pm = AppGlobals.getPackageManager();
   7352             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
   7353             for (String pkg : process.pkgList) {
   7354                 sb.append("Package: ").append(pkg);
   7355                 try {
   7356                     PackageInfo pi = pm.getPackageInfo(pkg, 0);
   7357                     if (pi != null) {
   7358                         sb.append(" v").append(pi.versionCode);
   7359                         if (pi.versionName != null) {
   7360                             sb.append(" (").append(pi.versionName).append(")");
   7361                         }
   7362                     }
   7363                 } catch (RemoteException e) {
   7364                     Slog.e(TAG, "Error getting package info: " + pkg, e);
   7365                 }
   7366                 sb.append("\n");
   7367             }
   7368         }
   7369     }
   7370 
   7371     private static String processClass(ProcessRecord process) {
   7372         if (process == null || process.pid == MY_PID) {
   7373             return "system_server";
   7374         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   7375             return "system_app";
   7376         } else {
   7377             return "data_app";
   7378         }
   7379     }
   7380 
   7381     /**
   7382      * Write a description of an error (crash, WTF, ANR) to the drop box.
   7383      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
   7384      * @param process which caused the error, null means the system server
   7385      * @param activity which triggered the error, null if unknown
   7386      * @param parent activity related to the error, null if unknown
   7387      * @param subject line related to the error, null if absent
   7388      * @param report in long form describing the error, null if absent
   7389      * @param logFile to include in the report, null if none
   7390      * @param crashInfo giving an application stack trace, null if absent
   7391      */
   7392     public void addErrorToDropBox(String eventType,
   7393             ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
   7394             final String report, final File logFile,
   7395             final ApplicationErrorReport.CrashInfo crashInfo) {
   7396         // NOTE -- this must never acquire the ActivityManagerService lock,
   7397         // otherwise the watchdog may be prevented from resetting the system.
   7398 
   7399         final String dropboxTag = processClass(process) + "_" + eventType;
   7400         final DropBoxManager dbox = (DropBoxManager)
   7401                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   7402 
   7403         // Exit early if the dropbox isn't configured to accept this report type.
   7404         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   7405 
   7406         final StringBuilder sb = new StringBuilder(1024);
   7407         appendDropBoxProcessHeaders(process, sb);
   7408         if (activity != null) {
   7409             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
   7410         }
   7411         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
   7412             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
   7413         }
   7414         if (parent != null && parent != activity) {
   7415             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
   7416         }
   7417         if (subject != null) {
   7418             sb.append("Subject: ").append(subject).append("\n");
   7419         }
   7420         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   7421         if (Debug.isDebuggerConnected()) {
   7422             sb.append("Debugger: Connected\n");
   7423         }
   7424         sb.append("\n");
   7425 
   7426         // Do the rest in a worker thread to avoid blocking the caller on I/O
   7427         // (After this point, we shouldn't access AMS internal data structures.)
   7428         Thread worker = new Thread("Error dump: " + dropboxTag) {
   7429             @Override
   7430             public void run() {
   7431                 if (report != null) {
   7432                     sb.append(report);
   7433                 }
   7434                 if (logFile != null) {
   7435                     try {
   7436                         sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
   7437                     } catch (IOException e) {
   7438                         Slog.e(TAG, "Error reading " + logFile, e);
   7439                     }
   7440                 }
   7441                 if (crashInfo != null && crashInfo.stackTrace != null) {
   7442                     sb.append(crashInfo.stackTrace);
   7443                 }
   7444 
   7445                 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
   7446                 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
   7447                 if (lines > 0) {
   7448                     sb.append("\n");
   7449 
   7450                     // Merge several logcat streams, and take the last N lines
   7451                     InputStreamReader input = null;
   7452                     try {
   7453                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
   7454                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
   7455                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
   7456 
   7457                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
   7458                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
   7459                         input = new InputStreamReader(logcat.getInputStream());
   7460 
   7461                         int num;
   7462                         char[] buf = new char[8192];
   7463                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
   7464                     } catch (IOException e) {
   7465                         Slog.e(TAG, "Error running logcat", e);
   7466                     } finally {
   7467                         if (input != null) try { input.close(); } catch (IOException e) {}
   7468                     }
   7469                 }
   7470 
   7471                 dbox.addText(dropboxTag, sb.toString());
   7472             }
   7473         };
   7474 
   7475         if (process == null || process.pid == MY_PID) {
   7476             worker.run();  // We may be about to die -- need to run this synchronously
   7477         } else {
   7478             worker.start();
   7479         }
   7480     }
   7481 
   7482     /**
   7483      * Bring up the "unexpected error" dialog box for a crashing app.
   7484      * Deal with edge cases (intercepts from instrumented applications,
   7485      * ActivityController, error intent receivers, that sort of thing).
   7486      * @param r the application crashing
   7487      * @param crashInfo describing the failure
   7488      */
   7489     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
   7490         long timeMillis = System.currentTimeMillis();
   7491         String shortMsg = crashInfo.exceptionClassName;
   7492         String longMsg = crashInfo.exceptionMessage;
   7493         String stackTrace = crashInfo.stackTrace;
   7494         if (shortMsg != null && longMsg != null) {
   7495             longMsg = shortMsg + ": " + longMsg;
   7496         } else if (shortMsg != null) {
   7497             longMsg = shortMsg;
   7498         }
   7499 
   7500         AppErrorResult result = new AppErrorResult();
   7501         synchronized (this) {
   7502             if (mController != null) {
   7503                 try {
   7504                     String name = r != null ? r.processName : null;
   7505                     int pid = r != null ? r.pid : Binder.getCallingPid();
   7506                     if (!mController.appCrashed(name, pid,
   7507                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
   7508                         Slog.w(TAG, "Force-killing crashed app " + name
   7509                                 + " at watcher's request");
   7510                         Process.killProcess(pid);
   7511                         return;
   7512                     }
   7513                 } catch (RemoteException e) {
   7514                     mController = null;
   7515                 }
   7516             }
   7517 
   7518             final long origId = Binder.clearCallingIdentity();
   7519 
   7520             // If this process is running instrumentation, finish it.
   7521             if (r != null && r.instrumentationClass != null) {
   7522                 Slog.w(TAG, "Error in app " + r.processName
   7523                       + " running instrumentation " + r.instrumentationClass + ":");
   7524                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
   7525                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
   7526                 Bundle info = new Bundle();
   7527                 info.putString("shortMsg", shortMsg);
   7528                 info.putString("longMsg", longMsg);
   7529                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
   7530                 Binder.restoreCallingIdentity(origId);
   7531                 return;
   7532             }
   7533 
   7534             // If we can't identify the process or it's already exceeded its crash quota,
   7535             // quit right away without showing a crash dialog.
   7536             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
   7537                 Binder.restoreCallingIdentity(origId);
   7538                 return;
   7539             }
   7540 
   7541             Message msg = Message.obtain();
   7542             msg.what = SHOW_ERROR_MSG;
   7543             HashMap data = new HashMap();
   7544             data.put("result", result);
   7545             data.put("app", r);
   7546             msg.obj = data;
   7547             mHandler.sendMessage(msg);
   7548 
   7549             Binder.restoreCallingIdentity(origId);
   7550         }
   7551 
   7552         int res = result.get();
   7553 
   7554         Intent appErrorIntent = null;
   7555         synchronized (this) {
   7556             if (r != null) {
   7557                 mProcessCrashTimes.put(r.info.processName, r.info.uid,
   7558                         SystemClock.uptimeMillis());
   7559             }
   7560             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
   7561                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
   7562             }
   7563         }
   7564 
   7565         if (appErrorIntent != null) {
   7566             try {
   7567                 mContext.startActivity(appErrorIntent);
   7568             } catch (ActivityNotFoundException e) {
   7569                 Slog.w(TAG, "bug report receiver dissappeared", e);
   7570             }
   7571         }
   7572     }
   7573 
   7574     Intent createAppErrorIntentLocked(ProcessRecord r,
   7575             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   7576         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
   7577         if (report == null) {
   7578             return null;
   7579         }
   7580         Intent result = new Intent(Intent.ACTION_APP_ERROR);
   7581         result.setComponent(r.errorReportReceiver);
   7582         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
   7583         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   7584         return result;
   7585     }
   7586 
   7587     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
   7588             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   7589         if (r.errorReportReceiver == null) {
   7590             return null;
   7591         }
   7592 
   7593         if (!r.crashing && !r.notResponding) {
   7594             return null;
   7595         }
   7596 
   7597         ApplicationErrorReport report = new ApplicationErrorReport();
   7598         report.packageName = r.info.packageName;
   7599         report.installerPackageName = r.errorReportReceiver.getPackageName();
   7600         report.processName = r.processName;
   7601         report.time = timeMillis;
   7602         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   7603 
   7604         if (r.crashing) {
   7605             report.type = ApplicationErrorReport.TYPE_CRASH;
   7606             report.crashInfo = crashInfo;
   7607         } else if (r.notResponding) {
   7608             report.type = ApplicationErrorReport.TYPE_ANR;
   7609             report.anrInfo = new ApplicationErrorReport.AnrInfo();
   7610 
   7611             report.anrInfo.activity = r.notRespondingReport.tag;
   7612             report.anrInfo.cause = r.notRespondingReport.shortMsg;
   7613             report.anrInfo.info = r.notRespondingReport.longMsg;
   7614         }
   7615 
   7616         return report;
   7617     }
   7618 
   7619     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
   7620         // assume our apps are happy - lazy create the list
   7621         List<ActivityManager.ProcessErrorStateInfo> errList = null;
   7622 
   7623         synchronized (this) {
   7624 
   7625             // iterate across all processes
   7626             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   7627                 ProcessRecord app = mLruProcesses.get(i);
   7628                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
   7629                     // This one's in trouble, so we'll generate a report for it
   7630                     // crashes are higher priority (in case there's a crash *and* an anr)
   7631                     ActivityManager.ProcessErrorStateInfo report = null;
   7632                     if (app.crashing) {
   7633                         report = app.crashingReport;
   7634                     } else if (app.notResponding) {
   7635                         report = app.notRespondingReport;
   7636                     }
   7637 
   7638                     if (report != null) {
   7639                         if (errList == null) {
   7640                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
   7641                         }
   7642                         errList.add(report);
   7643                     } else {
   7644                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
   7645                                 " crashing = " + app.crashing +
   7646                                 " notResponding = " + app.notResponding);
   7647                     }
   7648                 }
   7649             }
   7650         }
   7651 
   7652         return errList;
   7653     }
   7654 
   7655     static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
   7656         if (adj >= ProcessList.EMPTY_APP_ADJ) {
   7657             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
   7658         } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   7659             if (currApp != null) {
   7660                 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
   7661             }
   7662             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   7663         } else if (adj >= ProcessList.HOME_APP_ADJ) {
   7664             if (currApp != null) {
   7665                 currApp.lru = 0;
   7666             }
   7667             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   7668         } else if (adj >= ProcessList.SECONDARY_SERVER_ADJ) {
   7669             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   7670         } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   7671             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
   7672         } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   7673             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
   7674         } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
   7675             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
   7676         } else {
   7677             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
   7678         }
   7679     }
   7680 
   7681     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
   7682         // Lazy instantiation of list
   7683         List<ActivityManager.RunningAppProcessInfo> runList = null;
   7684         synchronized (this) {
   7685             // Iterate across all processes
   7686             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   7687                 ProcessRecord app = mLruProcesses.get(i);
   7688                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
   7689                     // Generate process state info for running application
   7690                     ActivityManager.RunningAppProcessInfo currApp =
   7691                         new ActivityManager.RunningAppProcessInfo(app.processName,
   7692                                 app.pid, app.getPackageList());
   7693                     currApp.uid = app.info.uid;
   7694                     if (mHeavyWeightProcess == app) {
   7695                         currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
   7696                     }
   7697                     if (app.persistent) {
   7698                         currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
   7699                     }
   7700                     int adj = app.curAdj;
   7701                     currApp.importance = oomAdjToImportance(adj, currApp);
   7702                     currApp.importanceReasonCode = app.adjTypeCode;
   7703                     if (app.adjSource instanceof ProcessRecord) {
   7704                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
   7705                         currApp.importanceReasonImportance = oomAdjToImportance(
   7706                                 app.adjSourceOom, null);
   7707                     } else if (app.adjSource instanceof ActivityRecord) {
   7708                         ActivityRecord r = (ActivityRecord)app.adjSource;
   7709                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
   7710                     }
   7711                     if (app.adjTarget instanceof ComponentName) {
   7712                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
   7713                     }
   7714                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
   7715                     //        + " lru=" + currApp.lru);
   7716                     if (runList == null) {
   7717                         runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
   7718                     }
   7719                     runList.add(currApp);
   7720                 }
   7721             }
   7722         }
   7723         return runList;
   7724     }
   7725 
   7726     public List<ApplicationInfo> getRunningExternalApplications() {
   7727         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
   7728         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
   7729         if (runningApps != null && runningApps.size() > 0) {
   7730             Set<String> extList = new HashSet<String>();
   7731             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
   7732                 if (app.pkgList != null) {
   7733                     for (String pkg : app.pkgList) {
   7734                         extList.add(pkg);
   7735                     }
   7736                 }
   7737             }
   7738             IPackageManager pm = AppGlobals.getPackageManager();
   7739             for (String pkg : extList) {
   7740                 try {
   7741                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
   7742                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
   7743                         retList.add(info);
   7744                     }
   7745                 } catch (RemoteException e) {
   7746                 }
   7747             }
   7748         }
   7749         return retList;
   7750     }
   7751 
   7752     @Override
   7753     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   7754         if (checkCallingPermission(android.Manifest.permission.DUMP)
   7755                 != PackageManager.PERMISSION_GRANTED) {
   7756             pw.println("Permission Denial: can't dump ActivityManager from from pid="
   7757                     + Binder.getCallingPid()
   7758                     + ", uid=" + Binder.getCallingUid()
   7759                     + " without permission "
   7760                     + android.Manifest.permission.DUMP);
   7761             return;
   7762         }
   7763 
   7764         boolean dumpAll = false;
   7765         boolean dumpClient = false;
   7766 
   7767         int opti = 0;
   7768         while (opti < args.length) {
   7769             String opt = args[opti];
   7770             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   7771                 break;
   7772             }
   7773             opti++;
   7774             if ("-a".equals(opt)) {
   7775                 dumpAll = true;
   7776             } else if ("-c".equals(opt)) {
   7777                 dumpClient = true;
   7778             } else if ("-h".equals(opt)) {
   7779                 pw.println("Activity manager dump options:");
   7780                 pw.println("  [-a] [-c] [-h] [cmd] ...");
   7781                 pw.println("  cmd may be one of:");
   7782                 pw.println("    a[ctivities]: activity stack state");
   7783                 pw.println("    b[roadcasts]: broadcast state");
   7784                 pw.println("    i[ntents]: pending intent state");
   7785                 pw.println("    p[rocesses]: process state");
   7786                 pw.println("    o[om]: out of memory management");
   7787                 pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
   7788                 pw.println("    s[ervices] [COMP_SPEC ...]: service state");
   7789                 pw.println("    service [COMP_SPEC]: service client-side state");
   7790                 pw.println("    all: dump all activities");
   7791                 pw.println("    top: dump the top activity");
   7792                 pw.println("  cmd may also be a COMP_SPEC to dump activities.");
   7793                 pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
   7794                 pw.println("    a partial substring in a component name, a");
   7795                 pw.println("    hex object identifier.");
   7796                 pw.println("  -a: include all available server state.");
   7797                 pw.println("  -c: include client state.");
   7798                 return;
   7799             } else {
   7800                 pw.println("Unknown argument: " + opt + "; use -h for help");
   7801             }
   7802         }
   7803 
   7804         // Is the caller requesting to dump a particular piece of data?
   7805         if (opti < args.length) {
   7806             String cmd = args[opti];
   7807             opti++;
   7808             if ("activities".equals(cmd) || "a".equals(cmd)) {
   7809                 synchronized (this) {
   7810                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
   7811                 }
   7812                 return;
   7813             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
   7814                 synchronized (this) {
   7815                     dumpBroadcastsLocked(fd, pw, args, opti, true);
   7816                 }
   7817                 return;
   7818             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
   7819                 synchronized (this) {
   7820                     dumpPendingIntentsLocked(fd, pw, args, opti, true);
   7821                 }
   7822                 return;
   7823             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
   7824                 synchronized (this) {
   7825                     dumpProcessesLocked(fd, pw, args, opti, true);
   7826                 }
   7827                 return;
   7828             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
   7829                 synchronized (this) {
   7830                     dumpOomLocked(fd, pw, args, opti, true);
   7831                 }
   7832                 return;
   7833             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
   7834                 synchronized (this) {
   7835                     dumpProvidersLocked(fd, pw, args, opti, true);
   7836                 }
   7837                 return;
   7838             } else if ("service".equals(cmd)) {
   7839                 String[] newArgs;
   7840                 String name;
   7841                 if (opti >= args.length) {
   7842                     name = null;
   7843                     newArgs = EMPTY_STRING_ARRAY;
   7844                 } else {
   7845                     name = args[opti];
   7846                     opti++;
   7847                     newArgs = new String[args.length - opti];
   7848                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   7849                 }
   7850                 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
   7851                     pw.println("No services match: " + name);
   7852                     pw.println("Use -h for help.");
   7853                 }
   7854                 return;
   7855             } else if ("services".equals(cmd) || "s".equals(cmd)) {
   7856                 synchronized (this) {
   7857                     dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
   7858                 }
   7859                 return;
   7860             } else {
   7861                 // Dumping a single activity?
   7862                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
   7863                     pw.println("Bad activity command, or no activities match: " + cmd);
   7864                     pw.println("Use -h for help.");
   7865                 }
   7866                 return;
   7867             }
   7868         }
   7869 
   7870         // No piece of data specified, dump everything.
   7871         synchronized (this) {
   7872             boolean needSep;
   7873             needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
   7874             if (needSep) {
   7875                 pw.println(" ");
   7876             }
   7877             if (dumpAll) {
   7878                 pw.println("-------------------------------------------------------------------------------");
   7879             }
   7880             needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
   7881             if (needSep) {
   7882                 pw.println(" ");
   7883             }
   7884             if (dumpAll) {
   7885                 pw.println("-------------------------------------------------------------------------------");
   7886             }
   7887             needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
   7888             if (needSep) {
   7889                 pw.println(" ");
   7890             }
   7891             if (dumpAll) {
   7892                 pw.println("-------------------------------------------------------------------------------");
   7893             }
   7894             needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
   7895             if (needSep) {
   7896                 pw.println(" ");
   7897             }
   7898             if (dumpAll) {
   7899                 pw.println("-------------------------------------------------------------------------------");
   7900             }
   7901             needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
   7902             if (needSep) {
   7903                 pw.println(" ");
   7904             }
   7905             if (dumpAll) {
   7906                 pw.println("-------------------------------------------------------------------------------");
   7907             }
   7908             dumpProcessesLocked(fd, pw, args, opti, dumpAll);
   7909         }
   7910     }
   7911 
   7912     boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   7913             int opti, boolean dumpAll, boolean dumpClient) {
   7914         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
   7915         pw.println("  Main stack:");
   7916         dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient);
   7917         pw.println(" ");
   7918         pw.println("  Running activities (most recent first):");
   7919         dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false);
   7920         if (mMainStack.mWaitingVisibleActivities.size() > 0) {
   7921             pw.println(" ");
   7922             pw.println("  Activities waiting for another to become visible:");
   7923             dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
   7924                     !dumpAll, false);
   7925         }
   7926         if (mMainStack.mStoppingActivities.size() > 0) {
   7927             pw.println(" ");
   7928             pw.println("  Activities waiting to stop:");
   7929             dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
   7930                     !dumpAll, false);
   7931         }
   7932         if (mMainStack.mGoingToSleepActivities.size() > 0) {
   7933             pw.println(" ");
   7934             pw.println("  Activities waiting to sleep:");
   7935             dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
   7936                     !dumpAll, false);
   7937         }
   7938         if (mMainStack.mFinishingActivities.size() > 0) {
   7939             pw.println(" ");
   7940             pw.println("  Activities waiting to finish:");
   7941             dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
   7942                     !dumpAll, false);
   7943         }
   7944 
   7945         pw.println(" ");
   7946         if (mMainStack.mPausingActivity != null) {
   7947             pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
   7948         }
   7949         pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
   7950         pw.println("  mFocusedActivity: " + mFocusedActivity);
   7951         if (dumpAll) {
   7952             pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
   7953             pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
   7954             pw.println("  mDismissKeyguardOnNextActivity: "
   7955                     + mMainStack.mDismissKeyguardOnNextActivity);
   7956         }
   7957 
   7958         if (mRecentTasks.size() > 0) {
   7959             pw.println();
   7960             pw.println("  Recent tasks:");
   7961 
   7962             final int N = mRecentTasks.size();
   7963             for (int i=0; i<N; i++) {
   7964                 TaskRecord tr = mRecentTasks.get(i);
   7965                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
   7966                         pw.println(tr);
   7967                 if (dumpAll) {
   7968                     mRecentTasks.get(i).dump(pw, "    ");
   7969                 }
   7970             }
   7971         }
   7972 
   7973         if (dumpAll) {
   7974             pw.println(" ");
   7975             pw.println("  mCurTask: " + mCurTask);
   7976         }
   7977 
   7978         return true;
   7979     }
   7980 
   7981     boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   7982             int opti, boolean dumpAll) {
   7983         boolean needSep = false;
   7984         int numPers = 0;
   7985 
   7986         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
   7987 
   7988         if (dumpAll) {
   7989             for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
   7990                 final int NA = procs.size();
   7991                 for (int ia=0; ia<NA; ia++) {
   7992                     if (!needSep) {
   7993                         pw.println("  All known processes:");
   7994                         needSep = true;
   7995                     }
   7996                     ProcessRecord r = procs.valueAt(ia);
   7997                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
   7998                         pw.print(" UID "); pw.print(procs.keyAt(ia));
   7999                         pw.print(" "); pw.println(r);
   8000                     r.dump(pw, "    ");
   8001                     if (r.persistent) {
   8002                         numPers++;
   8003                     }
   8004                 }
   8005             }
   8006         }
   8007 
   8008         if (mLruProcesses.size() > 0) {
   8009             if (needSep) pw.println(" ");
   8010             needSep = true;
   8011             pw.println("  Process LRU list (sorted by oom_adj):");
   8012             dumpProcessOomList(pw, this, mLruProcesses, "    ",
   8013                     "Proc", "PERS", false);
   8014             needSep = true;
   8015         }
   8016 
   8017         if (dumpAll) {
   8018             synchronized (mPidsSelfLocked) {
   8019                 if (mPidsSelfLocked.size() > 0) {
   8020                     if (needSep) pw.println(" ");
   8021                     needSep = true;
   8022                     pw.println("  PID mappings:");
   8023                     for (int i=0; i<mPidsSelfLocked.size(); i++) {
   8024                         pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
   8025                             pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
   8026                     }
   8027                 }
   8028             }
   8029         }
   8030 
   8031         if (mForegroundProcesses.size() > 0) {
   8032             if (needSep) pw.println(" ");
   8033             needSep = true;
   8034             pw.println("  Foreground Processes:");
   8035             for (int i=0; i<mForegroundProcesses.size(); i++) {
   8036                 pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
   8037                         pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
   8038             }
   8039         }
   8040 
   8041         if (mPersistentStartingProcesses.size() > 0) {
   8042             if (needSep) pw.println(" ");
   8043             needSep = true;
   8044             pw.println("  Persisent processes that are starting:");
   8045             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
   8046                     "Starting Norm", "Restarting PERS");
   8047         }
   8048 
   8049         if (mRemovedProcesses.size() > 0) {
   8050             if (needSep) pw.println(" ");
   8051             needSep = true;
   8052             pw.println("  Processes that are being removed:");
   8053             dumpProcessList(pw, this, mRemovedProcesses, "    ",
   8054                     "Removed Norm", "Removed PERS");
   8055         }
   8056 
   8057         if (mProcessesOnHold.size() > 0) {
   8058             if (needSep) pw.println(" ");
   8059             needSep = true;
   8060             pw.println("  Processes that are on old until the system is ready:");
   8061             dumpProcessList(pw, this, mProcessesOnHold, "    ",
   8062                     "OnHold Norm", "OnHold PERS");
   8063         }
   8064 
   8065         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
   8066 
   8067         if (mProcessCrashTimes.getMap().size() > 0) {
   8068             if (needSep) pw.println(" ");
   8069             needSep = true;
   8070             pw.println("  Time since processes crashed:");
   8071             long now = SystemClock.uptimeMillis();
   8072             for (Map.Entry<String, SparseArray<Long>> procs
   8073                     : mProcessCrashTimes.getMap().entrySet()) {
   8074                 SparseArray<Long> uids = procs.getValue();
   8075                 final int N = uids.size();
   8076                 for (int i=0; i<N; i++) {
   8077                     pw.print("    Process "); pw.print(procs.getKey());
   8078                             pw.print(" uid "); pw.print(uids.keyAt(i));
   8079                             pw.print(": last crashed ");
   8080                             pw.print((now-uids.valueAt(i)));
   8081                             pw.println(" ms ago");
   8082                 }
   8083             }
   8084         }
   8085 
   8086         if (mBadProcesses.getMap().size() > 0) {
   8087             if (needSep) pw.println(" ");
   8088             needSep = true;
   8089             pw.println("  Bad processes:");
   8090             for (Map.Entry<String, SparseArray<Long>> procs
   8091                     : mBadProcesses.getMap().entrySet()) {
   8092                 SparseArray<Long> uids = procs.getValue();
   8093                 final int N = uids.size();
   8094                 for (int i=0; i<N; i++) {
   8095                     pw.print("    Bad process "); pw.print(procs.getKey());
   8096                             pw.print(" uid "); pw.print(uids.keyAt(i));
   8097                             pw.print(": crashed at time ");
   8098                             pw.println(uids.valueAt(i));
   8099                 }
   8100             }
   8101         }
   8102 
   8103         pw.println();
   8104         pw.println("  mHomeProcess: " + mHomeProcess);
   8105         if (mHeavyWeightProcess != null) {
   8106             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   8107         }
   8108         pw.println("  mConfiguration: " + mConfiguration);
   8109         if (dumpAll) {
   8110             pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
   8111             if (mCompatModePackages.getPackages().size() > 0) {
   8112                 pw.println("  mScreenCompatPackages:");
   8113                 for (Map.Entry<String, Integer> entry
   8114                         : mCompatModePackages.getPackages().entrySet()) {
   8115                     String pkg = entry.getKey();
   8116                     int mode = entry.getValue();
   8117                     pw.print("    "); pw.print(pkg); pw.print(": ");
   8118                             pw.print(mode); pw.println();
   8119                 }
   8120             }
   8121         }
   8122         pw.println("  mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
   8123         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
   8124                 || mOrigWaitForDebugger) {
   8125             pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
   8126                     + " mDebugTransient=" + mDebugTransient
   8127                     + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
   8128         }
   8129         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
   8130                 || mProfileFd != null) {
   8131             pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
   8132             pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
   8133             pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
   8134                     + mAutoStopProfiler);
   8135         }
   8136         if (mAlwaysFinishActivities || mController != null) {
   8137             pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
   8138                     + " mController=" + mController);
   8139         }
   8140         if (dumpAll) {
   8141             pw.println("  Total persistent processes: " + numPers);
   8142             pw.println("  mStartRunning=" + mStartRunning
   8143                     + " mProcessesReady=" + mProcessesReady
   8144                     + " mSystemReady=" + mSystemReady);
   8145             pw.println("  mBooting=" + mBooting
   8146                     + " mBooted=" + mBooted
   8147                     + " mFactoryTest=" + mFactoryTest);
   8148             pw.print("  mLastPowerCheckRealtime=");
   8149                     TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
   8150                     pw.println("");
   8151             pw.print("  mLastPowerCheckUptime=");
   8152                     TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
   8153                     pw.println("");
   8154             pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
   8155             pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
   8156             pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
   8157         }
   8158 
   8159         return true;
   8160     }
   8161 
   8162     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
   8163             int opti, boolean needSep, boolean dumpAll) {
   8164         if (mProcessesToGc.size() > 0) {
   8165             if (needSep) pw.println(" ");
   8166             needSep = true;
   8167             pw.println("  Processes that are waiting to GC:");
   8168             long now = SystemClock.uptimeMillis();
   8169             for (int i=0; i<mProcessesToGc.size(); i++) {
   8170                 ProcessRecord proc = mProcessesToGc.get(i);
   8171                 pw.print("    Process "); pw.println(proc);
   8172                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
   8173                         pw.print(", last gced=");
   8174                         pw.print(now-proc.lastRequestedGc);
   8175                         pw.print(" ms ago, last lowMem=");
   8176                         pw.print(now-proc.lastLowMemory);
   8177                         pw.println(" ms ago");
   8178 
   8179             }
   8180         }
   8181         return needSep;
   8182     }
   8183 
   8184     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   8185             int opti, boolean dumpAll) {
   8186         boolean needSep = false;
   8187 
   8188         if (mLruProcesses.size() > 0) {
   8189             if (needSep) pw.println(" ");
   8190             needSep = true;
   8191             pw.println("  OOM levels:");
   8192             pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
   8193             pw.print("    CORE_SERVER_ADJ: "); pw.println(ProcessList.CORE_SERVER_ADJ);
   8194             pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
   8195             pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
   8196             pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
   8197             pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
   8198             pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
   8199             pw.print("    SECONDARY_SERVER_ADJ: "); pw.println(ProcessList.SECONDARY_SERVER_ADJ);
   8200             pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
   8201             pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
   8202             pw.print("    EMPTY_APP_ADJ: "); pw.println(ProcessList.EMPTY_APP_ADJ);
   8203 
   8204             if (needSep) pw.println(" ");
   8205             needSep = true;
   8206             pw.println("  Process OOM control:");
   8207             dumpProcessOomList(pw, this, mLruProcesses, "    ",
   8208                     "Proc", "PERS", true);
   8209             needSep = true;
   8210         }
   8211 
   8212         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
   8213 
   8214         pw.println();
   8215         pw.println("  mHomeProcess: " + mHomeProcess);
   8216         if (mHeavyWeightProcess != null) {
   8217             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   8218         }
   8219 
   8220         return true;
   8221     }
   8222 
   8223     /**
   8224      * There are three ways to call this:
   8225      *  - no service specified: dump all the services
   8226      *  - a flattened component name that matched an existing service was specified as the
   8227      *    first arg: dump that one service
   8228      *  - the first arg isn't the flattened component name of an existing service:
   8229      *    dump all services whose component contains the first arg as a substring
   8230      */
   8231     protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   8232             int opti, boolean dumpAll) {
   8233         ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
   8234 
   8235         if ("all".equals(name)) {
   8236             synchronized (this) {
   8237                 for (ServiceRecord r1 : mServices.values()) {
   8238                     services.add(r1);
   8239                 }
   8240             }
   8241         } else {
   8242             ComponentName componentName = name != null
   8243                     ? ComponentName.unflattenFromString(name) : null;
   8244             int objectId = 0;
   8245             if (componentName == null) {
   8246                 // Not a '/' separated full component name; maybe an object ID?
   8247                 try {
   8248                     objectId = Integer.parseInt(name, 16);
   8249                     name = null;
   8250                     componentName = null;
   8251                 } catch (RuntimeException e) {
   8252                 }
   8253             }
   8254 
   8255             synchronized (this) {
   8256                 for (ServiceRecord r1 : mServices.values()) {
   8257                     if (componentName != null) {
   8258                         if (r1.name.equals(componentName)) {
   8259                             services.add(r1);
   8260                         }
   8261                     } else if (name != null) {
   8262                         if (r1.name.flattenToString().contains(name)) {
   8263                             services.add(r1);
   8264                         }
   8265                     } else if (System.identityHashCode(r1) == objectId) {
   8266                         services.add(r1);
   8267                     }
   8268                 }
   8269             }
   8270         }
   8271 
   8272         if (services.size() <= 0) {
   8273             return false;
   8274         }
   8275 
   8276         boolean needSep = false;
   8277         for (int i=0; i<services.size(); i++) {
   8278             if (needSep) {
   8279                 pw.println();
   8280             }
   8281             needSep = true;
   8282             dumpService("", fd, pw, services.get(i), args, dumpAll);
   8283         }
   8284         return true;
   8285     }
   8286 
   8287     /**
   8288      * Invokes IApplicationThread.dumpService() on the thread of the specified service if
   8289      * there is a thread associated with the service.
   8290      */
   8291     private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
   8292             final ServiceRecord r, String[] args, boolean dumpAll) {
   8293         String innerPrefix = prefix + "  ";
   8294         synchronized (this) {
   8295             pw.print(prefix); pw.print("SERVICE ");
   8296                     pw.print(r.shortName); pw.print(" ");
   8297                     pw.print(Integer.toHexString(System.identityHashCode(r)));
   8298                     pw.print(" pid=");
   8299                     if (r.app != null) pw.println(r.app.pid);
   8300                     else pw.println("(not running)");
   8301             if (dumpAll) {
   8302                 r.dump(pw, innerPrefix);
   8303             }
   8304         }
   8305         if (r.app != null && r.app.thread != null) {
   8306             pw.print(prefix); pw.println("  Client:");
   8307             pw.flush();
   8308             try {
   8309                 TransferPipe tp = new TransferPipe();
   8310                 try {
   8311                     r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
   8312                     tp.setBufferPrefix(prefix + "    ");
   8313                     tp.go(fd);
   8314                 } finally {
   8315                     tp.kill();
   8316                 }
   8317             } catch (IOException e) {
   8318                 pw.println(prefix + "    Failure while dumping the service: " + e);
   8319             } catch (RemoteException e) {
   8320                 pw.println(prefix + "    Got a RemoteException while dumping the service");
   8321             }
   8322         }
   8323     }
   8324 
   8325     static class ItemMatcher {
   8326         ArrayList<ComponentName> components;
   8327         ArrayList<String> strings;
   8328         ArrayList<Integer> objects;
   8329         boolean all;
   8330 
   8331         ItemMatcher() {
   8332             all = true;
   8333         }
   8334 
   8335         void build(String name) {
   8336             ComponentName componentName = ComponentName.unflattenFromString(name);
   8337             if (componentName != null) {
   8338                 if (components == null) {
   8339                     components = new ArrayList<ComponentName>();
   8340                 }
   8341                 components.add(componentName);
   8342                 all = false;
   8343             } else {
   8344                 int objectId = 0;
   8345                 // Not a '/' separated full component name; maybe an object ID?
   8346                 try {
   8347                     objectId = Integer.parseInt(name, 16);
   8348                     if (objects == null) {
   8349                         objects = new ArrayList<Integer>();
   8350                     }
   8351                     objects.add(objectId);
   8352                     all = false;
   8353                 } catch (RuntimeException e) {
   8354                     // Not an integer; just do string match.
   8355                     if (strings == null) {
   8356                         strings = new ArrayList<String>();
   8357                     }
   8358                     strings.add(name);
   8359                     all = false;
   8360                 }
   8361             }
   8362         }
   8363 
   8364         int build(String[] args, int opti) {
   8365             for (; opti<args.length; opti++) {
   8366                 String name = args[opti];
   8367                 if ("--".equals(name)) {
   8368                     return opti+1;
   8369                 }
   8370                 build(name);
   8371             }
   8372             return opti;
   8373         }
   8374 
   8375         boolean match(Object object, ComponentName comp) {
   8376             if (all) {
   8377                 return true;
   8378             }
   8379             if (components != null) {
   8380                 for (int i=0; i<components.size(); i++) {
   8381                     if (components.get(i).equals(comp)) {
   8382                         return true;
   8383                     }
   8384                 }
   8385             }
   8386             if (objects != null) {
   8387                 for (int i=0; i<objects.size(); i++) {
   8388                     if (System.identityHashCode(object) == objects.get(i)) {
   8389                         return true;
   8390                     }
   8391                 }
   8392             }
   8393             if (strings != null) {
   8394                 String flat = comp.flattenToString();
   8395                 for (int i=0; i<strings.size(); i++) {
   8396                     if (flat.contains(strings.get(i))) {
   8397                         return true;
   8398                     }
   8399                 }
   8400             }
   8401             return false;
   8402         }
   8403     }
   8404 
   8405     /**
   8406      * There are three things that cmd can be:
   8407      *  - a flattened component name that matches an existing activity
   8408      *  - the cmd arg isn't the flattened component name of an existing activity:
   8409      *    dump all activity whose component contains the cmd as a substring
   8410      *  - A hex number of the ActivityRecord object instance.
   8411      */
   8412     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   8413             int opti, boolean dumpAll) {
   8414         ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
   8415 
   8416         if ("all".equals(name)) {
   8417             synchronized (this) {
   8418                 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
   8419                     activities.add(r1);
   8420                 }
   8421             }
   8422         } else if ("top".equals(name)) {
   8423             synchronized (this) {
   8424                 final int N = mMainStack.mHistory.size();
   8425                 if (N > 0) {
   8426                     activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
   8427                 }
   8428             }
   8429         } else {
   8430             ItemMatcher matcher = new ItemMatcher();
   8431             matcher.build(name);
   8432 
   8433             synchronized (this) {
   8434                 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
   8435                     if (matcher.match(r1, r1.intent.getComponent())) {
   8436                         activities.add(r1);
   8437                     }
   8438                 }
   8439             }
   8440         }
   8441 
   8442         if (activities.size() <= 0) {
   8443             return false;
   8444         }
   8445 
   8446         String[] newArgs = new String[args.length - opti];
   8447         if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   8448 
   8449         TaskRecord lastTask = null;
   8450         boolean needSep = false;
   8451         for (int i=activities.size()-1; i>=0; i--) {
   8452             ActivityRecord r = (ActivityRecord)activities.get(i);
   8453             if (needSep) {
   8454                 pw.println();
   8455             }
   8456             needSep = true;
   8457             synchronized (this) {
   8458                 if (lastTask != r.task) {
   8459                     lastTask = r.task;
   8460                     pw.print("TASK "); pw.print(lastTask.affinity);
   8461                             pw.print(" id="); pw.println(lastTask.taskId);
   8462                     if (dumpAll) {
   8463                         lastTask.dump(pw, "  ");
   8464                     }
   8465                 }
   8466             }
   8467             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
   8468         }
   8469         return true;
   8470     }
   8471 
   8472     /**
   8473      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
   8474      * there is a thread associated with the activity.
   8475      */
   8476     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
   8477             final ActivityRecord r, String[] args, boolean dumpAll) {
   8478         String innerPrefix = prefix + "  ";
   8479         synchronized (this) {
   8480             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
   8481                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
   8482                     pw.print(" pid=");
   8483                     if (r.app != null) pw.println(r.app.pid);
   8484                     else pw.println("(not running)");
   8485             if (dumpAll) {
   8486                 r.dump(pw, innerPrefix);
   8487             }
   8488         }
   8489         if (r.app != null && r.app.thread != null) {
   8490             // flush anything that is already in the PrintWriter since the thread is going
   8491             // to write to the file descriptor directly
   8492             pw.flush();
   8493             try {
   8494                 TransferPipe tp = new TransferPipe();
   8495                 try {
   8496                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
   8497                             innerPrefix, args);
   8498                     tp.go(fd);
   8499                 } finally {
   8500                     tp.kill();
   8501                 }
   8502             } catch (IOException e) {
   8503                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   8504             } catch (RemoteException e) {
   8505                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   8506             }
   8507         }
   8508     }
   8509 
   8510     boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   8511             int opti, boolean dumpAll) {
   8512         boolean needSep = false;
   8513 
   8514         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
   8515         if (dumpAll) {
   8516             if (mRegisteredReceivers.size() > 0) {
   8517                 pw.println("  Registered Receivers:");
   8518                 Iterator it = mRegisteredReceivers.values().iterator();
   8519                 while (it.hasNext()) {
   8520                     ReceiverList r = (ReceiverList)it.next();
   8521                     pw.print("  * "); pw.println(r);
   8522                     r.dump(pw, "    ");
   8523                 }
   8524             }
   8525 
   8526             pw.println();
   8527             pw.println("  Receiver Resolver Table:");
   8528             mReceiverResolver.dump(pw, null, "    ", null, false);
   8529             needSep = true;
   8530         }
   8531 
   8532         if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
   8533                 || mPendingBroadcast != null) {
   8534             if (mParallelBroadcasts.size() > 0) {
   8535                 pw.println();
   8536                 pw.println("  Active broadcasts:");
   8537             }
   8538             for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
   8539                 pw.println("  Broadcast #" + i + ":");
   8540                 mParallelBroadcasts.get(i).dump(pw, "    ");
   8541             }
   8542             if (mOrderedBroadcasts.size() > 0) {
   8543                 pw.println();
   8544                 pw.println("  Active ordered broadcasts:");
   8545             }
   8546             for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
   8547                 pw.println("  Serialized Broadcast #" + i + ":");
   8548                 mOrderedBroadcasts.get(i).dump(pw, "    ");
   8549             }
   8550             pw.println();
   8551             pw.println("  Pending broadcast:");
   8552             if (mPendingBroadcast != null) {
   8553                 mPendingBroadcast.dump(pw, "    ");
   8554             } else {
   8555                 pw.println("    (null)");
   8556             }
   8557             needSep = true;
   8558         }
   8559 
   8560         if (needSep) {
   8561             pw.println();
   8562         }
   8563         pw.println("  Historical broadcasts:");
   8564         for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
   8565             BroadcastRecord r = mBroadcastHistory[i];
   8566             if (r == null) {
   8567                 break;
   8568             }
   8569             if (dumpAll) {
   8570                 pw.print("  Historical Broadcast #"); pw.print(i); pw.println(":");
   8571                 r.dump(pw, "    ");
   8572             } else {
   8573                 if (i >= 50) {
   8574                     pw.println("  ...");
   8575                     break;
   8576                 }
   8577                 pw.print("  #"); pw.print(i); pw.print(": "); pw.println(r);
   8578             }
   8579         }
   8580         needSep = true;
   8581 
   8582         if (mStickyBroadcasts != null) {
   8583             pw.println();
   8584             pw.println("  Sticky broadcasts:");
   8585             StringBuilder sb = new StringBuilder(128);
   8586             for (Map.Entry<String, ArrayList<Intent>> ent
   8587                     : mStickyBroadcasts.entrySet()) {
   8588                 pw.print("  * Sticky action "); pw.print(ent.getKey());
   8589                 if (dumpAll) {
   8590                     pw.println(":");
   8591                     ArrayList<Intent> intents = ent.getValue();
   8592                     final int N = intents.size();
   8593                     for (int i=0; i<N; i++) {
   8594                         sb.setLength(0);
   8595                         sb.append("    Intent: ");
   8596                         intents.get(i).toShortString(sb, false, true, false);
   8597                         pw.println(sb.toString());
   8598                         Bundle bundle = intents.get(i).getExtras();
   8599                         if (bundle != null) {
   8600                             pw.print("      ");
   8601                             pw.println(bundle.toString());
   8602                         }
   8603                     }
   8604                 } else {
   8605                     pw.println("");
   8606                 }
   8607             }
   8608             needSep = true;
   8609         }
   8610 
   8611         if (dumpAll) {
   8612             pw.println();
   8613             pw.println("  mBroadcastsScheduled=" + mBroadcastsScheduled);
   8614             pw.println("  mHandler:");
   8615             mHandler.dump(new PrintWriterPrinter(pw), "    ");
   8616             needSep = true;
   8617         }
   8618 
   8619         return needSep;
   8620     }
   8621 
   8622     boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   8623             int opti, boolean dumpAll, boolean dumpClient) {
   8624         boolean needSep = false;
   8625 
   8626         ItemMatcher matcher = new ItemMatcher();
   8627         matcher.build(args, opti);
   8628 
   8629         pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
   8630         if (mServices.size() > 0) {
   8631             pw.println("  Active services:");
   8632             long nowReal = SystemClock.elapsedRealtime();
   8633             Iterator<ServiceRecord> it = mServices.values().iterator();
   8634             needSep = false;
   8635             while (it.hasNext()) {
   8636                 ServiceRecord r = it.next();
   8637                 if (!matcher.match(r, r.name)) {
   8638                     continue;
   8639                 }
   8640                 if (needSep) {
   8641                     pw.println();
   8642                 }
   8643                 pw.print("  * "); pw.println(r);
   8644                 if (dumpAll) {
   8645                     r.dump(pw, "    ");
   8646                     needSep = true;
   8647                 } else {
   8648                     pw.print("    app="); pw.println(r.app);
   8649                     pw.print("    created=");
   8650                         TimeUtils.formatDuration(r.createTime, nowReal, pw);
   8651                         pw.print(" started="); pw.print(r.startRequested);
   8652                         pw.print(" connections="); pw.println(r.connections.size());
   8653                 }
   8654                 if (dumpClient && r.app != null && r.app.thread != null) {
   8655                     pw.println("    Client:");
   8656                     pw.flush();
   8657                     try {
   8658                         TransferPipe tp = new TransferPipe();
   8659                         try {
   8660                             r.app.thread.dumpService(
   8661                                     tp.getWriteFd().getFileDescriptor(), r, args);
   8662                             tp.setBufferPrefix("      ");
   8663                             // Short timeout, since blocking here can
   8664                             // deadlock with the application.
   8665                             tp.go(fd, 2000);
   8666                         } finally {
   8667                             tp.kill();
   8668                         }
   8669                     } catch (IOException e) {
   8670                         pw.println("      Failure while dumping the service: " + e);
   8671                     } catch (RemoteException e) {
   8672                         pw.println("      Got a RemoteException while dumping the service");
   8673                     }
   8674                     needSep = true;
   8675                 }
   8676             }
   8677             needSep = true;
   8678         }
   8679 
   8680         if (mPendingServices.size() > 0) {
   8681             if (needSep) pw.println(" ");
   8682             pw.println("  Pending services:");
   8683             for (int i=0; i<mPendingServices.size(); i++) {
   8684                 ServiceRecord r = mPendingServices.get(i);
   8685                 if (!matcher.match(r, r.name)) {
   8686                     continue;
   8687                 }
   8688                 pw.print("  * Pending "); pw.println(r);
   8689                 r.dump(pw, "    ");
   8690             }
   8691             needSep = true;
   8692         }
   8693 
   8694         if (mRestartingServices.size() > 0) {
   8695             if (needSep) pw.println(" ");
   8696             pw.println("  Restarting services:");
   8697             for (int i=0; i<mRestartingServices.size(); i++) {
   8698                 ServiceRecord r = mRestartingServices.get(i);
   8699                 if (!matcher.match(r, r.name)) {
   8700                     continue;
   8701                 }
   8702                 pw.print("  * Restarting "); pw.println(r);
   8703                 r.dump(pw, "    ");
   8704             }
   8705             needSep = true;
   8706         }
   8707 
   8708         if (mStoppingServices.size() > 0) {
   8709             if (needSep) pw.println(" ");
   8710             pw.println("  Stopping services:");
   8711             for (int i=0; i<mStoppingServices.size(); i++) {
   8712                 ServiceRecord r = mStoppingServices.get(i);
   8713                 if (!matcher.match(r, r.name)) {
   8714                     continue;
   8715                 }
   8716                 pw.print("  * Stopping "); pw.println(r);
   8717                 r.dump(pw, "    ");
   8718             }
   8719             needSep = true;
   8720         }
   8721 
   8722         if (dumpAll) {
   8723             if (mServiceConnections.size() > 0) {
   8724                 if (needSep) pw.println(" ");
   8725                 pw.println("  Connection bindings to services:");
   8726                 Iterator<ArrayList<ConnectionRecord>> it
   8727                         = mServiceConnections.values().iterator();
   8728                 while (it.hasNext()) {
   8729                     ArrayList<ConnectionRecord> r = it.next();
   8730                     for (int i=0; i<r.size(); i++) {
   8731                         ConnectionRecord cr = r.get(i);
   8732                         if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
   8733                             continue;
   8734                         }
   8735                         pw.print("  * "); pw.println(cr);
   8736                         cr.dump(pw, "    ");
   8737                     }
   8738                 }
   8739                 needSep = true;
   8740             }
   8741         }
   8742 
   8743         return needSep;
   8744     }
   8745 
   8746     boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   8747             int opti, boolean dumpAll) {
   8748         boolean needSep = false;
   8749 
   8750         ItemMatcher matcher = new ItemMatcher();
   8751         matcher.build(args, opti);
   8752 
   8753         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
   8754         if (mProvidersByClass.size() > 0) {
   8755             if (needSep) pw.println(" ");
   8756             pw.println("  Published content providers (by class):");
   8757             Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it
   8758                     = mProvidersByClass.entrySet().iterator();
   8759             while (it.hasNext()) {
   8760                 Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
   8761                 ContentProviderRecord r = e.getValue();
   8762                 ComponentName comp = e.getKey();
   8763                 String cls = comp.getClassName();
   8764                 int end = cls.lastIndexOf('.');
   8765                 if (end > 0 && end < (cls.length()-2)) {
   8766                     cls = cls.substring(end+1);
   8767                 }
   8768                 if (!matcher.match(r, comp)) {
   8769                     continue;
   8770                 }
   8771                 pw.print("  * "); pw.print(cls); pw.print(" (");
   8772                         pw.print(comp.flattenToShortString()); pw.print(")");
   8773                 if (dumpAll) {
   8774                     pw.println();
   8775                     r.dump(pw, "      ");
   8776                 } else {
   8777                     pw.print("  * "); pw.print(e.getKey().flattenToShortString());
   8778                     if (r.proc != null) {
   8779                         pw.println(":");
   8780                         pw.print("      "); pw.println(r.proc);
   8781                     } else {
   8782                         pw.println();
   8783                     }
   8784                 }
   8785             }
   8786             needSep = true;
   8787         }
   8788 
   8789         if (dumpAll) {
   8790             if (mProvidersByName.size() > 0) {
   8791                 pw.println(" ");
   8792                 pw.println("  Authority to provider mappings:");
   8793                 Iterator<Map.Entry<String, ContentProviderRecord>> it
   8794                         = mProvidersByName.entrySet().iterator();
   8795                 while (it.hasNext()) {
   8796                     Map.Entry<String, ContentProviderRecord> e = it.next();
   8797                     ContentProviderRecord r = e.getValue();
   8798                     if (!matcher.match(r, r.name)) {
   8799                         continue;
   8800                     }
   8801                     pw.print("  "); pw.print(e.getKey()); pw.print(": ");
   8802                             pw.println(r);
   8803                 }
   8804                 needSep = true;
   8805             }
   8806         }
   8807 
   8808         if (mLaunchingProviders.size() > 0) {
   8809             if (needSep) pw.println(" ");
   8810             pw.println("  Launching content providers:");
   8811             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
   8812                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
   8813                         pw.println(mLaunchingProviders.get(i));
   8814             }
   8815             needSep = true;
   8816         }
   8817 
   8818         if (mGrantedUriPermissions.size() > 0) {
   8819             pw.println();
   8820             pw.println("Granted Uri Permissions:");
   8821             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
   8822                 int uid = mGrantedUriPermissions.keyAt(i);
   8823                 HashMap<Uri, UriPermission> perms
   8824                         = mGrantedUriPermissions.valueAt(i);
   8825                 pw.print("  * UID "); pw.print(uid);
   8826                         pw.println(" holds:");
   8827                 for (UriPermission perm : perms.values()) {
   8828                     pw.print("    "); pw.println(perm);
   8829                     if (dumpAll) {
   8830                         perm.dump(pw, "      ");
   8831                     }
   8832                 }
   8833             }
   8834             needSep = true;
   8835         }
   8836 
   8837         return needSep;
   8838     }
   8839 
   8840     boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   8841             int opti, boolean dumpAll) {
   8842         boolean needSep = false;
   8843 
   8844         if (this.mIntentSenderRecords.size() > 0) {
   8845             pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
   8846             Iterator<WeakReference<PendingIntentRecord>> it
   8847                     = mIntentSenderRecords.values().iterator();
   8848             while (it.hasNext()) {
   8849                 WeakReference<PendingIntentRecord> ref = it.next();
   8850                 PendingIntentRecord rec = ref != null ? ref.get(): null;
   8851                 needSep = true;
   8852                 if (rec != null) {
   8853                     pw.print("  * "); pw.println(rec);
   8854                     if (dumpAll) {
   8855                         rec.dump(pw, "    ");
   8856                     }
   8857                 } else {
   8858                     pw.print("  * "); pw.println(ref);
   8859                 }
   8860             }
   8861         }
   8862 
   8863         return needSep;
   8864     }
   8865 
   8866     private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
   8867             String prefix, String label, boolean complete, boolean brief, boolean client) {
   8868         TaskRecord lastTask = null;
   8869         boolean needNL = false;
   8870         final String innerPrefix = prefix + "      ";
   8871         final String[] args = new String[0];
   8872         for (int i=list.size()-1; i>=0; i--) {
   8873             final ActivityRecord r = (ActivityRecord)list.get(i);
   8874             final boolean full = !brief && (complete || !r.isInHistory());
   8875             if (needNL) {
   8876                 pw.println(" ");
   8877                 needNL = false;
   8878             }
   8879             if (lastTask != r.task) {
   8880                 lastTask = r.task;
   8881                 pw.print(prefix);
   8882                 pw.print(full ? "* " : "  ");
   8883                 pw.println(lastTask);
   8884                 if (full) {
   8885                     lastTask.dump(pw, prefix + "  ");
   8886                 } else if (complete) {
   8887                     // Complete + brief == give a summary.  Isn't that obvious?!?
   8888                     if (lastTask.intent != null) {
   8889                         pw.print(prefix); pw.print("  ");
   8890                                 pw.println(lastTask.intent.toInsecureString());
   8891                     }
   8892                 }
   8893             }
   8894             pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
   8895             pw.print(" #"); pw.print(i); pw.print(": ");
   8896             pw.println(r);
   8897             if (full) {
   8898                 r.dump(pw, innerPrefix);
   8899             } else if (complete) {
   8900                 // Complete + brief == give a summary.  Isn't that obvious?!?
   8901                 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
   8902                 if (r.app != null) {
   8903                     pw.print(innerPrefix); pw.println(r.app);
   8904                 }
   8905             }
   8906             if (client && r.app != null && r.app.thread != null) {
   8907                 // flush anything that is already in the PrintWriter since the thread is going
   8908                 // to write to the file descriptor directly
   8909                 pw.flush();
   8910                 try {
   8911                     TransferPipe tp = new TransferPipe();
   8912                     try {
   8913                         r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
   8914                                 innerPrefix, args);
   8915                         // Short timeout, since blocking here can
   8916                         // deadlock with the application.
   8917                         tp.go(fd, 2000);
   8918                     } finally {
   8919                         tp.kill();
   8920                     }
   8921                 } catch (IOException e) {
   8922                     pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   8923                 } catch (RemoteException e) {
   8924                     pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   8925                 }
   8926                 needNL = true;
   8927             }
   8928         }
   8929     }
   8930 
   8931     private static String buildOomTag(String prefix, String space, int val, int base) {
   8932         if (val == base) {
   8933             if (space == null) return prefix;
   8934             return prefix + "  ";
   8935         }
   8936         return prefix + "+" + Integer.toString(val-base);
   8937     }
   8938 
   8939     private static final int dumpProcessList(PrintWriter pw,
   8940             ActivityManagerService service, List list,
   8941             String prefix, String normalLabel, String persistentLabel) {
   8942         int numPers = 0;
   8943         final int N = list.size()-1;
   8944         for (int i=N; i>=0; i--) {
   8945             ProcessRecord r = (ProcessRecord)list.get(i);
   8946             pw.println(String.format("%s%s #%2d: %s",
   8947                     prefix, (r.persistent ? persistentLabel : normalLabel),
   8948                     i, r.toString()));
   8949             if (r.persistent) {
   8950                 numPers++;
   8951             }
   8952         }
   8953         return numPers;
   8954     }
   8955 
   8956     private static final void dumpProcessOomList(PrintWriter pw,
   8957             ActivityManagerService service, List<ProcessRecord> origList,
   8958             String prefix, String normalLabel, String persistentLabel,
   8959             boolean inclDetails) {
   8960 
   8961         ArrayList<Pair<ProcessRecord, Integer>> list
   8962                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
   8963         for (int i=0; i<origList.size(); i++) {
   8964             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
   8965         }
   8966 
   8967         Comparator<Pair<ProcessRecord, Integer>> comparator
   8968                 = new Comparator<Pair<ProcessRecord, Integer>>() {
   8969             @Override
   8970             public int compare(Pair<ProcessRecord, Integer> object1,
   8971                     Pair<ProcessRecord, Integer> object2) {
   8972                 if (object1.first.setAdj != object2.first.setAdj) {
   8973                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
   8974                 }
   8975                 if (object1.second.intValue() != object2.second.intValue()) {
   8976                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
   8977                 }
   8978                 return 0;
   8979             }
   8980         };
   8981 
   8982         Collections.sort(list, comparator);
   8983 
   8984         final long curRealtime = SystemClock.elapsedRealtime();
   8985         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
   8986         final long curUptime = SystemClock.uptimeMillis();
   8987         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
   8988 
   8989         final int N = list.size()-1;
   8990         for (int i=N; i>=0; i--) {
   8991             ProcessRecord r = list.get(i).first;
   8992             String oomAdj;
   8993             if (r.setAdj >= ProcessList.EMPTY_APP_ADJ) {
   8994                 oomAdj = buildOomTag("empty", null, r.setAdj, ProcessList.EMPTY_APP_ADJ);
   8995             } else if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   8996                 oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
   8997             } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
   8998                 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
   8999             } else if (r.setAdj >= ProcessList.SECONDARY_SERVER_ADJ) {
   9000                 oomAdj = buildOomTag("svc", "  ", r.setAdj, ProcessList.SECONDARY_SERVER_ADJ);
   9001             } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
   9002                 oomAdj = buildOomTag("bckup", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
   9003             } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   9004                 oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
   9005             } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   9006                 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
   9007             } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
   9008                 oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
   9009             } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
   9010                 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
   9011             } else if (r.setAdj >= ProcessList.CORE_SERVER_ADJ) {
   9012                 oomAdj = buildOomTag("core ", null, r.setAdj, ProcessList.CORE_SERVER_ADJ);
   9013             } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
   9014                 oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
   9015             } else {
   9016                 oomAdj = Integer.toString(r.setAdj);
   9017             }
   9018             String schedGroup;
   9019             switch (r.setSchedGroup) {
   9020                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
   9021                     schedGroup = "B";
   9022                     break;
   9023                 case Process.THREAD_GROUP_DEFAULT:
   9024                     schedGroup = "F";
   9025                     break;
   9026                 default:
   9027                     schedGroup = Integer.toString(r.setSchedGroup);
   9028                     break;
   9029             }
   9030             String foreground;
   9031             if (r.foregroundActivities) {
   9032                 foreground = "A";
   9033             } else if (r.foregroundServices) {
   9034                 foreground = "S";
   9035             } else {
   9036                 foreground = " ";
   9037             }
   9038             pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
   9039                     prefix, (r.persistent ? persistentLabel : normalLabel),
   9040                     N-list.get(i).second, oomAdj, schedGroup, foreground, r.trimMemoryLevel,
   9041                     r.toShortString(), r.adjType));
   9042             if (r.adjSource != null || r.adjTarget != null) {
   9043                 pw.print(prefix);
   9044                 pw.print("    ");
   9045                 if (r.adjTarget instanceof ComponentName) {
   9046                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
   9047                 } else if (r.adjTarget != null) {
   9048                     pw.print(r.adjTarget.toString());
   9049                 } else {
   9050                     pw.print("{null}");
   9051                 }
   9052                 pw.print("<=");
   9053                 if (r.adjSource instanceof ProcessRecord) {
   9054                     pw.print("Proc{");
   9055                     pw.print(((ProcessRecord)r.adjSource).toShortString());
   9056                     pw.println("}");
   9057                 } else if (r.adjSource != null) {
   9058                     pw.println(r.adjSource.toString());
   9059                 } else {
   9060                     pw.println("{null}");
   9061                 }
   9062             }
   9063             if (inclDetails) {
   9064                 pw.print(prefix);
   9065                 pw.print("    ");
   9066                 pw.print("oom: max="); pw.print(r.maxAdj);
   9067                 pw.print(" hidden="); pw.print(r.hiddenAdj);
   9068                 pw.print(" curRaw="); pw.print(r.curRawAdj);
   9069                 pw.print(" setRaw="); pw.print(r.setRawAdj);
   9070                 pw.print(" cur="); pw.print(r.curAdj);
   9071                 pw.print(" set="); pw.println(r.setAdj);
   9072                 pw.print(prefix);
   9073                 pw.print("    ");
   9074                 pw.print("keeping="); pw.print(r.keeping);
   9075                 pw.print(" hidden="); pw.print(r.hidden);
   9076                 pw.print(" empty="); pw.print(r.empty);
   9077                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
   9078 
   9079                 if (!r.keeping) {
   9080                     if (r.lastWakeTime != 0) {
   9081                         long wtime;
   9082                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
   9083                         synchronized (stats) {
   9084                             wtime = stats.getProcessWakeTime(r.info.uid,
   9085                                     r.pid, curRealtime);
   9086                         }
   9087                         long timeUsed = wtime - r.lastWakeTime;
   9088                         pw.print(prefix);
   9089                         pw.print("    ");
   9090                         pw.print("keep awake over ");
   9091                         TimeUtils.formatDuration(realtimeSince, pw);
   9092                         pw.print(" used ");
   9093                         TimeUtils.formatDuration(timeUsed, pw);
   9094                         pw.print(" (");
   9095                         pw.print((timeUsed*100)/realtimeSince);
   9096                         pw.println("%)");
   9097                     }
   9098                     if (r.lastCpuTime != 0) {
   9099                         long timeUsed = r.curCpuTime - r.lastCpuTime;
   9100                         pw.print(prefix);
   9101                         pw.print("    ");
   9102                         pw.print("run cpu over ");
   9103                         TimeUtils.formatDuration(uptimeSince, pw);
   9104                         pw.print(" used ");
   9105                         TimeUtils.formatDuration(timeUsed, pw);
   9106                         pw.print(" (");
   9107                         pw.print((timeUsed*100)/uptimeSince);
   9108                         pw.println("%)");
   9109                     }
   9110                 }
   9111             }
   9112         }
   9113     }
   9114 
   9115     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
   9116         ArrayList<ProcessRecord> procs;
   9117         synchronized (this) {
   9118             if (args != null && args.length > start
   9119                     && args[start].charAt(0) != '-') {
   9120                 procs = new ArrayList<ProcessRecord>();
   9121                 int pid = -1;
   9122                 try {
   9123                     pid = Integer.parseInt(args[start]);
   9124                 } catch (NumberFormatException e) {
   9125 
   9126                 }
   9127                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   9128                     ProcessRecord proc = mLruProcesses.get(i);
   9129                     if (proc.pid == pid) {
   9130                         procs.add(proc);
   9131                     } else if (proc.processName.equals(args[start])) {
   9132                         procs.add(proc);
   9133                     }
   9134                 }
   9135                 if (procs.size() <= 0) {
   9136                     pw.println("No process found for: " + args[start]);
   9137                     return null;
   9138                 }
   9139             } else {
   9140                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
   9141             }
   9142         }
   9143         return procs;
   9144     }
   9145 
   9146     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
   9147             PrintWriter pw, String[] args) {
   9148         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
   9149         if (procs == null) {
   9150             return;
   9151         }
   9152 
   9153         long uptime = SystemClock.uptimeMillis();
   9154         long realtime = SystemClock.elapsedRealtime();
   9155         pw.println("Applications Graphics Acceleration Info:");
   9156         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   9157 
   9158         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   9159             ProcessRecord r = procs.get(i);
   9160             if (r.thread != null) {
   9161                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
   9162                 pw.flush();
   9163                 try {
   9164                     TransferPipe tp = new TransferPipe();
   9165                     try {
   9166                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
   9167                         tp.go(fd);
   9168                     } finally {
   9169                         tp.kill();
   9170                     }
   9171                 } catch (IOException e) {
   9172                     pw.println("Failure while dumping the app: " + r);
   9173                     pw.flush();
   9174                 } catch (RemoteException e) {
   9175                     pw.println("Got a RemoteException while dumping the app " + r);
   9176                     pw.flush();
   9177                 }
   9178             }
   9179         }
   9180     }
   9181 
   9182     final static class MemItem {
   9183         final String label;
   9184         final long pss;
   9185         ArrayList<MemItem> subitems;
   9186 
   9187         public MemItem(String _label, long _pss) {
   9188             label = _label;
   9189             pss = _pss;
   9190         }
   9191     }
   9192 
   9193     final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
   9194             boolean sort) {
   9195         if (sort) {
   9196             Collections.sort(items, new Comparator<MemItem>() {
   9197                 @Override
   9198                 public int compare(MemItem lhs, MemItem rhs) {
   9199                     if (lhs.pss < rhs.pss) {
   9200                         return 1;
   9201                     } else if (lhs.pss > rhs.pss) {
   9202                         return -1;
   9203                     }
   9204                     return 0;
   9205                 }
   9206             });
   9207         }
   9208 
   9209         for (int i=0; i<items.size(); i++) {
   9210             MemItem mi = items.get(i);
   9211             pw.print(prefix); pw.printf("%7d Kb: ", mi.pss); pw.println(mi.label);
   9212             if (mi.subitems != null) {
   9213                 dumpMemItems(pw, prefix + "           ", mi.subitems, true);
   9214             }
   9215         }
   9216     }
   9217 
   9218     final void dumpApplicationMemoryUsage(FileDescriptor fd,
   9219             PrintWriter pw, String prefix, String[] args) {
   9220         boolean dumpAll = false;
   9221 
   9222         int opti = 0;
   9223         while (opti < args.length) {
   9224             String opt = args[opti];
   9225             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   9226                 break;
   9227             }
   9228             opti++;
   9229             if ("-a".equals(opt)) {
   9230                 dumpAll = true;
   9231             } else if ("-h".equals(opt)) {
   9232                 pw.println("meminfo dump options: [-a] [process]");
   9233                 pw.println("  -a: include all available information for each process.");
   9234                 pw.println("If [process] is specified it can be the name or ");
   9235                 pw.println("pid of a specific process to dump.");
   9236                 return;
   9237             } else {
   9238                 pw.println("Unknown argument: " + opt + "; use -h for help");
   9239             }
   9240         }
   9241 
   9242         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
   9243         if (procs == null) {
   9244             return;
   9245         }
   9246 
   9247         final boolean isCheckinRequest = scanArgs(args, "--checkin");
   9248         long uptime = SystemClock.uptimeMillis();
   9249         long realtime = SystemClock.elapsedRealtime();
   9250 
   9251         if (procs.size() == 1 || isCheckinRequest) {
   9252             dumpAll = true;
   9253         }
   9254 
   9255         if (isCheckinRequest) {
   9256             // short checkin version
   9257             pw.println(uptime + "," + realtime);
   9258             pw.flush();
   9259         } else {
   9260             pw.println("Applications Memory Usage (kB):");
   9261             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   9262         }
   9263 
   9264         String[] innerArgs = new String[args.length-opti];
   9265         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
   9266 
   9267         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
   9268         long nativePss=0, dalvikPss=0, otherPss=0;
   9269         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
   9270 
   9271         final int[] oomAdj = new int[] {
   9272             ProcessList.SYSTEM_ADJ, ProcessList.CORE_SERVER_ADJ, ProcessList.FOREGROUND_APP_ADJ,
   9273             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
   9274             ProcessList.BACKUP_APP_ADJ, ProcessList.SECONDARY_SERVER_ADJ, ProcessList.HOME_APP_ADJ, ProcessList.EMPTY_APP_ADJ
   9275         };
   9276         final String[] oomLabel = new String[] {
   9277                 "System", "Persistent", "Foreground",
   9278                 "Visible", "Perceptible", "Heavy Weight",
   9279                 "Backup", "Services", "Home", "Background"
   9280         };
   9281         long oomPss[] = new long[oomLabel.length];
   9282         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])new ArrayList[oomLabel.length];
   9283 
   9284         long totalPss = 0;
   9285 
   9286         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   9287             ProcessRecord r = procs.get(i);
   9288             if (r.thread != null) {
   9289                 if (!isCheckinRequest && dumpAll) {
   9290                     pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
   9291                     pw.flush();
   9292                 }
   9293                 Debug.MemoryInfo mi = null;
   9294                 if (dumpAll) {
   9295                     try {
   9296                         mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
   9297                     } catch (RemoteException e) {
   9298                         if (!isCheckinRequest) {
   9299                             pw.println("Got RemoteException!");
   9300                             pw.flush();
   9301                         }
   9302                     }
   9303                 } else {
   9304                     mi = new Debug.MemoryInfo();
   9305                     Debug.getMemoryInfo(r.pid, mi);
   9306                 }
   9307 
   9308                 if (!isCheckinRequest && mi != null) {
   9309                     long myTotalPss = mi.getTotalPss();
   9310                     totalPss += myTotalPss;
   9311                     MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
   9312                             myTotalPss);
   9313                     procMems.add(pssItem);
   9314 
   9315                     nativePss += mi.nativePss;
   9316                     dalvikPss += mi.dalvikPss;
   9317                     otherPss += mi.otherPss;
   9318                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   9319                         long mem = mi.getOtherPss(j);
   9320                         miscPss[j] += mem;
   9321                         otherPss -= mem;
   9322                     }
   9323 
   9324                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
   9325                         if (r.setAdj <= oomAdj[oomIndex] || oomIndex == (oomPss.length-1)) {
   9326                             oomPss[oomIndex] += myTotalPss;
   9327                             if (oomProcs[oomIndex] == null) {
   9328                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
   9329                             }
   9330                             oomProcs[oomIndex].add(pssItem);
   9331                             break;
   9332                         }
   9333                     }
   9334                 }
   9335             }
   9336         }
   9337 
   9338         if (!isCheckinRequest && procs.size() > 1) {
   9339             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
   9340 
   9341             catMems.add(new MemItem("Native", nativePss));
   9342             catMems.add(new MemItem("Dalvik", dalvikPss));
   9343             catMems.add(new MemItem("Unknown", otherPss));
   9344             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   9345                 catMems.add(new MemItem(Debug.MemoryInfo.getOtherLabel(j), miscPss[j]));
   9346             }
   9347 
   9348             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
   9349             for (int j=0; j<oomPss.length; j++) {
   9350                 if (oomPss[j] != 0) {
   9351                     MemItem item = new MemItem(oomLabel[j], oomPss[j]);
   9352                     item.subitems = oomProcs[j];
   9353                     oomMems.add(item);
   9354                 }
   9355             }
   9356 
   9357             pw.println();
   9358             pw.println("Total PSS by process:");
   9359             dumpMemItems(pw, "  ", procMems, true);
   9360             pw.println();
   9361             pw.println("Total PSS by OOM adjustment:");
   9362             dumpMemItems(pw, "  ", oomMems, false);
   9363             pw.println();
   9364             pw.println("Total PSS by category:");
   9365             dumpMemItems(pw, "  ", catMems, true);
   9366             pw.println();
   9367             pw.print("Total PSS: "); pw.print(totalPss); pw.println(" Kb");
   9368         }
   9369     }
   9370 
   9371     /**
   9372      * Searches array of arguments for the specified string
   9373      * @param args array of argument strings
   9374      * @param value value to search for
   9375      * @return true if the value is contained in the array
   9376      */
   9377     private static boolean scanArgs(String[] args, String value) {
   9378         if (args != null) {
   9379             for (String arg : args) {
   9380                 if (value.equals(arg)) {
   9381                     return true;
   9382                 }
   9383             }
   9384         }
   9385         return false;
   9386     }
   9387 
   9388     private final void killServicesLocked(ProcessRecord app,
   9389             boolean allowRestart) {
   9390         // Report disconnected services.
   9391         if (false) {
   9392             // XXX we are letting the client link to the service for
   9393             // death notifications.
   9394             if (app.services.size() > 0) {
   9395                 Iterator<ServiceRecord> it = app.services.iterator();
   9396                 while (it.hasNext()) {
   9397                     ServiceRecord r = it.next();
   9398                     if (r.connections.size() > 0) {
   9399                         Iterator<ArrayList<ConnectionRecord>> jt
   9400                                 = r.connections.values().iterator();
   9401                         while (jt.hasNext()) {
   9402                             ArrayList<ConnectionRecord> cl = jt.next();
   9403                             for (int i=0; i<cl.size(); i++) {
   9404                                 ConnectionRecord c = cl.get(i);
   9405                                 if (c.binding.client != app) {
   9406                                     try {
   9407                                         //c.conn.connected(r.className, null);
   9408                                     } catch (Exception e) {
   9409                                         // todo: this should be asynchronous!
   9410                                         Slog.w(TAG, "Exception thrown disconnected servce "
   9411                                               + r.shortName
   9412                                               + " from app " + app.processName, e);
   9413                                     }
   9414                                 }
   9415                             }
   9416                         }
   9417                     }
   9418                 }
   9419             }
   9420         }
   9421 
   9422         // Clean up any connections this application has to other services.
   9423         if (app.connections.size() > 0) {
   9424             Iterator<ConnectionRecord> it = app.connections.iterator();
   9425             while (it.hasNext()) {
   9426                 ConnectionRecord r = it.next();
   9427                 removeConnectionLocked(r, app, null);
   9428             }
   9429         }
   9430         app.connections.clear();
   9431 
   9432         if (app.services.size() != 0) {
   9433             // Any services running in the application need to be placed
   9434             // back in the pending list.
   9435             Iterator<ServiceRecord> it = app.services.iterator();
   9436             while (it.hasNext()) {
   9437                 ServiceRecord sr = it.next();
   9438                 synchronized (sr.stats.getBatteryStats()) {
   9439                     sr.stats.stopLaunchedLocked();
   9440                 }
   9441                 sr.app = null;
   9442                 sr.executeNesting = 0;
   9443                 if (mStoppingServices.remove(sr)) {
   9444                     if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
   9445                 }
   9446 
   9447                 boolean hasClients = sr.bindings.size() > 0;
   9448                 if (hasClients) {
   9449                     Iterator<IntentBindRecord> bindings
   9450                             = sr.bindings.values().iterator();
   9451                     while (bindings.hasNext()) {
   9452                         IntentBindRecord b = bindings.next();
   9453                         if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
   9454                                 + ": shouldUnbind=" + b.hasBound);
   9455                         b.binder = null;
   9456                         b.requested = b.received = b.hasBound = false;
   9457                     }
   9458                 }
   9459 
   9460                 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
   9461                         &ApplicationInfo.FLAG_PERSISTENT) == 0) {
   9462                     Slog.w(TAG, "Service crashed " + sr.crashCount
   9463                             + " times, stopping: " + sr);
   9464                     EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
   9465                             sr.crashCount, sr.shortName, app.pid);
   9466                     bringDownServiceLocked(sr, true);
   9467                 } else if (!allowRestart) {
   9468                     bringDownServiceLocked(sr, true);
   9469                 } else {
   9470                     boolean canceled = scheduleServiceRestartLocked(sr, true);
   9471 
   9472                     // Should the service remain running?  Note that in the
   9473                     // extreme case of so many attempts to deliver a command
   9474                     // that it failed we also will stop it here.
   9475                     if (sr.startRequested && (sr.stopIfKilled || canceled)) {
   9476                         if (sr.pendingStarts.size() == 0) {
   9477                             sr.startRequested = false;
   9478                             if (!hasClients) {
   9479                                 // Whoops, no reason to restart!
   9480                                 bringDownServiceLocked(sr, true);
   9481                             }
   9482                         }
   9483                     }
   9484                 }
   9485             }
   9486 
   9487             if (!allowRestart) {
   9488                 app.services.clear();
   9489             }
   9490         }
   9491 
   9492         // Make sure we have no more records on the stopping list.
   9493         int i = mStoppingServices.size();
   9494         while (i > 0) {
   9495             i--;
   9496             ServiceRecord sr = mStoppingServices.get(i);
   9497             if (sr.app == app) {
   9498                 mStoppingServices.remove(i);
   9499                 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
   9500             }
   9501         }
   9502 
   9503         app.executingServices.clear();
   9504     }
   9505 
   9506     private final void removeDyingProviderLocked(ProcessRecord proc,
   9507             ContentProviderRecord cpr) {
   9508         synchronized (cpr) {
   9509             cpr.launchingApp = null;
   9510             cpr.notifyAll();
   9511         }
   9512 
   9513         mProvidersByClass.remove(cpr.name);
   9514         String names[] = cpr.info.authority.split(";");
   9515         for (int j = 0; j < names.length; j++) {
   9516             mProvidersByName.remove(names[j]);
   9517         }
   9518 
   9519         Iterator<ProcessRecord> cit = cpr.clients.iterator();
   9520         while (cit.hasNext()) {
   9521             ProcessRecord capp = cit.next();
   9522             if (!capp.persistent && capp.thread != null
   9523                     && capp.pid != 0
   9524                     && capp.pid != MY_PID) {
   9525                 Slog.i(TAG, "Kill " + capp.processName
   9526                         + " (pid " + capp.pid + "): provider " + cpr.info.name
   9527                         + " in dying process " + (proc != null ? proc.processName : "??"));
   9528                 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
   9529                         capp.processName, capp.setAdj, "dying provider "
   9530                                 + cpr.name.toShortString());
   9531                 Process.killProcessQuiet(capp.pid);
   9532             }
   9533         }
   9534 
   9535         mLaunchingProviders.remove(cpr);
   9536     }
   9537 
   9538     /**
   9539      * Main code for cleaning up a process when it has gone away.  This is
   9540      * called both as a result of the process dying, or directly when stopping
   9541      * a process when running in single process mode.
   9542      */
   9543     private final void cleanUpApplicationRecordLocked(ProcessRecord app,
   9544             boolean restarting, boolean allowRestart, int index) {
   9545         if (index >= 0) {
   9546             mLruProcesses.remove(index);
   9547         }
   9548 
   9549         mProcessesToGc.remove(app);
   9550 
   9551         // Dismiss any open dialogs.
   9552         if (app.crashDialog != null) {
   9553             app.crashDialog.dismiss();
   9554             app.crashDialog = null;
   9555         }
   9556         if (app.anrDialog != null) {
   9557             app.anrDialog.dismiss();
   9558             app.anrDialog = null;
   9559         }
   9560         if (app.waitDialog != null) {
   9561             app.waitDialog.dismiss();
   9562             app.waitDialog = null;
   9563         }
   9564 
   9565         app.crashing = false;
   9566         app.notResponding = false;
   9567 
   9568         app.resetPackageList();
   9569         app.unlinkDeathRecipient();
   9570         app.thread = null;
   9571         app.forcingToForeground = null;
   9572         app.foregroundServices = false;
   9573         app.foregroundActivities = false;
   9574         app.hasShownUi = false;
   9575         app.hasAboveClient = false;
   9576 
   9577         killServicesLocked(app, allowRestart);
   9578 
   9579         boolean restart = false;
   9580 
   9581         int NL = mLaunchingProviders.size();
   9582 
   9583         // Remove published content providers.
   9584         if (!app.pubProviders.isEmpty()) {
   9585             Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
   9586             while (it.hasNext()) {
   9587                 ContentProviderRecord cpr = it.next();
   9588                 cpr.provider = null;
   9589                 cpr.proc = null;
   9590 
   9591                 // See if someone is waiting for this provider...  in which
   9592                 // case we don't remove it, but just let it restart.
   9593                 int i = 0;
   9594                 if (!app.bad && allowRestart) {
   9595                     for (; i<NL; i++) {
   9596                         if (mLaunchingProviders.get(i) == cpr) {
   9597                             restart = true;
   9598                             break;
   9599                         }
   9600                     }
   9601                 } else {
   9602                     i = NL;
   9603                 }
   9604 
   9605                 if (i >= NL) {
   9606                     removeDyingProviderLocked(app, cpr);
   9607                     NL = mLaunchingProviders.size();
   9608                 }
   9609             }
   9610             app.pubProviders.clear();
   9611         }
   9612 
   9613         // Take care of any launching providers waiting for this process.
   9614         if (checkAppInLaunchingProvidersLocked(app, false)) {
   9615             restart = true;
   9616         }
   9617 
   9618         // Unregister from connected content providers.
   9619         if (!app.conProviders.isEmpty()) {
   9620             Iterator it = app.conProviders.keySet().iterator();
   9621             while (it.hasNext()) {
   9622                 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
   9623                 cpr.clients.remove(app);
   9624             }
   9625             app.conProviders.clear();
   9626         }
   9627 
   9628         // At this point there may be remaining entries in mLaunchingProviders
   9629         // where we were the only one waiting, so they are no longer of use.
   9630         // Look for these and clean up if found.
   9631         // XXX Commented out for now.  Trying to figure out a way to reproduce
   9632         // the actual situation to identify what is actually going on.
   9633         if (false) {
   9634             for (int i=0; i<NL; i++) {
   9635                 ContentProviderRecord cpr = (ContentProviderRecord)
   9636                         mLaunchingProviders.get(i);
   9637                 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
   9638                     synchronized (cpr) {
   9639                         cpr.launchingApp = null;
   9640                         cpr.notifyAll();
   9641                     }
   9642                 }
   9643             }
   9644         }
   9645 
   9646         skipCurrentReceiverLocked(app);
   9647 
   9648         // Unregister any receivers.
   9649         if (app.receivers.size() > 0) {
   9650             Iterator<ReceiverList> it = app.receivers.iterator();
   9651             while (it.hasNext()) {
   9652                 removeReceiverLocked(it.next());
   9653             }
   9654             app.receivers.clear();
   9655         }
   9656 
   9657         // If the app is undergoing backup, tell the backup manager about it
   9658         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
   9659             if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
   9660             try {
   9661                 IBackupManager bm = IBackupManager.Stub.asInterface(
   9662                         ServiceManager.getService(Context.BACKUP_SERVICE));
   9663                 bm.agentDisconnected(app.info.packageName);
   9664             } catch (RemoteException e) {
   9665                 // can't happen; backup manager is local
   9666             }
   9667         }
   9668 
   9669         mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
   9670 
   9671         // If the caller is restarting this app, then leave it in its
   9672         // current lists and let the caller take care of it.
   9673         if (restarting) {
   9674             return;
   9675         }
   9676 
   9677         if (!app.persistent) {
   9678             if (DEBUG_PROCESSES) Slog.v(TAG,
   9679                     "Removing non-persistent process during cleanup: " + app);
   9680             mProcessNames.remove(app.processName, app.info.uid);
   9681             if (mHeavyWeightProcess == app) {
   9682                 mHeavyWeightProcess = null;
   9683                 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
   9684             }
   9685         } else if (!app.removed) {
   9686             // This app is persistent, so we need to keep its record around.
   9687             // If it is not already on the pending app list, add it there
   9688             // and start a new process for it.
   9689             if (mPersistentStartingProcesses.indexOf(app) < 0) {
   9690                 mPersistentStartingProcesses.add(app);
   9691                 restart = true;
   9692             }
   9693         }
   9694         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   9695                 "Clean-up removing on hold: " + app);
   9696         mProcessesOnHold.remove(app);
   9697 
   9698         if (app == mHomeProcess) {
   9699             mHomeProcess = null;
   9700         }
   9701 
   9702         if (restart) {
   9703             // We have components that still need to be running in the
   9704             // process, so re-launch it.
   9705             mProcessNames.put(app.processName, app.info.uid, app);
   9706             startProcessLocked(app, "restart", app.processName);
   9707         } else if (app.pid > 0 && app.pid != MY_PID) {
   9708             // Goodbye!
   9709             synchronized (mPidsSelfLocked) {
   9710                 mPidsSelfLocked.remove(app.pid);
   9711                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   9712             }
   9713             app.setPid(0);
   9714         }
   9715     }
   9716 
   9717     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
   9718         // Look through the content providers we are waiting to have launched,
   9719         // and if any run in this process then either schedule a restart of
   9720         // the process or kill the client waiting for it if this process has
   9721         // gone bad.
   9722         int NL = mLaunchingProviders.size();
   9723         boolean restart = false;
   9724         for (int i=0; i<NL; i++) {
   9725             ContentProviderRecord cpr = mLaunchingProviders.get(i);
   9726             if (cpr.launchingApp == app) {
   9727                 if (!alwaysBad && !app.bad) {
   9728                     restart = true;
   9729                 } else {
   9730                     removeDyingProviderLocked(app, cpr);
   9731                     NL = mLaunchingProviders.size();
   9732                 }
   9733             }
   9734         }
   9735         return restart;
   9736     }
   9737 
   9738     // =========================================================
   9739     // SERVICES
   9740     // =========================================================
   9741 
   9742     ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
   9743         ActivityManager.RunningServiceInfo info =
   9744             new ActivityManager.RunningServiceInfo();
   9745         info.service = r.name;
   9746         if (r.app != null) {
   9747             info.pid = r.app.pid;
   9748         }
   9749         info.uid = r.appInfo.uid;
   9750         info.process = r.processName;
   9751         info.foreground = r.isForeground;
   9752         info.activeSince = r.createTime;
   9753         info.started = r.startRequested;
   9754         info.clientCount = r.connections.size();
   9755         info.crashCount = r.crashCount;
   9756         info.lastActivityTime = r.lastActivity;
   9757         if (r.isForeground) {
   9758             info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
   9759         }
   9760         if (r.startRequested) {
   9761             info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
   9762         }
   9763         if (r.app != null && r.app.pid == MY_PID) {
   9764             info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
   9765         }
   9766         if (r.app != null && r.app.persistent) {
   9767             info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
   9768         }
   9769 
   9770         for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
   9771             for (int i=0; i<connl.size(); i++) {
   9772                 ConnectionRecord conn = connl.get(i);
   9773                 if (conn.clientLabel != 0) {
   9774                     info.clientPackage = conn.binding.client.info.packageName;
   9775                     info.clientLabel = conn.clientLabel;
   9776                     return info;
   9777                 }
   9778             }
   9779         }
   9780         return info;
   9781     }
   9782 
   9783     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
   9784             int flags) {
   9785         synchronized (this) {
   9786             ArrayList<ActivityManager.RunningServiceInfo> res
   9787                     = new ArrayList<ActivityManager.RunningServiceInfo>();
   9788 
   9789             if (mServices.size() > 0) {
   9790                 Iterator<ServiceRecord> it = mServices.values().iterator();
   9791                 while (it.hasNext() && res.size() < maxNum) {
   9792                     res.add(makeRunningServiceInfoLocked(it.next()));
   9793                 }
   9794             }
   9795 
   9796             for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
   9797                 ServiceRecord r = mRestartingServices.get(i);
   9798                 ActivityManager.RunningServiceInfo info =
   9799                         makeRunningServiceInfoLocked(r);
   9800                 info.restarting = r.nextRestartTime;
   9801                 res.add(info);
   9802             }
   9803 
   9804             return res;
   9805         }
   9806     }
   9807 
   9808     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
   9809         synchronized (this) {
   9810             ServiceRecord r = mServices.get(name);
   9811             if (r != null) {
   9812                 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
   9813                     for (int i=0; i<conn.size(); i++) {
   9814                         if (conn.get(i).clientIntent != null) {
   9815                             return conn.get(i).clientIntent;
   9816                         }
   9817                     }
   9818                 }
   9819             }
   9820         }
   9821         return null;
   9822     }
   9823 
   9824     private final ServiceRecord findServiceLocked(ComponentName name,
   9825             IBinder token) {
   9826         ServiceRecord r = mServices.get(name);
   9827         return r == token ? r : null;
   9828     }
   9829 
   9830     private final class ServiceLookupResult {
   9831         final ServiceRecord record;
   9832         final String permission;
   9833 
   9834         ServiceLookupResult(ServiceRecord _record, String _permission) {
   9835             record = _record;
   9836             permission = _permission;
   9837         }
   9838     };
   9839 
   9840     private ServiceLookupResult findServiceLocked(Intent service,
   9841             String resolvedType) {
   9842         ServiceRecord r = null;
   9843         if (service.getComponent() != null) {
   9844             r = mServices.get(service.getComponent());
   9845         }
   9846         if (r == null) {
   9847             Intent.FilterComparison filter = new Intent.FilterComparison(service);
   9848             r = mServicesByIntent.get(filter);
   9849         }
   9850 
   9851         if (r == null) {
   9852             try {
   9853                 ResolveInfo rInfo =
   9854                     AppGlobals.getPackageManager().resolveService(
   9855                             service, resolvedType, 0);
   9856                 ServiceInfo sInfo =
   9857                     rInfo != null ? rInfo.serviceInfo : null;
   9858                 if (sInfo == null) {
   9859                     return null;
   9860                 }
   9861 
   9862                 ComponentName name = new ComponentName(
   9863                         sInfo.applicationInfo.packageName, sInfo.name);
   9864                 r = mServices.get(name);
   9865             } catch (RemoteException ex) {
   9866                 // pm is in same process, this will never happen.
   9867             }
   9868         }
   9869         if (r != null) {
   9870             int callingPid = Binder.getCallingPid();
   9871             int callingUid = Binder.getCallingUid();
   9872             if (checkComponentPermission(r.permission,
   9873                     callingPid, callingUid, r.appInfo.uid, r.exported)
   9874                     != PackageManager.PERMISSION_GRANTED) {
   9875                 if (!r.exported) {
   9876                     Slog.w(TAG, "Permission Denial: Accessing service " + r.name
   9877                             + " from pid=" + callingPid
   9878                             + ", uid=" + callingUid
   9879                             + " that is not exported from uid " + r.appInfo.uid);
   9880                     return new ServiceLookupResult(null, "not exported from uid "
   9881                             + r.appInfo.uid);
   9882                 }
   9883                 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
   9884                         + " from pid=" + callingPid
   9885                         + ", uid=" + callingUid
   9886                         + " requires " + r.permission);
   9887                 return new ServiceLookupResult(null, r.permission);
   9888             }
   9889             return new ServiceLookupResult(r, null);
   9890         }
   9891         return null;
   9892     }
   9893 
   9894     private class ServiceRestarter implements Runnable {
   9895         private ServiceRecord mService;
   9896 
   9897         void setService(ServiceRecord service) {
   9898             mService = service;
   9899         }
   9900 
   9901         public void run() {
   9902             synchronized(ActivityManagerService.this) {
   9903                 performServiceRestartLocked(mService);
   9904             }
   9905         }
   9906     }
   9907 
   9908     private ServiceLookupResult retrieveServiceLocked(Intent service,
   9909             String resolvedType, int callingPid, int callingUid) {
   9910         ServiceRecord r = null;
   9911         if (service.getComponent() != null) {
   9912             r = mServices.get(service.getComponent());
   9913         }
   9914         Intent.FilterComparison filter = new Intent.FilterComparison(service);
   9915         r = mServicesByIntent.get(filter);
   9916         if (r == null) {
   9917             try {
   9918                 ResolveInfo rInfo =
   9919                     AppGlobals.getPackageManager().resolveService(
   9920                             service, resolvedType, STOCK_PM_FLAGS);
   9921                 ServiceInfo sInfo =
   9922                     rInfo != null ? rInfo.serviceInfo : null;
   9923                 if (sInfo == null) {
   9924                     Slog.w(TAG, "Unable to start service " + service +
   9925                           ": not found");
   9926                     return null;
   9927                 }
   9928 
   9929                 ComponentName name = new ComponentName(
   9930                         sInfo.applicationInfo.packageName, sInfo.name);
   9931                 r = mServices.get(name);
   9932                 if (r == null) {
   9933                     filter = new Intent.FilterComparison(service.cloneFilter());
   9934                     ServiceRestarter res = new ServiceRestarter();
   9935                     BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   9936                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   9937                     synchronized (stats) {
   9938                         ss = stats.getServiceStatsLocked(
   9939                                 sInfo.applicationInfo.uid, sInfo.packageName,
   9940                                 sInfo.name);
   9941                     }
   9942                     r = new ServiceRecord(this, ss, name, filter, sInfo, res);
   9943                     res.setService(r);
   9944                     mServices.put(name, r);
   9945                     mServicesByIntent.put(filter, r);
   9946 
   9947                     // Make sure this component isn't in the pending list.
   9948                     int N = mPendingServices.size();
   9949                     for (int i=0; i<N; i++) {
   9950                         ServiceRecord pr = mPendingServices.get(i);
   9951                         if (pr.name.equals(name)) {
   9952                             mPendingServices.remove(i);
   9953                             i--;
   9954                             N--;
   9955                         }
   9956                     }
   9957                 }
   9958             } catch (RemoteException ex) {
   9959                 // pm is in same process, this will never happen.
   9960             }
   9961         }
   9962         if (r != null) {
   9963             if (checkComponentPermission(r.permission,
   9964                     callingPid, callingUid, r.appInfo.uid, r.exported)
   9965                     != PackageManager.PERMISSION_GRANTED) {
   9966                 if (!r.exported) {
   9967                     Slog.w(TAG, "Permission Denial: Accessing service " + r.name
   9968                             + " from pid=" + callingPid
   9969                             + ", uid=" + callingUid
   9970                             + " that is not exported from uid " + r.appInfo.uid);
   9971                     return new ServiceLookupResult(null, "not exported from uid "
   9972                             + r.appInfo.uid);
   9973                 }
   9974                 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
   9975                         + " from pid=" + callingPid
   9976                         + ", uid=" + callingUid
   9977                         + " requires " + r.permission);
   9978                 return new ServiceLookupResult(null, r.permission);
   9979             }
   9980             return new ServiceLookupResult(r, null);
   9981         }
   9982         return null;
   9983     }
   9984 
   9985     private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
   9986         if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
   9987                 + why + " of " + r + " in app " + r.app);
   9988         else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
   9989                 + why + " of " + r.shortName);
   9990         long now = SystemClock.uptimeMillis();
   9991         if (r.executeNesting == 0 && r.app != null) {
   9992             if (r.app.executingServices.size() == 0) {
   9993                 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   9994                 msg.obj = r.app;
   9995                 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
   9996             }
   9997             r.app.executingServices.add(r);
   9998         }
   9999         r.executeNesting++;
   10000         r.executingStart = now;
   10001     }
   10002 
   10003     private final void sendServiceArgsLocked(ServiceRecord r,
   10004             boolean oomAdjusted) {
   10005         final int N = r.pendingStarts.size();
   10006         if (N == 0) {
   10007             return;
   10008         }
   10009 
   10010         while (r.pendingStarts.size() > 0) {
   10011             try {
   10012                 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
   10013                 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
   10014                         + r + " " + r.intent + " args=" + si.intent);
   10015                 if (si.intent == null && N > 1) {
   10016                     // If somehow we got a dummy null intent in the middle,
   10017                     // then skip it.  DO NOT skip a null intent when it is
   10018                     // the only one in the list -- this is to support the
   10019                     // onStartCommand(null) case.
   10020                     continue;
   10021                 }
   10022                 si.deliveredTime = SystemClock.uptimeMillis();
   10023                 r.deliveredStarts.add(si);
   10024                 si.deliveryCount++;
   10025                 if (si.targetPermissionUid >= 0 && si.intent != null) {
   10026                     grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
   10027                             r.packageName, si.intent, si.getUriPermissionsLocked());
   10028                 }
   10029                 bumpServiceExecutingLocked(r, "start");
   10030                 if (!oomAdjusted) {
   10031                     oomAdjusted = true;
   10032                     updateOomAdjLocked(r.app);
   10033                 }
   10034                 int flags = 0;
   10035                 if (si.deliveryCount > 0) {
   10036                     flags |= Service.START_FLAG_RETRY;
   10037                 }
   10038                 if (si.doneExecutingCount > 0) {
   10039                     flags |= Service.START_FLAG_REDELIVERY;
   10040                 }
   10041                 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
   10042             } catch (RemoteException e) {
   10043                 // Remote process gone...  we'll let the normal cleanup take
   10044                 // care of this.
   10045                 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
   10046                 break;
   10047             } catch (Exception e) {
   10048                 Slog.w(TAG, "Unexpected exception", e);
   10049                 break;
   10050             }
   10051         }
   10052     }
   10053 
   10054     private final boolean requestServiceBindingLocked(ServiceRecord r,
   10055             IntentBindRecord i, boolean rebind) {
   10056         if (r.app == null || r.app.thread == null) {
   10057             // If service is not currently running, can't yet bind.
   10058             return false;
   10059         }
   10060         if ((!i.requested || rebind) && i.apps.size() > 0) {
   10061             try {
   10062                 bumpServiceExecutingLocked(r, "bind");
   10063                 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
   10064                 if (!rebind) {
   10065                     i.requested = true;
   10066                 }
   10067                 i.hasBound = true;
   10068                 i.doRebind = false;
   10069             } catch (RemoteException e) {
   10070                 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
   10071                 return false;
   10072             }
   10073         }
   10074         return true;
   10075     }
   10076 
   10077     private final void requestServiceBindingsLocked(ServiceRecord r) {
   10078         Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
   10079         while (bindings.hasNext()) {
   10080             IntentBindRecord i = bindings.next();
   10081             if (!requestServiceBindingLocked(r, i, false)) {
   10082                 break;
   10083             }
   10084         }
   10085     }
   10086 
   10087     private final void realStartServiceLocked(ServiceRecord r,
   10088             ProcessRecord app) throws RemoteException {
   10089         if (app.thread == null) {
   10090             throw new RemoteException();
   10091         }
   10092 
   10093         r.app = app;
   10094         r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
   10095 
   10096         app.services.add(r);
   10097         bumpServiceExecutingLocked(r, "create");
   10098         updateLruProcessLocked(app, true, true);
   10099 
   10100         boolean created = false;
   10101         try {
   10102             mStringBuilder.setLength(0);
   10103             r.intent.getIntent().toShortString(mStringBuilder, true, false, true);
   10104             EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
   10105                     System.identityHashCode(r), r.shortName,
   10106                     mStringBuilder.toString(), r.app.pid);
   10107             synchronized (r.stats.getBatteryStats()) {
   10108                 r.stats.startLaunchedLocked();
   10109             }
   10110             ensurePackageDexOpt(r.serviceInfo.packageName);
   10111             app.thread.scheduleCreateService(r, r.serviceInfo,
   10112                     compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
   10113             r.postNotification();
   10114             created = true;
   10115         } finally {
   10116             if (!created) {
   10117                 app.services.remove(r);
   10118                 scheduleServiceRestartLocked(r, false);
   10119             }
   10120         }
   10121 
   10122         requestServiceBindingsLocked(r);
   10123 
   10124         // If the service is in the started state, and there are no
   10125         // pending arguments, then fake up one so its onStartCommand() will
   10126         // be called.
   10127         if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
   10128             r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
   10129                     null, -1));
   10130         }
   10131 
   10132         sendServiceArgsLocked(r, true);
   10133     }
   10134 
   10135     private final boolean scheduleServiceRestartLocked(ServiceRecord r,
   10136             boolean allowCancel) {
   10137         boolean canceled = false;
   10138 
   10139         final long now = SystemClock.uptimeMillis();
   10140         long minDuration = SERVICE_RESTART_DURATION;
   10141         long resetTime = SERVICE_RESET_RUN_DURATION;
   10142 
   10143         if ((r.serviceInfo.applicationInfo.flags
   10144                 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
   10145             minDuration /= 4;
   10146         }
   10147 
   10148         // Any delivered but not yet finished starts should be put back
   10149         // on the pending list.
   10150         final int N = r.deliveredStarts.size();
   10151         if (N > 0) {
   10152             for (int i=N-1; i>=0; i--) {
   10153                 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
   10154                 si.removeUriPermissionsLocked();
   10155                 if (si.intent == null) {
   10156                     // We'll generate this again if needed.
   10157                 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
   10158                         && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
   10159                     r.pendingStarts.add(0, si);
   10160                     long dur = SystemClock.uptimeMillis() - si.deliveredTime;
   10161                     dur *= 2;
   10162                     if (minDuration < dur) minDuration = dur;
   10163                     if (resetTime < dur) resetTime = dur;
   10164                 } else {
   10165                     Slog.w(TAG, "Canceling start item " + si.intent + " in service "
   10166                             + r.name);
   10167                     canceled = true;
   10168                 }
   10169             }
   10170             r.deliveredStarts.clear();
   10171         }
   10172 
   10173         r.totalRestartCount++;
   10174         if (r.restartDelay == 0) {
   10175             r.restartCount++;
   10176             r.restartDelay = minDuration;
   10177         } else {
   10178             // If it has been a "reasonably long time" since the service
   10179             // was started, then reset our restart duration back to
   10180             // the beginning, so we don't infinitely increase the duration
   10181             // on a service that just occasionally gets killed (which is
   10182             // a normal case, due to process being killed to reclaim memory).
   10183             if (now > (r.restartTime+resetTime)) {
   10184                 r.restartCount = 1;
   10185                 r.restartDelay = minDuration;
   10186             } else {
   10187                 if ((r.serviceInfo.applicationInfo.flags
   10188                         &ApplicationInfo.FLAG_PERSISTENT) != 0) {
   10189                     // Services in peristent processes will restart much more
   10190                     // quickly, since they are pretty important.  (Think SystemUI).
   10191                     r.restartDelay += minDuration/2;
   10192                 } else {
   10193                     r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
   10194                     if (r.restartDelay < minDuration) {
   10195                         r.restartDelay = minDuration;
   10196                     }
   10197                 }
   10198             }
   10199         }
   10200 
   10201         r.nextRestartTime = now + r.restartDelay;
   10202 
   10203         // Make sure that we don't end up restarting a bunch of services
   10204         // all at the same time.
   10205         boolean repeat;
   10206         do {
   10207             repeat = false;
   10208             for (int i=mRestartingServices.size()-1; i>=0; i--) {
   10209                 ServiceRecord r2 = mRestartingServices.get(i);
   10210                 if (r2 != r && r.nextRestartTime
   10211                         >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
   10212                         && r.nextRestartTime
   10213                         < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
   10214                     r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
   10215                     r.restartDelay = r.nextRestartTime - now;
   10216                     repeat = true;
   10217                     break;
   10218                 }
   10219             }
   10220         } while (repeat);
   10221 
   10222         if (!mRestartingServices.contains(r)) {
   10223             mRestartingServices.add(r);
   10224         }
   10225 
   10226         r.cancelNotification();
   10227 
   10228         mHandler.removeCallbacks(r.restarter);
   10229         mHandler.postAtTime(r.restarter, r.nextRestartTime);
   10230         r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
   10231         Slog.w(TAG, "Scheduling restart of crashed service "
   10232                 + r.shortName + " in " + r.restartDelay + "ms");
   10233         EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
   10234                 r.shortName, r.restartDelay);
   10235 
   10236         return canceled;
   10237     }
   10238 
   10239     final void performServiceRestartLocked(ServiceRecord r) {
   10240         if (!mRestartingServices.contains(r)) {
   10241             return;
   10242         }
   10243         bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
   10244     }
   10245 
   10246     private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
   10247         if (r.restartDelay == 0) {
   10248             return false;
   10249         }
   10250         r.resetRestartCounter();
   10251         mRestartingServices.remove(r);
   10252         mHandler.removeCallbacks(r.restarter);
   10253         return true;
   10254     }
   10255 
   10256     private final boolean bringUpServiceLocked(ServiceRecord r,
   10257             int intentFlags, boolean whileRestarting) {
   10258         //Slog.i(TAG, "Bring up service:");
   10259         //r.dump("  ");
   10260 
   10261         if (r.app != null && r.app.thread != null) {
   10262             sendServiceArgsLocked(r, false);
   10263             return true;
   10264         }
   10265 
   10266         if (!whileRestarting && r.restartDelay > 0) {
   10267             // If waiting for a restart, then do nothing.
   10268             return true;
   10269         }
   10270 
   10271         if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
   10272 
   10273         // We are now bringing the service up, so no longer in the
   10274         // restarting state.
   10275         mRestartingServices.remove(r);
   10276 
   10277         // Service is now being launched, its package can't be stopped.
   10278         try {
   10279             AppGlobals.getPackageManager().setPackageStoppedState(
   10280                     r.packageName, false);
   10281         } catch (RemoteException e) {
   10282         } catch (IllegalArgumentException e) {
   10283             Slog.w(TAG, "Failed trying to unstop package "
   10284                     + r.packageName + ": " + e);
   10285         }
   10286 
   10287         final String appName = r.processName;
   10288         ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
   10289         if (app != null && app.thread != null) {
   10290             try {
   10291                 app.addPackage(r.appInfo.packageName);
   10292                 realStartServiceLocked(r, app);
   10293                 return true;
   10294             } catch (RemoteException e) {
   10295                 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
   10296             }
   10297 
   10298             // If a dead object exception was thrown -- fall through to
   10299             // restart the application.
   10300         }
   10301 
   10302         // Not running -- get it started, and enqueue this service record
   10303         // to be executed when the app comes up.
   10304         if (startProcessLocked(appName, r.appInfo, true, intentFlags,
   10305                 "service", r.name, false) == null) {
   10306             Slog.w(TAG, "Unable to launch app "
   10307                     + r.appInfo.packageName + "/"
   10308                     + r.appInfo.uid + " for service "
   10309                     + r.intent.getIntent() + ": process is bad");
   10310             bringDownServiceLocked(r, true);
   10311             return false;
   10312         }
   10313 
   10314         if (!mPendingServices.contains(r)) {
   10315             mPendingServices.add(r);
   10316         }
   10317 
   10318         return true;
   10319     }
   10320 
   10321     private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
   10322         //Slog.i(TAG, "Bring down service:");
   10323         //r.dump("  ");
   10324 
   10325         // Does it still need to run?
   10326         if (!force && r.startRequested) {
   10327             return;
   10328         }
   10329         if (r.connections.size() > 0) {
   10330             if (!force) {
   10331                 // XXX should probably keep a count of the number of auto-create
   10332                 // connections directly in the service.
   10333                 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
   10334                 while (it.hasNext()) {
   10335                     ArrayList<ConnectionRecord> cr = it.next();
   10336                     for (int i=0; i<cr.size(); i++) {
   10337                         if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
   10338                             return;
   10339                         }
   10340                     }
   10341                 }
   10342             }
   10343 
   10344             // Report to all of the connections that the service is no longer
   10345             // available.
   10346             Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
   10347             while (it.hasNext()) {
   10348                 ArrayList<ConnectionRecord> c = it.next();
   10349                 for (int i=0; i<c.size(); i++) {
   10350                     ConnectionRecord cr = c.get(i);
   10351                     // There is still a connection to the service that is
   10352                     // being brought down.  Mark it as dead.
   10353                     cr.serviceDead = true;
   10354                     try {
   10355                         cr.conn.connected(r.name, null);
   10356                     } catch (Exception e) {
   10357                         Slog.w(TAG, "Failure disconnecting service " + r.name +
   10358                               " to connection " + c.get(i).conn.asBinder() +
   10359                               " (in " + c.get(i).binding.client.processName + ")", e);
   10360                     }
   10361                 }
   10362             }
   10363         }
   10364 
   10365         // Tell the service that it has been unbound.
   10366         if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
   10367             Iterator<IntentBindRecord> it = r.bindings.values().iterator();
   10368             while (it.hasNext()) {
   10369                 IntentBindRecord ibr = it.next();
   10370                 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
   10371                         + ": hasBound=" + ibr.hasBound);
   10372                 if (r.app != null && r.app.thread != null && ibr.hasBound) {
   10373                     try {
   10374                         bumpServiceExecutingLocked(r, "bring down unbind");
   10375                         updateOomAdjLocked(r.app);
   10376                         ibr.hasBound = false;
   10377                         r.app.thread.scheduleUnbindService(r,
   10378                                 ibr.intent.getIntent());
   10379                     } catch (Exception e) {
   10380                         Slog.w(TAG, "Exception when unbinding service "
   10381                                 + r.shortName, e);
   10382                         serviceDoneExecutingLocked(r, true);
   10383                     }
   10384                 }
   10385             }
   10386         }
   10387 
   10388         if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
   10389         EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
   10390                 System.identityHashCode(r), r.shortName,
   10391                 (r.app != null) ? r.app.pid : -1);
   10392 
   10393         mServices.remove(r.name);
   10394         mServicesByIntent.remove(r.intent);
   10395         r.totalRestartCount = 0;
   10396         unscheduleServiceRestartLocked(r);
   10397 
   10398         // Also make sure it is not on the pending list.
   10399         int N = mPendingServices.size();
   10400         for (int i=0; i<N; i++) {
   10401             if (mPendingServices.get(i) == r) {
   10402                 mPendingServices.remove(i);
   10403                 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
   10404                 i--;
   10405                 N--;
   10406             }
   10407         }
   10408 
   10409         r.cancelNotification();
   10410         r.isForeground = false;
   10411         r.foregroundId = 0;
   10412         r.foregroundNoti = null;
   10413 
   10414         // Clear start entries.
   10415         r.clearDeliveredStartsLocked();
   10416         r.pendingStarts.clear();
   10417 
   10418         if (r.app != null) {
   10419             synchronized (r.stats.getBatteryStats()) {
   10420                 r.stats.stopLaunchedLocked();
   10421             }
   10422             r.app.services.remove(r);
   10423             if (r.app.thread != null) {
   10424                 try {
   10425                     bumpServiceExecutingLocked(r, "stop");
   10426                     mStoppingServices.add(r);
   10427                     updateOomAdjLocked(r.app);
   10428                     r.app.thread.scheduleStopService(r);
   10429                 } catch (Exception e) {
   10430                     Slog.w(TAG, "Exception when stopping service "
   10431                             + r.shortName, e);
   10432                     serviceDoneExecutingLocked(r, true);
   10433                 }
   10434                 updateServiceForegroundLocked(r.app, false);
   10435             } else {
   10436                 if (DEBUG_SERVICE) Slog.v(
   10437                     TAG, "Removed service that has no process: " + r);
   10438             }
   10439         } else {
   10440             if (DEBUG_SERVICE) Slog.v(
   10441                 TAG, "Removed service that is not running: " + r);
   10442         }
   10443 
   10444         if (r.bindings.size() > 0) {
   10445             r.bindings.clear();
   10446         }
   10447 
   10448         if (r.restarter instanceof ServiceRestarter) {
   10449            ((ServiceRestarter)r.restarter).setService(null);
   10450         }
   10451     }
   10452 
   10453     ComponentName startServiceLocked(IApplicationThread caller,
   10454             Intent service, String resolvedType,
   10455             int callingPid, int callingUid) {
   10456         synchronized(this) {
   10457             if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
   10458                     + " type=" + resolvedType + " args=" + service.getExtras());
   10459 
   10460             if (caller != null) {
   10461                 final ProcessRecord callerApp = getRecordForAppLocked(caller);
   10462                 if (callerApp == null) {
   10463                     throw new SecurityException(
   10464                             "Unable to find app for caller " + caller
   10465                             + " (pid=" + Binder.getCallingPid()
   10466                             + ") when starting service " + service);
   10467                 }
   10468             }
   10469 
   10470             ServiceLookupResult res =
   10471                 retrieveServiceLocked(service, resolvedType,
   10472                         callingPid, callingUid);
   10473             if (res == null) {
   10474                 return null;
   10475             }
   10476             if (res.record == null) {
   10477                 return new ComponentName("!", res.permission != null
   10478                         ? res.permission : "private to package");
   10479             }
   10480             ServiceRecord r = res.record;
   10481             int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
   10482                     callingUid, r.packageName, service);
   10483             if (unscheduleServiceRestartLocked(r)) {
   10484                 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
   10485             }
   10486             r.startRequested = true;
   10487             r.callStart = false;
   10488             r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
   10489                     service, targetPermissionUid));
   10490             r.lastActivity = SystemClock.uptimeMillis();
   10491             synchronized (r.stats.getBatteryStats()) {
   10492                 r.stats.startRunningLocked();
   10493             }
   10494             if (!bringUpServiceLocked(r, service.getFlags(), false)) {
   10495                 return new ComponentName("!", "Service process is bad");
   10496             }
   10497             return r.name;
   10498         }
   10499     }
   10500 
   10501     public ComponentName startService(IApplicationThread caller, Intent service,
   10502             String resolvedType) {
   10503         // Refuse possible leaked file descriptors
   10504         if (service != null && service.hasFileDescriptors() == true) {
   10505             throw new IllegalArgumentException("File descriptors passed in Intent");
   10506         }
   10507 
   10508         synchronized(this) {
   10509             final int callingPid = Binder.getCallingPid();
   10510             final int callingUid = Binder.getCallingUid();
   10511             final long origId = Binder.clearCallingIdentity();
   10512             ComponentName res = startServiceLocked(caller, service,
   10513                     resolvedType, callingPid, callingUid);
   10514             Binder.restoreCallingIdentity(origId);
   10515             return res;
   10516         }
   10517     }
   10518 
   10519     ComponentName startServiceInPackage(int uid,
   10520             Intent service, String resolvedType) {
   10521         synchronized(this) {
   10522             final long origId = Binder.clearCallingIdentity();
   10523             ComponentName res = startServiceLocked(null, service,
   10524                     resolvedType, -1, uid);
   10525             Binder.restoreCallingIdentity(origId);
   10526             return res;
   10527         }
   10528     }
   10529 
   10530     private void stopServiceLocked(ServiceRecord service) {
   10531         synchronized (service.stats.getBatteryStats()) {
   10532             service.stats.stopRunningLocked();
   10533         }
   10534         service.startRequested = false;
   10535         service.callStart = false;
   10536         bringDownServiceLocked(service, false);
   10537     }
   10538 
   10539     public int stopService(IApplicationThread caller, Intent service,
   10540             String resolvedType) {
   10541         // Refuse possible leaked file descriptors
   10542         if (service != null && service.hasFileDescriptors() == true) {
   10543             throw new IllegalArgumentException("File descriptors passed in Intent");
   10544         }
   10545 
   10546         synchronized(this) {
   10547             if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
   10548                     + " type=" + resolvedType);
   10549 
   10550             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   10551             if (caller != null && callerApp == null) {
   10552                 throw new SecurityException(
   10553                         "Unable to find app for caller " + caller
   10554                         + " (pid=" + Binder.getCallingPid()
   10555                         + ") when stopping service " + service);
   10556             }
   10557 
   10558             // If this service is active, make sure it is stopped.
   10559             ServiceLookupResult r = findServiceLocked(service, resolvedType);
   10560             if (r != null) {
   10561                 if (r.record != null) {
   10562                     final long origId = Binder.clearCallingIdentity();
   10563                     try {
   10564                         stopServiceLocked(r.record);
   10565                     } finally {
   10566                         Binder.restoreCallingIdentity(origId);
   10567                     }
   10568                     return 1;
   10569                 }
   10570                 return -1;
   10571             }
   10572         }
   10573 
   10574         return 0;
   10575     }
   10576 
   10577     public IBinder peekService(Intent service, String resolvedType) {
   10578         // Refuse possible leaked file descriptors
   10579         if (service != null && service.hasFileDescriptors() == true) {
   10580             throw new IllegalArgumentException("File descriptors passed in Intent");
   10581         }
   10582 
   10583         IBinder ret = null;
   10584 
   10585         synchronized(this) {
   10586             ServiceLookupResult r = findServiceLocked(service, resolvedType);
   10587 
   10588             if (r != null) {
   10589                 // r.record is null if findServiceLocked() failed the caller permission check
   10590                 if (r.record == null) {
   10591                     throw new SecurityException(
   10592                             "Permission Denial: Accessing service " + r.record.name
   10593                             + " from pid=" + Binder.getCallingPid()
   10594                             + ", uid=" + Binder.getCallingUid()
   10595                             + " requires " + r.permission);
   10596                 }
   10597                 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
   10598                 if (ib != null) {
   10599                     ret = ib.binder;
   10600                 }
   10601             }
   10602         }
   10603 
   10604         return ret;
   10605     }
   10606 
   10607     public boolean stopServiceToken(ComponentName className, IBinder token,
   10608             int startId) {
   10609         synchronized(this) {
   10610             if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
   10611                     + " " + token + " startId=" + startId);
   10612             ServiceRecord r = findServiceLocked(className, token);
   10613             if (r != null) {
   10614                 if (startId >= 0) {
   10615                     // Asked to only stop if done with all work.  Note that
   10616                     // to avoid leaks, we will take this as dropping all
   10617                     // start items up to and including this one.
   10618                     ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
   10619                     if (si != null) {
   10620                         while (r.deliveredStarts.size() > 0) {
   10621                             ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
   10622                             cur.removeUriPermissionsLocked();
   10623                             if (cur == si) {
   10624                                 break;
   10625                             }
   10626                         }
   10627                     }
   10628 
   10629                     if (r.getLastStartId() != startId) {
   10630                         return false;
   10631                     }
   10632 
   10633                     if (r.deliveredStarts.size() > 0) {
   10634                         Slog.w(TAG, "stopServiceToken startId " + startId
   10635                                 + " is last, but have " + r.deliveredStarts.size()
   10636                                 + " remaining args");
   10637                     }
   10638                 }
   10639 
   10640                 synchronized (r.stats.getBatteryStats()) {
   10641                     r.stats.stopRunningLocked();
   10642                     r.startRequested = false;
   10643                     r.callStart = false;
   10644                 }
   10645                 final long origId = Binder.clearCallingIdentity();
   10646                 bringDownServiceLocked(r, false);
   10647                 Binder.restoreCallingIdentity(origId);
   10648                 return true;
   10649             }
   10650         }
   10651         return false;
   10652     }
   10653 
   10654     public void setServiceForeground(ComponentName className, IBinder token,
   10655             int id, Notification notification, boolean removeNotification) {
   10656         final long origId = Binder.clearCallingIdentity();
   10657         try {
   10658         synchronized(this) {
   10659             ServiceRecord r = findServiceLocked(className, token);
   10660             if (r != null) {
   10661                 if (id != 0) {
   10662                     if (notification == null) {
   10663                         throw new IllegalArgumentException("null notification");
   10664                     }
   10665                     if (r.foregroundId != id) {
   10666                         r.cancelNotification();
   10667                         r.foregroundId = id;
   10668                     }
   10669                     notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
   10670                     r.foregroundNoti = notification;
   10671                     r.isForeground = true;
   10672                     r.postNotification();
   10673                     if (r.app != null) {
   10674                         updateServiceForegroundLocked(r.app, true);
   10675                     }
   10676                 } else {
   10677                     if (r.isForeground) {
   10678                         r.isForeground = false;
   10679                         if (r.app != null) {
   10680                             updateLruProcessLocked(r.app, false, true);
   10681                             updateServiceForegroundLocked(r.app, true);
   10682                         }
   10683                     }
   10684                     if (removeNotification) {
   10685                         r.cancelNotification();
   10686                         r.foregroundId = 0;
   10687                         r.foregroundNoti = null;
   10688                     }
   10689                 }
   10690             }
   10691         }
   10692         } finally {
   10693             Binder.restoreCallingIdentity(origId);
   10694         }
   10695     }
   10696 
   10697     public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
   10698         boolean anyForeground = false;
   10699         for (ServiceRecord sr : proc.services) {
   10700             if (sr.isForeground) {
   10701                 anyForeground = true;
   10702                 break;
   10703             }
   10704         }
   10705         if (anyForeground != proc.foregroundServices) {
   10706             proc.foregroundServices = anyForeground;
   10707             if (oomAdj) {
   10708                 updateOomAdjLocked();
   10709             }
   10710         }
   10711     }
   10712 
   10713     public int bindService(IApplicationThread caller, IBinder token,
   10714             Intent service, String resolvedType,
   10715             IServiceConnection connection, int flags) {
   10716         // Refuse possible leaked file descriptors
   10717         if (service != null && service.hasFileDescriptors() == true) {
   10718             throw new IllegalArgumentException("File descriptors passed in Intent");
   10719         }
   10720 
   10721         synchronized(this) {
   10722             if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
   10723                     + " type=" + resolvedType + " conn=" + connection.asBinder()
   10724                     + " flags=0x" + Integer.toHexString(flags));
   10725             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   10726             if (callerApp == null) {
   10727                 throw new SecurityException(
   10728                         "Unable to find app for caller " + caller
   10729                         + " (pid=" + Binder.getCallingPid()
   10730                         + ") when binding service " + service);
   10731             }
   10732 
   10733             ActivityRecord activity = null;
   10734             if (token != null) {
   10735                 activity = mMainStack.isInStackLocked(token);
   10736                 if (activity == null) {
   10737                     Slog.w(TAG, "Binding with unknown activity: " + token);
   10738                     return 0;
   10739                 }
   10740             }
   10741 
   10742             int clientLabel = 0;
   10743             PendingIntent clientIntent = null;
   10744 
   10745             if (callerApp.info.uid == Process.SYSTEM_UID) {
   10746                 // Hacky kind of thing -- allow system stuff to tell us
   10747                 // what they are, so we can report this elsewhere for
   10748                 // others to know why certain services are running.
   10749                 try {
   10750                     clientIntent = (PendingIntent)service.getParcelableExtra(
   10751                             Intent.EXTRA_CLIENT_INTENT);
   10752                 } catch (RuntimeException e) {
   10753                 }
   10754                 if (clientIntent != null) {
   10755                     clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
   10756                     if (clientLabel != 0) {
   10757                         // There are no useful extras in the intent, trash them.
   10758                         // System code calling with this stuff just needs to know
   10759                         // this will happen.
   10760                         service = service.cloneFilter();
   10761                     }
   10762                 }
   10763             }
   10764 
   10765             ServiceLookupResult res =
   10766                 retrieveServiceLocked(service, resolvedType,
   10767                         Binder.getCallingPid(), Binder.getCallingUid());
   10768             if (res == null) {
   10769                 return 0;
   10770             }
   10771             if (res.record == null) {
   10772                 return -1;
   10773             }
   10774             ServiceRecord s = res.record;
   10775 
   10776             final long origId = Binder.clearCallingIdentity();
   10777 
   10778             if (unscheduleServiceRestartLocked(s)) {
   10779                 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
   10780                         + s);
   10781             }
   10782 
   10783             AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
   10784             ConnectionRecord c = new ConnectionRecord(b, activity,
   10785                     connection, flags, clientLabel, clientIntent);
   10786 
   10787             IBinder binder = connection.asBinder();
   10788             ArrayList<ConnectionRecord> clist = s.connections.get(binder);
   10789             if (clist == null) {
   10790                 clist = new ArrayList<ConnectionRecord>();
   10791                 s.connections.put(binder, clist);
   10792             }
   10793             clist.add(c);
   10794             b.connections.add(c);
   10795             if (activity != null) {
   10796                 if (activity.connections == null) {
   10797                     activity.connections = new HashSet<ConnectionRecord>();
   10798                 }
   10799                 activity.connections.add(c);
   10800             }
   10801             b.client.connections.add(c);
   10802             if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
   10803                 b.client.hasAboveClient = true;
   10804             }
   10805             clist = mServiceConnections.get(binder);
   10806             if (clist == null) {
   10807                 clist = new ArrayList<ConnectionRecord>();
   10808                 mServiceConnections.put(binder, clist);
   10809             }
   10810             clist.add(c);
   10811 
   10812             if ((flags&Context.BIND_AUTO_CREATE) != 0) {
   10813                 s.lastActivity = SystemClock.uptimeMillis();
   10814                 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
   10815                     return 0;
   10816                 }
   10817             }
   10818 
   10819             if (s.app != null) {
   10820                 // This could have made the service more important.
   10821                 updateOomAdjLocked(s.app);
   10822             }
   10823 
   10824             if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
   10825                     + ": received=" + b.intent.received
   10826                     + " apps=" + b.intent.apps.size()
   10827                     + " doRebind=" + b.intent.doRebind);
   10828 
   10829             if (s.app != null && b.intent.received) {
   10830                 // Service is already running, so we can immediately
   10831                 // publish the connection.
   10832                 try {
   10833                     c.conn.connected(s.name, b.intent.binder);
   10834                 } catch (Exception e) {
   10835                     Slog.w(TAG, "Failure sending service " + s.shortName
   10836                             + " to connection " + c.conn.asBinder()
   10837                             + " (in " + c.binding.client.processName + ")", e);
   10838                 }
   10839 
   10840                 // If this is the first app connected back to this binding,
   10841                 // and the service had previously asked to be told when
   10842                 // rebound, then do so.
   10843                 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
   10844                     requestServiceBindingLocked(s, b.intent, true);
   10845                 }
   10846             } else if (!b.intent.requested) {
   10847                 requestServiceBindingLocked(s, b.intent, false);
   10848             }
   10849 
   10850             Binder.restoreCallingIdentity(origId);
   10851         }
   10852 
   10853         return 1;
   10854     }
   10855 
   10856     void removeConnectionLocked(
   10857         ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
   10858         IBinder binder = c.conn.asBinder();
   10859         AppBindRecord b = c.binding;
   10860         ServiceRecord s = b.service;
   10861         ArrayList<ConnectionRecord> clist = s.connections.get(binder);
   10862         if (clist != null) {
   10863             clist.remove(c);
   10864             if (clist.size() == 0) {
   10865                 s.connections.remove(binder);
   10866             }
   10867         }
   10868         b.connections.remove(c);
   10869         if (c.activity != null && c.activity != skipAct) {
   10870             if (c.activity.connections != null) {
   10871                 c.activity.connections.remove(c);
   10872             }
   10873         }
   10874         if (b.client != skipApp) {
   10875             b.client.connections.remove(c);
   10876             if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
   10877                 b.client.updateHasAboveClientLocked();
   10878             }
   10879         }
   10880         clist = mServiceConnections.get(binder);
   10881         if (clist != null) {
   10882             clist.remove(c);
   10883             if (clist.size() == 0) {
   10884                 mServiceConnections.remove(binder);
   10885             }
   10886         }
   10887 
   10888         if (b.connections.size() == 0) {
   10889             b.intent.apps.remove(b.client);
   10890         }
   10891 
   10892         if (!c.serviceDead) {
   10893             if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
   10894                     + ": shouldUnbind=" + b.intent.hasBound);
   10895             if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
   10896                     && b.intent.hasBound) {
   10897                 try {
   10898                     bumpServiceExecutingLocked(s, "unbind");
   10899                     updateOomAdjLocked(s.app);
   10900                     b.intent.hasBound = false;
   10901                     // Assume the client doesn't want to know about a rebind;
   10902                     // we will deal with that later if it asks for one.
   10903                     b.intent.doRebind = false;
   10904                     s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
   10905                 } catch (Exception e) {
   10906                     Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
   10907                     serviceDoneExecutingLocked(s, true);
   10908                 }
   10909             }
   10910 
   10911             if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
   10912                 bringDownServiceLocked(s, false);
   10913             }
   10914         }
   10915     }
   10916 
   10917     public boolean unbindService(IServiceConnection connection) {
   10918         synchronized (this) {
   10919             IBinder binder = connection.asBinder();
   10920             if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
   10921             ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
   10922             if (clist == null) {
   10923                 Slog.w(TAG, "Unbind failed: could not find connection for "
   10924                       + connection.asBinder());
   10925                 return false;
   10926             }
   10927 
   10928             final long origId = Binder.clearCallingIdentity();
   10929 
   10930             while (clist.size() > 0) {
   10931                 ConnectionRecord r = clist.get(0);
   10932                 removeConnectionLocked(r, null, null);
   10933 
   10934                 if (r.binding.service.app != null) {
   10935                     // This could have made the service less important.
   10936                     updateOomAdjLocked(r.binding.service.app);
   10937                 }
   10938             }
   10939 
   10940             Binder.restoreCallingIdentity(origId);
   10941         }
   10942 
   10943         return true;
   10944     }
   10945 
   10946     public void publishService(IBinder token, Intent intent, IBinder service) {
   10947         // Refuse possible leaked file descriptors
   10948         if (intent != null && intent.hasFileDescriptors() == true) {
   10949             throw new IllegalArgumentException("File descriptors passed in Intent");
   10950         }
   10951 
   10952         synchronized(this) {
   10953             if (!(token instanceof ServiceRecord)) {
   10954                 throw new IllegalArgumentException("Invalid service token");
   10955             }
   10956             ServiceRecord r = (ServiceRecord)token;
   10957 
   10958             final long origId = Binder.clearCallingIdentity();
   10959 
   10960             if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
   10961                     + " " + intent + ": " + service);
   10962             if (r != null) {
   10963                 Intent.FilterComparison filter
   10964                         = new Intent.FilterComparison(intent);
   10965                 IntentBindRecord b = r.bindings.get(filter);
   10966                 if (b != null && !b.received) {
   10967                     b.binder = service;
   10968                     b.requested = true;
   10969                     b.received = true;
   10970                     if (r.connections.size() > 0) {
   10971                         Iterator<ArrayList<ConnectionRecord>> it
   10972                                 = r.connections.values().iterator();
   10973                         while (it.hasNext()) {
   10974                             ArrayList<ConnectionRecord> clist = it.next();
   10975                             for (int i=0; i<clist.size(); i++) {
   10976                                 ConnectionRecord c = clist.get(i);
   10977                                 if (!filter.equals(c.binding.intent.intent)) {
   10978                                     if (DEBUG_SERVICE) Slog.v(
   10979                                             TAG, "Not publishing to: " + c);
   10980                                     if (DEBUG_SERVICE) Slog.v(
   10981                                             TAG, "Bound intent: " + c.binding.intent.intent);
   10982                                     if (DEBUG_SERVICE) Slog.v(
   10983                                             TAG, "Published intent: " + intent);
   10984                                     continue;
   10985                                 }
   10986                                 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
   10987                                 try {
   10988                                     c.conn.connected(r.name, service);
   10989                                 } catch (Exception e) {
   10990                                     Slog.w(TAG, "Failure sending service " + r.name +
   10991                                           " to connection " + c.conn.asBinder() +
   10992                                           " (in " + c.binding.client.processName + ")", e);
   10993                                 }
   10994                             }
   10995                         }
   10996                     }
   10997                 }
   10998 
   10999                 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
   11000 
   11001                 Binder.restoreCallingIdentity(origId);
   11002             }
   11003         }
   11004     }
   11005 
   11006     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
   11007         // Refuse possible leaked file descriptors
   11008         if (intent != null && intent.hasFileDescriptors() == true) {
   11009             throw new IllegalArgumentException("File descriptors passed in Intent");
   11010         }
   11011 
   11012         synchronized(this) {
   11013             if (!(token instanceof ServiceRecord)) {
   11014                 throw new IllegalArgumentException("Invalid service token");
   11015             }
   11016             ServiceRecord r = (ServiceRecord)token;
   11017 
   11018             final long origId = Binder.clearCallingIdentity();
   11019 
   11020             if (r != null) {
   11021                 Intent.FilterComparison filter
   11022                         = new Intent.FilterComparison(intent);
   11023                 IntentBindRecord b = r.bindings.get(filter);
   11024                 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
   11025                         + " at " + b + ": apps="
   11026                         + (b != null ? b.apps.size() : 0));
   11027 
   11028                 boolean inStopping = mStoppingServices.contains(r);
   11029                 if (b != null) {
   11030                     if (b.apps.size() > 0 && !inStopping) {
   11031                         // Applications have already bound since the last
   11032                         // unbind, so just rebind right here.
   11033                         requestServiceBindingLocked(r, b, true);
   11034                     } else {
   11035                         // Note to tell the service the next time there is
   11036                         // a new client.
   11037                         b.doRebind = true;
   11038                     }
   11039                 }
   11040 
   11041                 serviceDoneExecutingLocked(r, inStopping);
   11042 
   11043                 Binder.restoreCallingIdentity(origId);
   11044             }
   11045         }
   11046     }
   11047 
   11048     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
   11049         synchronized(this) {
   11050             if (!(token instanceof ServiceRecord)) {
   11051                 throw new IllegalArgumentException("Invalid service token");
   11052             }
   11053             ServiceRecord r = (ServiceRecord)token;
   11054             boolean inStopping = mStoppingServices.contains(token);
   11055             if (r != null) {
   11056                 if (r != token) {
   11057                     Slog.w(TAG, "Done executing service " + r.name
   11058                           + " with incorrect token: given " + token
   11059                           + ", expected " + r);
   11060                     return;
   11061                 }
   11062 
   11063                 if (type == 1) {
   11064                     // This is a call from a service start...  take care of
   11065                     // book-keeping.
   11066                     r.callStart = true;
   11067                     switch (res) {
   11068                         case Service.START_STICKY_COMPATIBILITY:
   11069                         case Service.START_STICKY: {
   11070                             // We are done with the associated start arguments.
   11071                             r.findDeliveredStart(startId, true);
   11072                             // Don't stop if killed.
   11073                             r.stopIfKilled = false;
   11074                             break;
   11075                         }
   11076                         case Service.START_NOT_STICKY: {
   11077                             // We are done with the associated start arguments.
   11078                             r.findDeliveredStart(startId, true);
   11079                             if (r.getLastStartId() == startId) {
   11080                                 // There is no more work, and this service
   11081                                 // doesn't want to hang around if killed.
   11082                                 r.stopIfKilled = true;
   11083                             }
   11084                             break;
   11085                         }
   11086                         case Service.START_REDELIVER_INTENT: {
   11087                             // We'll keep this item until they explicitly
   11088                             // call stop for it, but keep track of the fact
   11089                             // that it was delivered.
   11090                             ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
   11091                             if (si != null) {
   11092                                 si.deliveryCount = 0;
   11093                                 si.doneExecutingCount++;
   11094                                 // Don't stop if killed.
   11095                                 r.stopIfKilled = true;
   11096                             }
   11097                             break;
   11098                         }
   11099                         case Service.START_TASK_REMOVED_COMPLETE: {
   11100                             // Special processing for onTaskRemoved().  Don't
   11101                             // impact normal onStartCommand() processing.
   11102                             r.findDeliveredStart(startId, true);
   11103                             break;
   11104                         }
   11105                         default:
   11106                             throw new IllegalArgumentException(
   11107                                     "Unknown service start result: " + res);
   11108                     }
   11109                     if (res == Service.START_STICKY_COMPATIBILITY) {
   11110                         r.callStart = false;
   11111                     }
   11112                 }
   11113 
   11114                 final long origId = Binder.clearCallingIdentity();
   11115                 serviceDoneExecutingLocked(r, inStopping);
   11116                 Binder.restoreCallingIdentity(origId);
   11117             } else {
   11118                 Slog.w(TAG, "Done executing unknown service from pid "
   11119                         + Binder.getCallingPid());
   11120             }
   11121         }
   11122     }
   11123 
   11124     public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
   11125         if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
   11126                 + ": nesting=" + r.executeNesting
   11127                 + ", inStopping=" + inStopping + ", app=" + r.app);
   11128         else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
   11129         r.executeNesting--;
   11130         if (r.executeNesting <= 0 && r.app != null) {
   11131             if (DEBUG_SERVICE) Slog.v(TAG,
   11132                     "Nesting at 0 of " + r.shortName);
   11133             r.app.executingServices.remove(r);
   11134             if (r.app.executingServices.size() == 0) {
   11135                 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
   11136                         "No more executingServices of " + r.shortName);
   11137                 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
   11138             }
   11139             if (inStopping) {
   11140                 if (DEBUG_SERVICE) Slog.v(TAG,
   11141                         "doneExecuting remove stopping " + r);
   11142                 mStoppingServices.remove(r);
   11143                 r.bindings.clear();
   11144             }
   11145             updateOomAdjLocked(r.app);
   11146         }
   11147     }
   11148 
   11149     void serviceTimeout(ProcessRecord proc) {
   11150         String anrMessage = null;
   11151 
   11152         synchronized(this) {
   11153             if (proc.executingServices.size() == 0 || proc.thread == null) {
   11154                 return;
   11155             }
   11156             long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
   11157             Iterator<ServiceRecord> it = proc.executingServices.iterator();
   11158             ServiceRecord timeout = null;
   11159             long nextTime = 0;
   11160             while (it.hasNext()) {
   11161                 ServiceRecord sr = it.next();
   11162                 if (sr.executingStart < maxTime) {
   11163                     timeout = sr;
   11164                     break;
   11165                 }
   11166                 if (sr.executingStart > nextTime) {
   11167                     nextTime = sr.executingStart;
   11168                 }
   11169             }
   11170             if (timeout != null && mLruProcesses.contains(proc)) {
   11171                 Slog.w(TAG, "Timeout executing service: " + timeout);
   11172                 anrMessage = "Executing service " + timeout.shortName;
   11173             } else {
   11174                 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   11175                 msg.obj = proc;
   11176                 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
   11177             }
   11178         }
   11179 
   11180         if (anrMessage != null) {
   11181             appNotResponding(proc, null, null, anrMessage);
   11182         }
   11183     }
   11184 
   11185     // =========================================================
   11186     // BACKUP AND RESTORE
   11187     // =========================================================
   11188 
   11189     // Cause the target app to be launched if necessary and its backup agent
   11190     // instantiated.  The backup agent will invoke backupAgentCreated() on the
   11191     // activity manager to announce its creation.
   11192     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
   11193         if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
   11194         enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
   11195 
   11196         synchronized(this) {
   11197             // !!! TODO: currently no check here that we're already bound
   11198             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   11199             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   11200             synchronized (stats) {
   11201                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
   11202             }
   11203 
   11204             // Backup agent is now in use, its package can't be stopped.
   11205             try {
   11206                 AppGlobals.getPackageManager().setPackageStoppedState(
   11207                         app.packageName, false);
   11208             } catch (RemoteException e) {
   11209             } catch (IllegalArgumentException e) {
   11210                 Slog.w(TAG, "Failed trying to unstop package "
   11211                         + app.packageName + ": " + e);
   11212             }
   11213 
   11214             BackupRecord r = new BackupRecord(ss, app, backupMode);
   11215             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
   11216                     ? new ComponentName(app.packageName, app.backupAgentName)
   11217                     : new ComponentName("android", "FullBackupAgent");
   11218             // startProcessLocked() returns existing proc's record if it's already running
   11219             ProcessRecord proc = startProcessLocked(app.processName, app,
   11220                     false, 0, "backup", hostingName, false);
   11221             if (proc == null) {
   11222                 Slog.e(TAG, "Unable to start backup agent process " + r);
   11223                 return false;
   11224             }
   11225 
   11226             r.app = proc;
   11227             mBackupTarget = r;
   11228             mBackupAppName = app.packageName;
   11229 
   11230             // Try not to kill the process during backup
   11231             updateOomAdjLocked(proc);
   11232 
   11233             // If the process is already attached, schedule the creation of the backup agent now.
   11234             // If it is not yet live, this will be done when it attaches to the framework.
   11235             if (proc.thread != null) {
   11236                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
   11237                 try {
   11238                     proc.thread.scheduleCreateBackupAgent(app,
   11239                             compatibilityInfoForPackageLocked(app), backupMode);
   11240                 } catch (RemoteException e) {
   11241                     // Will time out on the backup manager side
   11242                 }
   11243             } else {
   11244                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
   11245             }
   11246             // Invariants: at this point, the target app process exists and the application
   11247             // is either already running or in the process of coming up.  mBackupTarget and
   11248             // mBackupAppName describe the app, so that when it binds back to the AM we
   11249             // know that it's scheduled for a backup-agent operation.
   11250         }
   11251 
   11252         return true;
   11253     }
   11254 
   11255     // A backup agent has just come up
   11256     public void backupAgentCreated(String agentPackageName, IBinder agent) {
   11257         if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
   11258                 + " = " + agent);
   11259 
   11260         synchronized(this) {
   11261             if (!agentPackageName.equals(mBackupAppName)) {
   11262                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
   11263                 return;
   11264             }
   11265         }
   11266 
   11267         long oldIdent = Binder.clearCallingIdentity();
   11268         try {
   11269             IBackupManager bm = IBackupManager.Stub.asInterface(
   11270                     ServiceManager.getService(Context.BACKUP_SERVICE));
   11271             bm.agentConnected(agentPackageName, agent);
   11272         } catch (RemoteException e) {
   11273             // can't happen; the backup manager service is local
   11274         } catch (Exception e) {
   11275             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
   11276             e.printStackTrace();
   11277         } finally {
   11278             Binder.restoreCallingIdentity(oldIdent);
   11279         }
   11280     }
   11281 
   11282     // done with this agent
   11283     public void unbindBackupAgent(ApplicationInfo appInfo) {
   11284         if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
   11285         if (appInfo == null) {
   11286             Slog.w(TAG, "unbind backup agent for null app");
   11287             return;
   11288         }
   11289 
   11290         synchronized(this) {
   11291             if (mBackupAppName == null) {
   11292                 Slog.w(TAG, "Unbinding backup agent with no active backup");
   11293                 return;
   11294             }
   11295 
   11296             if (!mBackupAppName.equals(appInfo.packageName)) {
   11297                 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
   11298                 return;
   11299             }
   11300 
   11301             ProcessRecord proc = mBackupTarget.app;
   11302             mBackupTarget = null;
   11303             mBackupAppName = null;
   11304 
   11305             // Not backing this app up any more; reset its OOM adjustment
   11306             updateOomAdjLocked(proc);
   11307 
   11308             // If the app crashed during backup, 'thread' will be null here
   11309             if (proc.thread != null) {
   11310                 try {
   11311                     proc.thread.scheduleDestroyBackupAgent(appInfo,
   11312                             compatibilityInfoForPackageLocked(appInfo));
   11313                 } catch (Exception e) {
   11314                     Slog.e(TAG, "Exception when unbinding backup agent:");
   11315                     e.printStackTrace();
   11316                 }
   11317             }
   11318         }
   11319     }
   11320     // =========================================================
   11321     // BROADCASTS
   11322     // =========================================================
   11323 
   11324     private final List getStickiesLocked(String action, IntentFilter filter,
   11325             List cur) {
   11326         final ContentResolver resolver = mContext.getContentResolver();
   11327         final ArrayList<Intent> list = mStickyBroadcasts.get(action);
   11328         if (list == null) {
   11329             return cur;
   11330         }
   11331         int N = list.size();
   11332         for (int i=0; i<N; i++) {
   11333             Intent intent = list.get(i);
   11334             if (filter.match(resolver, intent, true, TAG) >= 0) {
   11335                 if (cur == null) {
   11336                     cur = new ArrayList<Intent>();
   11337                 }
   11338                 cur.add(intent);
   11339             }
   11340         }
   11341         return cur;
   11342     }
   11343 
   11344     private final void scheduleBroadcastsLocked() {
   11345         if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
   11346                 + mBroadcastsScheduled);
   11347 
   11348         if (mBroadcastsScheduled) {
   11349             return;
   11350         }
   11351         mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
   11352         mBroadcastsScheduled = true;
   11353     }
   11354 
   11355     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
   11356             IIntentReceiver receiver, IntentFilter filter, String permission) {
   11357         synchronized(this) {
   11358             ProcessRecord callerApp = null;
   11359             if (caller != null) {
   11360                 callerApp = getRecordForAppLocked(caller);
   11361                 if (callerApp == null) {
   11362                     throw new SecurityException(
   11363                             "Unable to find app for caller " + caller
   11364                             + " (pid=" + Binder.getCallingPid()
   11365                             + ") when registering receiver " + receiver);
   11366                 }
   11367                 if (callerApp.info.uid != Process.SYSTEM_UID &&
   11368                         !callerApp.pkgList.contains(callerPackage)) {
   11369                     throw new SecurityException("Given caller package " + callerPackage
   11370                             + " is not running in process " + callerApp);
   11371                 }
   11372             } else {
   11373                 callerPackage = null;
   11374             }
   11375 
   11376             List allSticky = null;
   11377 
   11378             // Look for any matching sticky broadcasts...
   11379             Iterator actions = filter.actionsIterator();
   11380             if (actions != null) {
   11381                 while (actions.hasNext()) {
   11382                     String action = (String)actions.next();
   11383                     allSticky = getStickiesLocked(action, filter, allSticky);
   11384                 }
   11385             } else {
   11386                 allSticky = getStickiesLocked(null, filter, allSticky);
   11387             }
   11388 
   11389             // The first sticky in the list is returned directly back to
   11390             // the client.
   11391             Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
   11392 
   11393             if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
   11394                     + ": " + sticky);
   11395 
   11396             if (receiver == null) {
   11397                 return sticky;
   11398             }
   11399 
   11400             ReceiverList rl
   11401                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   11402             if (rl == null) {
   11403                 rl = new ReceiverList(this, callerApp,
   11404                         Binder.getCallingPid(),
   11405                         Binder.getCallingUid(), receiver);
   11406                 if (rl.app != null) {
   11407                     rl.app.receivers.add(rl);
   11408                 } else {
   11409                     try {
   11410                         receiver.asBinder().linkToDeath(rl, 0);
   11411                     } catch (RemoteException e) {
   11412                         return sticky;
   11413                     }
   11414                     rl.linkedToDeath = true;
   11415                 }
   11416                 mRegisteredReceivers.put(receiver.asBinder(), rl);
   11417             }
   11418             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
   11419             rl.add(bf);
   11420             if (!bf.debugCheck()) {
   11421                 Slog.w(TAG, "==> For Dynamic broadast");
   11422             }
   11423             mReceiverResolver.addFilter(bf);
   11424 
   11425             // Enqueue broadcasts for all existing stickies that match
   11426             // this filter.
   11427             if (allSticky != null) {
   11428                 ArrayList receivers = new ArrayList();
   11429                 receivers.add(bf);
   11430 
   11431                 int N = allSticky.size();
   11432                 for (int i=0; i<N; i++) {
   11433                     Intent intent = (Intent)allSticky.get(i);
   11434                     BroadcastRecord r = new BroadcastRecord(intent, null,
   11435                             null, -1, -1, null, receivers, null, 0, null, null,
   11436                             false, true, true);
   11437                     if (mParallelBroadcasts.size() == 0) {
   11438                         scheduleBroadcastsLocked();
   11439                     }
   11440                     mParallelBroadcasts.add(r);
   11441                 }
   11442             }
   11443 
   11444             return sticky;
   11445         }
   11446     }
   11447 
   11448     public void unregisterReceiver(IIntentReceiver receiver) {
   11449         if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
   11450 
   11451         boolean doNext = false;
   11452 
   11453         synchronized(this) {
   11454             ReceiverList rl
   11455                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   11456             if (rl != null) {
   11457                 if (rl.curBroadcast != null) {
   11458                     BroadcastRecord r = rl.curBroadcast;
   11459                     doNext = finishReceiverLocked(
   11460                         receiver.asBinder(), r.resultCode, r.resultData,
   11461                         r.resultExtras, r.resultAbort, true);
   11462                 }
   11463 
   11464                 if (rl.app != null) {
   11465                     rl.app.receivers.remove(rl);
   11466                 }
   11467                 removeReceiverLocked(rl);
   11468                 if (rl.linkedToDeath) {
   11469                     rl.linkedToDeath = false;
   11470                     rl.receiver.asBinder().unlinkToDeath(rl, 0);
   11471                 }
   11472             }
   11473         }
   11474 
   11475         if (!doNext) {
   11476             return;
   11477         }
   11478 
   11479         final long origId = Binder.clearCallingIdentity();
   11480         processNextBroadcast(false);
   11481         trimApplications();
   11482         Binder.restoreCallingIdentity(origId);
   11483     }
   11484 
   11485     void removeReceiverLocked(ReceiverList rl) {
   11486         mRegisteredReceivers.remove(rl.receiver.asBinder());
   11487         int N = rl.size();
   11488         for (int i=0; i<N; i++) {
   11489             mReceiverResolver.removeFilter(rl.get(i));
   11490         }
   11491     }
   11492 
   11493     private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
   11494         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   11495             ProcessRecord r = mLruProcesses.get(i);
   11496             if (r.thread != null) {
   11497                 try {
   11498                     r.thread.dispatchPackageBroadcast(cmd, packages);
   11499                 } catch (RemoteException ex) {
   11500                 }
   11501             }
   11502         }
   11503     }
   11504 
   11505     private final int broadcastIntentLocked(ProcessRecord callerApp,
   11506             String callerPackage, Intent intent, String resolvedType,
   11507             IIntentReceiver resultTo, int resultCode, String resultData,
   11508             Bundle map, String requiredPermission,
   11509             boolean ordered, boolean sticky, int callingPid, int callingUid) {
   11510         intent = new Intent(intent);
   11511 
   11512         // By default broadcasts do not go to stopped apps.
   11513         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
   11514 
   11515         if (DEBUG_BROADCAST_LIGHT) Slog.v(
   11516             TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
   11517             + " ordered=" + ordered);
   11518         if ((resultTo != null) && !ordered) {
   11519             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
   11520         }
   11521 
   11522         // Handle special intents: if this broadcast is from the package
   11523         // manager about a package being removed, we need to remove all of
   11524         // its activities from the history stack.
   11525         final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
   11526                 intent.getAction());
   11527         if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
   11528                 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
   11529                 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
   11530                 || uidRemoved) {
   11531             if (checkComponentPermission(
   11532                     android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
   11533                     callingPid, callingUid, -1, true)
   11534                     == PackageManager.PERMISSION_GRANTED) {
   11535                 if (uidRemoved) {
   11536                     final Bundle intentExtras = intent.getExtras();
   11537                     final int uid = intentExtras != null
   11538                             ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
   11539                     if (uid >= 0) {
   11540                         BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
   11541                         synchronized (bs) {
   11542                             bs.removeUidStatsLocked(uid);
   11543                         }
   11544                     }
   11545                 } else {
   11546                     // If resources are unvailble just force stop all
   11547                     // those packages and flush the attribute cache as well.
   11548                     if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
   11549                         String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   11550                         if (list != null && (list.length > 0)) {
   11551                             for (String pkg : list) {
   11552                                 forceStopPackageLocked(pkg, -1, false, true, true, false);
   11553                             }
   11554                             sendPackageBroadcastLocked(
   11555                                     IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
   11556                         }
   11557                     } else {
   11558                         Uri data = intent.getData();
   11559                         String ssp;
   11560                         if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   11561                             if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
   11562                                 forceStopPackageLocked(ssp,
   11563                                         intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
   11564                             }
   11565                             if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
   11566                                 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
   11567                                         new String[] {ssp});
   11568                             }
   11569                         }
   11570                     }
   11571                 }
   11572             } else {
   11573                 String msg = "Permission Denial: " + intent.getAction()
   11574                         + " broadcast from " + callerPackage + " (pid=" + callingPid
   11575                         + ", uid=" + callingUid + ")"
   11576                         + " requires "
   11577                         + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
   11578                 Slog.w(TAG, msg);
   11579                 throw new SecurityException(msg);
   11580             }
   11581 
   11582         // Special case for adding a package: by default turn on compatibility
   11583         // mode.
   11584         } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
   11585             Uri data = intent.getData();
   11586             String ssp;
   11587             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   11588                 mCompatModePackages.handlePackageAddedLocked(ssp,
   11589                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
   11590             }
   11591         }
   11592 
   11593         /*
   11594          * If this is the time zone changed action, queue up a message that will reset the timezone
   11595          * of all currently running processes. This message will get queued up before the broadcast
   11596          * happens.
   11597          */
   11598         if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
   11599             mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
   11600         }
   11601 
   11602         if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
   11603             mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
   11604         }
   11605 
   11606         if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
   11607             ProxyProperties proxy = intent.getParcelableExtra("proxy");
   11608             mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
   11609         }
   11610 
   11611         /*
   11612          * Prevent non-system code (defined here to be non-persistent
   11613          * processes) from sending protected broadcasts.
   11614          */
   11615         if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
   11616                 || callingUid == Process.SHELL_UID || callingUid == 0) {
   11617             // Always okay.
   11618         } else if (callerApp == null || !callerApp.persistent) {
   11619             try {
   11620                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
   11621                         intent.getAction())) {
   11622                     String msg = "Permission Denial: not allowed to send broadcast "
   11623                             + intent.getAction() + " from pid="
   11624                             + callingPid + ", uid=" + callingUid;
   11625                     Slog.w(TAG, msg);
   11626                     throw new SecurityException(msg);
   11627                 }
   11628             } catch (RemoteException e) {
   11629                 Slog.w(TAG, "Remote exception", e);
   11630                 return BROADCAST_SUCCESS;
   11631             }
   11632         }
   11633 
   11634         // Add to the sticky list if requested.
   11635         if (sticky) {
   11636             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
   11637                     callingPid, callingUid)
   11638                     != PackageManager.PERMISSION_GRANTED) {
   11639                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
   11640                         + callingPid + ", uid=" + callingUid
   11641                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   11642                 Slog.w(TAG, msg);
   11643                 throw new SecurityException(msg);
   11644             }
   11645             if (requiredPermission != null) {
   11646                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
   11647                         + " and enforce permission " + requiredPermission);
   11648                 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
   11649             }
   11650             if (intent.getComponent() != null) {
   11651                 throw new SecurityException(
   11652                         "Sticky broadcasts can't target a specific component");
   11653             }
   11654             ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
   11655             if (list == null) {
   11656                 list = new ArrayList<Intent>();
   11657                 mStickyBroadcasts.put(intent.getAction(), list);
   11658             }
   11659             int N = list.size();
   11660             int i;
   11661             for (i=0; i<N; i++) {
   11662                 if (intent.filterEquals(list.get(i))) {
   11663                     // This sticky already exists, replace it.
   11664                     list.set(i, new Intent(intent));
   11665                     break;
   11666                 }
   11667             }
   11668             if (i >= N) {
   11669                 list.add(new Intent(intent));
   11670             }
   11671         }
   11672 
   11673         // Figure out who all will receive this broadcast.
   11674         List receivers = null;
   11675         List<BroadcastFilter> registeredReceivers = null;
   11676         try {
   11677             if (intent.getComponent() != null) {
   11678                 // Broadcast is going to one specific receiver class...
   11679                 ActivityInfo ai = AppGlobals.getPackageManager().
   11680                     getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
   11681                 if (ai != null) {
   11682                     receivers = new ArrayList();
   11683                     ResolveInfo ri = new ResolveInfo();
   11684                     ri.activityInfo = ai;
   11685                     receivers.add(ri);
   11686                 }
   11687             } else {
   11688                 // Need to resolve the intent to interested receivers...
   11689                 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
   11690                          == 0) {
   11691                     receivers =
   11692                         AppGlobals.getPackageManager().queryIntentReceivers(
   11693                                 intent, resolvedType, STOCK_PM_FLAGS);
   11694                 }
   11695                 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
   11696             }
   11697         } catch (RemoteException ex) {
   11698             // pm is in same process, this will never happen.
   11699         }
   11700 
   11701         final boolean replacePending =
   11702                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
   11703 
   11704         if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
   11705                 + " replacePending=" + replacePending);
   11706 
   11707         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
   11708         if (!ordered && NR > 0) {
   11709             // If we are not serializing this broadcast, then send the
   11710             // registered receivers separately so they don't wait for the
   11711             // components to be launched.
   11712             BroadcastRecord r = new BroadcastRecord(intent, callerApp,
   11713                     callerPackage, callingPid, callingUid, requiredPermission,
   11714                     registeredReceivers, resultTo, resultCode, resultData, map,
   11715                     ordered, sticky, false);
   11716             if (DEBUG_BROADCAST) Slog.v(
   11717                     TAG, "Enqueueing parallel broadcast " + r
   11718                     + ": prev had " + mParallelBroadcasts.size());
   11719             boolean replaced = false;
   11720             if (replacePending) {
   11721                 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
   11722                     if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
   11723                         if (DEBUG_BROADCAST) Slog.v(TAG,
   11724                                 "***** DROPPING PARALLEL: " + intent);
   11725                         mParallelBroadcasts.set(i, r);
   11726                         replaced = true;
   11727                         break;
   11728                     }
   11729                 }
   11730             }
   11731             if (!replaced) {
   11732                 mParallelBroadcasts.add(r);
   11733                 scheduleBroadcastsLocked();
   11734             }
   11735             registeredReceivers = null;
   11736             NR = 0;
   11737         }
   11738 
   11739         // Merge into one list.
   11740         int ir = 0;
   11741         if (receivers != null) {
   11742             // A special case for PACKAGE_ADDED: do not allow the package
   11743             // being added to see this broadcast.  This prevents them from
   11744             // using this as a back door to get run as soon as they are
   11745             // installed.  Maybe in the future we want to have a special install
   11746             // broadcast or such for apps, but we'd like to deliberately make
   11747             // this decision.
   11748             String skipPackages[] = null;
   11749             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
   11750                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
   11751                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
   11752                 Uri data = intent.getData();
   11753                 if (data != null) {
   11754                     String pkgName = data.getSchemeSpecificPart();
   11755                     if (pkgName != null) {
   11756                         skipPackages = new String[] { pkgName };
   11757                     }
   11758                 }
   11759             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
   11760                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   11761             }
   11762             if (skipPackages != null && (skipPackages.length > 0)) {
   11763                 for (String skipPackage : skipPackages) {
   11764                     if (skipPackage != null) {
   11765                         int NT = receivers.size();
   11766                         for (int it=0; it<NT; it++) {
   11767                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
   11768                             if (curt.activityInfo.packageName.equals(skipPackage)) {
   11769                                 receivers.remove(it);
   11770                                 it--;
   11771                                 NT--;
   11772                             }
   11773                         }
   11774                     }
   11775                 }
   11776             }
   11777 
   11778             int NT = receivers != null ? receivers.size() : 0;
   11779             int it = 0;
   11780             ResolveInfo curt = null;
   11781             BroadcastFilter curr = null;
   11782             while (it < NT && ir < NR) {
   11783                 if (curt == null) {
   11784                     curt = (ResolveInfo)receivers.get(it);
   11785                 }
   11786                 if (curr == null) {
   11787                     curr = registeredReceivers.get(ir);
   11788                 }
   11789                 if (curr.getPriority() >= curt.priority) {
   11790                     // Insert this broadcast record into the final list.
   11791                     receivers.add(it, curr);
   11792                     ir++;
   11793                     curr = null;
   11794                     it++;
   11795                     NT++;
   11796                 } else {
   11797                     // Skip to the next ResolveInfo in the final list.
   11798                     it++;
   11799                     curt = null;
   11800                 }
   11801             }
   11802         }
   11803         while (ir < NR) {
   11804             if (receivers == null) {
   11805                 receivers = new ArrayList();
   11806             }
   11807             receivers.add(registeredReceivers.get(ir));
   11808             ir++;
   11809         }
   11810 
   11811         if ((receivers != null && receivers.size() > 0)
   11812                 || resultTo != null) {
   11813             BroadcastRecord r = new BroadcastRecord(intent, callerApp,
   11814                     callerPackage, callingPid, callingUid, requiredPermission,
   11815                     receivers, resultTo, resultCode, resultData, map, ordered,
   11816                     sticky, false);
   11817             if (DEBUG_BROADCAST) Slog.v(
   11818                     TAG, "Enqueueing ordered broadcast " + r
   11819                     + ": prev had " + mOrderedBroadcasts.size());
   11820             if (DEBUG_BROADCAST) {
   11821                 int seq = r.intent.getIntExtra("seq", -1);
   11822                 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
   11823             }
   11824             boolean replaced = false;
   11825             if (replacePending) {
   11826                 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
   11827                     if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
   11828                         if (DEBUG_BROADCAST) Slog.v(TAG,
   11829                                 "***** DROPPING ORDERED: " + intent);
   11830                         mOrderedBroadcasts.set(i, r);
   11831                         replaced = true;
   11832                         break;
   11833                     }
   11834                 }
   11835             }
   11836             if (!replaced) {
   11837                 mOrderedBroadcasts.add(r);
   11838                 scheduleBroadcastsLocked();
   11839             }
   11840         }
   11841 
   11842         return BROADCAST_SUCCESS;
   11843     }
   11844 
   11845     final Intent verifyBroadcastLocked(Intent intent) {
   11846         // Refuse possible leaked file descriptors
   11847         if (intent != null && intent.hasFileDescriptors() == true) {
   11848             throw new IllegalArgumentException("File descriptors passed in Intent");
   11849         }
   11850 
   11851         int flags = intent.getFlags();
   11852 
   11853         if (!mProcessesReady) {
   11854             // if the caller really truly claims to know what they're doing, go
   11855             // ahead and allow the broadcast without launching any receivers
   11856             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
   11857                 intent = new Intent(intent);
   11858                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   11859             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
   11860                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
   11861                         + " before boot completion");
   11862                 throw new IllegalStateException("Cannot broadcast before boot completed");
   11863             }
   11864         }
   11865 
   11866         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   11867             throw new IllegalArgumentException(
   11868                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   11869         }
   11870 
   11871         return intent;
   11872     }
   11873 
   11874     public final int broadcastIntent(IApplicationThread caller,
   11875             Intent intent, String resolvedType, IIntentReceiver resultTo,
   11876             int resultCode, String resultData, Bundle map,
   11877             String requiredPermission, boolean serialized, boolean sticky) {
   11878         synchronized(this) {
   11879             intent = verifyBroadcastLocked(intent);
   11880 
   11881             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   11882             final int callingPid = Binder.getCallingPid();
   11883             final int callingUid = Binder.getCallingUid();
   11884             final long origId = Binder.clearCallingIdentity();
   11885             int res = broadcastIntentLocked(callerApp,
   11886                     callerApp != null ? callerApp.info.packageName : null,
   11887                     intent, resolvedType, resultTo,
   11888                     resultCode, resultData, map, requiredPermission, serialized,
   11889                     sticky, callingPid, callingUid);
   11890             Binder.restoreCallingIdentity(origId);
   11891             return res;
   11892         }
   11893     }
   11894 
   11895     int broadcastIntentInPackage(String packageName, int uid,
   11896             Intent intent, String resolvedType, IIntentReceiver resultTo,
   11897             int resultCode, String resultData, Bundle map,
   11898             String requiredPermission, boolean serialized, boolean sticky) {
   11899         synchronized(this) {
   11900             intent = verifyBroadcastLocked(intent);
   11901 
   11902             final long origId = Binder.clearCallingIdentity();
   11903             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
   11904                     resultTo, resultCode, resultData, map, requiredPermission,
   11905                     serialized, sticky, -1, uid);
   11906             Binder.restoreCallingIdentity(origId);
   11907             return res;
   11908         }
   11909     }
   11910 
   11911     public final void unbroadcastIntent(IApplicationThread caller,
   11912             Intent intent) {
   11913         // Refuse possible leaked file descriptors
   11914         if (intent != null && intent.hasFileDescriptors() == true) {
   11915             throw new IllegalArgumentException("File descriptors passed in Intent");
   11916         }
   11917 
   11918         synchronized(this) {
   11919             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
   11920                     != PackageManager.PERMISSION_GRANTED) {
   11921                 String msg = "Permission Denial: unbroadcastIntent() from pid="
   11922                         + Binder.getCallingPid()
   11923                         + ", uid=" + Binder.getCallingUid()
   11924                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   11925                 Slog.w(TAG, msg);
   11926                 throw new SecurityException(msg);
   11927             }
   11928             ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
   11929             if (list != null) {
   11930                 int N = list.size();
   11931                 int i;
   11932                 for (i=0; i<N; i++) {
   11933                     if (intent.filterEquals(list.get(i))) {
   11934                         list.remove(i);
   11935                         break;
   11936                     }
   11937                 }
   11938             }
   11939         }
   11940     }
   11941 
   11942     private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
   11943             String resultData, Bundle resultExtras, boolean resultAbort,
   11944             boolean explicit) {
   11945         if (mOrderedBroadcasts.size() == 0) {
   11946             if (explicit) {
   11947                 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
   11948             }
   11949             return false;
   11950         }
   11951         BroadcastRecord r = mOrderedBroadcasts.get(0);
   11952         if (r.receiver == null) {
   11953             if (explicit) {
   11954                 Slog.w(TAG, "finishReceiver called but none active");
   11955             }
   11956             return false;
   11957         }
   11958         if (r.receiver != receiver) {
   11959             Slog.w(TAG, "finishReceiver called but active receiver is different");
   11960             return false;
   11961         }
   11962         int state = r.state;
   11963         r.state = BroadcastRecord.IDLE;
   11964         if (state == BroadcastRecord.IDLE) {
   11965             if (explicit) {
   11966                 Slog.w(TAG, "finishReceiver called but state is IDLE");
   11967             }
   11968         }
   11969         r.receiver = null;
   11970         r.intent.setComponent(null);
   11971         if (r.curApp != null) {
   11972             r.curApp.curReceiver = null;
   11973         }
   11974         if (r.curFilter != null) {
   11975             r.curFilter.receiverList.curBroadcast = null;
   11976         }
   11977         r.curFilter = null;
   11978         r.curApp = null;
   11979         r.curComponent = null;
   11980         r.curReceiver = null;
   11981         mPendingBroadcast = null;
   11982 
   11983         r.resultCode = resultCode;
   11984         r.resultData = resultData;
   11985         r.resultExtras = resultExtras;
   11986         r.resultAbort = resultAbort;
   11987 
   11988         // We will process the next receiver right now if this is finishing
   11989         // an app receiver (which is always asynchronous) or after we have
   11990         // come back from calling a receiver.
   11991         return state == BroadcastRecord.APP_RECEIVE
   11992                 || state == BroadcastRecord.CALL_DONE_RECEIVE;
   11993     }
   11994 
   11995     public void finishReceiver(IBinder who, int resultCode, String resultData,
   11996             Bundle resultExtras, boolean resultAbort) {
   11997         if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
   11998 
   11999         // Refuse possible leaked file descriptors
   12000         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
   12001             throw new IllegalArgumentException("File descriptors passed in Bundle");
   12002         }
   12003 
   12004         boolean doNext;
   12005 
   12006         final long origId = Binder.clearCallingIdentity();
   12007 
   12008         synchronized(this) {
   12009             doNext = finishReceiverLocked(
   12010                 who, resultCode, resultData, resultExtras, resultAbort, true);
   12011         }
   12012 
   12013         if (doNext) {
   12014             processNextBroadcast(false);
   12015         }
   12016         trimApplications();
   12017 
   12018         Binder.restoreCallingIdentity(origId);
   12019     }
   12020 
   12021     private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
   12022         if (r.nextReceiver > 0) {
   12023             Object curReceiver = r.receivers.get(r.nextReceiver-1);
   12024             if (curReceiver instanceof BroadcastFilter) {
   12025                 BroadcastFilter bf = (BroadcastFilter) curReceiver;
   12026                 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
   12027                         System.identityHashCode(r),
   12028                         r.intent.getAction(),
   12029                         r.nextReceiver - 1,
   12030                         System.identityHashCode(bf));
   12031             } else {
   12032                 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
   12033                         System.identityHashCode(r),
   12034                         r.intent.getAction(),
   12035                         r.nextReceiver - 1,
   12036                         ((ResolveInfo)curReceiver).toString());
   12037             }
   12038         } else {
   12039             Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
   12040                     + r);
   12041             EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
   12042                     System.identityHashCode(r),
   12043                     r.intent.getAction(),
   12044                     r.nextReceiver,
   12045                     "NONE");
   12046         }
   12047     }
   12048 
   12049     private final void setBroadcastTimeoutLocked(long timeoutTime) {
   12050         if (! mPendingBroadcastTimeoutMessage) {
   12051             Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
   12052             mHandler.sendMessageAtTime(msg, timeoutTime);
   12053             mPendingBroadcastTimeoutMessage = true;
   12054         }
   12055     }
   12056 
   12057     private final void cancelBroadcastTimeoutLocked() {
   12058         if (mPendingBroadcastTimeoutMessage) {
   12059             mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
   12060             mPendingBroadcastTimeoutMessage = false;
   12061         }
   12062     }
   12063 
   12064     private final void broadcastTimeoutLocked(boolean fromMsg) {
   12065         if (fromMsg) {
   12066             mPendingBroadcastTimeoutMessage = false;
   12067         }
   12068 
   12069         if (mOrderedBroadcasts.size() == 0) {
   12070             return;
   12071         }
   12072 
   12073         long now = SystemClock.uptimeMillis();
   12074         BroadcastRecord r = mOrderedBroadcasts.get(0);
   12075         if (fromMsg) {
   12076             if (mDidDexOpt) {
   12077                 // Delay timeouts until dexopt finishes.
   12078                 mDidDexOpt = false;
   12079                 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
   12080                 setBroadcastTimeoutLocked(timeoutTime);
   12081                 return;
   12082             }
   12083             if (! mProcessesReady) {
   12084                 // Only process broadcast timeouts if the system is ready. That way
   12085                 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
   12086                 // to do heavy lifting for system up.
   12087                 return;
   12088             }
   12089 
   12090             long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
   12091             if (timeoutTime > now) {
   12092                 // We can observe premature timeouts because we do not cancel and reset the
   12093                 // broadcast timeout message after each receiver finishes.  Instead, we set up
   12094                 // an initial timeout then kick it down the road a little further as needed
   12095                 // when it expires.
   12096                 if (DEBUG_BROADCAST) Slog.v(TAG,
   12097                         "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
   12098                         + timeoutTime);
   12099                 setBroadcastTimeoutLocked(timeoutTime);
   12100                 return;
   12101             }
   12102         }
   12103 
   12104         Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
   12105                 + ", started " + (now - r.receiverTime) + "ms ago");
   12106         r.receiverTime = now;
   12107         r.anrCount++;
   12108 
   12109         // Current receiver has passed its expiration date.
   12110         if (r.nextReceiver <= 0) {
   12111             Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
   12112             return;
   12113         }
   12114 
   12115         ProcessRecord app = null;
   12116         String anrMessage = null;
   12117 
   12118         Object curReceiver = r.receivers.get(r.nextReceiver-1);
   12119         Slog.w(TAG, "Receiver during timeout: " + curReceiver);
   12120         logBroadcastReceiverDiscardLocked(r);
   12121         if (curReceiver instanceof BroadcastFilter) {
   12122             BroadcastFilter bf = (BroadcastFilter)curReceiver;
   12123             if (bf.receiverList.pid != 0
   12124                     && bf.receiverList.pid != MY_PID) {
   12125                 synchronized (this.mPidsSelfLocked) {
   12126                     app = this.mPidsSelfLocked.get(
   12127                             bf.receiverList.pid);
   12128                 }
   12129             }
   12130         } else {
   12131             app = r.curApp;
   12132         }
   12133 
   12134         if (app != null) {
   12135             anrMessage = "Broadcast of " + r.intent.toString();
   12136         }
   12137 
   12138         if (mPendingBroadcast == r) {
   12139             mPendingBroadcast = null;
   12140         }
   12141 
   12142         // Move on to the next receiver.
   12143         finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
   12144                 r.resultExtras, r.resultAbort, true);
   12145         scheduleBroadcastsLocked();
   12146 
   12147         if (anrMessage != null) {
   12148             // Post the ANR to the handler since we do not want to process ANRs while
   12149             // potentially holding our lock.
   12150             mHandler.post(new AppNotResponding(app, anrMessage));
   12151         }
   12152     }
   12153 
   12154     private final void processCurBroadcastLocked(BroadcastRecord r,
   12155             ProcessRecord app) throws RemoteException {
   12156         if (DEBUG_BROADCAST)  Slog.v(TAG,
   12157                 "Process cur broadcast " + r + " for app " + app);
   12158         if (app.thread == null) {
   12159             throw new RemoteException();
   12160         }
   12161         r.receiver = app.thread.asBinder();
   12162         r.curApp = app;
   12163         app.curReceiver = r;
   12164         updateLruProcessLocked(app, true, true);
   12165 
   12166         // Tell the application to launch this receiver.
   12167         r.intent.setComponent(r.curComponent);
   12168 
   12169         boolean started = false;
   12170         try {
   12171             if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
   12172                     "Delivering to component " + r.curComponent
   12173                     + ": " + r);
   12174             ensurePackageDexOpt(r.intent.getComponent().getPackageName());
   12175             app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
   12176                     compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
   12177                     r.resultCode, r.resultData, r.resultExtras, r.ordered);
   12178             if (DEBUG_BROADCAST)  Slog.v(TAG,
   12179                     "Process cur broadcast " + r + " DELIVERED for app " + app);
   12180             started = true;
   12181         } finally {
   12182             if (!started) {
   12183                 if (DEBUG_BROADCAST)  Slog.v(TAG,
   12184                         "Process cur broadcast " + r + ": NOT STARTED!");
   12185                 r.receiver = null;
   12186                 r.curApp = null;
   12187                 app.curReceiver = null;
   12188             }
   12189         }
   12190 
   12191     }
   12192 
   12193     static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
   12194             Intent intent, int resultCode, String data, Bundle extras,
   12195             boolean ordered, boolean sticky) throws RemoteException {
   12196         // Send the intent to the receiver asynchronously using one-way binder calls.
   12197         if (app != null && app.thread != null) {
   12198             // If we have an app thread, do the call through that so it is
   12199             // correctly ordered with other one-way calls.
   12200             app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
   12201                     data, extras, ordered, sticky);
   12202         } else {
   12203             receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
   12204         }
   12205     }
   12206 
   12207     private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
   12208             BroadcastFilter filter, boolean ordered) {
   12209         boolean skip = false;
   12210         if (filter.requiredPermission != null) {
   12211             int perm = checkComponentPermission(filter.requiredPermission,
   12212                     r.callingPid, r.callingUid, -1, true);
   12213             if (perm != PackageManager.PERMISSION_GRANTED) {
   12214                 Slog.w(TAG, "Permission Denial: broadcasting "
   12215                         + r.intent.toString()
   12216                         + " from " + r.callerPackage + " (pid="
   12217                         + r.callingPid + ", uid=" + r.callingUid + ")"
   12218                         + " requires " + filter.requiredPermission
   12219                         + " due to registered receiver " + filter);
   12220                 skip = true;
   12221             }
   12222         }
   12223         if (r.requiredPermission != null) {
   12224             int perm = checkComponentPermission(r.requiredPermission,
   12225                     filter.receiverList.pid, filter.receiverList.uid, -1, true);
   12226             if (perm != PackageManager.PERMISSION_GRANTED) {
   12227                 Slog.w(TAG, "Permission Denial: receiving "
   12228                         + r.intent.toString()
   12229                         + " to " + filter.receiverList.app
   12230                         + " (pid=" + filter.receiverList.pid
   12231                         + ", uid=" + filter.receiverList.uid + ")"
   12232                         + " requires " + r.requiredPermission
   12233                         + " due to sender " + r.callerPackage
   12234                         + " (uid " + r.callingUid + ")");
   12235                 skip = true;
   12236             }
   12237         }
   12238 
   12239         if (!skip) {
   12240             // If this is not being sent as an ordered broadcast, then we
   12241             // don't want to touch the fields that keep track of the current
   12242             // state of ordered broadcasts.
   12243             if (ordered) {
   12244                 r.receiver = filter.receiverList.receiver.asBinder();
   12245                 r.curFilter = filter;
   12246                 filter.receiverList.curBroadcast = r;
   12247                 r.state = BroadcastRecord.CALL_IN_RECEIVE;
   12248                 if (filter.receiverList.app != null) {
   12249                     // Bump hosting application to no longer be in background
   12250                     // scheduling class.  Note that we can't do that if there
   12251                     // isn't an app...  but we can only be in that case for
   12252                     // things that directly call the IActivityManager API, which
   12253                     // are already core system stuff so don't matter for this.
   12254                     r.curApp = filter.receiverList.app;
   12255                     filter.receiverList.app.curReceiver = r;
   12256                     updateOomAdjLocked();
   12257                 }
   12258             }
   12259             try {
   12260                 if (DEBUG_BROADCAST_LIGHT) {
   12261                     int seq = r.intent.getIntExtra("seq", -1);
   12262                     Slog.i(TAG, "Delivering to " + filter
   12263                             + " (seq=" + seq + "): " + r);
   12264                 }
   12265                 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
   12266                     new Intent(r.intent), r.resultCode,
   12267                     r.resultData, r.resultExtras, r.ordered, r.initialSticky);
   12268                 if (ordered) {
   12269                     r.state = BroadcastRecord.CALL_DONE_RECEIVE;
   12270                 }
   12271             } catch (RemoteException e) {
   12272                 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
   12273                 if (ordered) {
   12274                     r.receiver = null;
   12275                     r.curFilter = null;
   12276                     filter.receiverList.curBroadcast = null;
   12277                     if (filter.receiverList.app != null) {
   12278                         filter.receiverList.app.curReceiver = null;
   12279                     }
   12280                 }
   12281             }
   12282         }
   12283     }
   12284 
   12285     private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
   12286         if (r.callingUid < 0) {
   12287             // This was from a registerReceiver() call; ignore it.
   12288             return;
   12289         }
   12290         System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
   12291                 MAX_BROADCAST_HISTORY-1);
   12292         r.finishTime = SystemClock.uptimeMillis();
   12293         mBroadcastHistory[0] = r;
   12294     }
   12295 
   12296     private final void processNextBroadcast(boolean fromMsg) {
   12297         synchronized(this) {
   12298             BroadcastRecord r;
   12299 
   12300             if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
   12301                     + mParallelBroadcasts.size() + " broadcasts, "
   12302                     + mOrderedBroadcasts.size() + " ordered broadcasts");
   12303 
   12304             updateCpuStats();
   12305 
   12306             if (fromMsg) {
   12307                 mBroadcastsScheduled = false;
   12308             }
   12309 
   12310             // First, deliver any non-serialized broadcasts right away.
   12311             while (mParallelBroadcasts.size() > 0) {
   12312                 r = mParallelBroadcasts.remove(0);
   12313                 r.dispatchTime = SystemClock.uptimeMillis();
   12314                 r.dispatchClockTime = System.currentTimeMillis();
   12315                 final int N = r.receivers.size();
   12316                 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
   12317                         + r);
   12318                 for (int i=0; i<N; i++) {
   12319                     Object target = r.receivers.get(i);
   12320                     if (DEBUG_BROADCAST)  Slog.v(TAG,
   12321                             "Delivering non-ordered to registered "
   12322                             + target + ": " + r);
   12323                     deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
   12324                 }
   12325                 addBroadcastToHistoryLocked(r);
   12326                 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
   12327                         + r);
   12328             }
   12329 
   12330             // Now take care of the next serialized one...
   12331 
   12332             // If we are waiting for a process to come up to handle the next
   12333             // broadcast, then do nothing at this point.  Just in case, we
   12334             // check that the process we're waiting for still exists.
   12335             if (mPendingBroadcast != null) {
   12336                 if (DEBUG_BROADCAST_LIGHT) {
   12337                     Slog.v(TAG, "processNextBroadcast: waiting for "
   12338                             + mPendingBroadcast.curApp);
   12339                 }
   12340 
   12341                 boolean isDead;
   12342                 synchronized (mPidsSelfLocked) {
   12343                     isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
   12344                 }
   12345                 if (!isDead) {
   12346                     // It's still alive, so keep waiting
   12347                     return;
   12348                 } else {
   12349                     Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
   12350                             + " died before responding to broadcast");
   12351                     mPendingBroadcast.state = BroadcastRecord.IDLE;
   12352                     mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
   12353                     mPendingBroadcast = null;
   12354                 }
   12355             }
   12356 
   12357             boolean looped = false;
   12358 
   12359             do {
   12360                 if (mOrderedBroadcasts.size() == 0) {
   12361                     // No more broadcasts pending, so all done!
   12362                     scheduleAppGcsLocked();
   12363                     if (looped) {
   12364                         // If we had finished the last ordered broadcast, then
   12365                         // make sure all processes have correct oom and sched
   12366                         // adjustments.
   12367                         updateOomAdjLocked();
   12368                     }
   12369                     return;
   12370                 }
   12371                 r = mOrderedBroadcasts.get(0);
   12372                 boolean forceReceive = false;
   12373 
   12374                 // Ensure that even if something goes awry with the timeout
   12375                 // detection, we catch "hung" broadcasts here, discard them,
   12376                 // and continue to make progress.
   12377                 //
   12378                 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
   12379                 // receivers don't get executed with timeouts. They're intended for
   12380                 // one time heavy lifting after system upgrades and can take
   12381                 // significant amounts of time.
   12382                 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
   12383                 if (mProcessesReady && r.dispatchTime > 0) {
   12384                     long now = SystemClock.uptimeMillis();
   12385                     if ((numReceivers > 0) &&
   12386                             (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
   12387                         Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
   12388                                 + " now=" + now
   12389                                 + " dispatchTime=" + r.dispatchTime
   12390                                 + " startTime=" + r.receiverTime
   12391                                 + " intent=" + r.intent
   12392                                 + " numReceivers=" + numReceivers
   12393                                 + " nextReceiver=" + r.nextReceiver
   12394                                 + " state=" + r.state);
   12395                         broadcastTimeoutLocked(false); // forcibly finish this broadcast
   12396                         forceReceive = true;
   12397                         r.state = BroadcastRecord.IDLE;
   12398                     }
   12399                 }
   12400 
   12401                 if (r.state != BroadcastRecord.IDLE) {
   12402                     if (DEBUG_BROADCAST) Slog.d(TAG,
   12403                             "processNextBroadcast() called when not idle (state="
   12404                             + r.state + ")");
   12405                     return;
   12406                 }
   12407 
   12408                 if (r.receivers == null || r.nextReceiver >= numReceivers
   12409                         || r.resultAbort || forceReceive) {
   12410                     // No more receivers for this broadcast!  Send the final
   12411                     // result if requested...
   12412                     if (r.resultTo != null) {
   12413                         try {
   12414                             if (DEBUG_BROADCAST) {
   12415                                 int seq = r.intent.getIntExtra("seq", -1);
   12416                                 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
   12417                                         + " seq=" + seq + " app=" + r.callerApp);
   12418                             }
   12419                             performReceiveLocked(r.callerApp, r.resultTo,
   12420                                 new Intent(r.intent), r.resultCode,
   12421                                 r.resultData, r.resultExtras, false, false);
   12422                             // Set this to null so that the reference
   12423                             // (local and remote) isnt kept in the mBroadcastHistory.
   12424                             r.resultTo = null;
   12425                         } catch (RemoteException e) {
   12426                             Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
   12427                         }
   12428                     }
   12429 
   12430                     if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
   12431                     cancelBroadcastTimeoutLocked();
   12432 
   12433                     if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
   12434                             + r);
   12435 
   12436                     // ... and on to the next...
   12437                     addBroadcastToHistoryLocked(r);
   12438                     mOrderedBroadcasts.remove(0);
   12439                     r = null;
   12440                     looped = true;
   12441                     continue;
   12442                 }
   12443             } while (r == null);
   12444 
   12445             // Get the next receiver...
   12446             int recIdx = r.nextReceiver++;
   12447 
   12448             // Keep track of when this receiver started, and make sure there
   12449             // is a timeout message pending to kill it if need be.
   12450             r.receiverTime = SystemClock.uptimeMillis();
   12451             if (recIdx == 0) {
   12452                 r.dispatchTime = r.receiverTime;
   12453                 r.dispatchClockTime = System.currentTimeMillis();
   12454                 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
   12455                         + r);
   12456             }
   12457             if (! mPendingBroadcastTimeoutMessage) {
   12458                 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
   12459                 if (DEBUG_BROADCAST) Slog.v(TAG,
   12460                         "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
   12461                 setBroadcastTimeoutLocked(timeoutTime);
   12462             }
   12463 
   12464             Object nextReceiver = r.receivers.get(recIdx);
   12465             if (nextReceiver instanceof BroadcastFilter) {
   12466                 // Simple case: this is a registered receiver who gets
   12467                 // a direct call.
   12468                 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
   12469                 if (DEBUG_BROADCAST)  Slog.v(TAG,
   12470                         "Delivering ordered to registered "
   12471                         + filter + ": " + r);
   12472                 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
   12473                 if (r.receiver == null || !r.ordered) {
   12474                     // The receiver has already finished, so schedule to
   12475                     // process the next one.
   12476                     if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
   12477                             + r.ordered + " receiver=" + r.receiver);
   12478                     r.state = BroadcastRecord.IDLE;
   12479                     scheduleBroadcastsLocked();
   12480                 }
   12481                 return;
   12482             }
   12483 
   12484             // Hard case: need to instantiate the receiver, possibly
   12485             // starting its application process to host it.
   12486 
   12487             ResolveInfo info =
   12488                 (ResolveInfo)nextReceiver;
   12489 
   12490             boolean skip = false;
   12491             int perm = checkComponentPermission(info.activityInfo.permission,
   12492                     r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
   12493                     info.activityInfo.exported);
   12494             if (perm != PackageManager.PERMISSION_GRANTED) {
   12495                 if (!info.activityInfo.exported) {
   12496                     Slog.w(TAG, "Permission Denial: broadcasting "
   12497                             + r.intent.toString()
   12498                             + " from " + r.callerPackage + " (pid=" + r.callingPid
   12499                             + ", uid=" + r.callingUid + ")"
   12500                             + " is not exported from uid " + info.activityInfo.applicationInfo.uid
   12501                             + " due to receiver " + info.activityInfo.packageName
   12502                             + "/" + info.activityInfo.name);
   12503                 } else {
   12504                     Slog.w(TAG, "Permission Denial: broadcasting "
   12505                             + r.intent.toString()
   12506                             + " from " + r.callerPackage + " (pid=" + r.callingPid
   12507                             + ", uid=" + r.callingUid + ")"
   12508                             + " requires " + info.activityInfo.permission
   12509                             + " due to receiver " + info.activityInfo.packageName
   12510                             + "/" + info.activityInfo.name);
   12511                 }
   12512                 skip = true;
   12513             }
   12514             if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
   12515                 r.requiredPermission != null) {
   12516                 try {
   12517                     perm = AppGlobals.getPackageManager().
   12518                             checkPermission(r.requiredPermission,
   12519                                     info.activityInfo.applicationInfo.packageName);
   12520                 } catch (RemoteException e) {
   12521                     perm = PackageManager.PERMISSION_DENIED;
   12522                 }
   12523                 if (perm != PackageManager.PERMISSION_GRANTED) {
   12524                     Slog.w(TAG, "Permission Denial: receiving "
   12525                             + r.intent + " to "
   12526                             + info.activityInfo.applicationInfo.packageName
   12527                             + " requires " + r.requiredPermission
   12528                             + " due to sender " + r.callerPackage
   12529                             + " (uid " + r.callingUid + ")");
   12530                     skip = true;
   12531                 }
   12532             }
   12533             if (r.curApp != null && r.curApp.crashing) {
   12534                 // If the target process is crashing, just skip it.
   12535                 if (DEBUG_BROADCAST)  Slog.v(TAG,
   12536                         "Skipping deliver ordered " + r + " to " + r.curApp
   12537                         + ": process crashing");
   12538                 skip = true;
   12539             }
   12540 
   12541             if (skip) {
   12542                 if (DEBUG_BROADCAST)  Slog.v(TAG,
   12543                         "Skipping delivery of ordered " + r + " for whatever reason");
   12544                 r.receiver = null;
   12545                 r.curFilter = null;
   12546                 r.state = BroadcastRecord.IDLE;
   12547                 scheduleBroadcastsLocked();
   12548                 return;
   12549             }
   12550 
   12551             r.state = BroadcastRecord.APP_RECEIVE;
   12552             String targetProcess = info.activityInfo.processName;
   12553             r.curComponent = new ComponentName(
   12554                     info.activityInfo.applicationInfo.packageName,
   12555                     info.activityInfo.name);
   12556             r.curReceiver = info.activityInfo;
   12557 
   12558             // Broadcast is being executed, its package can't be stopped.
   12559             try {
   12560                 AppGlobals.getPackageManager().setPackageStoppedState(
   12561                         r.curComponent.getPackageName(), false);
   12562             } catch (RemoteException e) {
   12563             } catch (IllegalArgumentException e) {
   12564                 Slog.w(TAG, "Failed trying to unstop package "
   12565                         + r.curComponent.getPackageName() + ": " + e);
   12566             }
   12567 
   12568             // Is this receiver's application already running?
   12569             ProcessRecord app = getProcessRecordLocked(targetProcess,
   12570                     info.activityInfo.applicationInfo.uid);
   12571             if (app != null && app.thread != null) {
   12572                 try {
   12573                     app.addPackage(info.activityInfo.packageName);
   12574                     processCurBroadcastLocked(r, app);
   12575                     return;
   12576                 } catch (RemoteException e) {
   12577                     Slog.w(TAG, "Exception when sending broadcast to "
   12578                           + r.curComponent, e);
   12579                 }
   12580 
   12581                 // If a dead object exception was thrown -- fall through to
   12582                 // restart the application.
   12583             }
   12584 
   12585             // Not running -- get it started, to be executed when the app comes up.
   12586             if (DEBUG_BROADCAST)  Slog.v(TAG,
   12587                     "Need to start app " + targetProcess + " for broadcast " + r);
   12588             if ((r.curApp=startProcessLocked(targetProcess,
   12589                     info.activityInfo.applicationInfo, true,
   12590                     r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
   12591                     "broadcast", r.curComponent,
   12592                     (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
   12593                             == null) {
   12594                 // Ah, this recipient is unavailable.  Finish it if necessary,
   12595                 // and mark the broadcast record as ready for the next.
   12596                 Slog.w(TAG, "Unable to launch app "
   12597                         + info.activityInfo.applicationInfo.packageName + "/"
   12598                         + info.activityInfo.applicationInfo.uid + " for broadcast "
   12599                         + r.intent + ": process is bad");
   12600                 logBroadcastReceiverDiscardLocked(r);
   12601                 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
   12602                         r.resultExtras, r.resultAbort, true);
   12603                 scheduleBroadcastsLocked();
   12604                 r.state = BroadcastRecord.IDLE;
   12605                 return;
   12606             }
   12607 
   12608             mPendingBroadcast = r;
   12609             mPendingBroadcastRecvIndex = recIdx;
   12610         }
   12611     }
   12612 
   12613     // =========================================================
   12614     // INSTRUMENTATION
   12615     // =========================================================
   12616 
   12617     public boolean startInstrumentation(ComponentName className,
   12618             String profileFile, int flags, Bundle arguments,
   12619             IInstrumentationWatcher watcher) {
   12620         // Refuse possible leaked file descriptors
   12621         if (arguments != null && arguments.hasFileDescriptors()) {
   12622             throw new IllegalArgumentException("File descriptors passed in Bundle");
   12623         }
   12624 
   12625         synchronized(this) {
   12626             InstrumentationInfo ii = null;
   12627             ApplicationInfo ai = null;
   12628             try {
   12629                 ii = mContext.getPackageManager().getInstrumentationInfo(
   12630                     className, STOCK_PM_FLAGS);
   12631                 ai = mContext.getPackageManager().getApplicationInfo(
   12632                     ii.targetPackage, STOCK_PM_FLAGS);
   12633             } catch (PackageManager.NameNotFoundException e) {
   12634             }
   12635             if (ii == null) {
   12636                 reportStartInstrumentationFailure(watcher, className,
   12637                         "Unable to find instrumentation info for: " + className);
   12638                 return false;
   12639             }
   12640             if (ai == null) {
   12641                 reportStartInstrumentationFailure(watcher, className,
   12642                         "Unable to find instrumentation target package: " + ii.targetPackage);
   12643                 return false;
   12644             }
   12645 
   12646             int match = mContext.getPackageManager().checkSignatures(
   12647                     ii.targetPackage, ii.packageName);
   12648             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
   12649                 String msg = "Permission Denial: starting instrumentation "
   12650                         + className + " from pid="
   12651                         + Binder.getCallingPid()
   12652                         + ", uid=" + Binder.getCallingPid()
   12653                         + " not allowed because package " + ii.packageName
   12654                         + " does not have a signature matching the target "
   12655                         + ii.targetPackage;
   12656                 reportStartInstrumentationFailure(watcher, className, msg);
   12657                 throw new SecurityException(msg);
   12658             }
   12659 
   12660             final long origId = Binder.clearCallingIdentity();
   12661             // Instrumentation can kill and relaunch even persistent processes
   12662             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
   12663             ProcessRecord app = addAppLocked(ai);
   12664             app.instrumentationClass = className;
   12665             app.instrumentationInfo = ai;
   12666             app.instrumentationProfileFile = profileFile;
   12667             app.instrumentationArguments = arguments;
   12668             app.instrumentationWatcher = watcher;
   12669             app.instrumentationResultClass = className;
   12670             Binder.restoreCallingIdentity(origId);
   12671         }
   12672 
   12673         return true;
   12674     }
   12675 
   12676     /**
   12677      * Report errors that occur while attempting to start Instrumentation.  Always writes the
   12678      * error to the logs, but if somebody is watching, send the report there too.  This enables
   12679      * the "am" command to report errors with more information.
   12680      *
   12681      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
   12682      * @param cn The component name of the instrumentation.
   12683      * @param report The error report.
   12684      */
   12685     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
   12686             ComponentName cn, String report) {
   12687         Slog.w(TAG, report);
   12688         try {
   12689             if (watcher != null) {
   12690                 Bundle results = new Bundle();
   12691                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
   12692                 results.putString("Error", report);
   12693                 watcher.instrumentationStatus(cn, -1, results);
   12694             }
   12695         } catch (RemoteException e) {
   12696             Slog.w(TAG, e);
   12697         }
   12698     }
   12699 
   12700     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
   12701         if (app.instrumentationWatcher != null) {
   12702             try {
   12703                 // NOTE:  IInstrumentationWatcher *must* be oneway here
   12704                 app.instrumentationWatcher.instrumentationFinished(
   12705                     app.instrumentationClass,
   12706                     resultCode,
   12707                     results);
   12708             } catch (RemoteException e) {
   12709             }
   12710         }
   12711         app.instrumentationWatcher = null;
   12712         app.instrumentationClass = null;
   12713         app.instrumentationInfo = null;
   12714         app.instrumentationProfileFile = null;
   12715         app.instrumentationArguments = null;
   12716 
   12717         forceStopPackageLocked(app.processName, -1, false, false, true, true);
   12718     }
   12719 
   12720     public void finishInstrumentation(IApplicationThread target,
   12721             int resultCode, Bundle results) {
   12722         // Refuse possible leaked file descriptors
   12723         if (results != null && results.hasFileDescriptors()) {
   12724             throw new IllegalArgumentException("File descriptors passed in Intent");
   12725         }
   12726 
   12727         synchronized(this) {
   12728             ProcessRecord app = getRecordForAppLocked(target);
   12729             if (app == null) {
   12730                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
   12731                 return;
   12732             }
   12733             final long origId = Binder.clearCallingIdentity();
   12734             finishInstrumentationLocked(app, resultCode, results);
   12735             Binder.restoreCallingIdentity(origId);
   12736         }
   12737     }
   12738 
   12739     // =========================================================
   12740     // CONFIGURATION
   12741     // =========================================================
   12742 
   12743     public ConfigurationInfo getDeviceConfigurationInfo() {
   12744         ConfigurationInfo config = new ConfigurationInfo();
   12745         synchronized (this) {
   12746             config.reqTouchScreen = mConfiguration.touchscreen;
   12747             config.reqKeyboardType = mConfiguration.keyboard;
   12748             config.reqNavigation = mConfiguration.navigation;
   12749             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
   12750                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
   12751                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
   12752             }
   12753             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
   12754                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
   12755                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
   12756             }
   12757             config.reqGlEsVersion = GL_ES_VERSION;
   12758         }
   12759         return config;
   12760     }
   12761 
   12762     public Configuration getConfiguration() {
   12763         Configuration ci;
   12764         synchronized(this) {
   12765             ci = new Configuration(mConfiguration);
   12766         }
   12767         return ci;
   12768     }
   12769 
   12770     public void updatePersistentConfiguration(Configuration values) {
   12771         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   12772                 "updateConfiguration()");
   12773         enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
   12774                 "updateConfiguration()");
   12775         if (values == null) {
   12776             throw new NullPointerException("Configuration must not be null");
   12777         }
   12778 
   12779         synchronized(this) {
   12780             final long origId = Binder.clearCallingIdentity();
   12781             updateConfigurationLocked(values, null, true);
   12782             Binder.restoreCallingIdentity(origId);
   12783         }
   12784     }
   12785 
   12786     public void updateConfiguration(Configuration values) {
   12787         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   12788                 "updateConfiguration()");
   12789 
   12790         synchronized(this) {
   12791             if (values == null && mWindowManager != null) {
   12792                 // sentinel: fetch the current configuration from the window manager
   12793                 values = mWindowManager.computeNewConfiguration();
   12794             }
   12795 
   12796             if (mWindowManager != null) {
   12797                 mProcessList.applyDisplaySize(mWindowManager);
   12798             }
   12799 
   12800             final long origId = Binder.clearCallingIdentity();
   12801             if (values != null) {
   12802                 Settings.System.clearConfiguration(values);
   12803             }
   12804             updateConfigurationLocked(values, null, false);
   12805             Binder.restoreCallingIdentity(origId);
   12806         }
   12807     }
   12808 
   12809     /**
   12810      * Do either or both things: (1) change the current configuration, and (2)
   12811      * make sure the given activity is running with the (now) current
   12812      * configuration.  Returns true if the activity has been left running, or
   12813      * false if <var>starting</var> is being destroyed to match the new
   12814      * configuration.
   12815      * @param persistent TODO
   12816      */
   12817     public boolean updateConfigurationLocked(Configuration values,
   12818             ActivityRecord starting, boolean persistent) {
   12819         int changes = 0;
   12820 
   12821         boolean kept = true;
   12822 
   12823         if (values != null) {
   12824             Configuration newConfig = new Configuration(mConfiguration);
   12825             changes = newConfig.updateFrom(values);
   12826             if (changes != 0) {
   12827                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
   12828                     Slog.i(TAG, "Updating configuration to: " + values);
   12829                 }
   12830 
   12831                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
   12832 
   12833                 if (values.locale != null) {
   12834                     saveLocaleLocked(values.locale,
   12835                                      !values.locale.equals(mConfiguration.locale),
   12836                                      values.userSetLocale);
   12837                 }
   12838 
   12839                 mConfigurationSeq++;
   12840                 if (mConfigurationSeq <= 0) {
   12841                     mConfigurationSeq = 1;
   12842                 }
   12843                 newConfig.seq = mConfigurationSeq;
   12844                 mConfiguration = newConfig;
   12845                 Slog.i(TAG, "Config changed: " + newConfig);
   12846 
   12847                 AttributeCache ac = AttributeCache.instance();
   12848                 if (ac != null) {
   12849                     ac.updateConfiguration(mConfiguration);
   12850                 }
   12851 
   12852                 // Make sure all resources in our process are updated
   12853                 // right now, so that anyone who is going to retrieve
   12854                 // resource values after we return will be sure to get
   12855                 // the new ones.  This is especially important during
   12856                 // boot, where the first config change needs to guarantee
   12857                 // all resources have that config before following boot
   12858                 // code is executed.
   12859                 mSystemThread.applyConfigurationToResources(newConfig);
   12860 
   12861                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
   12862                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
   12863                     msg.obj = new Configuration(mConfiguration);
   12864                     mHandler.sendMessage(msg);
   12865                 }
   12866 
   12867                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   12868                     ProcessRecord app = mLruProcesses.get(i);
   12869                     try {
   12870                         if (app.thread != null) {
   12871                             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
   12872                                     + app.processName + " new config " + mConfiguration);
   12873                             app.thread.scheduleConfigurationChanged(mConfiguration);
   12874                         }
   12875                     } catch (Exception e) {
   12876                     }
   12877                 }
   12878                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
   12879                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   12880                         | Intent.FLAG_RECEIVER_REPLACE_PENDING);
   12881                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
   12882                         null, false, false, MY_PID, Process.SYSTEM_UID);
   12883                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
   12884                     broadcastIntentLocked(null, null,
   12885                             new Intent(Intent.ACTION_LOCALE_CHANGED),
   12886                             null, null, 0, null, null,
   12887                             null, false, false, MY_PID, Process.SYSTEM_UID);
   12888                 }
   12889             }
   12890         }
   12891 
   12892         if (changes != 0 && starting == null) {
   12893             // If the configuration changed, and the caller is not already
   12894             // in the process of starting an activity, then find the top
   12895             // activity to check if its configuration needs to change.
   12896             starting = mMainStack.topRunningActivityLocked(null);
   12897         }
   12898 
   12899         if (starting != null) {
   12900             kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
   12901             // And we need to make sure at this point that all other activities
   12902             // are made visible with the correct configuration.
   12903             mMainStack.ensureActivitiesVisibleLocked(starting, changes);
   12904         }
   12905 
   12906         if (values != null && mWindowManager != null) {
   12907             mWindowManager.setNewConfiguration(mConfiguration);
   12908         }
   12909 
   12910         return kept;
   12911     }
   12912 
   12913     /**
   12914      * Save the locale.  You must be inside a synchronized (this) block.
   12915      */
   12916     private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
   12917         if(isDiff) {
   12918             SystemProperties.set("user.language", l.getLanguage());
   12919             SystemProperties.set("user.region", l.getCountry());
   12920         }
   12921 
   12922         if(isPersist) {
   12923             SystemProperties.set("persist.sys.language", l.getLanguage());
   12924             SystemProperties.set("persist.sys.country", l.getCountry());
   12925             SystemProperties.set("persist.sys.localevar", l.getVariant());
   12926         }
   12927     }
   12928 
   12929     // =========================================================
   12930     // LIFETIME MANAGEMENT
   12931     // =========================================================
   12932 
   12933     private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
   12934             ProcessRecord TOP_APP, boolean recursed) {
   12935         if (mAdjSeq == app.adjSeq) {
   12936             // This adjustment has already been computed.  If we are calling
   12937             // from the top, we may have already computed our adjustment with
   12938             // an earlier hidden adjustment that isn't really for us... if
   12939             // so, use the new hidden adjustment.
   12940             if (!recursed && app.hidden) {
   12941                 app.curAdj = app.curRawAdj = hiddenAdj;
   12942             }
   12943             return app.curRawAdj;
   12944         }
   12945 
   12946         if (app.thread == null) {
   12947             app.adjSeq = mAdjSeq;
   12948             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   12949             return (app.curAdj=ProcessList.EMPTY_APP_ADJ);
   12950         }
   12951 
   12952         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
   12953         app.adjSource = null;
   12954         app.adjTarget = null;
   12955         app.empty = false;
   12956         app.hidden = false;
   12957 
   12958         final int activitiesSize = app.activities.size();
   12959 
   12960         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   12961             // The max adjustment doesn't allow this app to be anything
   12962             // below foreground, so it is not worth doing work for it.
   12963             app.adjType = "fixed";
   12964             app.adjSeq = mAdjSeq;
   12965             app.curRawAdj = app.maxAdj;
   12966             app.foregroundActivities = false;
   12967             app.keeping = true;
   12968             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
   12969             // System process can do UI, and when they do we want to have
   12970             // them trim their memory after the user leaves the UI.  To
   12971             // facilitate this, here we need to determine whether or not it
   12972             // is currently showing UI.
   12973             app.systemNoUi = true;
   12974             if (app == TOP_APP) {
   12975                 app.systemNoUi = false;
   12976             } else if (activitiesSize > 0) {
   12977                 for (int j = 0; j < activitiesSize; j++) {
   12978                     final ActivityRecord r = app.activities.get(j);
   12979                     if (r.visible) {
   12980                         app.systemNoUi = false;
   12981                         break;
   12982                     }
   12983                 }
   12984             }
   12985             return (app.curAdj=app.maxAdj);
   12986         }
   12987 
   12988         final boolean hadForegroundActivities = app.foregroundActivities;
   12989 
   12990         app.foregroundActivities = false;
   12991         app.keeping = false;
   12992         app.systemNoUi = false;
   12993 
   12994         // Determine the importance of the process, starting with most
   12995         // important to least, and assign an appropriate OOM adjustment.
   12996         int adj;
   12997         int schedGroup;
   12998         if (app == TOP_APP) {
   12999             // The last app on the list is the foreground app.
   13000             adj = ProcessList.FOREGROUND_APP_ADJ;
   13001             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13002             app.adjType = "top-activity";
   13003             app.foregroundActivities = true;
   13004         } else if (app.instrumentationClass != null) {
   13005             // Don't want to kill running instrumentation.
   13006             adj = ProcessList.FOREGROUND_APP_ADJ;
   13007             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13008             app.adjType = "instrumentation";
   13009         } else if (app.curReceiver != null ||
   13010                 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
   13011             // An app that is currently receiving a broadcast also
   13012             // counts as being in the foreground.
   13013             adj = ProcessList.FOREGROUND_APP_ADJ;
   13014             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13015             app.adjType = "broadcast";
   13016         } else if (app.executingServices.size() > 0) {
   13017             // An app that is currently executing a service callback also
   13018             // counts as being in the foreground.
   13019             adj = ProcessList.FOREGROUND_APP_ADJ;
   13020             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13021             app.adjType = "exec-service";
   13022         } else if (activitiesSize > 0) {
   13023             // This app is in the background with paused activities.
   13024             // We inspect activities to potentially upgrade adjustment further below.
   13025             adj = hiddenAdj;
   13026             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13027             app.hidden = true;
   13028             app.adjType = "bg-activities";
   13029         } else {
   13030             // A very not-needed process.  If this is lower in the lru list,
   13031             // we will push it in to the empty bucket.
   13032             adj = hiddenAdj;
   13033             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13034             app.hidden = true;
   13035             app.empty = true;
   13036             app.adjType = "bg-empty";
   13037         }
   13038 
   13039         // Examine all activities if not already foreground.
   13040         if (!app.foregroundActivities && activitiesSize > 0) {
   13041             for (int j = 0; j < activitiesSize; j++) {
   13042                 final ActivityRecord r = app.activities.get(j);
   13043                 if (r.visible) {
   13044                     // App has a visible activity; only upgrade adjustment.
   13045                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   13046                         adj = ProcessList.VISIBLE_APP_ADJ;
   13047                         app.adjType = "visible";
   13048                     }
   13049                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   13050                     app.hidden = false;
   13051                     app.foregroundActivities = true;
   13052                     break;
   13053                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
   13054                         || r.state == ActivityState.STOPPING) {
   13055                     // Only upgrade adjustment.
   13056                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   13057                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   13058                         app.adjType = "stopping";
   13059                     }
   13060                     app.foregroundActivities = true;
   13061                 }
   13062             }
   13063         }
   13064 
   13065         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   13066             if (app.foregroundServices) {
   13067                 // The user is aware of this app, so make it visible.
   13068                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   13069                 app.hidden = false;
   13070                 app.adjType = "foreground-service";
   13071                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   13072             } else if (app.forcingToForeground != null) {
   13073                 // The user is aware of this app, so make it visible.
   13074                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   13075                 app.hidden = false;
   13076                 app.adjType = "force-foreground";
   13077                 app.adjSource = app.forcingToForeground;
   13078                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   13079             }
   13080         }
   13081 
   13082         if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
   13083             // We don't want to kill the current heavy-weight process.
   13084             adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
   13085             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13086             app.hidden = false;
   13087             app.adjType = "heavy";
   13088         }
   13089 
   13090         if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
   13091             // This process is hosting what we currently consider to be the
   13092             // home app, so we don't want to let it go into the background.
   13093             adj = ProcessList.HOME_APP_ADJ;
   13094             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13095             app.hidden = false;
   13096             app.adjType = "home";
   13097         }
   13098 
   13099         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
   13100                 + " reason=" + app.adjType);
   13101 
   13102         // By default, we use the computed adjustment.  It may be changed if
   13103         // there are applications dependent on our services or providers, but
   13104         // this gives us a baseline and makes sure we don't get into an
   13105         // infinite recursion.
   13106         app.adjSeq = mAdjSeq;
   13107         app.curRawAdj = adj;
   13108 
   13109         if (mBackupTarget != null && app == mBackupTarget.app) {
   13110             // If possible we want to avoid killing apps while they're being backed up
   13111             if (adj > ProcessList.BACKUP_APP_ADJ) {
   13112                 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
   13113                 adj = ProcessList.BACKUP_APP_ADJ;
   13114                 app.adjType = "backup";
   13115                 app.hidden = false;
   13116             }
   13117         }
   13118 
   13119         if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   13120                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   13121             final long now = SystemClock.uptimeMillis();
   13122             // This process is more important if the top activity is
   13123             // bound to the service.
   13124             Iterator<ServiceRecord> jt = app.services.iterator();
   13125             while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
   13126                 ServiceRecord s = jt.next();
   13127                 if (s.startRequested) {
   13128                     if (app.hasShownUi && app != mHomeProcess) {
   13129                         // If this process has shown some UI, let it immediately
   13130                         // go to the LRU list because it may be pretty heavy with
   13131                         // UI stuff.  We'll tag it with a label just to help
   13132                         // debug and understand what is going on.
   13133                         if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
   13134                             app.adjType = "started-bg-ui-services";
   13135                         }
   13136                     } else {
   13137                         if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
   13138                             // This service has seen some activity within
   13139                             // recent memory, so we will keep its process ahead
   13140                             // of the background processes.
   13141                             if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
   13142                                 adj = ProcessList.SECONDARY_SERVER_ADJ;
   13143                                 app.adjType = "started-services";
   13144                                 app.hidden = false;
   13145                             }
   13146                         }
   13147                         // If we have let the service slide into the background
   13148                         // state, still have some text describing what it is doing
   13149                         // even though the service no longer has an impact.
   13150                         if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
   13151                             app.adjType = "started-bg-services";
   13152                         }
   13153                     }
   13154                     // Don't kill this process because it is doing work; it
   13155                     // has said it is doing work.
   13156                     app.keeping = true;
   13157                 }
   13158                 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   13159                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   13160                     Iterator<ArrayList<ConnectionRecord>> kt
   13161                             = s.connections.values().iterator();
   13162                     while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
   13163                         ArrayList<ConnectionRecord> clist = kt.next();
   13164                         for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
   13165                             // XXX should compute this based on the max of
   13166                             // all connected clients.
   13167                             ConnectionRecord cr = clist.get(i);
   13168                             if (cr.binding.client == app) {
   13169                                 // Binding to ourself is not interesting.
   13170                                 continue;
   13171                             }
   13172                             if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
   13173                                 ProcessRecord client = cr.binding.client;
   13174                                 int clientAdj = adj;
   13175                                 int myHiddenAdj = hiddenAdj;
   13176                                 if (myHiddenAdj > client.hiddenAdj) {
   13177                                     if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
   13178                                         myHiddenAdj = client.hiddenAdj;
   13179                                     } else {
   13180                                         myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
   13181                                     }
   13182                                 }
   13183                                 clientAdj = computeOomAdjLocked(
   13184                                     client, myHiddenAdj, TOP_APP, true);
   13185                                 String adjType = null;
   13186                                 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
   13187                                     // Not doing bind OOM management, so treat
   13188                                     // this guy more like a started service.
   13189                                     if (app.hasShownUi && app != mHomeProcess) {
   13190                                         // If this process has shown some UI, let it immediately
   13191                                         // go to the LRU list because it may be pretty heavy with
   13192                                         // UI stuff.  We'll tag it with a label just to help
   13193                                         // debug and understand what is going on.
   13194                                         if (adj > clientAdj) {
   13195                                             adjType = "bound-bg-ui-services";
   13196                                         }
   13197                                         app.hidden = false;
   13198                                         clientAdj = adj;
   13199                                     } else {
   13200                                         if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
   13201                                             // This service has not seen activity within
   13202                                             // recent memory, so allow it to drop to the
   13203                                             // LRU list if there is no other reason to keep
   13204                                             // it around.  We'll also tag it with a label just
   13205                                             // to help debug and undertand what is going on.
   13206                                             if (adj > clientAdj) {
   13207                                                 adjType = "bound-bg-services";
   13208                                             }
   13209                                             clientAdj = adj;
   13210                                         }
   13211                                     }
   13212                                 }
   13213                                 if (adj > clientAdj) {
   13214                                     // If this process has recently shown UI, and
   13215                                     // the process that is binding to it is less
   13216                                     // important than being visible, then we don't
   13217                                     // care about the binding as much as we care
   13218                                     // about letting this process get into the LRU
   13219                                     // list to be killed and restarted if needed for
   13220                                     // memory.
   13221                                     if (app.hasShownUi && app != mHomeProcess
   13222                                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   13223                                         adjType = "bound-bg-ui-services";
   13224                                     } else {
   13225                                         if ((cr.flags&(Context.BIND_ABOVE_CLIENT
   13226                                                 |Context.BIND_IMPORTANT)) != 0) {
   13227                                             adj = clientAdj;
   13228                                         } else if (clientAdj >= ProcessList.VISIBLE_APP_ADJ) {
   13229                                             adj = clientAdj;
   13230                                         } else {
   13231                                             adj = ProcessList.VISIBLE_APP_ADJ;
   13232                                         }
   13233                                         if (!client.hidden) {
   13234                                             app.hidden = false;
   13235                                         }
   13236                                         if (client.keeping) {
   13237                                             app.keeping = true;
   13238                                         }
   13239                                         adjType = "service";
   13240                                     }
   13241                                 }
   13242                                 if (adjType != null) {
   13243                                     app.adjType = adjType;
   13244                                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   13245                                             .REASON_SERVICE_IN_USE;
   13246                                     app.adjSource = cr.binding.client;
   13247                                     app.adjSourceOom = clientAdj;
   13248                                     app.adjTarget = s.name;
   13249                                 }
   13250                                 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   13251                                     if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   13252                                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   13253                                     }
   13254                                 }
   13255                             }
   13256                             if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
   13257                                 ActivityRecord a = cr.activity;
   13258                                 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
   13259                                         (a.visible || a.state == ActivityState.RESUMED
   13260                                          || a.state == ActivityState.PAUSING)) {
   13261                                     adj = ProcessList.FOREGROUND_APP_ADJ;
   13262                                     if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   13263                                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   13264                                     }
   13265                                     app.hidden = false;
   13266                                     app.adjType = "service";
   13267                                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   13268                                             .REASON_SERVICE_IN_USE;
   13269                                     app.adjSource = a;
   13270                                     app.adjSourceOom = adj;
   13271                                     app.adjTarget = s.name;
   13272                                 }
   13273                             }
   13274                         }
   13275                     }
   13276                 }
   13277             }
   13278 
   13279             // Finally, if this process has active services running in it, we
   13280             // would like to avoid killing it unless it would prevent the current
   13281             // application from running.  By default we put the process in
   13282             // with the rest of the background processes; as we scan through
   13283             // its services we may bump it up from there.
   13284             if (adj > hiddenAdj) {
   13285                 adj = hiddenAdj;
   13286                 app.hidden = false;
   13287                 app.adjType = "bg-services";
   13288             }
   13289         }
   13290 
   13291         if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   13292                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   13293             Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
   13294             while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
   13295                     || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   13296                 ContentProviderRecord cpr = jt.next();
   13297                 if (cpr.clients.size() != 0) {
   13298                     Iterator<ProcessRecord> kt = cpr.clients.iterator();
   13299                     while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
   13300                         ProcessRecord client = kt.next();
   13301                         if (client == app) {
   13302                             // Being our own client is not interesting.
   13303                             continue;
   13304                         }
   13305                         int myHiddenAdj = hiddenAdj;
   13306                         if (myHiddenAdj > client.hiddenAdj) {
   13307                             if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
   13308                                 myHiddenAdj = client.hiddenAdj;
   13309                             } else {
   13310                                 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
   13311                             }
   13312                         }
   13313                         int clientAdj = computeOomAdjLocked(
   13314                             client, myHiddenAdj, TOP_APP, true);
   13315                         if (adj > clientAdj) {
   13316                             if (app.hasShownUi && app != mHomeProcess
   13317                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   13318                                 app.adjType = "bg-ui-provider";
   13319                             } else {
   13320                                 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
   13321                                         ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
   13322                                 app.adjType = "provider";
   13323                             }
   13324                             if (!client.hidden) {
   13325                                 app.hidden = false;
   13326                             }
   13327                             if (client.keeping) {
   13328                                 app.keeping = true;
   13329                             }
   13330                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   13331                                     .REASON_PROVIDER_IN_USE;
   13332                             app.adjSource = client;
   13333                             app.adjSourceOom = clientAdj;
   13334                             app.adjTarget = cpr.name;
   13335                         }
   13336                         if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   13337                             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13338                         }
   13339                     }
   13340                 }
   13341                 // If the provider has external (non-framework) process
   13342                 // dependencies, ensure that its adjustment is at least
   13343                 // FOREGROUND_APP_ADJ.
   13344                 if (cpr.externals != 0) {
   13345                     if (adj > ProcessList.FOREGROUND_APP_ADJ) {
   13346                         adj = ProcessList.FOREGROUND_APP_ADJ;
   13347                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   13348                         app.hidden = false;
   13349                         app.keeping = true;
   13350                         app.adjType = "provider";
   13351                         app.adjTarget = cpr.name;
   13352                     }
   13353                 }
   13354             }
   13355         }
   13356 
   13357         app.curRawAdj = adj;
   13358 
   13359         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
   13360         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
   13361         if (adj > app.maxAdj) {
   13362             adj = app.maxAdj;
   13363             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   13364                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   13365             }
   13366         }
   13367         if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
   13368             app.keeping = true;
   13369         }
   13370 
   13371         if (app.hasAboveClient) {
   13372             // If this process has bound to any services with BIND_ABOVE_CLIENT,
   13373             // then we need to drop its adjustment to be lower than the service's
   13374             // in order to honor the request.  We want to drop it by one adjustment
   13375             // level...  but there is special meaning applied to various levels so
   13376             // we will skip some of them.
   13377             if (adj < ProcessList.FOREGROUND_APP_ADJ) {
   13378                 // System process will not get dropped, ever
   13379             } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
   13380                 adj = ProcessList.VISIBLE_APP_ADJ;
   13381             } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
   13382                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   13383             } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
   13384                 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
   13385             } else if (adj < ProcessList.EMPTY_APP_ADJ) {
   13386                 adj++;
   13387             }
   13388         }
   13389 
   13390         app.curAdj = adj;
   13391         app.curSchedGroup = schedGroup;
   13392 
   13393         if (hadForegroundActivities != app.foregroundActivities) {
   13394             mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
   13395                     app.foregroundActivities).sendToTarget();
   13396         }
   13397 
   13398         return app.curRawAdj;
   13399     }
   13400 
   13401     /**
   13402      * Ask a given process to GC right now.
   13403      */
   13404     final void performAppGcLocked(ProcessRecord app) {
   13405         try {
   13406             app.lastRequestedGc = SystemClock.uptimeMillis();
   13407             if (app.thread != null) {
   13408                 if (app.reportLowMemory) {
   13409                     app.reportLowMemory = false;
   13410                     app.thread.scheduleLowMemory();
   13411                 } else {
   13412                     app.thread.processInBackground();
   13413                 }
   13414             }
   13415         } catch (Exception e) {
   13416             // whatever.
   13417         }
   13418     }
   13419 
   13420     /**
   13421      * Returns true if things are idle enough to perform GCs.
   13422      */
   13423     private final boolean canGcNowLocked() {
   13424         return mParallelBroadcasts.size() == 0
   13425                 && mOrderedBroadcasts.size() == 0
   13426                 && (mSleeping || (mMainStack.mResumedActivity != null &&
   13427                         mMainStack.mResumedActivity.idle));
   13428     }
   13429 
   13430     /**
   13431      * Perform GCs on all processes that are waiting for it, but only
   13432      * if things are idle.
   13433      */
   13434     final void performAppGcsLocked() {
   13435         final int N = mProcessesToGc.size();
   13436         if (N <= 0) {
   13437             return;
   13438         }
   13439         if (canGcNowLocked()) {
   13440             while (mProcessesToGc.size() > 0) {
   13441                 ProcessRecord proc = mProcessesToGc.remove(0);
   13442                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
   13443                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
   13444                             <= SystemClock.uptimeMillis()) {
   13445                         // To avoid spamming the system, we will GC processes one
   13446                         // at a time, waiting a few seconds between each.
   13447                         performAppGcLocked(proc);
   13448                         scheduleAppGcsLocked();
   13449                         return;
   13450                     } else {
   13451                         // It hasn't been long enough since we last GCed this
   13452                         // process...  put it in the list to wait for its time.
   13453                         addProcessToGcListLocked(proc);
   13454                         break;
   13455                     }
   13456                 }
   13457             }
   13458 
   13459             scheduleAppGcsLocked();
   13460         }
   13461     }
   13462 
   13463     /**
   13464      * If all looks good, perform GCs on all processes waiting for them.
   13465      */
   13466     final void performAppGcsIfAppropriateLocked() {
   13467         if (canGcNowLocked()) {
   13468             performAppGcsLocked();
   13469             return;
   13470         }
   13471         // Still not idle, wait some more.
   13472         scheduleAppGcsLocked();
   13473     }
   13474 
   13475     /**
   13476      * Schedule the execution of all pending app GCs.
   13477      */
   13478     final void scheduleAppGcsLocked() {
   13479         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
   13480 
   13481         if (mProcessesToGc.size() > 0) {
   13482             // Schedule a GC for the time to the next process.
   13483             ProcessRecord proc = mProcessesToGc.get(0);
   13484             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
   13485 
   13486             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
   13487             long now = SystemClock.uptimeMillis();
   13488             if (when < (now+GC_TIMEOUT)) {
   13489                 when = now + GC_TIMEOUT;
   13490             }
   13491             mHandler.sendMessageAtTime(msg, when);
   13492         }
   13493     }
   13494 
   13495     /**
   13496      * Add a process to the array of processes waiting to be GCed.  Keeps the
   13497      * list in sorted order by the last GC time.  The process can't already be
   13498      * on the list.
   13499      */
   13500     final void addProcessToGcListLocked(ProcessRecord proc) {
   13501         boolean added = false;
   13502         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
   13503             if (mProcessesToGc.get(i).lastRequestedGc <
   13504                     proc.lastRequestedGc) {
   13505                 added = true;
   13506                 mProcessesToGc.add(i+1, proc);
   13507                 break;
   13508             }
   13509         }
   13510         if (!added) {
   13511             mProcessesToGc.add(0, proc);
   13512         }
   13513     }
   13514 
   13515     /**
   13516      * Set up to ask a process to GC itself.  This will either do it
   13517      * immediately, or put it on the list of processes to gc the next
   13518      * time things are idle.
   13519      */
   13520     final void scheduleAppGcLocked(ProcessRecord app) {
   13521         long now = SystemClock.uptimeMillis();
   13522         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
   13523             return;
   13524         }
   13525         if (!mProcessesToGc.contains(app)) {
   13526             addProcessToGcListLocked(app);
   13527             scheduleAppGcsLocked();
   13528         }
   13529     }
   13530 
   13531     final void checkExcessivePowerUsageLocked(boolean doKills) {
   13532         updateCpuStatsNow();
   13533 
   13534         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   13535         boolean doWakeKills = doKills;
   13536         boolean doCpuKills = doKills;
   13537         if (mLastPowerCheckRealtime == 0) {
   13538             doWakeKills = false;
   13539         }
   13540         if (mLastPowerCheckUptime == 0) {
   13541             doCpuKills = false;
   13542         }
   13543         if (stats.isScreenOn()) {
   13544             doWakeKills = false;
   13545         }
   13546         final long curRealtime = SystemClock.elapsedRealtime();
   13547         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
   13548         final long curUptime = SystemClock.uptimeMillis();
   13549         final long uptimeSince = curUptime - mLastPowerCheckUptime;
   13550         mLastPowerCheckRealtime = curRealtime;
   13551         mLastPowerCheckUptime = curUptime;
   13552         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
   13553             doWakeKills = false;
   13554         }
   13555         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
   13556             doCpuKills = false;
   13557         }
   13558         int i = mLruProcesses.size();
   13559         while (i > 0) {
   13560             i--;
   13561             ProcessRecord app = mLruProcesses.get(i);
   13562             if (!app.keeping) {
   13563                 long wtime;
   13564                 synchronized (stats) {
   13565                     wtime = stats.getProcessWakeTime(app.info.uid,
   13566                             app.pid, curRealtime);
   13567                 }
   13568                 long wtimeUsed = wtime - app.lastWakeTime;
   13569                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
   13570                 if (DEBUG_POWER) {
   13571                     StringBuilder sb = new StringBuilder(128);
   13572                     sb.append("Wake for ");
   13573                     app.toShortString(sb);
   13574                     sb.append(": over ");
   13575                     TimeUtils.formatDuration(realtimeSince, sb);
   13576                     sb.append(" used ");
   13577                     TimeUtils.formatDuration(wtimeUsed, sb);
   13578                     sb.append(" (");
   13579                     sb.append((wtimeUsed*100)/realtimeSince);
   13580                     sb.append("%)");
   13581                     Slog.i(TAG, sb.toString());
   13582                     sb.setLength(0);
   13583                     sb.append("CPU for ");
   13584                     app.toShortString(sb);
   13585                     sb.append(": over ");
   13586                     TimeUtils.formatDuration(uptimeSince, sb);
   13587                     sb.append(" used ");
   13588                     TimeUtils.formatDuration(cputimeUsed, sb);
   13589                     sb.append(" (");
   13590                     sb.append((cputimeUsed*100)/uptimeSince);
   13591                     sb.append("%)");
   13592                     Slog.i(TAG, sb.toString());
   13593                 }
   13594                 // If a process has held a wake lock for more
   13595                 // than 50% of the time during this period,
   13596                 // that sounds pad.  Kill!
   13597                 if (doWakeKills && realtimeSince > 0
   13598                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
   13599                     synchronized (stats) {
   13600                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
   13601                                 realtimeSince, wtimeUsed);
   13602                     }
   13603                     Slog.w(TAG, "Excessive wake lock in " + app.processName
   13604                             + " (pid " + app.pid + "): held " + wtimeUsed
   13605                             + " during " + realtimeSince);
   13606                     EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   13607                             app.processName, app.setAdj, "excessive wake lock");
   13608                     Process.killProcessQuiet(app.pid);
   13609                 } else if (doCpuKills && uptimeSince > 0
   13610                         && ((cputimeUsed*100)/uptimeSince) >= 50) {
   13611                     synchronized (stats) {
   13612                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
   13613                                 uptimeSince, cputimeUsed);
   13614                     }
   13615                     Slog.w(TAG, "Excessive CPU in " + app.processName
   13616                             + " (pid " + app.pid + "): used " + cputimeUsed
   13617                             + " during " + uptimeSince);
   13618                     EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   13619                             app.processName, app.setAdj, "excessive cpu");
   13620                     Process.killProcessQuiet(app.pid);
   13621                 } else {
   13622                     app.lastWakeTime = wtime;
   13623                     app.lastCpuTime = app.curCpuTime;
   13624                 }
   13625             }
   13626         }
   13627     }
   13628 
   13629     private final boolean updateOomAdjLocked(
   13630             ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
   13631         app.hiddenAdj = hiddenAdj;
   13632 
   13633         if (app.thread == null) {
   13634             return false;
   13635         }
   13636 
   13637         final boolean wasKeeping = app.keeping;
   13638 
   13639         boolean success = true;
   13640 
   13641         computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
   13642 
   13643         if (app.curRawAdj != app.setRawAdj) {
   13644             if (false) {
   13645                 // Removing for now.  Forcing GCs is not so useful anymore
   13646                 // with Dalvik, and the new memory level hint facility is
   13647                 // better for what we need to do these days.
   13648                 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
   13649                         && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   13650                     // If this app is transitioning from foreground to
   13651                     // non-foreground, have it do a gc.
   13652                     scheduleAppGcLocked(app);
   13653                 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
   13654                         && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
   13655                     // Likewise do a gc when an app is moving in to the
   13656                     // background (such as a service stopping).
   13657                     scheduleAppGcLocked(app);
   13658                 }
   13659             }
   13660 
   13661             if (wasKeeping && !app.keeping) {
   13662                 // This app is no longer something we want to keep.  Note
   13663                 // its current wake lock time to later know to kill it if
   13664                 // it is not behaving well.
   13665                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   13666                 synchronized (stats) {
   13667                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
   13668                             app.pid, SystemClock.elapsedRealtime());
   13669                 }
   13670                 app.lastCpuTime = app.curCpuTime;
   13671             }
   13672 
   13673             app.setRawAdj = app.curRawAdj;
   13674         }
   13675         if (app.curAdj != app.setAdj) {
   13676             if (Process.setOomAdj(app.pid, app.curAdj)) {
   13677                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
   13678                     TAG, "Set app " + app.processName +
   13679                     " oom adj to " + app.curAdj + " because " + app.adjType);
   13680                 app.setAdj = app.curAdj;
   13681             } else {
   13682                 success = false;
   13683                 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
   13684             }
   13685         }
   13686         if (app.setSchedGroup != app.curSchedGroup) {
   13687             app.setSchedGroup = app.curSchedGroup;
   13688             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   13689                     "Setting process group of " + app.processName
   13690                     + " to " + app.curSchedGroup);
   13691             if (app.waitingToKill != null &&
   13692                     app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
   13693                 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
   13694                 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   13695                         app.processName, app.setAdj, app.waitingToKill);
   13696                 Process.killProcessQuiet(app.pid);
   13697                 success = false;
   13698             } else {
   13699                 if (true) {
   13700                     long oldId = Binder.clearCallingIdentity();
   13701                     try {
   13702                         Process.setProcessGroup(app.pid, app.curSchedGroup);
   13703                     } catch (Exception e) {
   13704                         Slog.w(TAG, "Failed setting process group of " + app.pid
   13705                                 + " to " + app.curSchedGroup);
   13706                         e.printStackTrace();
   13707                     } finally {
   13708                         Binder.restoreCallingIdentity(oldId);
   13709                     }
   13710                 } else {
   13711                     if (app.thread != null) {
   13712                         try {
   13713                             app.thread.setSchedulingGroup(app.curSchedGroup);
   13714                         } catch (RemoteException e) {
   13715                         }
   13716                     }
   13717                 }
   13718             }
   13719         }
   13720         return success;
   13721     }
   13722 
   13723     private final ActivityRecord resumedAppLocked() {
   13724         ActivityRecord resumedActivity = mMainStack.mResumedActivity;
   13725         if (resumedActivity == null || resumedActivity.app == null) {
   13726             resumedActivity = mMainStack.mPausingActivity;
   13727             if (resumedActivity == null || resumedActivity.app == null) {
   13728                 resumedActivity = mMainStack.topRunningActivityLocked(null);
   13729             }
   13730         }
   13731         return resumedActivity;
   13732     }
   13733 
   13734     private final boolean updateOomAdjLocked(ProcessRecord app) {
   13735         final ActivityRecord TOP_ACT = resumedAppLocked();
   13736         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   13737         int curAdj = app.curAdj;
   13738         final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
   13739             && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
   13740 
   13741         mAdjSeq++;
   13742 
   13743         boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
   13744         final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
   13745             && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
   13746         if (nowHidden != wasHidden) {
   13747             // Changed to/from hidden state, so apps after it in the LRU
   13748             // list may also be changed.
   13749             updateOomAdjLocked();
   13750         }
   13751         return success;
   13752     }
   13753 
   13754     final void updateOomAdjLocked() {
   13755         final ActivityRecord TOP_ACT = resumedAppLocked();
   13756         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   13757 
   13758         if (false) {
   13759             RuntimeException e = new RuntimeException();
   13760             e.fillInStackTrace();
   13761             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
   13762         }
   13763 
   13764         mAdjSeq++;
   13765 
   13766         // Let's determine how many processes we have running vs.
   13767         // how many slots we have for background processes; we may want
   13768         // to put multiple processes in a slot of there are enough of
   13769         // them.
   13770         int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
   13771         int factor = (mLruProcesses.size()-4)/numSlots;
   13772         if (factor < 1) factor = 1;
   13773         int step = 0;
   13774         int numHidden = 0;
   13775 
   13776         // First update the OOM adjustment for each of the
   13777         // application processes based on their current state.
   13778         int i = mLruProcesses.size();
   13779         int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
   13780         int numBg = 0;
   13781         while (i > 0) {
   13782             i--;
   13783             ProcessRecord app = mLruProcesses.get(i);
   13784             //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
   13785             updateOomAdjLocked(app, curHiddenAdj, TOP_APP);
   13786             if (curHiddenAdj < ProcessList.EMPTY_APP_ADJ
   13787                 && app.curAdj == curHiddenAdj) {
   13788                 step++;
   13789                 if (step >= factor) {
   13790                     step = 0;
   13791                     curHiddenAdj++;
   13792                 }
   13793             }
   13794             if (!app.killedBackground) {
   13795                 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   13796                     numHidden++;
   13797                     if (numHidden > mProcessLimit) {
   13798                         Slog.i(TAG, "No longer want " + app.processName
   13799                                 + " (pid " + app.pid + "): hidden #" + numHidden);
   13800                         EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   13801                                 app.processName, app.setAdj, "too many background");
   13802                         app.killedBackground = true;
   13803                         Process.killProcessQuiet(app.pid);
   13804                     } else {
   13805                         numBg++;
   13806                     }
   13807                 } else if (app.curAdj >= ProcessList.HOME_APP_ADJ) {
   13808                     numBg++;
   13809                 }
   13810             }
   13811         }
   13812 
   13813         // Now determine the memory trimming level of background processes.
   13814         // Unfortunately we need to start at the back of the list to do this
   13815         // properly.  We only do this if the number of background apps we
   13816         // are managing to keep around is less than half the maximum we desire;
   13817         // if we are keeping a good number around, we'll let them use whatever
   13818         // memory they want.
   13819         if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
   13820             final int N = mLruProcesses.size();
   13821             factor = numBg/3;
   13822             step = 0;
   13823             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
   13824             for (i=0; i<N; i++) {
   13825                 ProcessRecord app = mLruProcesses.get(i);
   13826                 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ && !app.killedBackground) {
   13827                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
   13828                         try {
   13829                             app.thread.scheduleTrimMemory(curLevel);
   13830                         } catch (RemoteException e) {
   13831                         }
   13832                         if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
   13833                             // For these apps we will also finish their activities
   13834                             // to help them free memory.
   13835                             mMainStack.destroyActivitiesLocked(app, false);
   13836                         }
   13837                     }
   13838                     app.trimMemoryLevel = curLevel;
   13839                     step++;
   13840                     if (step >= factor) {
   13841                         switch (curLevel) {
   13842                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
   13843                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
   13844                                 break;
   13845                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
   13846                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   13847                                 break;
   13848                         }
   13849                     }
   13850                 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   13851                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
   13852                             && app.thread != null) {
   13853                         try {
   13854                             app.thread.scheduleTrimMemory(
   13855                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   13856                         } catch (RemoteException e) {
   13857                         }
   13858                     }
   13859                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   13860                 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
   13861                         && app.pendingUiClean) {
   13862                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
   13863                             && app.thread != null) {
   13864                         try {
   13865                             app.thread.scheduleTrimMemory(
   13866                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   13867                         } catch (RemoteException e) {
   13868                         }
   13869                     }
   13870                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
   13871                     app.pendingUiClean = false;
   13872                 } else {
   13873                     app.trimMemoryLevel = 0;
   13874                 }
   13875             }
   13876         } else {
   13877             final int N = mLruProcesses.size();
   13878             for (i=0; i<N; i++) {
   13879                 ProcessRecord app = mLruProcesses.get(i);
   13880                 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
   13881                         && app.pendingUiClean) {
   13882                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
   13883                             && app.thread != null) {
   13884                         try {
   13885                             app.thread.scheduleTrimMemory(
   13886                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   13887                         } catch (RemoteException e) {
   13888                         }
   13889                     }
   13890                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
   13891                     app.pendingUiClean = false;
   13892                 } else {
   13893                     app.trimMemoryLevel = 0;
   13894                 }
   13895             }
   13896         }
   13897 
   13898         if (mAlwaysFinishActivities) {
   13899             mMainStack.destroyActivitiesLocked(null, false);
   13900         }
   13901     }
   13902 
   13903     final void trimApplications() {
   13904         synchronized (this) {
   13905             int i;
   13906 
   13907             // First remove any unused application processes whose package
   13908             // has been removed.
   13909             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
   13910                 final ProcessRecord app = mRemovedProcesses.get(i);
   13911                 if (app.activities.size() == 0
   13912                         && app.curReceiver == null && app.services.size() == 0) {
   13913                     Slog.i(
   13914                         TAG, "Exiting empty application process "
   13915                         + app.processName + " ("
   13916                         + (app.thread != null ? app.thread.asBinder() : null)
   13917                         + ")\n");
   13918                     if (app.pid > 0 && app.pid != MY_PID) {
   13919                         EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   13920                                 app.processName, app.setAdj, "empty");
   13921                         Process.killProcessQuiet(app.pid);
   13922                     } else {
   13923                         try {
   13924                             app.thread.scheduleExit();
   13925                         } catch (Exception e) {
   13926                             // Ignore exceptions.
   13927                         }
   13928                     }
   13929                     cleanUpApplicationRecordLocked(app, false, true, -1);
   13930                     mRemovedProcesses.remove(i);
   13931 
   13932                     if (app.persistent) {
   13933                         if (app.persistent) {
   13934                             addAppLocked(app.info);
   13935                         }
   13936                     }
   13937                 }
   13938             }
   13939 
   13940             // Now update the oom adj for all processes.
   13941             updateOomAdjLocked();
   13942         }
   13943     }
   13944 
   13945     /** This method sends the specified signal to each of the persistent apps */
   13946     public void signalPersistentProcesses(int sig) throws RemoteException {
   13947         if (sig != Process.SIGNAL_USR1) {
   13948             throw new SecurityException("Only SIGNAL_USR1 is allowed");
   13949         }
   13950 
   13951         synchronized (this) {
   13952             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
   13953                     != PackageManager.PERMISSION_GRANTED) {
   13954                 throw new SecurityException("Requires permission "
   13955                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
   13956             }
   13957 
   13958             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   13959                 ProcessRecord r = mLruProcesses.get(i);
   13960                 if (r.thread != null && r.persistent) {
   13961                     Process.sendSignal(r.pid, sig);
   13962                 }
   13963             }
   13964         }
   13965     }
   13966 
   13967     private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
   13968         if (proc == null || proc == mProfileProc) {
   13969             proc = mProfileProc;
   13970             path = mProfileFile;
   13971             profileType = mProfileType;
   13972             clearProfilerLocked();
   13973         }
   13974         if (proc == null) {
   13975             return;
   13976         }
   13977         try {
   13978             proc.thread.profilerControl(false, path, null, profileType);
   13979         } catch (RemoteException e) {
   13980             throw new IllegalStateException("Process disappeared");
   13981         }
   13982     }
   13983 
   13984     private void clearProfilerLocked() {
   13985         if (mProfileFd != null) {
   13986             try {
   13987                 mProfileFd.close();
   13988             } catch (IOException e) {
   13989             }
   13990         }
   13991         mProfileApp = null;
   13992         mProfileProc = null;
   13993         mProfileFile = null;
   13994         mProfileType = 0;
   13995         mAutoStopProfiler = false;
   13996     }
   13997 
   13998     public boolean profileControl(String process, boolean start,
   13999             String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
   14000 
   14001         try {
   14002             synchronized (this) {
   14003                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   14004                 // its own permission.
   14005                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   14006                         != PackageManager.PERMISSION_GRANTED) {
   14007                     throw new SecurityException("Requires permission "
   14008                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   14009                 }
   14010 
   14011                 if (start && fd == null) {
   14012                     throw new IllegalArgumentException("null fd");
   14013                 }
   14014 
   14015                 ProcessRecord proc = null;
   14016                 if (process != null) {
   14017                     try {
   14018                         int pid = Integer.parseInt(process);
   14019                         synchronized (mPidsSelfLocked) {
   14020                             proc = mPidsSelfLocked.get(pid);
   14021                         }
   14022                     } catch (NumberFormatException e) {
   14023                     }
   14024 
   14025                     if (proc == null) {
   14026                         HashMap<String, SparseArray<ProcessRecord>> all
   14027                                 = mProcessNames.getMap();
   14028                         SparseArray<ProcessRecord> procs = all.get(process);
   14029                         if (procs != null && procs.size() > 0) {
   14030                             proc = procs.valueAt(0);
   14031                         }
   14032                     }
   14033                 }
   14034 
   14035                 if (start && (proc == null || proc.thread == null)) {
   14036                     throw new IllegalArgumentException("Unknown process: " + process);
   14037                 }
   14038 
   14039                 if (start) {
   14040                     stopProfilerLocked(null, null, 0);
   14041                     setProfileApp(proc.info, proc.processName, path, fd, false);
   14042                     mProfileProc = proc;
   14043                     mProfileType = profileType;
   14044                     try {
   14045                         fd = fd.dup();
   14046                     } catch (IOException e) {
   14047                         fd = null;
   14048                     }
   14049                     proc.thread.profilerControl(start, path, fd, profileType);
   14050                     fd = null;
   14051                     mProfileFd = null;
   14052                 } else {
   14053                     stopProfilerLocked(proc, path, profileType);
   14054                     if (fd != null) {
   14055                         try {
   14056                             fd.close();
   14057                         } catch (IOException e) {
   14058                         }
   14059                     }
   14060                 }
   14061 
   14062                 return true;
   14063             }
   14064         } catch (RemoteException e) {
   14065             throw new IllegalStateException("Process disappeared");
   14066         } finally {
   14067             if (fd != null) {
   14068                 try {
   14069                     fd.close();
   14070                 } catch (IOException e) {
   14071                 }
   14072             }
   14073         }
   14074     }
   14075 
   14076     public boolean dumpHeap(String process, boolean managed,
   14077             String path, ParcelFileDescriptor fd) throws RemoteException {
   14078 
   14079         try {
   14080             synchronized (this) {
   14081                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   14082                 // its own permission (same as profileControl).
   14083                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   14084                         != PackageManager.PERMISSION_GRANTED) {
   14085                     throw new SecurityException("Requires permission "
   14086                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   14087                 }
   14088 
   14089                 if (fd == null) {
   14090                     throw new IllegalArgumentException("null fd");
   14091                 }
   14092 
   14093                 ProcessRecord proc = null;
   14094                 try {
   14095                     int pid = Integer.parseInt(process);
   14096                     synchronized (mPidsSelfLocked) {
   14097                         proc = mPidsSelfLocked.get(pid);
   14098                     }
   14099                 } catch (NumberFormatException e) {
   14100                 }
   14101 
   14102                 if (proc == null) {
   14103                     HashMap<String, SparseArray<ProcessRecord>> all
   14104                             = mProcessNames.getMap();
   14105                     SparseArray<ProcessRecord> procs = all.get(process);
   14106                     if (procs != null && procs.size() > 0) {
   14107                         proc = procs.valueAt(0);
   14108                     }
   14109                 }
   14110 
   14111                 if (proc == null || proc.thread == null) {
   14112                     throw new IllegalArgumentException("Unknown process: " + process);
   14113                 }
   14114 
   14115                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   14116                 if (!isDebuggable) {
   14117                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   14118                         throw new SecurityException("Process not debuggable: " + proc);
   14119                     }
   14120                 }
   14121 
   14122                 proc.thread.dumpHeap(managed, path, fd);
   14123                 fd = null;
   14124                 return true;
   14125             }
   14126         } catch (RemoteException e) {
   14127             throw new IllegalStateException("Process disappeared");
   14128         } finally {
   14129             if (fd != null) {
   14130                 try {
   14131                     fd.close();
   14132                 } catch (IOException e) {
   14133                 }
   14134             }
   14135         }
   14136     }
   14137 
   14138     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
   14139     public void monitor() {
   14140         synchronized (this) { }
   14141     }
   14142 
   14143     public void onCoreSettingsChange(Bundle settings) {
   14144         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   14145             ProcessRecord processRecord = mLruProcesses.get(i);
   14146             try {
   14147                 if (processRecord.thread != null) {
   14148                     processRecord.thread.setCoreSettings(settings);
   14149                 }
   14150             } catch (RemoteException re) {
   14151                 /* ignore */
   14152             }
   14153         }
   14154     }
   14155 
   14156     // Multi-user methods
   14157 
   14158     public boolean switchUser(int userid) {
   14159         // TODO
   14160         return true;
   14161     }
   14162 }
   14163