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.BufferedReader;
    124 import java.io.DataInputStream;
    125 import java.io.DataOutputStream;
    126 import java.io.File;
    127 import java.io.FileDescriptor;
    128 import java.io.FileInputStream;
    129 import java.io.FileNotFoundException;
    130 import java.io.FileOutputStream;
    131 import java.io.IOException;
    132 import java.io.InputStreamReader;
    133 import java.io.PrintWriter;
    134 import java.io.StringWriter;
    135 import java.lang.IllegalStateException;
    136 import java.lang.ref.WeakReference;
    137 import java.util.ArrayList;
    138 import java.util.Collections;
    139 import java.util.Comparator;
    140 import java.util.HashMap;
    141 import java.util.HashSet;
    142 import java.util.Iterator;
    143 import java.util.List;
    144 import java.util.Locale;
    145 import java.util.Map;
    146 import java.util.Set;
    147 import java.util.concurrent.atomic.AtomicBoolean;
    148 import java.util.concurrent.atomic.AtomicLong;
    149 
    150 public final class ActivityManagerService extends ActivityManagerNative
    151         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    152     static final String TAG = "ActivityManager";
    153     static final boolean DEBUG = false;
    154     static final boolean localLOGV = DEBUG;
    155     static final boolean DEBUG_SWITCH = localLOGV || false;
    156     static final boolean DEBUG_TASKS = localLOGV || false;
    157     static final boolean DEBUG_PAUSE = localLOGV || false;
    158     static final boolean DEBUG_OOM_ADJ = localLOGV || false;
    159     static final boolean DEBUG_TRANSITION = localLOGV || false;
    160     static final boolean DEBUG_BROADCAST = localLOGV || false;
    161     static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
    162     static final boolean DEBUG_SERVICE = localLOGV || false;
    163     static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
    164     static final boolean DEBUG_VISBILITY = localLOGV || false;
    165     static final boolean DEBUG_PROCESSES = localLOGV || false;
    166     static final boolean DEBUG_PROVIDER = localLOGV || false;
    167     static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
    168     static final boolean DEBUG_USER_LEAVING = localLOGV || false;
    169     static final boolean DEBUG_RESULTS = localLOGV || false;
    170     static final boolean DEBUG_BACKUP = localLOGV || false;
    171     static final boolean DEBUG_CONFIGURATION = localLOGV || false;
    172     static final boolean DEBUG_POWER = localLOGV || false;
    173     static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
    174     static final boolean VALIDATE_TOKENS = false;
    175     static final boolean SHOW_ACTIVITY_START_TIME = true;
    176 
    177     // Control over CPU and battery monitoring.
    178     static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
    179     static final boolean MONITOR_CPU_USAGE = true;
    180     static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
    181     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
    182     static final boolean MONITOR_THREAD_CPU_USAGE = false;
    183 
    184     // The flags that are set for all calls we make to the package manager.
    185     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
    186 
    187     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
    188 
    189     // Maximum number of recent tasks that we can remember.
    190     static final int MAX_RECENT_TASKS = 20;
    191 
    192     // Amount of time after a call to stopAppSwitches() during which we will
    193     // prevent further untrusted switches from happening.
    194     static final long APP_SWITCH_DELAY_TIME = 5*1000;
    195 
    196     // How long we wait for a launched process to attach to the activity manager
    197     // before we decide it's never going to come up for real.
    198     static final int PROC_START_TIMEOUT = 10*1000;
    199 
    200     // How long we wait for a launched process to attach to the activity manager
    201     // before we decide it's never going to come up for real, when the process was
    202     // started with a wrapper for instrumentation (such as Valgrind) because it
    203     // could take much longer than usual.
    204     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
    205 
    206     // How long to wait after going idle before forcing apps to GC.
    207     static final int GC_TIMEOUT = 5*1000;
    208 
    209     // The minimum amount of time between successive GC requests for a process.
    210     static final int GC_MIN_INTERVAL = 60*1000;
    211 
    212     // The rate at which we check for apps using excessive power -- 15 mins.
    213     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
    214 
    215     // The minimum sample duration we will allow before deciding we have
    216     // enough data on wake locks to start killing things.
    217     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    218 
    219     // The minimum sample duration we will allow before deciding we have
    220     // enough data on CPU usage to start killing things.
    221     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    222 
    223     // How long we allow a receiver to run before giving up on it.
    224     static final int BROADCAST_TIMEOUT = 10*1000;
    225 
    226     // How long we wait for a service to finish executing.
    227     static final int SERVICE_TIMEOUT = 20*1000;
    228 
    229     // How long a service needs to be running until restarting its process
    230     // is no longer considered to be a relaunch of the service.
    231     static final int SERVICE_RESTART_DURATION = 5*1000;
    232 
    233     // How long a service needs to be running until it will start back at
    234     // SERVICE_RESTART_DURATION after being killed.
    235     static final int SERVICE_RESET_RUN_DURATION = 60*1000;
    236 
    237     // Multiplying factor to increase restart duration time by, for each time
    238     // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
    239     static final int SERVICE_RESTART_DURATION_FACTOR = 4;
    240 
    241     // The minimum amount of time between restarting services that we allow.
    242     // That is, when multiple services are restarting, we won't allow each
    243     // to restart less than this amount of time from the last one.
    244     static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
    245 
    246     // Maximum amount of time for there to be no activity on a service before
    247     // we consider it non-essential and allow its process to go on the
    248     // LRU background list.
    249     static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
    250 
    251     // How long we wait until we timeout on key dispatching.
    252     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
    253 
    254     // How long we wait until we timeout on key dispatching during instrumentation.
    255     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
    256 
    257     static final int MY_PID = Process.myPid();
    258 
    259     static final String[] EMPTY_STRING_ARRAY = new String[0];
    260 
    261     public ActivityStack mMainStack;
    262 
    263     /**
    264      * Description of a request to start a new activity, which has been held
    265      * due to app switches being disabled.
    266      */
    267     static class PendingActivityLaunch {
    268         ActivityRecord r;
    269         ActivityRecord sourceRecord;
    270         Uri[] grantedUriPermissions;
    271         int grantedMode;
    272         boolean onlyIfNeeded;
    273     }
    274 
    275     final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
    276             = new ArrayList<PendingActivityLaunch>();
    277 
    278     /**
    279      * List of all active broadcasts that are to be executed immediately
    280      * (without waiting for another broadcast to finish).  Currently this only
    281      * contains broadcasts to registered receivers, to avoid spinning up
    282      * a bunch of processes to execute IntentReceiver components.
    283      */
    284     final ArrayList<BroadcastRecord> mParallelBroadcasts
    285             = new ArrayList<BroadcastRecord>();
    286 
    287     /**
    288      * List of all active broadcasts that are to be executed one at a time.
    289      * The object at the top of the list is the currently activity broadcasts;
    290      * those after it are waiting for the top to finish..
    291      */
    292     final ArrayList<BroadcastRecord> mOrderedBroadcasts
    293             = new ArrayList<BroadcastRecord>();
    294 
    295     /**
    296      * Historical data of past broadcasts, for debugging.
    297      */
    298     static final int MAX_BROADCAST_HISTORY = 25;
    299     final BroadcastRecord[] mBroadcastHistory
    300             = new BroadcastRecord[MAX_BROADCAST_HISTORY];
    301 
    302     /**
    303      * Set when we current have a BROADCAST_INTENT_MSG in flight.
    304      */
    305     boolean mBroadcastsScheduled = false;
    306 
    307     /**
    308      * Activity we have told the window manager to have key focus.
    309      */
    310     ActivityRecord mFocusedActivity = null;
    311     /**
    312      * List of intents that were used to start the most recent tasks.
    313      */
    314     final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
    315 
    316     /**
    317      * Process management.
    318      */
    319     final ProcessList mProcessList = new ProcessList();
    320 
    321     /**
    322      * All of the applications we currently have running organized by name.
    323      * The keys are strings of the application package name (as
    324      * returned by the package manager), and the keys are ApplicationRecord
    325      * objects.
    326      */
    327     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
    328 
    329     /**
    330      * The currently running heavy-weight process, if any.
    331      */
    332     ProcessRecord mHeavyWeightProcess = null;
    333 
    334     /**
    335      * The last time that various processes have crashed.
    336      */
    337     final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
    338 
    339     /**
    340      * Set of applications that we consider to be bad, and will reject
    341      * incoming broadcasts from (which the user has no control over).
    342      * Processes are added to this set when they have crashed twice within
    343      * a minimum amount of time; they are removed from it when they are
    344      * later restarted (hopefully due to some user action).  The value is the
    345      * time it was added to the list.
    346      */
    347     final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
    348 
    349     /**
    350      * All of the processes we currently have running organized by pid.
    351      * The keys are the pid running the application.
    352      *
    353      * <p>NOTE: This object is protected by its own lock, NOT the global
    354      * activity manager lock!
    355      */
    356     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
    357 
    358     /**
    359      * All of the processes that have been forced to be foreground.  The key
    360      * is the pid of the caller who requested it (we hold a death
    361      * link on it).
    362      */
    363     abstract class ForegroundToken implements IBinder.DeathRecipient {
    364         int pid;
    365         IBinder token;
    366     }
    367     final SparseArray<ForegroundToken> mForegroundProcesses
    368             = new SparseArray<ForegroundToken>();
    369 
    370     /**
    371      * List of records for processes that someone had tried to start before the
    372      * system was ready.  We don't start them at that point, but ensure they
    373      * are started by the time booting is complete.
    374      */
    375     final ArrayList<ProcessRecord> mProcessesOnHold
    376             = new ArrayList<ProcessRecord>();
    377 
    378     /**
    379      * List of persistent applications that are in the process
    380      * of being started.
    381      */
    382     final ArrayList<ProcessRecord> mPersistentStartingProcesses
    383             = new ArrayList<ProcessRecord>();
    384 
    385     /**
    386      * Processes that are being forcibly torn down.
    387      */
    388     final ArrayList<ProcessRecord> mRemovedProcesses
    389             = new ArrayList<ProcessRecord>();
    390 
    391     /**
    392      * List of running applications, sorted by recent usage.
    393      * The first entry in the list is the least recently used.
    394      * It contains ApplicationRecord objects.  This list does NOT include
    395      * any persistent application records (since we never want to exit them).
    396      */
    397     final ArrayList<ProcessRecord> mLruProcesses
    398             = new ArrayList<ProcessRecord>();
    399 
    400     /**
    401      * List of processes that should gc as soon as things are idle.
    402      */
    403     final ArrayList<ProcessRecord> mProcessesToGc
    404             = new ArrayList<ProcessRecord>();
    405 
    406     /**
    407      * This is the process holding what we currently consider to be
    408      * the "home" activity.
    409      */
    410     ProcessRecord mHomeProcess;
    411 
    412     /**
    413      * This is the process holding the activity the user last visited that
    414      * is in a different process from the one they are currently in.
    415      */
    416     ProcessRecord mPreviousProcess;
    417 
    418     /**
    419      * The time at which the previous process was last visible.
    420      */
    421     long mPreviousProcessVisibleTime;
    422 
    423     /**
    424      * Packages that the user has asked to have run in screen size
    425      * compatibility mode instead of filling the screen.
    426      */
    427     final CompatModePackages mCompatModePackages;
    428 
    429     /**
    430      * Set of PendingResultRecord objects that are currently active.
    431      */
    432     final HashSet mPendingResultRecords = new HashSet();
    433 
    434     /**
    435      * Set of IntentSenderRecord objects that are currently active.
    436      */
    437     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
    438             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
    439 
    440     /**
    441      * Fingerprints (hashCode()) of stack traces that we've
    442      * already logged DropBox entries for.  Guarded by itself.  If
    443      * something (rogue user app) forces this over
    444      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
    445      */
    446     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
    447     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
    448 
    449     /**
    450      * Strict Mode background batched logging state.
    451      *
    452      * The string buffer is guarded by itself, and its lock is also
    453      * used to determine if another batched write is already
    454      * in-flight.
    455      */
    456     private final StringBuilder mStrictModeBuffer = new StringBuilder();
    457 
    458     /**
    459      * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
    460      */
    461     private boolean mPendingBroadcastTimeoutMessage;
    462 
    463     /**
    464      * Intent broadcast that we have tried to start, but are
    465      * waiting for its application's process to be created.  We only
    466      * need one (instead of a list) because we always process broadcasts
    467      * one at a time, so no others can be started while waiting for this
    468      * one.
    469      */
    470     BroadcastRecord mPendingBroadcast = null;
    471 
    472     /**
    473      * The receiver index that is pending, to restart the broadcast if needed.
    474      */
    475     int mPendingBroadcastRecvIndex;
    476 
    477     /**
    478      * Keeps track of all IIntentReceivers that have been registered for
    479      * broadcasts.  Hash keys are the receiver IBinder, hash value is
    480      * a ReceiverList.
    481      */
    482     final HashMap mRegisteredReceivers = new HashMap();
    483 
    484     /**
    485      * Resolver for broadcast intents to registered receivers.
    486      * Holds BroadcastFilter (subclass of IntentFilter).
    487      */
    488     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
    489             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
    490         @Override
    491         protected boolean allowFilterResult(
    492                 BroadcastFilter filter, List<BroadcastFilter> dest) {
    493             IBinder target = filter.receiverList.receiver.asBinder();
    494             for (int i=dest.size()-1; i>=0; i--) {
    495                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
    496                     return false;
    497                 }
    498             }
    499             return true;
    500         }
    501 
    502         @Override
    503         protected String packageForFilter(BroadcastFilter filter) {
    504             return filter.packageName;
    505         }
    506     };
    507 
    508     /**
    509      * State of all active sticky broadcasts.  Keys are the action of the
    510      * sticky Intent, values are an ArrayList of all broadcasted intents with
    511      * that action (which should usually be one).
    512      */
    513     final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
    514             new HashMap<String, ArrayList<Intent>>();
    515 
    516     /**
    517      * All currently running services.
    518      */
    519     final HashMap<ComponentName, ServiceRecord> mServices =
    520         new HashMap<ComponentName, ServiceRecord>();
    521 
    522     /**
    523      * All currently running services indexed by the Intent used to start them.
    524      */
    525     final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
    526         new HashMap<Intent.FilterComparison, ServiceRecord>();
    527 
    528     /**
    529      * All currently bound service connections.  Keys are the IBinder of
    530      * the client's IServiceConnection.
    531      */
    532     final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
    533             = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
    534 
    535     /**
    536      * List of services that we have been asked to start,
    537      * but haven't yet been able to.  It is used to hold start requests
    538      * while waiting for their corresponding application thread to get
    539      * going.
    540      */
    541     final ArrayList<ServiceRecord> mPendingServices
    542             = new ArrayList<ServiceRecord>();
    543 
    544     /**
    545      * List of services that are scheduled to restart following a crash.
    546      */
    547     final ArrayList<ServiceRecord> mRestartingServices
    548             = new ArrayList<ServiceRecord>();
    549 
    550     /**
    551      * List of services that are in the process of being stopped.
    552      */
    553     final ArrayList<ServiceRecord> mStoppingServices
    554             = new ArrayList<ServiceRecord>();
    555 
    556     /**
    557      * Backup/restore process management
    558      */
    559     String mBackupAppName = null;
    560     BackupRecord mBackupTarget = null;
    561 
    562     /**
    563      * List of PendingThumbnailsRecord objects of clients who are still
    564      * waiting to receive all of the thumbnails for a task.
    565      */
    566     final ArrayList mPendingThumbnails = new ArrayList();
    567 
    568     /**
    569      * List of HistoryRecord objects that have been finished and must
    570      * still report back to a pending thumbnail receiver.
    571      */
    572     final ArrayList mCancelledThumbnails = new ArrayList();
    573 
    574     /**
    575      * All of the currently running global content providers.  Keys are a
    576      * string containing the provider name and values are a
    577      * ContentProviderRecord object containing the data about it.  Note
    578      * that a single provider may be published under multiple names, so
    579      * there may be multiple entries here for a single one in mProvidersByClass.
    580      */
    581     final HashMap<String, ContentProviderRecord> mProvidersByName
    582             = new HashMap<String, ContentProviderRecord>();
    583 
    584     /**
    585      * All of the currently running global content providers.  Keys are a
    586      * string containing the provider's implementation class and values are a
    587      * ContentProviderRecord object containing the data about it.
    588      */
    589     final HashMap<ComponentName, ContentProviderRecord> mProvidersByClass
    590             = new HashMap<ComponentName, ContentProviderRecord>();
    591 
    592     /**
    593      * List of content providers who have clients waiting for them.  The
    594      * application is currently being launched and the provider will be
    595      * removed from this list once it is published.
    596      */
    597     final ArrayList<ContentProviderRecord> mLaunchingProviders
    598             = new ArrayList<ContentProviderRecord>();
    599 
    600     /**
    601      * Global set of specific Uri permissions that have been granted.
    602      */
    603     final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
    604             = new SparseArray<HashMap<Uri, UriPermission>>();
    605 
    606     CoreSettingsObserver mCoreSettingsObserver;
    607 
    608     /**
    609      * Thread-local storage used to carry caller permissions over through
    610      * indirect content-provider access.
    611      * @see #ActivityManagerService.openContentUri()
    612      */
    613     private class Identity {
    614         public int pid;
    615         public int uid;
    616 
    617         Identity(int _pid, int _uid) {
    618             pid = _pid;
    619             uid = _uid;
    620         }
    621     }
    622     private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
    623 
    624     /**
    625      * All information we have collected about the runtime performance of
    626      * any user id that can impact battery performance.
    627      */
    628     final BatteryStatsService mBatteryStatsService;
    629 
    630     /**
    631      * information about component usage
    632      */
    633     final UsageStatsService mUsageStatsService;
    634 
    635     /**
    636      * Current configuration information.  HistoryRecord objects are given
    637      * a reference to this object to indicate which configuration they are
    638      * currently running in, so this object must be kept immutable.
    639      */
    640     Configuration mConfiguration = new Configuration();
    641 
    642     /**
    643      * Current sequencing integer of the configuration, for skipping old
    644      * configurations.
    645      */
    646     int mConfigurationSeq = 0;
    647 
    648     /**
    649      * Hardware-reported OpenGLES version.
    650      */
    651     final int GL_ES_VERSION;
    652 
    653     /**
    654      * List of initialization arguments to pass to all processes when binding applications to them.
    655      * For example, references to the commonly used services.
    656      */
    657     HashMap<String, IBinder> mAppBindArgs;
    658 
    659     /**
    660      * Temporary to avoid allocations.  Protected by main lock.
    661      */
    662     final StringBuilder mStringBuilder = new StringBuilder(256);
    663 
    664     /**
    665      * Used to control how we initialize the service.
    666      */
    667     boolean mStartRunning = false;
    668     ComponentName mTopComponent;
    669     String mTopAction;
    670     String mTopData;
    671     boolean mProcessesReady = false;
    672     boolean mSystemReady = false;
    673     boolean mBooting = false;
    674     boolean mWaitingUpdate = false;
    675     boolean mDidUpdate = false;
    676     boolean mOnBattery = false;
    677     boolean mLaunchWarningShown = false;
    678 
    679     Context mContext;
    680 
    681     int mFactoryTest;
    682 
    683     boolean mCheckedForSetup;
    684 
    685     /**
    686      * The time at which we will allow normal application switches again,
    687      * after a call to {@link #stopAppSwitches()}.
    688      */
    689     long mAppSwitchesAllowedTime;
    690 
    691     /**
    692      * This is set to true after the first switch after mAppSwitchesAllowedTime
    693      * is set; any switches after that will clear the time.
    694      */
    695     boolean mDidAppSwitch;
    696 
    697     /**
    698      * Last time (in realtime) at which we checked for power usage.
    699      */
    700     long mLastPowerCheckRealtime;
    701 
    702     /**
    703      * Last time (in uptime) at which we checked for power usage.
    704      */
    705     long mLastPowerCheckUptime;
    706 
    707     /**
    708      * Set while we are wanting to sleep, to prevent any
    709      * activities from being started/resumed.
    710      */
    711     boolean mSleeping = false;
    712 
    713     /**
    714      * Set if we are shutting down the system, similar to sleeping.
    715      */
    716     boolean mShuttingDown = false;
    717 
    718     /**
    719      * Task identifier that activities are currently being started
    720      * in.  Incremented each time a new task is created.
    721      * todo: Replace this with a TokenSpace class that generates non-repeating
    722      * integers that won't wrap.
    723      */
    724     int mCurTask = 1;
    725 
    726     /**
    727      * Current sequence id for oom_adj computation traversal.
    728      */
    729     int mAdjSeq = 0;
    730 
    731     /**
    732      * Current sequence id for process LRU updating.
    733      */
    734     int mLruSeq = 0;
    735 
    736     /**
    737      * Keep track of the number of service processes we last found, to
    738      * determine on the next iteration which should be B services.
    739      */
    740     int mNumServiceProcs = 0;
    741     int mNewNumServiceProcs = 0;
    742 
    743     /**
    744      * System monitoring: number of processes that died since the last
    745      * N procs were started.
    746      */
    747     int[] mProcDeaths = new int[20];
    748 
    749     /**
    750      * This is set if we had to do a delayed dexopt of an app before launching
    751      * it, to increasing the ANR timeouts in that case.
    752      */
    753     boolean mDidDexOpt;
    754 
    755     String mDebugApp = null;
    756     boolean mWaitForDebugger = false;
    757     boolean mDebugTransient = false;
    758     String mOrigDebugApp = null;
    759     boolean mOrigWaitForDebugger = false;
    760     boolean mAlwaysFinishActivities = false;
    761     IActivityController mController = null;
    762     String mProfileApp = null;
    763     ProcessRecord mProfileProc = null;
    764     String mProfileFile;
    765     ParcelFileDescriptor mProfileFd;
    766     int mProfileType = 0;
    767     boolean mAutoStopProfiler = false;
    768 
    769     final RemoteCallbackList<IActivityWatcher> mWatchers
    770             = new RemoteCallbackList<IActivityWatcher>();
    771 
    772     final RemoteCallbackList<IProcessObserver> mProcessObservers
    773             = new RemoteCallbackList<IProcessObserver>();
    774 
    775     /**
    776      * Callback of last caller to {@link #requestPss}.
    777      */
    778     Runnable mRequestPssCallback;
    779 
    780     /**
    781      * Remaining processes for which we are waiting results from the last
    782      * call to {@link #requestPss}.
    783      */
    784     final ArrayList<ProcessRecord> mRequestPssList
    785             = new ArrayList<ProcessRecord>();
    786 
    787     /**
    788      * Runtime statistics collection thread.  This object's lock is used to
    789      * protect all related state.
    790      */
    791     final Thread mProcessStatsThread;
    792 
    793     /**
    794      * Used to collect process stats when showing not responding dialog.
    795      * Protected by mProcessStatsThread.
    796      */
    797     final ProcessStats mProcessStats = new ProcessStats(
    798             MONITOR_THREAD_CPU_USAGE);
    799     final AtomicLong mLastCpuTime = new AtomicLong(0);
    800     final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
    801 
    802     long mLastWriteTime = 0;
    803 
    804     /**
    805      * Set to true after the system has finished booting.
    806      */
    807     boolean mBooted = false;
    808 
    809     int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
    810     int mProcessLimitOverride = -1;
    811 
    812     WindowManagerService mWindowManager;
    813 
    814     static ActivityManagerService mSelf;
    815     static ActivityThread mSystemThread;
    816 
    817     private final class AppDeathRecipient implements IBinder.DeathRecipient {
    818         final ProcessRecord mApp;
    819         final int mPid;
    820         final IApplicationThread mAppThread;
    821 
    822         AppDeathRecipient(ProcessRecord app, int pid,
    823                 IApplicationThread thread) {
    824             if (localLOGV) Slog.v(
    825                 TAG, "New death recipient " + this
    826                 + " for thread " + thread.asBinder());
    827             mApp = app;
    828             mPid = pid;
    829             mAppThread = thread;
    830         }
    831 
    832         public void binderDied() {
    833             if (localLOGV) Slog.v(
    834                 TAG, "Death received in " + this
    835                 + " for thread " + mAppThread.asBinder());
    836             synchronized(ActivityManagerService.this) {
    837                 appDiedLocked(mApp, mPid, mAppThread);
    838             }
    839         }
    840     }
    841 
    842     static final int SHOW_ERROR_MSG = 1;
    843     static final int SHOW_NOT_RESPONDING_MSG = 2;
    844     static final int SHOW_FACTORY_ERROR_MSG = 3;
    845     static final int UPDATE_CONFIGURATION_MSG = 4;
    846     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
    847     static final int WAIT_FOR_DEBUGGER_MSG = 6;
    848     static final int BROADCAST_INTENT_MSG = 7;
    849     static final int BROADCAST_TIMEOUT_MSG = 8;
    850     static final int SERVICE_TIMEOUT_MSG = 12;
    851     static final int UPDATE_TIME_ZONE = 13;
    852     static final int SHOW_UID_ERROR_MSG = 14;
    853     static final int IM_FEELING_LUCKY_MSG = 15;
    854     static final int PROC_START_TIMEOUT_MSG = 20;
    855     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
    856     static final int KILL_APPLICATION_MSG = 22;
    857     static final int FINALIZE_PENDING_INTENT_MSG = 23;
    858     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
    859     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
    860     static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
    861     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
    862     static final int CLEAR_DNS_CACHE = 28;
    863     static final int UPDATE_HTTP_PROXY = 29;
    864     static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
    865     static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
    866     static final int DISPATCH_PROCESS_DIED = 32;
    867     static final int REPORT_MEM_USAGE = 33;
    868 
    869     AlertDialog mUidAlert;
    870     CompatModeDialog mCompatModeDialog;
    871     long mLastMemUsageReportTime = 0;
    872 
    873     final Handler mHandler = new Handler() {
    874         //public Handler() {
    875         //    if (localLOGV) Slog.v(TAG, "Handler started!");
    876         //}
    877 
    878         public void handleMessage(Message msg) {
    879             switch (msg.what) {
    880             case SHOW_ERROR_MSG: {
    881                 HashMap data = (HashMap) msg.obj;
    882                 synchronized (ActivityManagerService.this) {
    883                     ProcessRecord proc = (ProcessRecord)data.get("app");
    884                     if (proc != null && proc.crashDialog != null) {
    885                         Slog.e(TAG, "App already has crash dialog: " + proc);
    886                         return;
    887                     }
    888                     AppErrorResult res = (AppErrorResult) data.get("result");
    889                     if (!mSleeping && !mShuttingDown) {
    890                         Dialog d = new AppErrorDialog(mContext, res, proc);
    891                         d.show();
    892                         proc.crashDialog = d;
    893                     } else {
    894                         // The device is asleep, so just pretend that the user
    895                         // saw a crash dialog and hit "force quit".
    896                         res.set(0);
    897                     }
    898                 }
    899 
    900                 ensureBootCompleted();
    901             } break;
    902             case SHOW_NOT_RESPONDING_MSG: {
    903                 synchronized (ActivityManagerService.this) {
    904                     HashMap data = (HashMap) msg.obj;
    905                     ProcessRecord proc = (ProcessRecord)data.get("app");
    906                     if (proc != null && proc.anrDialog != null) {
    907                         Slog.e(TAG, "App already has anr dialog: " + proc);
    908                         return;
    909                     }
    910 
    911                     Intent intent = new Intent("android.intent.action.ANR");
    912                     if (!mProcessesReady) {
    913                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
    914                     }
    915                     broadcastIntentLocked(null, null, intent,
    916                             null, null, 0, null, null, null,
    917                             false, false, MY_PID, Process.SYSTEM_UID);
    918 
    919                     Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
    920                             mContext, proc, (ActivityRecord)data.get("activity"));
    921                     d.show();
    922                     proc.anrDialog = d;
    923                 }
    924 
    925                 ensureBootCompleted();
    926             } break;
    927             case SHOW_STRICT_MODE_VIOLATION_MSG: {
    928                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
    929                 synchronized (ActivityManagerService.this) {
    930                     ProcessRecord proc = (ProcessRecord) data.get("app");
    931                     if (proc == null) {
    932                         Slog.e(TAG, "App not found when showing strict mode dialog.");
    933                         break;
    934                     }
    935                     if (proc.crashDialog != null) {
    936                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
    937                         return;
    938                     }
    939                     AppErrorResult res = (AppErrorResult) data.get("result");
    940                     if (!mSleeping && !mShuttingDown) {
    941                         Dialog d = new StrictModeViolationDialog(mContext, res, proc);
    942                         d.show();
    943                         proc.crashDialog = d;
    944                     } else {
    945                         // The device is asleep, so just pretend that the user
    946                         // saw a crash dialog and hit "force quit".
    947                         res.set(0);
    948                     }
    949                 }
    950                 ensureBootCompleted();
    951             } break;
    952             case SHOW_FACTORY_ERROR_MSG: {
    953                 Dialog d = new FactoryErrorDialog(
    954                     mContext, msg.getData().getCharSequence("msg"));
    955                 d.show();
    956                 ensureBootCompleted();
    957             } break;
    958             case UPDATE_CONFIGURATION_MSG: {
    959                 final ContentResolver resolver = mContext.getContentResolver();
    960                 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
    961             } break;
    962             case GC_BACKGROUND_PROCESSES_MSG: {
    963                 synchronized (ActivityManagerService.this) {
    964                     performAppGcsIfAppropriateLocked();
    965                 }
    966             } break;
    967             case WAIT_FOR_DEBUGGER_MSG: {
    968                 synchronized (ActivityManagerService.this) {
    969                     ProcessRecord app = (ProcessRecord)msg.obj;
    970                     if (msg.arg1 != 0) {
    971                         if (!app.waitedForDebugger) {
    972                             Dialog d = new AppWaitingForDebuggerDialog(
    973                                     ActivityManagerService.this,
    974                                     mContext, app);
    975                             app.waitDialog = d;
    976                             app.waitedForDebugger = true;
    977                             d.show();
    978                         }
    979                     } else {
    980                         if (app.waitDialog != null) {
    981                             app.waitDialog.dismiss();
    982                             app.waitDialog = null;
    983                         }
    984                     }
    985                 }
    986             } break;
    987             case BROADCAST_INTENT_MSG: {
    988                 if (DEBUG_BROADCAST) Slog.v(
    989                         TAG, "Received BROADCAST_INTENT_MSG");
    990                 processNextBroadcast(true);
    991             } break;
    992             case BROADCAST_TIMEOUT_MSG: {
    993                 synchronized (ActivityManagerService.this) {
    994                     broadcastTimeoutLocked(true);
    995                 }
    996             } break;
    997             case SERVICE_TIMEOUT_MSG: {
    998                 if (mDidDexOpt) {
    999                     mDidDexOpt = false;
   1000                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   1001                     nmsg.obj = msg.obj;
   1002                     mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
   1003                     return;
   1004                 }
   1005                 serviceTimeout((ProcessRecord)msg.obj);
   1006             } break;
   1007             case UPDATE_TIME_ZONE: {
   1008                 synchronized (ActivityManagerService.this) {
   1009                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1010                         ProcessRecord r = mLruProcesses.get(i);
   1011                         if (r.thread != null) {
   1012                             try {
   1013                                 r.thread.updateTimeZone();
   1014                             } catch (RemoteException ex) {
   1015                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
   1016                             }
   1017                         }
   1018                     }
   1019                 }
   1020             } break;
   1021             case CLEAR_DNS_CACHE: {
   1022                 synchronized (ActivityManagerService.this) {
   1023                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1024                         ProcessRecord r = mLruProcesses.get(i);
   1025                         if (r.thread != null) {
   1026                             try {
   1027                                 r.thread.clearDnsCache();
   1028                             } catch (RemoteException ex) {
   1029                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
   1030                             }
   1031                         }
   1032                     }
   1033                 }
   1034             } break;
   1035             case UPDATE_HTTP_PROXY: {
   1036                 ProxyProperties proxy = (ProxyProperties)msg.obj;
   1037                 String host = "";
   1038                 String port = "";
   1039                 String exclList = "";
   1040                 if (proxy != null) {
   1041                     host = proxy.getHost();
   1042                     port = Integer.toString(proxy.getPort());
   1043                     exclList = proxy.getExclusionList();
   1044                 }
   1045                 synchronized (ActivityManagerService.this) {
   1046                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1047                         ProcessRecord r = mLruProcesses.get(i);
   1048                         if (r.thread != null) {
   1049                             try {
   1050                                 r.thread.setHttpProxy(host, port, exclList);
   1051                             } catch (RemoteException ex) {
   1052                                 Slog.w(TAG, "Failed to update http proxy for: " +
   1053                                         r.info.processName);
   1054                             }
   1055                         }
   1056                     }
   1057                 }
   1058             } break;
   1059             case SHOW_UID_ERROR_MSG: {
   1060                 // XXX This is a temporary dialog, no need to localize.
   1061                 AlertDialog d = new BaseErrorDialog(mContext);
   1062                 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
   1063                 d.setCancelable(false);
   1064                 d.setTitle("System UIDs Inconsistent");
   1065                 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
   1066                 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
   1067                         mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
   1068                 mUidAlert = d;
   1069                 d.show();
   1070             } break;
   1071             case IM_FEELING_LUCKY_MSG: {
   1072                 if (mUidAlert != null) {
   1073                     mUidAlert.dismiss();
   1074                     mUidAlert = null;
   1075                 }
   1076             } break;
   1077             case PROC_START_TIMEOUT_MSG: {
   1078                 if (mDidDexOpt) {
   1079                     mDidDexOpt = false;
   1080                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   1081                     nmsg.obj = msg.obj;
   1082                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
   1083                     return;
   1084                 }
   1085                 ProcessRecord app = (ProcessRecord)msg.obj;
   1086                 synchronized (ActivityManagerService.this) {
   1087                     processStartTimedOutLocked(app);
   1088                 }
   1089             } break;
   1090             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
   1091                 synchronized (ActivityManagerService.this) {
   1092                     doPendingActivityLaunchesLocked(true);
   1093                 }
   1094             } break;
   1095             case KILL_APPLICATION_MSG: {
   1096                 synchronized (ActivityManagerService.this) {
   1097                     int uid = msg.arg1;
   1098                     boolean restart = (msg.arg2 == 1);
   1099                     String pkg = (String) msg.obj;
   1100                     forceStopPackageLocked(pkg, uid, restart, false, true, false);
   1101                 }
   1102             } break;
   1103             case FINALIZE_PENDING_INTENT_MSG: {
   1104                 ((PendingIntentRecord)msg.obj).completeFinalize();
   1105             } break;
   1106             case POST_HEAVY_NOTIFICATION_MSG: {
   1107                 INotificationManager inm = NotificationManager.getService();
   1108                 if (inm == null) {
   1109                     return;
   1110                 }
   1111 
   1112                 ActivityRecord root = (ActivityRecord)msg.obj;
   1113                 ProcessRecord process = root.app;
   1114                 if (process == null) {
   1115                     return;
   1116                 }
   1117 
   1118                 try {
   1119                     Context context = mContext.createPackageContext(process.info.packageName, 0);
   1120                     String text = mContext.getString(R.string.heavy_weight_notification,
   1121                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
   1122                     Notification notification = new Notification();
   1123                     notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
   1124                     notification.when = 0;
   1125                     notification.flags = Notification.FLAG_ONGOING_EVENT;
   1126                     notification.tickerText = text;
   1127                     notification.defaults = 0; // please be quiet
   1128                     notification.sound = null;
   1129                     notification.vibrate = null;
   1130                     notification.setLatestEventInfo(context, text,
   1131                             mContext.getText(R.string.heavy_weight_notification_detail),
   1132                             PendingIntent.getActivity(mContext, 0, root.intent,
   1133                                     PendingIntent.FLAG_CANCEL_CURRENT));
   1134 
   1135                     try {
   1136                         int[] outId = new int[1];
   1137                         inm.enqueueNotification("android", R.string.heavy_weight_notification,
   1138                                 notification, outId);
   1139                     } catch (RuntimeException e) {
   1140                         Slog.w(ActivityManagerService.TAG,
   1141                                 "Error showing notification for heavy-weight app", e);
   1142                     } catch (RemoteException e) {
   1143                     }
   1144                 } catch (NameNotFoundException e) {
   1145                     Slog.w(TAG, "Unable to create context for heavy notification", e);
   1146                 }
   1147             } break;
   1148             case CANCEL_HEAVY_NOTIFICATION_MSG: {
   1149                 INotificationManager inm = NotificationManager.getService();
   1150                 if (inm == null) {
   1151                     return;
   1152                 }
   1153                 try {
   1154                     inm.cancelNotification("android",
   1155                             R.string.heavy_weight_notification);
   1156                 } catch (RuntimeException e) {
   1157                     Slog.w(ActivityManagerService.TAG,
   1158                             "Error canceling notification for service", e);
   1159                 } catch (RemoteException e) {
   1160                 }
   1161             } break;
   1162             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
   1163                 synchronized (ActivityManagerService.this) {
   1164                     checkExcessivePowerUsageLocked(true);
   1165                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1166                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1167                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   1168                 }
   1169             } break;
   1170             case SHOW_COMPAT_MODE_DIALOG_MSG: {
   1171                 synchronized (ActivityManagerService.this) {
   1172                     ActivityRecord ar = (ActivityRecord)msg.obj;
   1173                     if (mCompatModeDialog != null) {
   1174                         if (mCompatModeDialog.mAppInfo.packageName.equals(
   1175                                 ar.info.applicationInfo.packageName)) {
   1176                             return;
   1177                         }
   1178                         mCompatModeDialog.dismiss();
   1179                         mCompatModeDialog = null;
   1180                     }
   1181                     if (ar != null && false) {
   1182                         if (mCompatModePackages.getPackageAskCompatModeLocked(
   1183                                 ar.packageName)) {
   1184                             int mode = mCompatModePackages.computeCompatModeLocked(
   1185                                     ar.info.applicationInfo);
   1186                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
   1187                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
   1188                                 mCompatModeDialog = new CompatModeDialog(
   1189                                         ActivityManagerService.this, mContext,
   1190                                         ar.info.applicationInfo);
   1191                                 mCompatModeDialog.show();
   1192                             }
   1193                         }
   1194                     }
   1195                 }
   1196                 break;
   1197             }
   1198             case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
   1199                 final int pid = msg.arg1;
   1200                 final int uid = msg.arg2;
   1201                 final boolean foregroundActivities = (Boolean) msg.obj;
   1202                 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
   1203                 break;
   1204             }
   1205             case DISPATCH_PROCESS_DIED: {
   1206                 final int pid = msg.arg1;
   1207                 final int uid = msg.arg2;
   1208                 dispatchProcessDied(pid, uid);
   1209                 break;
   1210             }
   1211             case REPORT_MEM_USAGE: {
   1212                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   1213                 if (!isDebuggable) {
   1214                     return;
   1215                 }
   1216                 synchronized (ActivityManagerService.this) {
   1217                     long now = SystemClock.uptimeMillis();
   1218                     if (now < (mLastMemUsageReportTime+5*60*1000)) {
   1219                         // Don't report more than every 5 minutes to somewhat
   1220                         // avoid spamming.
   1221                         return;
   1222                     }
   1223                     mLastMemUsageReportTime = now;
   1224                 }
   1225                 Thread thread = new Thread() {
   1226                     @Override public void run() {
   1227                         StringBuilder dropBuilder = new StringBuilder(1024);
   1228                         StringBuilder logBuilder = new StringBuilder(1024);
   1229                         StringWriter oomSw = new StringWriter();
   1230                         PrintWriter oomPw = new PrintWriter(oomSw);
   1231                         StringWriter catSw = new StringWriter();
   1232                         PrintWriter catPw = new PrintWriter(catSw);
   1233                         String[] emptyArgs = new String[] { };
   1234                         StringBuilder tag = new StringBuilder(128);
   1235                         StringBuilder stack = new StringBuilder(128);
   1236                         tag.append("Low on memory -- ");
   1237                         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
   1238                                 tag, stack);
   1239                         dropBuilder.append(stack);
   1240                         dropBuilder.append('\n');
   1241                         dropBuilder.append('\n');
   1242                         String oomString = oomSw.toString();
   1243                         dropBuilder.append(oomString);
   1244                         dropBuilder.append('\n');
   1245                         logBuilder.append(oomString);
   1246                         try {
   1247                             java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
   1248                                     "procrank", });
   1249                             final InputStreamReader converter = new InputStreamReader(
   1250                                     proc.getInputStream());
   1251                             BufferedReader in = new BufferedReader(converter);
   1252                             String line;
   1253                             while (true) {
   1254                                 line = in.readLine();
   1255                                 if (line == null) {
   1256                                     break;
   1257                                 }
   1258                                 if (line.length() > 0) {
   1259                                     logBuilder.append(line);
   1260                                     logBuilder.append('\n');
   1261                                 }
   1262                                 dropBuilder.append(line);
   1263                                 dropBuilder.append('\n');
   1264                             }
   1265                             converter.close();
   1266                         } catch (IOException e) {
   1267                         }
   1268                         synchronized (ActivityManagerService.this) {
   1269                             catPw.println();
   1270                             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
   1271                             catPw.println();
   1272                             dumpServicesLocked(null, catPw, emptyArgs, 0, false, false, null);
   1273                             catPw.println();
   1274                             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
   1275                         }
   1276                         dropBuilder.append(catSw.toString());
   1277                         addErrorToDropBox("lowmem", null, "system_server", null,
   1278                                 null, tag.toString(), dropBuilder.toString(), null, null);
   1279                         Slog.i(TAG, logBuilder.toString());
   1280                         synchronized (ActivityManagerService.this) {
   1281                             long now = SystemClock.uptimeMillis();
   1282                             if (mLastMemUsageReportTime < now) {
   1283                                 mLastMemUsageReportTime = now;
   1284                             }
   1285                         }
   1286                     }
   1287                 };
   1288                 thread.start();
   1289                 break;
   1290             }
   1291             }
   1292         }
   1293     };
   1294 
   1295     public static void setSystemProcess() {
   1296         try {
   1297             ActivityManagerService m = mSelf;
   1298 
   1299             ServiceManager.addService("activity", m);
   1300             ServiceManager.addService("meminfo", new MemBinder(m));
   1301             ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
   1302             if (MONITOR_CPU_USAGE) {
   1303                 ServiceManager.addService("cpuinfo", new CpuBinder(m));
   1304             }
   1305             ServiceManager.addService("permission", new PermissionController(m));
   1306 
   1307             ApplicationInfo info =
   1308                 mSelf.mContext.getPackageManager().getApplicationInfo(
   1309                         "android", STOCK_PM_FLAGS);
   1310             mSystemThread.installSystemApplicationInfo(info);
   1311 
   1312             synchronized (mSelf) {
   1313                 ProcessRecord app = mSelf.newProcessRecordLocked(
   1314                         mSystemThread.getApplicationThread(), info,
   1315                         info.processName);
   1316                 app.persistent = true;
   1317                 app.pid = MY_PID;
   1318                 app.maxAdj = ProcessList.SYSTEM_ADJ;
   1319                 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
   1320                 synchronized (mSelf.mPidsSelfLocked) {
   1321                     mSelf.mPidsSelfLocked.put(app.pid, app);
   1322                 }
   1323                 mSelf.updateLruProcessLocked(app, true, true);
   1324             }
   1325         } catch (PackageManager.NameNotFoundException e) {
   1326             throw new RuntimeException(
   1327                     "Unable to find android system package", e);
   1328         }
   1329     }
   1330 
   1331     public void setWindowManager(WindowManagerService wm) {
   1332         mWindowManager = wm;
   1333     }
   1334 
   1335     public static final Context main(int factoryTest) {
   1336         AThread thr = new AThread();
   1337         thr.start();
   1338 
   1339         synchronized (thr) {
   1340             while (thr.mService == null) {
   1341                 try {
   1342                     thr.wait();
   1343                 } catch (InterruptedException e) {
   1344                 }
   1345             }
   1346         }
   1347 
   1348         ActivityManagerService m = thr.mService;
   1349         mSelf = m;
   1350         ActivityThread at = ActivityThread.systemMain();
   1351         mSystemThread = at;
   1352         Context context = at.getSystemContext();
   1353         context.setTheme(android.R.style.Theme_Holo);
   1354         m.mContext = context;
   1355         m.mFactoryTest = factoryTest;
   1356         m.mMainStack = new ActivityStack(m, context, true);
   1357 
   1358         m.mBatteryStatsService.publish(context);
   1359         m.mUsageStatsService.publish(context);
   1360 
   1361         synchronized (thr) {
   1362             thr.mReady = true;
   1363             thr.notifyAll();
   1364         }
   1365 
   1366         m.startRunning(null, null, null, null);
   1367 
   1368         return context;
   1369     }
   1370 
   1371     public static ActivityManagerService self() {
   1372         return mSelf;
   1373     }
   1374 
   1375     static class AThread extends Thread {
   1376         ActivityManagerService mService;
   1377         boolean mReady = false;
   1378 
   1379         public AThread() {
   1380             super("ActivityManager");
   1381         }
   1382 
   1383         public void run() {
   1384             Looper.prepare();
   1385 
   1386             android.os.Process.setThreadPriority(
   1387                     android.os.Process.THREAD_PRIORITY_FOREGROUND);
   1388             android.os.Process.setCanSelfBackground(false);
   1389 
   1390             ActivityManagerService m = new ActivityManagerService();
   1391 
   1392             synchronized (this) {
   1393                 mService = m;
   1394                 notifyAll();
   1395             }
   1396 
   1397             synchronized (this) {
   1398                 while (!mReady) {
   1399                     try {
   1400                         wait();
   1401                     } catch (InterruptedException e) {
   1402                     }
   1403                 }
   1404             }
   1405 
   1406             // For debug builds, log event loop stalls to dropbox for analysis.
   1407             if (StrictMode.conditionallyEnableDebugLogging()) {
   1408                 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
   1409             }
   1410 
   1411             Looper.loop();
   1412         }
   1413     }
   1414 
   1415     static class MemBinder extends Binder {
   1416         ActivityManagerService mActivityManagerService;
   1417         MemBinder(ActivityManagerService activityManagerService) {
   1418             mActivityManagerService = activityManagerService;
   1419         }
   1420 
   1421         @Override
   1422         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1423             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1424                     != PackageManager.PERMISSION_GRANTED) {
   1425                 pw.println("Permission Denial: can't dump meminfo from from pid="
   1426                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1427                         + " without permission " + android.Manifest.permission.DUMP);
   1428                 return;
   1429             }
   1430 
   1431             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
   1432                     false, null, null, null);
   1433         }
   1434     }
   1435 
   1436     static class GraphicsBinder extends Binder {
   1437         ActivityManagerService mActivityManagerService;
   1438         GraphicsBinder(ActivityManagerService activityManagerService) {
   1439             mActivityManagerService = activityManagerService;
   1440         }
   1441 
   1442         @Override
   1443         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1444             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1445                     != PackageManager.PERMISSION_GRANTED) {
   1446                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
   1447                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1448                         + " without permission " + android.Manifest.permission.DUMP);
   1449                 return;
   1450             }
   1451 
   1452             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
   1453         }
   1454     }
   1455 
   1456     static class CpuBinder extends Binder {
   1457         ActivityManagerService mActivityManagerService;
   1458         CpuBinder(ActivityManagerService activityManagerService) {
   1459             mActivityManagerService = activityManagerService;
   1460         }
   1461 
   1462         @Override
   1463         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1464             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1465                     != PackageManager.PERMISSION_GRANTED) {
   1466                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
   1467                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1468                         + " without permission " + android.Manifest.permission.DUMP);
   1469                 return;
   1470             }
   1471 
   1472             synchronized (mActivityManagerService.mProcessStatsThread) {
   1473                 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
   1474                 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
   1475                         SystemClock.uptimeMillis()));
   1476             }
   1477         }
   1478     }
   1479 
   1480     private ActivityManagerService() {
   1481         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
   1482 
   1483         File dataDir = Environment.getDataDirectory();
   1484         File systemDir = new File(dataDir, "system");
   1485         systemDir.mkdirs();
   1486         mBatteryStatsService = new BatteryStatsService(new File(
   1487                 systemDir, "batterystats.bin").toString());
   1488         mBatteryStatsService.getActiveStatistics().readLocked();
   1489         mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
   1490         mOnBattery = DEBUG_POWER ? true
   1491                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
   1492         mBatteryStatsService.getActiveStatistics().setCallback(this);
   1493 
   1494         mUsageStatsService = new UsageStatsService(new File(
   1495                 systemDir, "usagestats").toString());
   1496 
   1497         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
   1498             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
   1499 
   1500         mConfiguration.setToDefaults();
   1501         mConfiguration.locale = Locale.getDefault();
   1502         mConfigurationSeq = mConfiguration.seq = 1;
   1503         mProcessStats.init();
   1504 
   1505         mCompatModePackages = new CompatModePackages(this, systemDir);
   1506 
   1507         // Add ourself to the Watchdog monitors.
   1508         Watchdog.getInstance().addMonitor(this);
   1509 
   1510         mProcessStatsThread = new Thread("ProcessStats") {
   1511             public void run() {
   1512                 while (true) {
   1513                     try {
   1514                         try {
   1515                             synchronized(this) {
   1516                                 final long now = SystemClock.uptimeMillis();
   1517                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
   1518                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
   1519                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
   1520                                 //        + ", write delay=" + nextWriteDelay);
   1521                                 if (nextWriteDelay < nextCpuDelay) {
   1522                                     nextCpuDelay = nextWriteDelay;
   1523                                 }
   1524                                 if (nextCpuDelay > 0) {
   1525                                     mProcessStatsMutexFree.set(true);
   1526                                     this.wait(nextCpuDelay);
   1527                                 }
   1528                             }
   1529                         } catch (InterruptedException e) {
   1530                         }
   1531                         updateCpuStatsNow();
   1532                     } catch (Exception e) {
   1533                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
   1534                     }
   1535                 }
   1536             }
   1537         };
   1538         mProcessStatsThread.start();
   1539     }
   1540 
   1541     @Override
   1542     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   1543             throws RemoteException {
   1544         try {
   1545             return super.onTransact(code, data, reply, flags);
   1546         } catch (RuntimeException e) {
   1547             // The activity manager only throws security exceptions, so let's
   1548             // log all others.
   1549             if (!(e instanceof SecurityException)) {
   1550                 Slog.e(TAG, "Activity Manager Crash", e);
   1551             }
   1552             throw e;
   1553         }
   1554     }
   1555 
   1556     void updateCpuStats() {
   1557         final long now = SystemClock.uptimeMillis();
   1558         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
   1559             return;
   1560         }
   1561         if (mProcessStatsMutexFree.compareAndSet(true, false)) {
   1562             synchronized (mProcessStatsThread) {
   1563                 mProcessStatsThread.notify();
   1564             }
   1565         }
   1566     }
   1567 
   1568     void updateCpuStatsNow() {
   1569         synchronized (mProcessStatsThread) {
   1570             mProcessStatsMutexFree.set(false);
   1571             final long now = SystemClock.uptimeMillis();
   1572             boolean haveNewCpuStats = false;
   1573 
   1574             if (MONITOR_CPU_USAGE &&
   1575                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
   1576                 mLastCpuTime.set(now);
   1577                 haveNewCpuStats = true;
   1578                 mProcessStats.update();
   1579                 //Slog.i(TAG, mProcessStats.printCurrentState());
   1580                 //Slog.i(TAG, "Total CPU usage: "
   1581                 //        + mProcessStats.getTotalCpuPercent() + "%");
   1582 
   1583                 // Slog the cpu usage if the property is set.
   1584                 if ("true".equals(SystemProperties.get("events.cpu"))) {
   1585                     int user = mProcessStats.getLastUserTime();
   1586                     int system = mProcessStats.getLastSystemTime();
   1587                     int iowait = mProcessStats.getLastIoWaitTime();
   1588                     int irq = mProcessStats.getLastIrqTime();
   1589                     int softIrq = mProcessStats.getLastSoftIrqTime();
   1590                     int idle = mProcessStats.getLastIdleTime();
   1591 
   1592                     int total = user + system + iowait + irq + softIrq + idle;
   1593                     if (total == 0) total = 1;
   1594 
   1595                     EventLog.writeEvent(EventLogTags.CPU,
   1596                             ((user+system+iowait+irq+softIrq) * 100) / total,
   1597                             (user * 100) / total,
   1598                             (system * 100) / total,
   1599                             (iowait * 100) / total,
   1600                             (irq * 100) / total,
   1601                             (softIrq * 100) / total);
   1602                 }
   1603             }
   1604 
   1605             long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
   1606             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
   1607             synchronized(bstats) {
   1608                 synchronized(mPidsSelfLocked) {
   1609                     if (haveNewCpuStats) {
   1610                         if (mOnBattery) {
   1611                             int perc = bstats.startAddingCpuLocked();
   1612                             int totalUTime = 0;
   1613                             int totalSTime = 0;
   1614                             final int N = mProcessStats.countStats();
   1615                             for (int i=0; i<N; i++) {
   1616                                 ProcessStats.Stats st = mProcessStats.getStats(i);
   1617                                 if (!st.working) {
   1618                                     continue;
   1619                                 }
   1620                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
   1621                                 int otherUTime = (st.rel_utime*perc)/100;
   1622                                 int otherSTime = (st.rel_stime*perc)/100;
   1623                                 totalUTime += otherUTime;
   1624                                 totalSTime += otherSTime;
   1625                                 if (pr != null) {
   1626                                     BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
   1627                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
   1628                                             st.rel_stime-otherSTime);
   1629                                     ps.addSpeedStepTimes(cpuSpeedTimes);
   1630                                     pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
   1631                                 } else {
   1632                                     BatteryStatsImpl.Uid.Proc ps =
   1633                                             bstats.getProcessStatsLocked(st.name, st.pid);
   1634                                     if (ps != null) {
   1635                                         ps.addCpuTimeLocked(st.rel_utime-otherUTime,
   1636                                                 st.rel_stime-otherSTime);
   1637                                         ps.addSpeedStepTimes(cpuSpeedTimes);
   1638                                     }
   1639                                 }
   1640                             }
   1641                             bstats.finishAddingCpuLocked(perc, totalUTime,
   1642                                     totalSTime, cpuSpeedTimes);
   1643                         }
   1644                     }
   1645                 }
   1646 
   1647                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
   1648                     mLastWriteTime = now;
   1649                     mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
   1650                 }
   1651             }
   1652         }
   1653     }
   1654 
   1655     @Override
   1656     public void batteryNeedsCpuUpdate() {
   1657         updateCpuStatsNow();
   1658     }
   1659 
   1660     @Override
   1661     public void batteryPowerChanged(boolean onBattery) {
   1662         // When plugging in, update the CPU stats first before changing
   1663         // the plug state.
   1664         updateCpuStatsNow();
   1665         synchronized (this) {
   1666             synchronized(mPidsSelfLocked) {
   1667                 mOnBattery = DEBUG_POWER ? true : onBattery;
   1668             }
   1669         }
   1670     }
   1671 
   1672     /**
   1673      * Initialize the application bind args. These are passed to each
   1674      * process when the bindApplication() IPC is sent to the process. They're
   1675      * lazily setup to make sure the services are running when they're asked for.
   1676      */
   1677     private HashMap<String, IBinder> getCommonServicesLocked() {
   1678         if (mAppBindArgs == null) {
   1679             mAppBindArgs = new HashMap<String, IBinder>();
   1680 
   1681             // Setup the application init args
   1682             mAppBindArgs.put("package", ServiceManager.getService("package"));
   1683             mAppBindArgs.put("window", ServiceManager.getService("window"));
   1684             mAppBindArgs.put(Context.ALARM_SERVICE,
   1685                     ServiceManager.getService(Context.ALARM_SERVICE));
   1686         }
   1687         return mAppBindArgs;
   1688     }
   1689 
   1690     final void setFocusedActivityLocked(ActivityRecord r) {
   1691         if (mFocusedActivity != r) {
   1692             mFocusedActivity = r;
   1693             if (r != null) {
   1694                 mWindowManager.setFocusedApp(r.appToken, true);
   1695             }
   1696         }
   1697     }
   1698 
   1699     private final void updateLruProcessInternalLocked(ProcessRecord app,
   1700             boolean oomAdj, boolean updateActivityTime, int bestPos) {
   1701         // put it on the LRU to keep track of when it should be exited.
   1702         int lrui = mLruProcesses.indexOf(app);
   1703         if (lrui >= 0) mLruProcesses.remove(lrui);
   1704 
   1705         int i = mLruProcesses.size()-1;
   1706         int skipTop = 0;
   1707 
   1708         app.lruSeq = mLruSeq;
   1709 
   1710         // compute the new weight for this process.
   1711         if (updateActivityTime) {
   1712             app.lastActivityTime = SystemClock.uptimeMillis();
   1713         }
   1714         if (app.activities.size() > 0) {
   1715             // If this process has activities, we more strongly want to keep
   1716             // it around.
   1717             app.lruWeight = app.lastActivityTime;
   1718         } else if (app.pubProviders.size() > 0) {
   1719             // If this process contains content providers, we want to keep
   1720             // it a little more strongly.
   1721             app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
   1722             // Also don't let it kick out the first few "real" hidden processes.
   1723             skipTop = ProcessList.MIN_HIDDEN_APPS;
   1724         } else {
   1725             // If this process doesn't have activities, we less strongly
   1726             // want to keep it around, and generally want to avoid getting
   1727             // in front of any very recently used activities.
   1728             app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
   1729             // Also don't let it kick out the first few "real" hidden processes.
   1730             skipTop = ProcessList.MIN_HIDDEN_APPS;
   1731         }
   1732 
   1733         while (i >= 0) {
   1734             ProcessRecord p = mLruProcesses.get(i);
   1735             // If this app shouldn't be in front of the first N background
   1736             // apps, then skip over that many that are currently hidden.
   1737             if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   1738                 skipTop--;
   1739             }
   1740             if (p.lruWeight <= app.lruWeight || i < bestPos) {
   1741                 mLruProcesses.add(i+1, app);
   1742                 break;
   1743             }
   1744             i--;
   1745         }
   1746         if (i < 0) {
   1747             mLruProcesses.add(0, app);
   1748         }
   1749 
   1750         // If the app is currently using a content provider or service,
   1751         // bump those processes as well.
   1752         if (app.connections.size() > 0) {
   1753             for (ConnectionRecord cr : app.connections) {
   1754                 if (cr.binding != null && cr.binding.service != null
   1755                         && cr.binding.service.app != null
   1756                         && cr.binding.service.app.lruSeq != mLruSeq) {
   1757                     updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
   1758                             updateActivityTime, i+1);
   1759                 }
   1760             }
   1761         }
   1762         if (app.conProviders.size() > 0) {
   1763             for (ContentProviderRecord cpr : app.conProviders.keySet()) {
   1764                 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
   1765                     updateLruProcessInternalLocked(cpr.proc, oomAdj,
   1766                             updateActivityTime, i+1);
   1767                 }
   1768             }
   1769         }
   1770 
   1771         //Slog.i(TAG, "Putting proc to front: " + app.processName);
   1772         if (oomAdj) {
   1773             updateOomAdjLocked();
   1774         }
   1775     }
   1776 
   1777     final void updateLruProcessLocked(ProcessRecord app,
   1778             boolean oomAdj, boolean updateActivityTime) {
   1779         mLruSeq++;
   1780         updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
   1781     }
   1782 
   1783     final ProcessRecord getProcessRecordLocked(
   1784             String processName, int uid) {
   1785         if (uid == Process.SYSTEM_UID) {
   1786             // The system gets to run in any process.  If there are multiple
   1787             // processes with the same uid, just pick the first (this
   1788             // should never happen).
   1789             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
   1790                     processName);
   1791             return procs != null ? procs.valueAt(0) : null;
   1792         }
   1793         ProcessRecord proc = mProcessNames.get(processName, uid);
   1794         return proc;
   1795     }
   1796 
   1797     void ensurePackageDexOpt(String packageName) {
   1798         IPackageManager pm = AppGlobals.getPackageManager();
   1799         try {
   1800             if (pm.performDexOpt(packageName)) {
   1801                 mDidDexOpt = true;
   1802             }
   1803         } catch (RemoteException e) {
   1804         }
   1805     }
   1806 
   1807     boolean isNextTransitionForward() {
   1808         int transit = mWindowManager.getPendingAppTransition();
   1809         return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
   1810                 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
   1811                 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
   1812     }
   1813 
   1814     final ProcessRecord startProcessLocked(String processName,
   1815             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
   1816             String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
   1817         ProcessRecord app = getProcessRecordLocked(processName, info.uid);
   1818         // We don't have to do anything more if:
   1819         // (1) There is an existing application record; and
   1820         // (2) The caller doesn't think it is dead, OR there is no thread
   1821         //     object attached to it so we know it couldn't have crashed; and
   1822         // (3) There is a pid assigned to it, so it is either starting or
   1823         //     already running.
   1824         if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
   1825                 + " app=" + app + " knownToBeDead=" + knownToBeDead
   1826                 + " thread=" + (app != null ? app.thread : null)
   1827                 + " pid=" + (app != null ? app.pid : -1));
   1828         if (app != null && app.pid > 0) {
   1829             if (!knownToBeDead || app.thread == null) {
   1830                 // We already have the app running, or are waiting for it to
   1831                 // come up (we have a pid but not yet its thread), so keep it.
   1832                 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
   1833                 // If this is a new package in the process, add the package to the list
   1834                 app.addPackage(info.packageName);
   1835                 return app;
   1836             } else {
   1837                 // An application record is attached to a previous process,
   1838                 // clean it up now.
   1839                 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
   1840                 handleAppDiedLocked(app, true, true);
   1841             }
   1842         }
   1843 
   1844         String hostingNameStr = hostingName != null
   1845                 ? hostingName.flattenToShortString() : null;
   1846 
   1847         if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
   1848             // If we are in the background, then check to see if this process
   1849             // is bad.  If so, we will just silently fail.
   1850             if (mBadProcesses.get(info.processName, info.uid) != null) {
   1851                 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
   1852                         + "/" + info.processName);
   1853                 return null;
   1854             }
   1855         } else {
   1856             // When the user is explicitly starting a process, then clear its
   1857             // crash count so that we won't make it bad until they see at
   1858             // least one crash dialog again, and make the process good again
   1859             // if it had been bad.
   1860             if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
   1861                     + "/" + info.processName);
   1862             mProcessCrashTimes.remove(info.processName, info.uid);
   1863             if (mBadProcesses.get(info.processName, info.uid) != null) {
   1864                 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
   1865                         info.processName);
   1866                 mBadProcesses.remove(info.processName, info.uid);
   1867                 if (app != null) {
   1868                     app.bad = false;
   1869                 }
   1870             }
   1871         }
   1872 
   1873         if (app == null) {
   1874             app = newProcessRecordLocked(null, info, processName);
   1875             mProcessNames.put(processName, info.uid, app);
   1876         } else {
   1877             // If this is a new package in the process, add the package to the list
   1878             app.addPackage(info.packageName);
   1879         }
   1880 
   1881         // If the system is not ready yet, then hold off on starting this
   1882         // process until it is.
   1883         if (!mProcessesReady
   1884                 && !isAllowedWhileBooting(info)
   1885                 && !allowWhileBooting) {
   1886             if (!mProcessesOnHold.contains(app)) {
   1887                 mProcessesOnHold.add(app);
   1888             }
   1889             if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
   1890             return app;
   1891         }
   1892 
   1893         startProcessLocked(app, hostingType, hostingNameStr);
   1894         return (app.pid != 0) ? app : null;
   1895     }
   1896 
   1897     boolean isAllowedWhileBooting(ApplicationInfo ai) {
   1898         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
   1899     }
   1900 
   1901     private final void startProcessLocked(ProcessRecord app,
   1902             String hostingType, String hostingNameStr) {
   1903         if (app.pid > 0 && app.pid != MY_PID) {
   1904             synchronized (mPidsSelfLocked) {
   1905                 mPidsSelfLocked.remove(app.pid);
   1906                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   1907             }
   1908             app.pid = 0;
   1909         }
   1910 
   1911         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   1912                 "startProcessLocked removing on hold: " + app);
   1913         mProcessesOnHold.remove(app);
   1914 
   1915         updateCpuStats();
   1916 
   1917         System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
   1918         mProcDeaths[0] = 0;
   1919 
   1920         try {
   1921             int uid = app.info.uid;
   1922             int[] gids = null;
   1923             try {
   1924                 gids = mContext.getPackageManager().getPackageGids(
   1925                         app.info.packageName);
   1926             } catch (PackageManager.NameNotFoundException e) {
   1927                 Slog.w(TAG, "Unable to retrieve gids", e);
   1928             }
   1929             if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
   1930                 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
   1931                         && mTopComponent != null
   1932                         && app.processName.equals(mTopComponent.getPackageName())) {
   1933                     uid = 0;
   1934                 }
   1935                 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
   1936                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
   1937                     uid = 0;
   1938                 }
   1939             }
   1940             int debugFlags = 0;
   1941             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   1942                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
   1943                 // Also turn on CheckJNI for debuggable apps. It's quite
   1944                 // awkward to turn on otherwise.
   1945                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   1946             }
   1947             // Run the app in safe mode if its manifest requests so or the
   1948             // system is booted in safe mode.
   1949             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
   1950                 Zygote.systemInSafeMode == true) {
   1951                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
   1952             }
   1953             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
   1954                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   1955             }
   1956             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
   1957                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
   1958             }
   1959             if ("1".equals(SystemProperties.get("debug.assert"))) {
   1960                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
   1961             }
   1962 
   1963             // Start the process.  It will either succeed and return a result containing
   1964             // the PID of the new process, or else throw a RuntimeException.
   1965             Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
   1966                     app.processName, uid, uid, gids, debugFlags,
   1967                     app.info.targetSdkVersion, null);
   1968 
   1969             BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
   1970             synchronized (bs) {
   1971                 if (bs.isOnBattery()) {
   1972                     app.batteryStats.incStartsLocked();
   1973                 }
   1974             }
   1975 
   1976             EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
   1977                     app.processName, hostingType,
   1978                     hostingNameStr != null ? hostingNameStr : "");
   1979 
   1980             if (app.persistent) {
   1981                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
   1982             }
   1983 
   1984             StringBuilder buf = mStringBuilder;
   1985             buf.setLength(0);
   1986             buf.append("Start proc ");
   1987             buf.append(app.processName);
   1988             buf.append(" for ");
   1989             buf.append(hostingType);
   1990             if (hostingNameStr != null) {
   1991                 buf.append(" ");
   1992                 buf.append(hostingNameStr);
   1993             }
   1994             buf.append(": pid=");
   1995             buf.append(startResult.pid);
   1996             buf.append(" uid=");
   1997             buf.append(uid);
   1998             buf.append(" gids={");
   1999             if (gids != null) {
   2000                 for (int gi=0; gi<gids.length; gi++) {
   2001                     if (gi != 0) buf.append(", ");
   2002                     buf.append(gids[gi]);
   2003 
   2004                 }
   2005             }
   2006             buf.append("}");
   2007             Slog.i(TAG, buf.toString());
   2008             app.pid = startResult.pid;
   2009             app.usingWrapper = startResult.usingWrapper;
   2010             app.removed = false;
   2011             synchronized (mPidsSelfLocked) {
   2012                 this.mPidsSelfLocked.put(startResult.pid, app);
   2013                 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   2014                 msg.obj = app;
   2015                 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
   2016                         ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
   2017             }
   2018         } catch (RuntimeException e) {
   2019             // XXX do better error recovery.
   2020             app.pid = 0;
   2021             Slog.e(TAG, "Failure starting process " + app.processName, e);
   2022         }
   2023     }
   2024 
   2025     void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
   2026         if (resumed) {
   2027             mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
   2028         } else {
   2029             mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
   2030         }
   2031     }
   2032 
   2033     boolean startHomeActivityLocked() {
   2034         if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
   2035                 && mTopAction == null) {
   2036             // We are running in factory test mode, but unable to find
   2037             // the factory test app, so just sit around displaying the
   2038             // error message and don't try to start anything.
   2039             return false;
   2040         }
   2041         Intent intent = new Intent(
   2042             mTopAction,
   2043             mTopData != null ? Uri.parse(mTopData) : null);
   2044         intent.setComponent(mTopComponent);
   2045         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   2046             intent.addCategory(Intent.CATEGORY_HOME);
   2047         }
   2048         ActivityInfo aInfo =
   2049             intent.resolveActivityInfo(mContext.getPackageManager(),
   2050                     STOCK_PM_FLAGS);
   2051         if (aInfo != null) {
   2052             intent.setComponent(new ComponentName(
   2053                     aInfo.applicationInfo.packageName, aInfo.name));
   2054             // Don't do this if the home app is currently being
   2055             // instrumented.
   2056             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
   2057                     aInfo.applicationInfo.uid);
   2058             if (app == null || app.instrumentationClass == null) {
   2059                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
   2060                 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
   2061                         null, null, 0, 0, 0, false, false, null);
   2062             }
   2063         }
   2064 
   2065 
   2066         return true;
   2067     }
   2068 
   2069     /**
   2070      * Starts the "new version setup screen" if appropriate.
   2071      */
   2072     void startSetupActivityLocked() {
   2073         // Only do this once per boot.
   2074         if (mCheckedForSetup) {
   2075             return;
   2076         }
   2077 
   2078         // We will show this screen if the current one is a different
   2079         // version than the last one shown, and we are not running in
   2080         // low-level factory test mode.
   2081         final ContentResolver resolver = mContext.getContentResolver();
   2082         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
   2083                 Settings.Secure.getInt(resolver,
   2084                         Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
   2085             mCheckedForSetup = true;
   2086 
   2087             // See if we should be showing the platform update setup UI.
   2088             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
   2089             List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
   2090                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
   2091 
   2092             // We don't allow third party apps to replace this.
   2093             ResolveInfo ri = null;
   2094             for (int i=0; ris != null && i<ris.size(); i++) {
   2095                 if ((ris.get(i).activityInfo.applicationInfo.flags
   2096                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
   2097                     ri = ris.get(i);
   2098                     break;
   2099                 }
   2100             }
   2101 
   2102             if (ri != null) {
   2103                 String vers = ri.activityInfo.metaData != null
   2104                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
   2105                         : null;
   2106                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
   2107                     vers = ri.activityInfo.applicationInfo.metaData.getString(
   2108                             Intent.METADATA_SETUP_VERSION);
   2109                 }
   2110                 String lastVers = Settings.Secure.getString(
   2111                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
   2112                 if (vers != null && !vers.equals(lastVers)) {
   2113                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   2114                     intent.setComponent(new ComponentName(
   2115                             ri.activityInfo.packageName, ri.activityInfo.name));
   2116                     mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
   2117                             null, null, 0, 0, 0, false, false, null);
   2118                 }
   2119             }
   2120         }
   2121     }
   2122 
   2123     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
   2124         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
   2125     }
   2126 
   2127     public int getFrontActivityScreenCompatMode() {
   2128         synchronized (this) {
   2129             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
   2130         }
   2131     }
   2132 
   2133     public void setFrontActivityScreenCompatMode(int mode) {
   2134         synchronized (this) {
   2135             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
   2136         }
   2137     }
   2138 
   2139     public int getPackageScreenCompatMode(String packageName) {
   2140         synchronized (this) {
   2141             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
   2142         }
   2143     }
   2144 
   2145     public void setPackageScreenCompatMode(String packageName, int mode) {
   2146         synchronized (this) {
   2147             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
   2148         }
   2149     }
   2150 
   2151     public boolean getPackageAskScreenCompat(String packageName) {
   2152         synchronized (this) {
   2153             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
   2154         }
   2155     }
   2156 
   2157     public void setPackageAskScreenCompat(String packageName, boolean ask) {
   2158         synchronized (this) {
   2159             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
   2160         }
   2161     }
   2162 
   2163     void reportResumedActivityLocked(ActivityRecord r) {
   2164         //Slog.i(TAG, "**** REPORT RESUME: " + r);
   2165 
   2166         final int identHash = System.identityHashCode(r);
   2167         updateUsageStats(r, true);
   2168 
   2169         int i = mWatchers.beginBroadcast();
   2170         while (i > 0) {
   2171             i--;
   2172             IActivityWatcher w = mWatchers.getBroadcastItem(i);
   2173             if (w != null) {
   2174                 try {
   2175                     w.activityResuming(identHash);
   2176                 } catch (RemoteException e) {
   2177                 }
   2178             }
   2179         }
   2180         mWatchers.finishBroadcast();
   2181     }
   2182 
   2183     private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
   2184         int i = mProcessObservers.beginBroadcast();
   2185         while (i > 0) {
   2186             i--;
   2187             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   2188             if (observer != null) {
   2189                 try {
   2190                     observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
   2191                 } catch (RemoteException e) {
   2192                 }
   2193             }
   2194         }
   2195         mProcessObservers.finishBroadcast();
   2196     }
   2197 
   2198     private void dispatchProcessDied(int pid, int uid) {
   2199         int i = mProcessObservers.beginBroadcast();
   2200         while (i > 0) {
   2201             i--;
   2202             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   2203             if (observer != null) {
   2204                 try {
   2205                     observer.onProcessDied(pid, uid);
   2206                 } catch (RemoteException e) {
   2207                 }
   2208             }
   2209         }
   2210         mProcessObservers.finishBroadcast();
   2211     }
   2212 
   2213     final void doPendingActivityLaunchesLocked(boolean doResume) {
   2214         final int N = mPendingActivityLaunches.size();
   2215         if (N <= 0) {
   2216             return;
   2217         }
   2218         for (int i=0; i<N; i++) {
   2219             PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
   2220             mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
   2221                     pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
   2222                     doResume && i == (N-1));
   2223         }
   2224         mPendingActivityLaunches.clear();
   2225     }
   2226 
   2227     public final int startActivity(IApplicationThread caller,
   2228             Intent intent, String resolvedType, Uri[] grantedUriPermissions,
   2229             int grantedMode, IBinder resultTo,
   2230             String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
   2231             String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
   2232         return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
   2233                 grantedUriPermissions, grantedMode, resultTo, resultWho,
   2234                 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
   2235                 null, null);
   2236     }
   2237 
   2238     public final WaitResult startActivityAndWait(IApplicationThread caller,
   2239             Intent intent, String resolvedType, Uri[] grantedUriPermissions,
   2240             int grantedMode, IBinder resultTo,
   2241             String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
   2242             String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
   2243         WaitResult res = new WaitResult();
   2244         mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
   2245                 grantedUriPermissions, grantedMode, resultTo, resultWho,
   2246                 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
   2247                 res, null);
   2248         return res;
   2249     }
   2250 
   2251     public final int startActivityWithConfig(IApplicationThread caller,
   2252             Intent intent, String resolvedType, Uri[] grantedUriPermissions,
   2253             int grantedMode, IBinder resultTo,
   2254             String resultWho, int requestCode, boolean onlyIfNeeded,
   2255             boolean debug, Configuration config) {
   2256         return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
   2257                 grantedUriPermissions, grantedMode, resultTo, resultWho,
   2258                 requestCode, onlyIfNeeded, debug, null, null, false, null, config);
   2259     }
   2260 
   2261     public int startActivityIntentSender(IApplicationThread caller,
   2262             IntentSender intent, Intent fillInIntent, String resolvedType,
   2263             IBinder resultTo, String resultWho, int requestCode,
   2264             int flagsMask, int flagsValues) {
   2265         // Refuse possible leaked file descriptors
   2266         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
   2267             throw new IllegalArgumentException("File descriptors passed in Intent");
   2268         }
   2269 
   2270         IIntentSender sender = intent.getTarget();
   2271         if (!(sender instanceof PendingIntentRecord)) {
   2272             throw new IllegalArgumentException("Bad PendingIntent object");
   2273         }
   2274 
   2275         PendingIntentRecord pir = (PendingIntentRecord)sender;
   2276 
   2277         synchronized (this) {
   2278             // If this is coming from the currently resumed activity, it is
   2279             // effectively saying that app switches are allowed at this point.
   2280             if (mMainStack.mResumedActivity != null
   2281                     && mMainStack.mResumedActivity.info.applicationInfo.uid ==
   2282                             Binder.getCallingUid()) {
   2283                 mAppSwitchesAllowedTime = 0;
   2284             }
   2285         }
   2286 
   2287         return pir.sendInner(0, fillInIntent, resolvedType, null,
   2288                 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
   2289     }
   2290 
   2291     public boolean startNextMatchingActivity(IBinder callingActivity,
   2292             Intent intent) {
   2293         // Refuse possible leaked file descriptors
   2294         if (intent != null && intent.hasFileDescriptors() == true) {
   2295             throw new IllegalArgumentException("File descriptors passed in Intent");
   2296         }
   2297 
   2298         synchronized (this) {
   2299             ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
   2300             if (r == null) {
   2301                 return false;
   2302             }
   2303             if (r.app == null || r.app.thread == null) {
   2304                 // The caller is not running...  d'oh!
   2305                 return false;
   2306             }
   2307             intent = new Intent(intent);
   2308             // The caller is not allowed to change the data.
   2309             intent.setDataAndType(r.intent.getData(), r.intent.getType());
   2310             // And we are resetting to find the next component...
   2311             intent.setComponent(null);
   2312 
   2313             ActivityInfo aInfo = null;
   2314             try {
   2315                 List<ResolveInfo> resolves =
   2316                     AppGlobals.getPackageManager().queryIntentActivities(
   2317                             intent, r.resolvedType,
   2318                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
   2319 
   2320                 // Look for the original activity in the list...
   2321                 final int N = resolves != null ? resolves.size() : 0;
   2322                 for (int i=0; i<N; i++) {
   2323                     ResolveInfo rInfo = resolves.get(i);
   2324                     if (rInfo.activityInfo.packageName.equals(r.packageName)
   2325                             && rInfo.activityInfo.name.equals(r.info.name)) {
   2326                         // We found the current one...  the next matching is
   2327                         // after it.
   2328                         i++;
   2329                         if (i<N) {
   2330                             aInfo = resolves.get(i).activityInfo;
   2331                         }
   2332                         break;
   2333                     }
   2334                 }
   2335             } catch (RemoteException e) {
   2336             }
   2337 
   2338             if (aInfo == null) {
   2339                 // Nobody who is next!
   2340                 return false;
   2341             }
   2342 
   2343             intent.setComponent(new ComponentName(
   2344                     aInfo.applicationInfo.packageName, aInfo.name));
   2345             intent.setFlags(intent.getFlags()&~(
   2346                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
   2347                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
   2348                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
   2349                     Intent.FLAG_ACTIVITY_NEW_TASK));
   2350 
   2351             // Okay now we need to start the new activity, replacing the
   2352             // currently running activity.  This is a little tricky because
   2353             // we want to start the new one as if the current one is finished,
   2354             // but not finish the current one first so that there is no flicker.
   2355             // And thus...
   2356             final boolean wasFinishing = r.finishing;
   2357             r.finishing = true;
   2358 
   2359             // Propagate reply information over to the new activity.
   2360             final ActivityRecord resultTo = r.resultTo;
   2361             final String resultWho = r.resultWho;
   2362             final int requestCode = r.requestCode;
   2363             r.resultTo = null;
   2364             if (resultTo != null) {
   2365                 resultTo.removeResultsLocked(r, resultWho, requestCode);
   2366             }
   2367 
   2368             final long origId = Binder.clearCallingIdentity();
   2369             // XXX we are not dealing with propagating grantedUriPermissions...
   2370             // those are not yet exposed to user code, so there is no need.
   2371             int res = mMainStack.startActivityLocked(r.app.thread, intent,
   2372                     r.resolvedType, null, 0, aInfo,
   2373                     resultTo != null ? resultTo.appToken : null, resultWho,
   2374                     requestCode, -1, r.launchedFromUid, false, false, null);
   2375             Binder.restoreCallingIdentity(origId);
   2376 
   2377             r.finishing = wasFinishing;
   2378             if (res != START_SUCCESS) {
   2379                 return false;
   2380             }
   2381             return true;
   2382         }
   2383     }
   2384 
   2385     public final int startActivityInPackage(int uid,
   2386             Intent intent, String resolvedType, IBinder resultTo,
   2387             String resultWho, int requestCode, boolean onlyIfNeeded) {
   2388 
   2389         // This is so super not safe, that only the system (or okay root)
   2390         // can do it.
   2391         final int callingUid = Binder.getCallingUid();
   2392         if (callingUid != 0 && callingUid != Process.myUid()) {
   2393             throw new SecurityException(
   2394                     "startActivityInPackage only available to the system");
   2395         }
   2396 
   2397         return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
   2398                 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
   2399                 null, null, false, null, null);
   2400     }
   2401 
   2402     public final int startActivities(IApplicationThread caller,
   2403             Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
   2404         return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
   2405     }
   2406 
   2407     public final int startActivitiesInPackage(int uid,
   2408             Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
   2409 
   2410         // This is so super not safe, that only the system (or okay root)
   2411         // can do it.
   2412         final int callingUid = Binder.getCallingUid();
   2413         if (callingUid != 0 && callingUid != Process.myUid()) {
   2414             throw new SecurityException(
   2415                     "startActivityInPackage only available to the system");
   2416         }
   2417 
   2418         return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
   2419     }
   2420 
   2421     final void addRecentTaskLocked(TaskRecord task) {
   2422         int N = mRecentTasks.size();
   2423         // Quick case: check if the top-most recent task is the same.
   2424         if (N > 0 && mRecentTasks.get(0) == task) {
   2425             return;
   2426         }
   2427         // Remove any existing entries that are the same kind of task.
   2428         for (int i=0; i<N; i++) {
   2429             TaskRecord tr = mRecentTasks.get(i);
   2430             if ((task.affinity != null && task.affinity.equals(tr.affinity))
   2431                     || (task.intent != null && task.intent.filterEquals(tr.intent))) {
   2432                 mRecentTasks.remove(i);
   2433                 i--;
   2434                 N--;
   2435                 if (task.intent == null) {
   2436                     // If the new recent task we are adding is not fully
   2437                     // specified, then replace it with the existing recent task.
   2438                     task = tr;
   2439                 }
   2440             }
   2441         }
   2442         if (N >= MAX_RECENT_TASKS) {
   2443             mRecentTasks.remove(N-1);
   2444         }
   2445         mRecentTasks.add(0, task);
   2446     }
   2447 
   2448     public void setRequestedOrientation(IBinder token,
   2449             int requestedOrientation) {
   2450         synchronized (this) {
   2451             ActivityRecord r = mMainStack.isInStackLocked(token);
   2452             if (r == null) {
   2453                 return;
   2454             }
   2455             final long origId = Binder.clearCallingIdentity();
   2456             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
   2457             Configuration config = mWindowManager.updateOrientationFromAppTokens(
   2458                     mConfiguration,
   2459                     r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
   2460             if (config != null) {
   2461                 r.frozenBeforeDestroy = true;
   2462                 if (!updateConfigurationLocked(config, r, false, false)) {
   2463                     mMainStack.resumeTopActivityLocked(null);
   2464                 }
   2465             }
   2466             Binder.restoreCallingIdentity(origId);
   2467         }
   2468     }
   2469 
   2470     public int getRequestedOrientation(IBinder token) {
   2471         synchronized (this) {
   2472             ActivityRecord r = mMainStack.isInStackLocked(token);
   2473             if (r == null) {
   2474                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
   2475             }
   2476             return mWindowManager.getAppOrientation(r.appToken);
   2477         }
   2478     }
   2479 
   2480     /**
   2481      * This is the internal entry point for handling Activity.finish().
   2482      *
   2483      * @param token The Binder token referencing the Activity we want to finish.
   2484      * @param resultCode Result code, if any, from this Activity.
   2485      * @param resultData Result data (Intent), if any, from this Activity.
   2486      *
   2487      * @return Returns true if the activity successfully finished, or false if it is still running.
   2488      */
   2489     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
   2490         // Refuse possible leaked file descriptors
   2491         if (resultData != null && resultData.hasFileDescriptors() == true) {
   2492             throw new IllegalArgumentException("File descriptors passed in Intent");
   2493         }
   2494 
   2495         synchronized(this) {
   2496             if (mController != null) {
   2497                 // Find the first activity that is not finishing.
   2498                 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
   2499                 if (next != null) {
   2500                     // ask watcher if this is allowed
   2501                     boolean resumeOK = true;
   2502                     try {
   2503                         resumeOK = mController.activityResuming(next.packageName);
   2504                     } catch (RemoteException e) {
   2505                         mController = null;
   2506                     }
   2507 
   2508                     if (!resumeOK) {
   2509                         return false;
   2510                     }
   2511                 }
   2512             }
   2513             final long origId = Binder.clearCallingIdentity();
   2514             boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
   2515                     resultData, "app-request");
   2516             Binder.restoreCallingIdentity(origId);
   2517             return res;
   2518         }
   2519     }
   2520 
   2521     public final void finishHeavyWeightApp() {
   2522         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   2523                 != PackageManager.PERMISSION_GRANTED) {
   2524             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
   2525                     + Binder.getCallingPid()
   2526                     + ", uid=" + Binder.getCallingUid()
   2527                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   2528             Slog.w(TAG, msg);
   2529             throw new SecurityException(msg);
   2530         }
   2531 
   2532         synchronized(this) {
   2533             if (mHeavyWeightProcess == null) {
   2534                 return;
   2535             }
   2536 
   2537             ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
   2538                     mHeavyWeightProcess.activities);
   2539             for (int i=0; i<activities.size(); i++) {
   2540                 ActivityRecord r = activities.get(i);
   2541                 if (!r.finishing) {
   2542                     int index = mMainStack.indexOfTokenLocked(r.appToken);
   2543                     if (index >= 0) {
   2544                         mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
   2545                                 null, "finish-heavy");
   2546                     }
   2547                 }
   2548             }
   2549 
   2550             mHeavyWeightProcess = null;
   2551             mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
   2552         }
   2553     }
   2554 
   2555     public void crashApplication(int uid, int initialPid, String packageName,
   2556             String message) {
   2557         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   2558                 != PackageManager.PERMISSION_GRANTED) {
   2559             String msg = "Permission Denial: crashApplication() from pid="
   2560                     + Binder.getCallingPid()
   2561                     + ", uid=" + Binder.getCallingUid()
   2562                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   2563             Slog.w(TAG, msg);
   2564             throw new SecurityException(msg);
   2565         }
   2566 
   2567         synchronized(this) {
   2568             ProcessRecord proc = null;
   2569 
   2570             // Figure out which process to kill.  We don't trust that initialPid
   2571             // still has any relation to current pids, so must scan through the
   2572             // list.
   2573             synchronized (mPidsSelfLocked) {
   2574                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   2575                     ProcessRecord p = mPidsSelfLocked.valueAt(i);
   2576                     if (p.info.uid != uid) {
   2577                         continue;
   2578                     }
   2579                     if (p.pid == initialPid) {
   2580                         proc = p;
   2581                         break;
   2582                     }
   2583                     for (String str : p.pkgList) {
   2584                         if (str.equals(packageName)) {
   2585                             proc = p;
   2586                         }
   2587                     }
   2588                 }
   2589             }
   2590 
   2591             if (proc == null) {
   2592                 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
   2593                         + " initialPid=" + initialPid
   2594                         + " packageName=" + packageName);
   2595                 return;
   2596             }
   2597 
   2598             if (proc.thread != null) {
   2599                 if (proc.pid == Process.myPid()) {
   2600                     Log.w(TAG, "crashApplication: trying to crash self!");
   2601                     return;
   2602                 }
   2603                 long ident = Binder.clearCallingIdentity();
   2604                 try {
   2605                     proc.thread.scheduleCrash(message);
   2606                 } catch (RemoteException e) {
   2607                 }
   2608                 Binder.restoreCallingIdentity(ident);
   2609             }
   2610         }
   2611     }
   2612 
   2613     public final void finishSubActivity(IBinder token, String resultWho,
   2614             int requestCode) {
   2615         synchronized(this) {
   2616             ActivityRecord self = mMainStack.isInStackLocked(token);
   2617             if (self == null) {
   2618                 return;
   2619             }
   2620 
   2621             final long origId = Binder.clearCallingIdentity();
   2622 
   2623             int i;
   2624             for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
   2625                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   2626                 if (r.resultTo == self && r.requestCode == requestCode) {
   2627                     if ((r.resultWho == null && resultWho == null) ||
   2628                         (r.resultWho != null && r.resultWho.equals(resultWho))) {
   2629                         mMainStack.finishActivityLocked(r, i,
   2630                                 Activity.RESULT_CANCELED, null, "request-sub");
   2631                     }
   2632                 }
   2633             }
   2634 
   2635             Binder.restoreCallingIdentity(origId);
   2636         }
   2637     }
   2638 
   2639     public boolean willActivityBeVisible(IBinder token) {
   2640         synchronized(this) {
   2641             int i;
   2642             for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
   2643                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   2644                 if (r.appToken == token) {
   2645                     return true;
   2646                 }
   2647                 if (r.fullscreen && !r.finishing) {
   2648                     return false;
   2649                 }
   2650             }
   2651             return true;
   2652         }
   2653     }
   2654 
   2655     public void overridePendingTransition(IBinder token, String packageName,
   2656             int enterAnim, int exitAnim) {
   2657         synchronized(this) {
   2658             ActivityRecord self = mMainStack.isInStackLocked(token);
   2659             if (self == null) {
   2660                 return;
   2661             }
   2662 
   2663             final long origId = Binder.clearCallingIdentity();
   2664 
   2665             if (self.state == ActivityState.RESUMED
   2666                     || self.state == ActivityState.PAUSING) {
   2667                 mWindowManager.overridePendingAppTransition(packageName,
   2668                         enterAnim, exitAnim);
   2669             }
   2670 
   2671             Binder.restoreCallingIdentity(origId);
   2672         }
   2673     }
   2674 
   2675     /**
   2676      * Main function for removing an existing process from the activity manager
   2677      * as a result of that process going away.  Clears out all connections
   2678      * to the process.
   2679      */
   2680     private final void handleAppDiedLocked(ProcessRecord app,
   2681             boolean restarting, boolean allowRestart) {
   2682         cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
   2683         if (!restarting) {
   2684             mLruProcesses.remove(app);
   2685         }
   2686 
   2687         if (mProfileProc == app) {
   2688             clearProfilerLocked();
   2689         }
   2690 
   2691         // Just in case...
   2692         if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
   2693             if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
   2694             mMainStack.mPausingActivity = null;
   2695         }
   2696         if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
   2697             mMainStack.mLastPausedActivity = null;
   2698         }
   2699 
   2700         // Remove this application's activities from active lists.
   2701         mMainStack.removeHistoryRecordsForAppLocked(app);
   2702 
   2703         boolean atTop = true;
   2704         boolean hasVisibleActivities = false;
   2705 
   2706         // Clean out the history list.
   2707         int i = mMainStack.mHistory.size();
   2708         if (localLOGV) Slog.v(
   2709             TAG, "Removing app " + app + " from history with " + i + " entries");
   2710         while (i > 0) {
   2711             i--;
   2712             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   2713             if (localLOGV) Slog.v(
   2714                 TAG, "Record #" + i + " " + r + ": app=" + r.app);
   2715             if (r.app == app) {
   2716                 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
   2717                     if (ActivityStack.DEBUG_ADD_REMOVE) {
   2718                         RuntimeException here = new RuntimeException("here");
   2719                         here.fillInStackTrace();
   2720                         Slog.i(TAG, "Removing activity " + r + " from stack at " + i
   2721                                 + ": haveState=" + r.haveState
   2722                                 + " stateNotNeeded=" + r.stateNotNeeded
   2723                                 + " finishing=" + r.finishing
   2724                                 + " state=" + r.state, here);
   2725                     }
   2726                     if (!r.finishing) {
   2727                         Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
   2728                         EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
   2729                                 System.identityHashCode(r),
   2730                                 r.task.taskId, r.shortComponentName,
   2731                                 "proc died without state saved");
   2732                     }
   2733                     r.makeFinishing();
   2734                     mMainStack.mHistory.remove(i);
   2735                     r.takeFromHistory();
   2736                     mWindowManager.removeAppToken(r.appToken);
   2737                     if (VALIDATE_TOKENS) {
   2738                         mMainStack.validateAppTokensLocked();
   2739                     }
   2740                     r.removeUriPermissionsLocked();
   2741 
   2742                 } else {
   2743                     // We have the current state for this activity, so
   2744                     // it can be restarted later when needed.
   2745                     if (localLOGV) Slog.v(
   2746                         TAG, "Keeping entry, setting app to null");
   2747                     if (r.visible) {
   2748                         hasVisibleActivities = true;
   2749                     }
   2750                     r.app = null;
   2751                     r.nowVisible = false;
   2752                     if (!r.haveState) {
   2753                         if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
   2754                                 "App died, clearing saved state of " + r);
   2755                         r.icicle = null;
   2756                     }
   2757                 }
   2758 
   2759                 r.stack.cleanUpActivityLocked(r, true, true);
   2760             }
   2761             atTop = false;
   2762         }
   2763 
   2764         app.activities.clear();
   2765 
   2766         if (app.instrumentationClass != null) {
   2767             Slog.w(TAG, "Crash of app " + app.processName
   2768                   + " running instrumentation " + app.instrumentationClass);
   2769             Bundle info = new Bundle();
   2770             info.putString("shortMsg", "Process crashed.");
   2771             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
   2772         }
   2773 
   2774         if (!restarting) {
   2775             if (!mMainStack.resumeTopActivityLocked(null)) {
   2776                 // If there was nothing to resume, and we are not already
   2777                 // restarting this process, but there is a visible activity that
   2778                 // is hosted by the process...  then make sure all visible
   2779                 // activities are running, taking care of restarting this
   2780                 // process.
   2781                 if (hasVisibleActivities) {
   2782                     mMainStack.ensureActivitiesVisibleLocked(null, 0);
   2783                 }
   2784             }
   2785         }
   2786     }
   2787 
   2788     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
   2789         IBinder threadBinder = thread.asBinder();
   2790 
   2791         // Find the application record.
   2792         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   2793             ProcessRecord rec = mLruProcesses.get(i);
   2794             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
   2795                 return i;
   2796             }
   2797         }
   2798         return -1;
   2799     }
   2800 
   2801     final ProcessRecord getRecordForAppLocked(
   2802             IApplicationThread thread) {
   2803         if (thread == null) {
   2804             return null;
   2805         }
   2806 
   2807         int appIndex = getLRURecordIndexForAppLocked(thread);
   2808         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
   2809     }
   2810 
   2811     final void appDiedLocked(ProcessRecord app, int pid,
   2812             IApplicationThread thread) {
   2813 
   2814         mProcDeaths[0]++;
   2815 
   2816         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   2817         synchronized (stats) {
   2818             stats.noteProcessDiedLocked(app.info.uid, pid);
   2819         }
   2820 
   2821         // Clean up already done if the process has been re-started.
   2822         if (app.pid == pid && app.thread != null &&
   2823                 app.thread.asBinder() == thread.asBinder()) {
   2824             if (!app.killedBackground) {
   2825                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   2826                         + ") has died.");
   2827             }
   2828             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
   2829             if (localLOGV) Slog.v(
   2830                 TAG, "Dying app: " + app + ", pid: " + pid
   2831                 + ", thread: " + thread.asBinder());
   2832             boolean doLowMem = app.instrumentationClass == null;
   2833             handleAppDiedLocked(app, false, true);
   2834 
   2835             if (doLowMem) {
   2836                 // If there are no longer any background processes running,
   2837                 // and the app that died was not running instrumentation,
   2838                 // then tell everyone we are now low on memory.
   2839                 boolean haveBg = false;
   2840                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   2841                     ProcessRecord rec = mLruProcesses.get(i);
   2842                     if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   2843                         haveBg = true;
   2844                         break;
   2845                     }
   2846                 }
   2847 
   2848                 if (!haveBg) {
   2849                     EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
   2850                     long now = SystemClock.uptimeMillis();
   2851                     for (int i=mLruProcesses.size()-1; i>=0; i--) {
   2852                         ProcessRecord rec = mLruProcesses.get(i);
   2853                         if (rec != app && rec.thread != null &&
   2854                                 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
   2855                             // The low memory report is overriding any current
   2856                             // state for a GC request.  Make sure to do
   2857                             // heavy/important/visible/foreground processes first.
   2858                             if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   2859                                 rec.lastRequestedGc = 0;
   2860                             } else {
   2861                                 rec.lastRequestedGc = rec.lastLowMemory;
   2862                             }
   2863                             rec.reportLowMemory = true;
   2864                             rec.lastLowMemory = now;
   2865                             mProcessesToGc.remove(rec);
   2866                             addProcessToGcListLocked(rec);
   2867                         }
   2868                     }
   2869                     mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
   2870                     scheduleAppGcsLocked();
   2871                 }
   2872             }
   2873         } else if (app.pid != pid) {
   2874             // A new process has already been started.
   2875             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   2876                     + ") has died and restarted (pid " + app.pid + ").");
   2877             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
   2878         } else if (DEBUG_PROCESSES) {
   2879             Slog.d(TAG, "Received spurious death notification for thread "
   2880                     + thread.asBinder());
   2881         }
   2882     }
   2883 
   2884     /**
   2885      * If a stack trace dump file is configured, dump process stack traces.
   2886      * @param clearTraces causes the dump file to be erased prior to the new
   2887      *    traces being written, if true; when false, the new traces will be
   2888      *    appended to any existing file content.
   2889      * @param firstPids of dalvik VM processes to dump stack traces for first
   2890      * @param lastPids of dalvik VM processes to dump stack traces for last
   2891      * @return file containing stack traces, or null if no dump file is configured
   2892      */
   2893     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
   2894             ProcessStats processStats, SparseArray<Boolean> lastPids) {
   2895         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   2896         if (tracesPath == null || tracesPath.length() == 0) {
   2897             return null;
   2898         }
   2899 
   2900         File tracesFile = new File(tracesPath);
   2901         try {
   2902             File tracesDir = tracesFile.getParentFile();
   2903             if (!tracesDir.exists()) tracesFile.mkdirs();
   2904             FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
   2905 
   2906             if (clearTraces && tracesFile.exists()) tracesFile.delete();
   2907             tracesFile.createNewFile();
   2908             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   2909         } catch (IOException e) {
   2910             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
   2911             return null;
   2912         }
   2913 
   2914         // Use a FileObserver to detect when traces finish writing.
   2915         // The order of traces is considered important to maintain for legibility.
   2916         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
   2917             public synchronized void onEvent(int event, String path) { notify(); }
   2918         };
   2919 
   2920         try {
   2921             observer.startWatching();
   2922 
   2923             // First collect all of the stacks of the most important pids.
   2924             try {
   2925                 int num = firstPids.size();
   2926                 for (int i = 0; i < num; i++) {
   2927                     synchronized (observer) {
   2928                         Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
   2929                         observer.wait(200);  // Wait for write-close, give up after 200msec
   2930                     }
   2931                 }
   2932             } catch (InterruptedException e) {
   2933                 Log.wtf(TAG, e);
   2934             }
   2935 
   2936             // Next measure CPU usage.
   2937             if (processStats != null) {
   2938                 processStats.init();
   2939                 System.gc();
   2940                 processStats.update();
   2941                 try {
   2942                     synchronized (processStats) {
   2943                         processStats.wait(500); // measure over 1/2 second.
   2944                     }
   2945                 } catch (InterruptedException e) {
   2946                 }
   2947                 processStats.update();
   2948 
   2949                 // We'll take the stack crawls of just the top apps using CPU.
   2950                 final int N = processStats.countWorkingStats();
   2951                 int numProcs = 0;
   2952                 for (int i=0; i<N && numProcs<5; i++) {
   2953                     ProcessStats.Stats stats = processStats.getWorkingStats(i);
   2954                     if (lastPids.indexOfKey(stats.pid) >= 0) {
   2955                         numProcs++;
   2956                         try {
   2957                             synchronized (observer) {
   2958                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
   2959                                 observer.wait(200);  // Wait for write-close, give up after 200msec
   2960                             }
   2961                         } catch (InterruptedException e) {
   2962                             Log.wtf(TAG, e);
   2963                         }
   2964 
   2965                     }
   2966                 }
   2967             }
   2968 
   2969             return tracesFile;
   2970 
   2971         } finally {
   2972             observer.stopWatching();
   2973         }
   2974     }
   2975 
   2976     private final class AppNotResponding implements Runnable {
   2977         private final ProcessRecord mApp;
   2978         private final String mAnnotation;
   2979 
   2980         public AppNotResponding(ProcessRecord app, String annotation) {
   2981             mApp = app;
   2982             mAnnotation = annotation;
   2983         }
   2984 
   2985         @Override
   2986         public void run() {
   2987             appNotResponding(mApp, null, null, mAnnotation);
   2988         }
   2989     }
   2990 
   2991     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
   2992             ActivityRecord parent, final String annotation) {
   2993         ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
   2994         SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
   2995 
   2996         if (mController != null) {
   2997             try {
   2998                 // 0 == continue, -1 = kill process immediately
   2999                 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
   3000                 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
   3001             } catch (RemoteException e) {
   3002                 mController = null;
   3003             }
   3004         }
   3005 
   3006         long anrTime = SystemClock.uptimeMillis();
   3007         if (MONITOR_CPU_USAGE) {
   3008             updateCpuStatsNow();
   3009         }
   3010 
   3011         synchronized (this) {
   3012             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
   3013             if (mShuttingDown) {
   3014                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
   3015                 return;
   3016             } else if (app.notResponding) {
   3017                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
   3018                 return;
   3019             } else if (app.crashing) {
   3020                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
   3021                 return;
   3022             }
   3023 
   3024             // In case we come through here for the same app before completing
   3025             // this one, mark as anring now so we will bail out.
   3026             app.notResponding = true;
   3027 
   3028             // Log the ANR to the event log.
   3029             EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
   3030                     annotation);
   3031 
   3032             // Dump thread traces as quickly as we can, starting with "interesting" processes.
   3033             firstPids.add(app.pid);
   3034 
   3035             int parentPid = app.pid;
   3036             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
   3037             if (parentPid != app.pid) firstPids.add(parentPid);
   3038 
   3039             if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
   3040 
   3041             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   3042                 ProcessRecord r = mLruProcesses.get(i);
   3043                 if (r != null && r.thread != null) {
   3044                     int pid = r.pid;
   3045                     if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
   3046                         if (r.persistent) {
   3047                             firstPids.add(pid);
   3048                         } else {
   3049                             lastPids.put(pid, Boolean.TRUE);
   3050                         }
   3051                     }
   3052                 }
   3053             }
   3054         }
   3055 
   3056         // Log the ANR to the main log.
   3057         StringBuilder info = mStringBuilder;
   3058         info.setLength(0);
   3059         info.append("ANR in ").append(app.processName);
   3060         if (activity != null && activity.shortComponentName != null) {
   3061             info.append(" (").append(activity.shortComponentName).append(")");
   3062         }
   3063         info.append("\n");
   3064         if (annotation != null) {
   3065             info.append("Reason: ").append(annotation).append("\n");
   3066         }
   3067         if (parent != null && parent != activity) {
   3068             info.append("Parent: ").append(parent.shortComponentName).append("\n");
   3069         }
   3070 
   3071         final ProcessStats processStats = new ProcessStats(true);
   3072 
   3073         File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
   3074 
   3075         String cpuInfo = null;
   3076         if (MONITOR_CPU_USAGE) {
   3077             updateCpuStatsNow();
   3078             synchronized (mProcessStatsThread) {
   3079                 cpuInfo = mProcessStats.printCurrentState(anrTime);
   3080             }
   3081             info.append(processStats.printCurrentLoad());
   3082             info.append(cpuInfo);
   3083         }
   3084 
   3085         info.append(processStats.printCurrentState(anrTime));
   3086 
   3087         Slog.e(TAG, info.toString());
   3088         if (tracesFile == null) {
   3089             // There is no trace file, so dump (only) the alleged culprit's threads to the log
   3090             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
   3091         }
   3092 
   3093         addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
   3094                 cpuInfo, tracesFile, null);
   3095 
   3096         if (mController != null) {
   3097             try {
   3098                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
   3099                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
   3100                 if (res != 0) {
   3101                     if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
   3102                     return;
   3103                 }
   3104             } catch (RemoteException e) {
   3105                 mController = null;
   3106             }
   3107         }
   3108 
   3109         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
   3110         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
   3111                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
   3112 
   3113         synchronized (this) {
   3114             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
   3115                 Slog.w(TAG, "Killing " + app + ": background ANR");
   3116                 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   3117                         app.processName, app.setAdj, "background ANR");
   3118                 Process.killProcessQuiet(app.pid);
   3119                 return;
   3120             }
   3121 
   3122             // Set the app's notResponding state, and look up the errorReportReceiver
   3123             makeAppNotRespondingLocked(app,
   3124                     activity != null ? activity.shortComponentName : null,
   3125                     annotation != null ? "ANR " + annotation : "ANR",
   3126                     info.toString());
   3127 
   3128             // Bring up the infamous App Not Responding dialog
   3129             Message msg = Message.obtain();
   3130             HashMap map = new HashMap();
   3131             msg.what = SHOW_NOT_RESPONDING_MSG;
   3132             msg.obj = map;
   3133             map.put("app", app);
   3134             if (activity != null) {
   3135                 map.put("activity", activity);
   3136             }
   3137 
   3138             mHandler.sendMessage(msg);
   3139         }
   3140     }
   3141 
   3142     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
   3143         if (!mLaunchWarningShown) {
   3144             mLaunchWarningShown = true;
   3145             mHandler.post(new Runnable() {
   3146                 @Override
   3147                 public void run() {
   3148                     synchronized (ActivityManagerService.this) {
   3149                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
   3150                         d.show();
   3151                         mHandler.postDelayed(new Runnable() {
   3152                             @Override
   3153                             public void run() {
   3154                                 synchronized (ActivityManagerService.this) {
   3155                                     d.dismiss();
   3156                                     mLaunchWarningShown = false;
   3157                                 }
   3158                             }
   3159                         }, 4000);
   3160                     }
   3161                 }
   3162             });
   3163         }
   3164     }
   3165 
   3166     public boolean clearApplicationUserData(final String packageName,
   3167             final IPackageDataObserver observer) {
   3168         int uid = Binder.getCallingUid();
   3169         int pid = Binder.getCallingPid();
   3170         long callingId = Binder.clearCallingIdentity();
   3171         try {
   3172             IPackageManager pm = AppGlobals.getPackageManager();
   3173             int pkgUid = -1;
   3174             synchronized(this) {
   3175                 try {
   3176                     pkgUid = pm.getPackageUid(packageName);
   3177                 } catch (RemoteException e) {
   3178                 }
   3179                 if (pkgUid == -1) {
   3180                     Slog.w(TAG, "Invalid packageName:" + packageName);
   3181                     return false;
   3182                 }
   3183                 if (uid == pkgUid || checkComponentPermission(
   3184                         android.Manifest.permission.CLEAR_APP_USER_DATA,
   3185                         pid, uid, -1, true)
   3186                         == PackageManager.PERMISSION_GRANTED) {
   3187                     forceStopPackageLocked(packageName, pkgUid);
   3188                 } else {
   3189                     throw new SecurityException(pid+" does not have permission:"+
   3190                             android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
   3191                                     "for process:"+packageName);
   3192                 }
   3193             }
   3194 
   3195             try {
   3196                 //clear application user data
   3197                 pm.clearApplicationUserData(packageName, observer);
   3198                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
   3199                         Uri.fromParts("package", packageName, null));
   3200                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
   3201                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
   3202                         null, null, 0, null, null, null, false, false);
   3203             } catch (RemoteException e) {
   3204             }
   3205         } finally {
   3206             Binder.restoreCallingIdentity(callingId);
   3207         }
   3208         return true;
   3209     }
   3210 
   3211     public void killBackgroundProcesses(final String packageName) {
   3212         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   3213                 != PackageManager.PERMISSION_GRANTED &&
   3214                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
   3215                         != PackageManager.PERMISSION_GRANTED) {
   3216             String msg = "Permission Denial: killBackgroundProcesses() from pid="
   3217                     + Binder.getCallingPid()
   3218                     + ", uid=" + Binder.getCallingUid()
   3219                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   3220             Slog.w(TAG, msg);
   3221             throw new SecurityException(msg);
   3222         }
   3223 
   3224         long callingId = Binder.clearCallingIdentity();
   3225         try {
   3226             IPackageManager pm = AppGlobals.getPackageManager();
   3227             int pkgUid = -1;
   3228             synchronized(this) {
   3229                 try {
   3230                     pkgUid = pm.getPackageUid(packageName);
   3231                 } catch (RemoteException e) {
   3232                 }
   3233                 if (pkgUid == -1) {
   3234                     Slog.w(TAG, "Invalid packageName: " + packageName);
   3235                     return;
   3236                 }
   3237                 killPackageProcessesLocked(packageName, pkgUid,
   3238                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
   3239             }
   3240         } finally {
   3241             Binder.restoreCallingIdentity(callingId);
   3242         }
   3243     }
   3244 
   3245     public void killAllBackgroundProcesses() {
   3246         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   3247                 != PackageManager.PERMISSION_GRANTED) {
   3248             String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
   3249                     + Binder.getCallingPid()
   3250                     + ", uid=" + Binder.getCallingUid()
   3251                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   3252             Slog.w(TAG, msg);
   3253             throw new SecurityException(msg);
   3254         }
   3255 
   3256         long callingId = Binder.clearCallingIdentity();
   3257         try {
   3258             synchronized(this) {
   3259                 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   3260                 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   3261                     final int NA = apps.size();
   3262                     for (int ia=0; ia<NA; ia++) {
   3263                         ProcessRecord app = apps.valueAt(ia);
   3264                         if (app.persistent) {
   3265                             // we don't kill persistent processes
   3266                             continue;
   3267                         }
   3268                         if (app.removed) {
   3269                             procs.add(app);
   3270                         } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   3271                             app.removed = true;
   3272                             procs.add(app);
   3273                         }
   3274                     }
   3275                 }
   3276 
   3277                 int N = procs.size();
   3278                 for (int i=0; i<N; i++) {
   3279                     removeProcessLocked(procs.get(i), false, true, "kill all background");
   3280                 }
   3281             }
   3282         } finally {
   3283             Binder.restoreCallingIdentity(callingId);
   3284         }
   3285     }
   3286 
   3287     public void forceStopPackage(final String packageName) {
   3288         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   3289                 != PackageManager.PERMISSION_GRANTED) {
   3290             String msg = "Permission Denial: forceStopPackage() from pid="
   3291                     + Binder.getCallingPid()
   3292                     + ", uid=" + Binder.getCallingUid()
   3293                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   3294             Slog.w(TAG, msg);
   3295             throw new SecurityException(msg);
   3296         }
   3297 
   3298         long callingId = Binder.clearCallingIdentity();
   3299         try {
   3300             IPackageManager pm = AppGlobals.getPackageManager();
   3301             int pkgUid = -1;
   3302             synchronized(this) {
   3303                 try {
   3304                     pkgUid = pm.getPackageUid(packageName);
   3305                 } catch (RemoteException e) {
   3306                 }
   3307                 if (pkgUid == -1) {
   3308                     Slog.w(TAG, "Invalid packageName: " + packageName);
   3309                     return;
   3310                 }
   3311                 forceStopPackageLocked(packageName, pkgUid);
   3312                 try {
   3313                     pm.setPackageStoppedState(packageName, true);
   3314                 } catch (RemoteException e) {
   3315                 } catch (IllegalArgumentException e) {
   3316                     Slog.w(TAG, "Failed trying to unstop package "
   3317                             + packageName + ": " + e);
   3318                 }
   3319             }
   3320         } finally {
   3321             Binder.restoreCallingIdentity(callingId);
   3322         }
   3323     }
   3324 
   3325     /*
   3326      * The pkg name and uid have to be specified.
   3327      * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
   3328      */
   3329     public void killApplicationWithUid(String pkg, int uid) {
   3330         if (pkg == null) {
   3331             return;
   3332         }
   3333         // Make sure the uid is valid.
   3334         if (uid < 0) {
   3335             Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
   3336             return;
   3337         }
   3338         int callerUid = Binder.getCallingUid();
   3339         // Only the system server can kill an application
   3340         if (callerUid == Process.SYSTEM_UID) {
   3341             // Post an aysnc message to kill the application
   3342             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
   3343             msg.arg1 = uid;
   3344             msg.arg2 = 0;
   3345             msg.obj = pkg;
   3346             mHandler.sendMessage(msg);
   3347         } else {
   3348             throw new SecurityException(callerUid + " cannot kill pkg: " +
   3349                     pkg);
   3350         }
   3351     }
   3352 
   3353     public void closeSystemDialogs(String reason) {
   3354         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
   3355         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   3356         if (reason != null) {
   3357             intent.putExtra("reason", reason);
   3358         }
   3359 
   3360         final int uid = Binder.getCallingUid();
   3361         final long origId = Binder.clearCallingIdentity();
   3362         synchronized (this) {
   3363             int i = mWatchers.beginBroadcast();
   3364             while (i > 0) {
   3365                 i--;
   3366                 IActivityWatcher w = mWatchers.getBroadcastItem(i);
   3367                 if (w != null) {
   3368                     try {
   3369                         w.closingSystemDialogs(reason);
   3370                     } catch (RemoteException e) {
   3371                     }
   3372                 }
   3373             }
   3374             mWatchers.finishBroadcast();
   3375 
   3376             mWindowManager.closeSystemDialogs(reason);
   3377 
   3378             for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
   3379                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   3380                 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
   3381                     r.stack.finishActivityLocked(r, i,
   3382                             Activity.RESULT_CANCELED, null, "close-sys");
   3383                 }
   3384             }
   3385 
   3386             broadcastIntentLocked(null, null, intent, null,
   3387                     null, 0, null, null, null, false, false, -1, uid);
   3388         }
   3389         Binder.restoreCallingIdentity(origId);
   3390     }
   3391 
   3392     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
   3393             throws RemoteException {
   3394         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
   3395         for (int i=pids.length-1; i>=0; i--) {
   3396             infos[i] = new Debug.MemoryInfo();
   3397             Debug.getMemoryInfo(pids[i], infos[i]);
   3398         }
   3399         return infos;
   3400     }
   3401 
   3402     public long[] getProcessPss(int[] pids) throws RemoteException {
   3403         long[] pss = new long[pids.length];
   3404         for (int i=pids.length-1; i>=0; i--) {
   3405             pss[i] = Debug.getPss(pids[i]);
   3406         }
   3407         return pss;
   3408     }
   3409 
   3410     public void killApplicationProcess(String processName, int uid) {
   3411         if (processName == null) {
   3412             return;
   3413         }
   3414 
   3415         int callerUid = Binder.getCallingUid();
   3416         // Only the system server can kill an application
   3417         if (callerUid == Process.SYSTEM_UID) {
   3418             synchronized (this) {
   3419                 ProcessRecord app = getProcessRecordLocked(processName, uid);
   3420                 if (app != null && app.thread != null) {
   3421                     try {
   3422                         app.thread.scheduleSuicide();
   3423                     } catch (RemoteException e) {
   3424                         // If the other end already died, then our work here is done.
   3425                     }
   3426                 } else {
   3427                     Slog.w(TAG, "Process/uid not found attempting kill of "
   3428                             + processName + " / " + uid);
   3429                 }
   3430             }
   3431         } else {
   3432             throw new SecurityException(callerUid + " cannot kill app process: " +
   3433                     processName);
   3434         }
   3435     }
   3436 
   3437     private void forceStopPackageLocked(final String packageName, int uid) {
   3438         forceStopPackageLocked(packageName, uid, false, false, true, false);
   3439         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
   3440                 Uri.fromParts("package", packageName, null));
   3441         if (!mProcessesReady) {
   3442             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   3443         }
   3444         intent.putExtra(Intent.EXTRA_UID, uid);
   3445         broadcastIntentLocked(null, null, intent,
   3446                 null, null, 0, null, null, null,
   3447                 false, false, MY_PID, Process.SYSTEM_UID);
   3448     }
   3449 
   3450     private final boolean killPackageProcessesLocked(String packageName, int uid,
   3451             int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
   3452             boolean evenPersistent, String reason) {
   3453         ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   3454 
   3455         // Remove all processes this package may have touched: all with the
   3456         // same UID (except for the system or root user), and all whose name
   3457         // matches the package name.
   3458         final String procNamePrefix = packageName + ":";
   3459         for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   3460             final int NA = apps.size();
   3461             for (int ia=0; ia<NA; ia++) {
   3462                 ProcessRecord app = apps.valueAt(ia);
   3463                 if (app.persistent && !evenPersistent) {
   3464                     // we don't kill persistent processes
   3465                     continue;
   3466                 }
   3467                 if (app.removed) {
   3468                     if (doit) {
   3469                         procs.add(app);
   3470                     }
   3471                 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
   3472                         || app.processName.equals(packageName)
   3473                         || app.processName.startsWith(procNamePrefix)) {
   3474                     if (app.setAdj >= minOomAdj) {
   3475                         if (!doit) {
   3476                             return true;
   3477                         }
   3478                         app.removed = true;
   3479                         procs.add(app);
   3480                     }
   3481                 }
   3482             }
   3483         }
   3484 
   3485         int N = procs.size();
   3486         for (int i=0; i<N; i++) {
   3487             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
   3488         }
   3489         return N > 0;
   3490     }
   3491 
   3492     private final boolean forceStopPackageLocked(String name, int uid,
   3493             boolean callerWillRestart, boolean purgeCache, boolean doit,
   3494             boolean evenPersistent) {
   3495         int i;
   3496         int N;
   3497 
   3498         if (uid < 0) {
   3499             try {
   3500                 uid = AppGlobals.getPackageManager().getPackageUid(name);
   3501             } catch (RemoteException e) {
   3502             }
   3503         }
   3504 
   3505         if (doit) {
   3506             Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
   3507 
   3508             Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
   3509             while (badApps.hasNext()) {
   3510                 SparseArray<Long> ba = badApps.next();
   3511                 if (ba.get(uid) != null) {
   3512                     badApps.remove();
   3513                 }
   3514             }
   3515         }
   3516 
   3517         boolean didSomething = killPackageProcessesLocked(name, uid, -100,
   3518                 callerWillRestart, false, doit, evenPersistent, "force stop");
   3519 
   3520         TaskRecord lastTask = null;
   3521         for (i=0; i<mMainStack.mHistory.size(); i++) {
   3522             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   3523             final boolean samePackage = r.packageName.equals(name);
   3524             if ((samePackage || r.task == lastTask)
   3525                     && (r.app == null || evenPersistent || !r.app.persistent)) {
   3526                 if (!doit) {
   3527                     if (r.finishing) {
   3528                         // If this activity is just finishing, then it is not
   3529                         // interesting as far as something to stop.
   3530                         continue;
   3531                     }
   3532                     return true;
   3533                 }
   3534                 didSomething = true;
   3535                 Slog.i(TAG, "  Force finishing activity " + r);
   3536                 if (samePackage) {
   3537                     if (r.app != null) {
   3538                         r.app.removed = true;
   3539                     }
   3540                     r.app = null;
   3541                 }
   3542                 lastTask = r.task;
   3543                 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
   3544                         null, "force-stop")) {
   3545                     i--;
   3546                 }
   3547             }
   3548         }
   3549 
   3550         ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
   3551         for (ServiceRecord service : mServices.values()) {
   3552             if (service.packageName.equals(name)
   3553                     && (service.app == null || evenPersistent || !service.app.persistent)) {
   3554                 if (!doit) {
   3555                     return true;
   3556                 }
   3557                 didSomething = true;
   3558                 Slog.i(TAG, "  Force stopping service " + service);
   3559                 if (service.app != null) {
   3560                     service.app.removed = true;
   3561                 }
   3562                 service.app = null;
   3563                 services.add(service);
   3564             }
   3565         }
   3566 
   3567         N = services.size();
   3568         for (i=0; i<N; i++) {
   3569             bringDownServiceLocked(services.get(i), true);
   3570         }
   3571 
   3572         ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
   3573         for (ContentProviderRecord provider : mProvidersByClass.values()) {
   3574             if (provider.info.packageName.equals(name)
   3575                     && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
   3576                 if (!doit) {
   3577                     return true;
   3578                 }
   3579                 didSomething = true;
   3580                 providers.add(provider);
   3581             }
   3582         }
   3583 
   3584         N = providers.size();
   3585         for (i=0; i<N; i++) {
   3586             removeDyingProviderLocked(null, providers.get(i));
   3587         }
   3588 
   3589         if (doit) {
   3590             if (purgeCache) {
   3591                 AttributeCache ac = AttributeCache.instance();
   3592                 if (ac != null) {
   3593                     ac.removePackage(name);
   3594                 }
   3595             }
   3596             if (mBooted) {
   3597                 mMainStack.resumeTopActivityLocked(null);
   3598                 mMainStack.scheduleIdleLocked();
   3599             }
   3600         }
   3601 
   3602         return didSomething;
   3603     }
   3604 
   3605     private final boolean removeProcessLocked(ProcessRecord app,
   3606             boolean callerWillRestart, boolean allowRestart, String reason) {
   3607         final String name = app.processName;
   3608         final int uid = app.info.uid;
   3609         if (DEBUG_PROCESSES) Slog.d(
   3610             TAG, "Force removing proc " + app.toShortString() + " (" + name
   3611             + "/" + uid + ")");
   3612 
   3613         mProcessNames.remove(name, uid);
   3614         if (mHeavyWeightProcess == app) {
   3615             mHeavyWeightProcess = null;
   3616             mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
   3617         }
   3618         boolean needRestart = false;
   3619         if (app.pid > 0 && app.pid != MY_PID) {
   3620             int pid = app.pid;
   3621             synchronized (mPidsSelfLocked) {
   3622                 mPidsSelfLocked.remove(pid);
   3623                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   3624             }
   3625             Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
   3626             handleAppDiedLocked(app, true, allowRestart);
   3627             mLruProcesses.remove(app);
   3628             Process.killProcessQuiet(pid);
   3629 
   3630             if (app.persistent) {
   3631                 if (!callerWillRestart) {
   3632                     addAppLocked(app.info);
   3633                 } else {
   3634                     needRestart = true;
   3635                 }
   3636             }
   3637         } else {
   3638             mRemovedProcesses.add(app);
   3639         }
   3640 
   3641         return needRestart;
   3642     }
   3643 
   3644     private final void processStartTimedOutLocked(ProcessRecord app) {
   3645         final int pid = app.pid;
   3646         boolean gone = false;
   3647         synchronized (mPidsSelfLocked) {
   3648             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
   3649             if (knownApp != null && knownApp.thread == null) {
   3650                 mPidsSelfLocked.remove(pid);
   3651                 gone = true;
   3652             }
   3653         }
   3654 
   3655         if (gone) {
   3656             Slog.w(TAG, "Process " + app + " failed to attach");
   3657             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
   3658                     app.processName);
   3659             mProcessNames.remove(app.processName, app.info.uid);
   3660             if (mHeavyWeightProcess == app) {
   3661                 mHeavyWeightProcess = null;
   3662                 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
   3663             }
   3664             // Take care of any launching providers waiting for this process.
   3665             checkAppInLaunchingProvidersLocked(app, true);
   3666             // Take care of any services that are waiting for the process.
   3667             for (int i=0; i<mPendingServices.size(); i++) {
   3668                 ServiceRecord sr = mPendingServices.get(i);
   3669                 if (app.info.uid == sr.appInfo.uid
   3670                         && app.processName.equals(sr.processName)) {
   3671                     Slog.w(TAG, "Forcing bringing down service: " + sr);
   3672                     mPendingServices.remove(i);
   3673                     i--;
   3674                     bringDownServiceLocked(sr, true);
   3675                 }
   3676             }
   3677             EventLog.writeEvent(EventLogTags.AM_KILL, pid,
   3678                     app.processName, app.setAdj, "start timeout");
   3679             Process.killProcessQuiet(pid);
   3680             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
   3681                 Slog.w(TAG, "Unattached app died before backup, skipping");
   3682                 try {
   3683                     IBackupManager bm = IBackupManager.Stub.asInterface(
   3684                             ServiceManager.getService(Context.BACKUP_SERVICE));
   3685                     bm.agentDisconnected(app.info.packageName);
   3686                 } catch (RemoteException e) {
   3687                     // Can't happen; the backup manager is local
   3688                 }
   3689             }
   3690             if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
   3691                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   3692                 mPendingBroadcast.state = BroadcastRecord.IDLE;
   3693                 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
   3694                 mPendingBroadcast = null;
   3695                 scheduleBroadcastsLocked();
   3696             }
   3697         } else {
   3698             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
   3699         }
   3700     }
   3701 
   3702     private final boolean attachApplicationLocked(IApplicationThread thread,
   3703             int pid) {
   3704 
   3705         // Find the application record that is being attached...  either via
   3706         // the pid if we are running in multiple processes, or just pull the
   3707         // next app record if we are emulating process with anonymous threads.
   3708         ProcessRecord app;
   3709         if (pid != MY_PID && pid >= 0) {
   3710             synchronized (mPidsSelfLocked) {
   3711                 app = mPidsSelfLocked.get(pid);
   3712             }
   3713         } else {
   3714             app = null;
   3715         }
   3716 
   3717         if (app == null) {
   3718             Slog.w(TAG, "No pending application record for pid " + pid
   3719                     + " (IApplicationThread " + thread + "); dropping process");
   3720             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
   3721             if (pid > 0 && pid != MY_PID) {
   3722                 Process.killProcessQuiet(pid);
   3723             } else {
   3724                 try {
   3725                     thread.scheduleExit();
   3726                 } catch (Exception e) {
   3727                     // Ignore exceptions.
   3728                 }
   3729             }
   3730             return false;
   3731         }
   3732 
   3733         // If this application record is still attached to a previous
   3734         // process, clean it up now.
   3735         if (app.thread != null) {
   3736             handleAppDiedLocked(app, true, true);
   3737         }
   3738 
   3739         // Tell the process all about itself.
   3740 
   3741         if (localLOGV) Slog.v(
   3742                 TAG, "Binding process pid " + pid + " to record " + app);
   3743 
   3744         String processName = app.processName;
   3745         try {
   3746             AppDeathRecipient adr = new AppDeathRecipient(
   3747                     app, pid, thread);
   3748             thread.asBinder().linkToDeath(adr, 0);
   3749             app.deathRecipient = adr;
   3750         } catch (RemoteException e) {
   3751             app.resetPackageList();
   3752             startProcessLocked(app, "link fail", processName);
   3753             return false;
   3754         }
   3755 
   3756         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
   3757 
   3758         app.thread = thread;
   3759         app.curAdj = app.setAdj = -100;
   3760         app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
   3761         app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   3762         app.forcingToForeground = null;
   3763         app.foregroundServices = false;
   3764         app.hasShownUi = false;
   3765         app.debugging = false;
   3766 
   3767         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   3768 
   3769         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
   3770         List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
   3771 
   3772         if (!normalMode) {
   3773             Slog.i(TAG, "Launching preboot mode app: " + app);
   3774         }
   3775 
   3776         if (localLOGV) Slog.v(
   3777             TAG, "New app record " + app
   3778             + " thread=" + thread.asBinder() + " pid=" + pid);
   3779         try {
   3780             int testMode = IApplicationThread.DEBUG_OFF;
   3781             if (mDebugApp != null && mDebugApp.equals(processName)) {
   3782                 testMode = mWaitForDebugger
   3783                     ? IApplicationThread.DEBUG_WAIT
   3784                     : IApplicationThread.DEBUG_ON;
   3785                 app.debugging = true;
   3786                 if (mDebugTransient) {
   3787                     mDebugApp = mOrigDebugApp;
   3788                     mWaitForDebugger = mOrigWaitForDebugger;
   3789                 }
   3790             }
   3791             String profileFile = app.instrumentationProfileFile;
   3792             ParcelFileDescriptor profileFd = null;
   3793             boolean profileAutoStop = false;
   3794             if (mProfileApp != null && mProfileApp.equals(processName)) {
   3795                 mProfileProc = app;
   3796                 profileFile = mProfileFile;
   3797                 profileFd = mProfileFd;
   3798                 profileAutoStop = mAutoStopProfiler;
   3799             }
   3800 
   3801             // If the app is being launched for restore or full backup, set it up specially
   3802             boolean isRestrictedBackupMode = false;
   3803             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
   3804                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
   3805                         || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
   3806                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
   3807             }
   3808 
   3809             ensurePackageDexOpt(app.instrumentationInfo != null
   3810                     ? app.instrumentationInfo.packageName
   3811                     : app.info.packageName);
   3812             if (app.instrumentationClass != null) {
   3813                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
   3814             }
   3815             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
   3816                     + processName + " with config " + mConfiguration);
   3817             ApplicationInfo appInfo = app.instrumentationInfo != null
   3818                     ? app.instrumentationInfo : app.info;
   3819             app.compat = compatibilityInfoForPackageLocked(appInfo);
   3820             if (profileFd != null) {
   3821                 profileFd = profileFd.dup();
   3822             }
   3823             thread.bindApplication(processName, appInfo, providers,
   3824                     app.instrumentationClass, profileFile, profileFd, profileAutoStop,
   3825                     app.instrumentationArguments, app.instrumentationWatcher, testMode,
   3826                     isRestrictedBackupMode || !normalMode, app.persistent,
   3827                     new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
   3828                     mCoreSettingsObserver.getCoreSettingsLocked());
   3829             updateLruProcessLocked(app, false, true);
   3830             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
   3831         } catch (Exception e) {
   3832             // todo: Yikes!  What should we do?  For now we will try to
   3833             // start another process, but that could easily get us in
   3834             // an infinite loop of restarting processes...
   3835             Slog.w(TAG, "Exception thrown during bind!", e);
   3836 
   3837             app.resetPackageList();
   3838             app.unlinkDeathRecipient();
   3839             startProcessLocked(app, "bind fail", processName);
   3840             return false;
   3841         }
   3842 
   3843         // Remove this record from the list of starting applications.
   3844         mPersistentStartingProcesses.remove(app);
   3845         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   3846                 "Attach application locked removing on hold: " + app);
   3847         mProcessesOnHold.remove(app);
   3848 
   3849         boolean badApp = false;
   3850         boolean didSomething = false;
   3851 
   3852         // See if the top visible activity is waiting to run in this process...
   3853         ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
   3854         if (hr != null && normalMode) {
   3855             if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
   3856                     && processName.equals(hr.processName)) {
   3857                 try {
   3858                     if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
   3859                         didSomething = true;
   3860                     }
   3861                 } catch (Exception e) {
   3862                     Slog.w(TAG, "Exception in new application when starting activity "
   3863                           + hr.intent.getComponent().flattenToShortString(), e);
   3864                     badApp = true;
   3865                 }
   3866             } else {
   3867                 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
   3868             }
   3869         }
   3870 
   3871         // Find any services that should be running in this process...
   3872         if (!badApp && mPendingServices.size() > 0) {
   3873             ServiceRecord sr = null;
   3874             try {
   3875                 for (int i=0; i<mPendingServices.size(); i++) {
   3876                     sr = mPendingServices.get(i);
   3877                     if (app.info.uid != sr.appInfo.uid
   3878                             || !processName.equals(sr.processName)) {
   3879                         continue;
   3880                     }
   3881 
   3882                     mPendingServices.remove(i);
   3883                     i--;
   3884                     realStartServiceLocked(sr, app);
   3885                     didSomething = true;
   3886                 }
   3887             } catch (Exception e) {
   3888                 Slog.w(TAG, "Exception in new application when starting service "
   3889                       + sr.shortName, e);
   3890                 badApp = true;
   3891             }
   3892         }
   3893 
   3894         // Check if the next broadcast receiver is in this process...
   3895         BroadcastRecord br = mPendingBroadcast;
   3896         if (!badApp && br != null && br.curApp == app) {
   3897             try {
   3898                 mPendingBroadcast = null;
   3899                 processCurBroadcastLocked(br, app);
   3900                 didSomething = true;
   3901             } catch (Exception e) {
   3902                 Slog.w(TAG, "Exception in new application when starting receiver "
   3903                       + br.curComponent.flattenToShortString(), e);
   3904                 badApp = true;
   3905                 logBroadcastReceiverDiscardLocked(br);
   3906                 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
   3907                         br.resultExtras, br.resultAbort, true);
   3908                 scheduleBroadcastsLocked();
   3909                 // We need to reset the state if we fails to start the receiver.
   3910                 br.state = BroadcastRecord.IDLE;
   3911             }
   3912         }
   3913 
   3914         // Check whether the next backup agent is in this process...
   3915         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
   3916             if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
   3917             ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
   3918             try {
   3919                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
   3920                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
   3921                         mBackupTarget.backupMode);
   3922             } catch (Exception e) {
   3923                 Slog.w(TAG, "Exception scheduling backup agent creation: ");
   3924                 e.printStackTrace();
   3925             }
   3926         }
   3927 
   3928         if (badApp) {
   3929             // todo: Also need to kill application to deal with all
   3930             // kinds of exceptions.
   3931             handleAppDiedLocked(app, false, true);
   3932             return false;
   3933         }
   3934 
   3935         if (!didSomething) {
   3936             updateOomAdjLocked();
   3937         }
   3938 
   3939         return true;
   3940     }
   3941 
   3942     public final void attachApplication(IApplicationThread thread) {
   3943         synchronized (this) {
   3944             int callingPid = Binder.getCallingPid();
   3945             final long origId = Binder.clearCallingIdentity();
   3946             attachApplicationLocked(thread, callingPid);
   3947             Binder.restoreCallingIdentity(origId);
   3948         }
   3949     }
   3950 
   3951     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
   3952         final long origId = Binder.clearCallingIdentity();
   3953         ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
   3954         if (stopProfiling) {
   3955             synchronized (this) {
   3956                 if (mProfileProc == r.app) {
   3957                     if (mProfileFd != null) {
   3958                         try {
   3959                             mProfileFd.close();
   3960                         } catch (IOException e) {
   3961                         }
   3962                         clearProfilerLocked();
   3963                     }
   3964                 }
   3965             }
   3966         }
   3967         Binder.restoreCallingIdentity(origId);
   3968     }
   3969 
   3970     void enableScreenAfterBoot() {
   3971         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
   3972                 SystemClock.uptimeMillis());
   3973         mWindowManager.enableScreenAfterBoot();
   3974     }
   3975 
   3976     public void showBootMessage(final CharSequence msg, final boolean always) {
   3977         mWindowManager.showBootMessage(msg, always);
   3978     }
   3979 
   3980     public void dismissKeyguardOnNextActivity() {
   3981         synchronized (this) {
   3982             mMainStack.dismissKeyguardOnNextActivityLocked();
   3983         }
   3984     }
   3985 
   3986     final void finishBooting() {
   3987         IntentFilter pkgFilter = new IntentFilter();
   3988         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
   3989         pkgFilter.addDataScheme("package");
   3990         mContext.registerReceiver(new BroadcastReceiver() {
   3991             @Override
   3992             public void onReceive(Context context, Intent intent) {
   3993                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
   3994                 if (pkgs != null) {
   3995                     for (String pkg : pkgs) {
   3996                         synchronized (ActivityManagerService.this) {
   3997                           if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
   3998                               setResultCode(Activity.RESULT_OK);
   3999                               return;
   4000                           }
   4001                        }
   4002                     }
   4003                 }
   4004             }
   4005         }, pkgFilter);
   4006 
   4007         synchronized (this) {
   4008             // Ensure that any processes we had put on hold are now started
   4009             // up.
   4010             final int NP = mProcessesOnHold.size();
   4011             if (NP > 0) {
   4012                 ArrayList<ProcessRecord> procs =
   4013                     new ArrayList<ProcessRecord>(mProcessesOnHold);
   4014                 for (int ip=0; ip<NP; ip++) {
   4015                     if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
   4016                             + procs.get(ip));
   4017                     startProcessLocked(procs.get(ip), "on-hold", null);
   4018                 }
   4019             }
   4020 
   4021             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   4022                 // Start looking for apps that are abusing wake locks.
   4023                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   4024                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   4025                 // Tell anyone interested that we are done booting!
   4026                 SystemProperties.set("sys.boot_completed", "1");
   4027                 broadcastIntentLocked(null, null,
   4028                         new Intent(Intent.ACTION_BOOT_COMPLETED, null),
   4029                         null, null, 0, null, null,
   4030                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
   4031                         false, false, MY_PID, Process.SYSTEM_UID);
   4032             }
   4033         }
   4034     }
   4035 
   4036     final void ensureBootCompleted() {
   4037         boolean booting;
   4038         boolean enableScreen;
   4039         synchronized (this) {
   4040             booting = mBooting;
   4041             mBooting = false;
   4042             enableScreen = !mBooted;
   4043             mBooted = true;
   4044         }
   4045 
   4046         if (booting) {
   4047             finishBooting();
   4048         }
   4049 
   4050         if (enableScreen) {
   4051             enableScreenAfterBoot();
   4052         }
   4053     }
   4054 
   4055     public final void activityPaused(IBinder token) {
   4056         final long origId = Binder.clearCallingIdentity();
   4057         mMainStack.activityPaused(token, false);
   4058         Binder.restoreCallingIdentity(origId);
   4059     }
   4060 
   4061     public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
   4062             CharSequence description) {
   4063         if (localLOGV) Slog.v(
   4064             TAG, "Activity stopped: token=" + token);
   4065 
   4066         // Refuse possible leaked file descriptors
   4067         if (icicle != null && icicle.hasFileDescriptors()) {
   4068             throw new IllegalArgumentException("File descriptors passed in Bundle");
   4069         }
   4070 
   4071         ActivityRecord r = null;
   4072 
   4073         final long origId = Binder.clearCallingIdentity();
   4074 
   4075         synchronized (this) {
   4076             r = mMainStack.isInStackLocked(token);
   4077             if (r != null) {
   4078                 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
   4079             }
   4080         }
   4081 
   4082         if (r != null) {
   4083             sendPendingThumbnail(r, null, null, null, false);
   4084         }
   4085 
   4086         trimApplications();
   4087 
   4088         Binder.restoreCallingIdentity(origId);
   4089     }
   4090 
   4091     public final void activityDestroyed(IBinder token) {
   4092         if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
   4093         mMainStack.activityDestroyed(token);
   4094     }
   4095 
   4096     public String getCallingPackage(IBinder token) {
   4097         synchronized (this) {
   4098             ActivityRecord r = getCallingRecordLocked(token);
   4099             return r != null && r.app != null ? r.info.packageName : null;
   4100         }
   4101     }
   4102 
   4103     public ComponentName getCallingActivity(IBinder token) {
   4104         synchronized (this) {
   4105             ActivityRecord r = getCallingRecordLocked(token);
   4106             return r != null ? r.intent.getComponent() : null;
   4107         }
   4108     }
   4109 
   4110     private ActivityRecord getCallingRecordLocked(IBinder token) {
   4111         ActivityRecord r = mMainStack.isInStackLocked(token);
   4112         if (r == null) {
   4113             return null;
   4114         }
   4115         return r.resultTo;
   4116     }
   4117 
   4118     public ComponentName getActivityClassForToken(IBinder token) {
   4119         synchronized(this) {
   4120             ActivityRecord r = mMainStack.isInStackLocked(token);
   4121             if (r == null) {
   4122                 return null;
   4123             }
   4124             return r.intent.getComponent();
   4125         }
   4126     }
   4127 
   4128     public String getPackageForToken(IBinder token) {
   4129         synchronized(this) {
   4130             ActivityRecord r = mMainStack.isInStackLocked(token);
   4131             if (r == null) {
   4132                 return null;
   4133             }
   4134             return r.packageName;
   4135         }
   4136     }
   4137 
   4138     public IIntentSender getIntentSender(int type,
   4139             String packageName, IBinder token, String resultWho,
   4140             int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
   4141         // Refuse possible leaked file descriptors
   4142         if (intents != null) {
   4143             if (intents.length < 1) {
   4144                 throw new IllegalArgumentException("Intents array length must be >= 1");
   4145             }
   4146             for (int i=0; i<intents.length; i++) {
   4147                 Intent intent = intents[i];
   4148                 if (intent != null) {
   4149                     if (intent.hasFileDescriptors()) {
   4150                         throw new IllegalArgumentException("File descriptors passed in Intent");
   4151                     }
   4152                     if (type == INTENT_SENDER_BROADCAST &&
   4153                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   4154                         throw new IllegalArgumentException(
   4155                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   4156                     }
   4157                     intents[i] = new Intent(intent);
   4158                 }
   4159             }
   4160             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
   4161                 throw new IllegalArgumentException(
   4162                         "Intent array length does not match resolvedTypes length");
   4163             }
   4164         }
   4165 
   4166         synchronized(this) {
   4167             int callingUid = Binder.getCallingUid();
   4168             try {
   4169                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   4170                     int uid = AppGlobals.getPackageManager()
   4171                             .getPackageUid(packageName);
   4172                     if (uid != Binder.getCallingUid()) {
   4173                         String msg = "Permission Denial: getIntentSender() from pid="
   4174                             + Binder.getCallingPid()
   4175                             + ", uid=" + Binder.getCallingUid()
   4176                             + ", (need uid=" + uid + ")"
   4177                             + " is not allowed to send as package " + packageName;
   4178                         Slog.w(TAG, msg);
   4179                         throw new SecurityException(msg);
   4180                     }
   4181                 }
   4182 
   4183                 return getIntentSenderLocked(type, packageName, callingUid,
   4184                         token, resultWho, requestCode, intents, resolvedTypes, flags);
   4185 
   4186             } catch (RemoteException e) {
   4187                 throw new SecurityException(e);
   4188             }
   4189         }
   4190     }
   4191 
   4192     IIntentSender getIntentSenderLocked(int type,
   4193             String packageName, int callingUid, IBinder token, String resultWho,
   4194             int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
   4195         ActivityRecord activity = null;
   4196         if (type == INTENT_SENDER_ACTIVITY_RESULT) {
   4197             activity = mMainStack.isInStackLocked(token);
   4198             if (activity == null) {
   4199                 return null;
   4200             }
   4201             if (activity.finishing) {
   4202                 return null;
   4203             }
   4204         }
   4205 
   4206         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
   4207         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
   4208         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
   4209         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
   4210                 |PendingIntent.FLAG_UPDATE_CURRENT);
   4211 
   4212         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
   4213                 type, packageName, activity, resultWho,
   4214                 requestCode, intents, resolvedTypes, flags);
   4215         WeakReference<PendingIntentRecord> ref;
   4216         ref = mIntentSenderRecords.get(key);
   4217         PendingIntentRecord rec = ref != null ? ref.get() : null;
   4218         if (rec != null) {
   4219             if (!cancelCurrent) {
   4220                 if (updateCurrent) {
   4221                     if (rec.key.requestIntent != null) {
   4222                         rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
   4223                     }
   4224                     if (intents != null) {
   4225                         intents[intents.length-1] = rec.key.requestIntent;
   4226                         rec.key.allIntents = intents;
   4227                         rec.key.allResolvedTypes = resolvedTypes;
   4228                     } else {
   4229                         rec.key.allIntents = null;
   4230                         rec.key.allResolvedTypes = null;
   4231                     }
   4232                 }
   4233                 return rec;
   4234             }
   4235             rec.canceled = true;
   4236             mIntentSenderRecords.remove(key);
   4237         }
   4238         if (noCreate) {
   4239             return rec;
   4240         }
   4241         rec = new PendingIntentRecord(this, key, callingUid);
   4242         mIntentSenderRecords.put(key, rec.ref);
   4243         if (type == INTENT_SENDER_ACTIVITY_RESULT) {
   4244             if (activity.pendingResults == null) {
   4245                 activity.pendingResults
   4246                         = new HashSet<WeakReference<PendingIntentRecord>>();
   4247             }
   4248             activity.pendingResults.add(rec.ref);
   4249         }
   4250         return rec;
   4251     }
   4252 
   4253     public void cancelIntentSender(IIntentSender sender) {
   4254         if (!(sender instanceof PendingIntentRecord)) {
   4255             return;
   4256         }
   4257         synchronized(this) {
   4258             PendingIntentRecord rec = (PendingIntentRecord)sender;
   4259             try {
   4260                 int uid = AppGlobals.getPackageManager()
   4261                         .getPackageUid(rec.key.packageName);
   4262                 if (uid != Binder.getCallingUid()) {
   4263                     String msg = "Permission Denial: cancelIntentSender() from pid="
   4264                         + Binder.getCallingPid()
   4265                         + ", uid=" + Binder.getCallingUid()
   4266                         + " is not allowed to cancel packges "
   4267                         + rec.key.packageName;
   4268                     Slog.w(TAG, msg);
   4269                     throw new SecurityException(msg);
   4270                 }
   4271             } catch (RemoteException e) {
   4272                 throw new SecurityException(e);
   4273             }
   4274             cancelIntentSenderLocked(rec, true);
   4275         }
   4276     }
   4277 
   4278     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
   4279         rec.canceled = true;
   4280         mIntentSenderRecords.remove(rec.key);
   4281         if (cleanActivity && rec.key.activity != null) {
   4282             rec.key.activity.pendingResults.remove(rec.ref);
   4283         }
   4284     }
   4285 
   4286     public String getPackageForIntentSender(IIntentSender pendingResult) {
   4287         if (!(pendingResult instanceof PendingIntentRecord)) {
   4288             return null;
   4289         }
   4290         try {
   4291             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   4292             return res.key.packageName;
   4293         } catch (ClassCastException e) {
   4294         }
   4295         return null;
   4296     }
   4297 
   4298     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
   4299         if (!(pendingResult instanceof PendingIntentRecord)) {
   4300             return false;
   4301         }
   4302         try {
   4303             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   4304             if (res.key.allIntents == null) {
   4305                 return false;
   4306             }
   4307             for (int i=0; i<res.key.allIntents.length; i++) {
   4308                 Intent intent = res.key.allIntents[i];
   4309                 if (intent.getPackage() != null && intent.getComponent() != null) {
   4310                     return false;
   4311                 }
   4312             }
   4313             return true;
   4314         } catch (ClassCastException e) {
   4315         }
   4316         return false;
   4317     }
   4318 
   4319     public void setProcessLimit(int max) {
   4320         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   4321                 "setProcessLimit()");
   4322         synchronized (this) {
   4323             mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
   4324             mProcessLimitOverride = max;
   4325         }
   4326         trimApplications();
   4327     }
   4328 
   4329     public int getProcessLimit() {
   4330         synchronized (this) {
   4331             return mProcessLimitOverride;
   4332         }
   4333     }
   4334 
   4335     void foregroundTokenDied(ForegroundToken token) {
   4336         synchronized (ActivityManagerService.this) {
   4337             synchronized (mPidsSelfLocked) {
   4338                 ForegroundToken cur
   4339                     = mForegroundProcesses.get(token.pid);
   4340                 if (cur != token) {
   4341                     return;
   4342                 }
   4343                 mForegroundProcesses.remove(token.pid);
   4344                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
   4345                 if (pr == null) {
   4346                     return;
   4347                 }
   4348                 pr.forcingToForeground = null;
   4349                 pr.foregroundServices = false;
   4350             }
   4351             updateOomAdjLocked();
   4352         }
   4353     }
   4354 
   4355     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
   4356         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   4357                 "setProcessForeground()");
   4358         synchronized(this) {
   4359             boolean changed = false;
   4360 
   4361             synchronized (mPidsSelfLocked) {
   4362                 ProcessRecord pr = mPidsSelfLocked.get(pid);
   4363                 if (pr == null) {
   4364                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
   4365                     return;
   4366                 }
   4367                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
   4368                 if (oldToken != null) {
   4369                     oldToken.token.unlinkToDeath(oldToken, 0);
   4370                     mForegroundProcesses.remove(pid);
   4371                     pr.forcingToForeground = null;
   4372                     changed = true;
   4373                 }
   4374                 if (isForeground && token != null) {
   4375                     ForegroundToken newToken = new ForegroundToken() {
   4376                         public void binderDied() {
   4377                             foregroundTokenDied(this);
   4378                         }
   4379                     };
   4380                     newToken.pid = pid;
   4381                     newToken.token = token;
   4382                     try {
   4383                         token.linkToDeath(newToken, 0);
   4384                         mForegroundProcesses.put(pid, newToken);
   4385                         pr.forcingToForeground = token;
   4386                         changed = true;
   4387                     } catch (RemoteException e) {
   4388                         // If the process died while doing this, we will later
   4389                         // do the cleanup with the process death link.
   4390                     }
   4391                 }
   4392             }
   4393 
   4394             if (changed) {
   4395                 updateOomAdjLocked();
   4396             }
   4397         }
   4398     }
   4399 
   4400     // =========================================================
   4401     // PERMISSIONS
   4402     // =========================================================
   4403 
   4404     static class PermissionController extends IPermissionController.Stub {
   4405         ActivityManagerService mActivityManagerService;
   4406         PermissionController(ActivityManagerService activityManagerService) {
   4407             mActivityManagerService = activityManagerService;
   4408         }
   4409 
   4410         public boolean checkPermission(String permission, int pid, int uid) {
   4411             return mActivityManagerService.checkPermission(permission, pid,
   4412                     uid) == PackageManager.PERMISSION_GRANTED;
   4413         }
   4414     }
   4415 
   4416     /**
   4417      * This can be called with or without the global lock held.
   4418      */
   4419     int checkComponentPermission(String permission, int pid, int uid,
   4420             int owningUid, boolean exported) {
   4421         // We might be performing an operation on behalf of an indirect binder
   4422         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
   4423         // client identity accordingly before proceeding.
   4424         Identity tlsIdentity = sCallerIdentity.get();
   4425         if (tlsIdentity != null) {
   4426             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
   4427                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
   4428             uid = tlsIdentity.uid;
   4429             pid = tlsIdentity.pid;
   4430         }
   4431 
   4432         // Root, system server and our own process get to do everything.
   4433         if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
   4434             return PackageManager.PERMISSION_GRANTED;
   4435         }
   4436         // If there is a uid that owns whatever is being accessed, it has
   4437         // blanket access to it regardless of the permissions it requires.
   4438         if (owningUid >= 0 && uid == owningUid) {
   4439             return PackageManager.PERMISSION_GRANTED;
   4440         }
   4441         // If the target is not exported, then nobody else can get to it.
   4442         if (!exported) {
   4443             Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
   4444             return PackageManager.PERMISSION_DENIED;
   4445         }
   4446         if (permission == null) {
   4447             return PackageManager.PERMISSION_GRANTED;
   4448         }
   4449         try {
   4450             return AppGlobals.getPackageManager()
   4451                     .checkUidPermission(permission, uid);
   4452         } catch (RemoteException e) {
   4453             // Should never happen, but if it does... deny!
   4454             Slog.e(TAG, "PackageManager is dead?!?", e);
   4455         }
   4456         return PackageManager.PERMISSION_DENIED;
   4457     }
   4458 
   4459     /**
   4460      * As the only public entry point for permissions checking, this method
   4461      * can enforce the semantic that requesting a check on a null global
   4462      * permission is automatically denied.  (Internally a null permission
   4463      * string is used when calling {@link #checkComponentPermission} in cases
   4464      * when only uid-based security is needed.)
   4465      *
   4466      * This can be called with or without the global lock held.
   4467      */
   4468     public int checkPermission(String permission, int pid, int uid) {
   4469         if (permission == null) {
   4470             return PackageManager.PERMISSION_DENIED;
   4471         }
   4472         return checkComponentPermission(permission, pid, uid, -1, true);
   4473     }
   4474 
   4475     /**
   4476      * Binder IPC calls go through the public entry point.
   4477      * This can be called with or without the global lock held.
   4478      */
   4479     int checkCallingPermission(String permission) {
   4480         return checkPermission(permission,
   4481                 Binder.getCallingPid(),
   4482                 Binder.getCallingUid());
   4483     }
   4484 
   4485     /**
   4486      * This can be called with or without the global lock held.
   4487      */
   4488     void enforceCallingPermission(String permission, String func) {
   4489         if (checkCallingPermission(permission)
   4490                 == PackageManager.PERMISSION_GRANTED) {
   4491             return;
   4492         }
   4493 
   4494         String msg = "Permission Denial: " + func + " from pid="
   4495                 + Binder.getCallingPid()
   4496                 + ", uid=" + Binder.getCallingUid()
   4497                 + " requires " + permission;
   4498         Slog.w(TAG, msg);
   4499         throw new SecurityException(msg);
   4500     }
   4501 
   4502     private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
   4503             ProviderInfo pi, Uri uri, int uid, int modeFlags) {
   4504         boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
   4505         boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
   4506         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4507                 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
   4508         try {
   4509             // Is the component private from the target uid?
   4510             final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
   4511 
   4512             // Acceptable if the there is no read permission needed from the
   4513             // target or the target is holding the read permission.
   4514             if (!readPerm) {
   4515                 if ((!prv && pi.readPermission == null) ||
   4516                         (pm.checkUidPermission(pi.readPermission, uid)
   4517                                 == PackageManager.PERMISSION_GRANTED)) {
   4518                     readPerm = true;
   4519                 }
   4520             }
   4521 
   4522             // Acceptable if the there is no write permission needed from the
   4523             // target or the target is holding the read permission.
   4524             if (!writePerm) {
   4525                 if (!prv && (pi.writePermission == null) ||
   4526                         (pm.checkUidPermission(pi.writePermission, uid)
   4527                                 == PackageManager.PERMISSION_GRANTED)) {
   4528                     writePerm = true;
   4529                 }
   4530             }
   4531 
   4532             // Acceptable if there is a path permission matching the URI that
   4533             // the target holds the permission on.
   4534             PathPermission[] pps = pi.pathPermissions;
   4535             if (pps != null && (!readPerm || !writePerm)) {
   4536                 final String path = uri.getPath();
   4537                 int i = pps.length;
   4538                 while (i > 0 && (!readPerm || !writePerm)) {
   4539                     i--;
   4540                     PathPermission pp = pps[i];
   4541                     if (!readPerm) {
   4542                         final String pprperm = pp.getReadPermission();
   4543                         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
   4544                                 + pprperm + " for " + pp.getPath()
   4545                                 + ": match=" + pp.match(path)
   4546                                 + " check=" + pm.checkUidPermission(pprperm, uid));
   4547                         if (pprperm != null && pp.match(path) &&
   4548                                 (pm.checkUidPermission(pprperm, uid)
   4549                                         == PackageManager.PERMISSION_GRANTED)) {
   4550                             readPerm = true;
   4551                         }
   4552                     }
   4553                     if (!writePerm) {
   4554                         final String ppwperm = pp.getWritePermission();
   4555                         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
   4556                                 + ppwperm + " for " + pp.getPath()
   4557                                 + ": match=" + pp.match(path)
   4558                                 + " check=" + pm.checkUidPermission(ppwperm, uid));
   4559                         if (ppwperm != null && pp.match(path) &&
   4560                                 (pm.checkUidPermission(ppwperm, uid)
   4561                                         == PackageManager.PERMISSION_GRANTED)) {
   4562                             writePerm = true;
   4563                         }
   4564                     }
   4565                 }
   4566             }
   4567         } catch (RemoteException e) {
   4568             return false;
   4569         }
   4570 
   4571         return readPerm && writePerm;
   4572     }
   4573 
   4574     private final boolean checkUriPermissionLocked(Uri uri, int uid,
   4575             int modeFlags) {
   4576         // Root gets to do everything.
   4577         if (uid == 0) {
   4578             return true;
   4579         }
   4580         HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   4581         if (perms == null) return false;
   4582         UriPermission perm = perms.get(uri);
   4583         if (perm == null) return false;
   4584         return (modeFlags&perm.modeFlags) == modeFlags;
   4585     }
   4586 
   4587     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
   4588         // Another redirected-binder-call permissions check as in
   4589         // {@link checkComponentPermission}.
   4590         Identity tlsIdentity = sCallerIdentity.get();
   4591         if (tlsIdentity != null) {
   4592             uid = tlsIdentity.uid;
   4593             pid = tlsIdentity.pid;
   4594         }
   4595 
   4596         // Our own process gets to do everything.
   4597         if (pid == MY_PID) {
   4598             return PackageManager.PERMISSION_GRANTED;
   4599         }
   4600         synchronized(this) {
   4601             return checkUriPermissionLocked(uri, uid, modeFlags)
   4602                     ? PackageManager.PERMISSION_GRANTED
   4603                     : PackageManager.PERMISSION_DENIED;
   4604         }
   4605     }
   4606 
   4607     /**
   4608      * Check if the targetPkg can be granted permission to access uri by
   4609      * the callingUid using the given modeFlags.  Throws a security exception
   4610      * if callingUid is not allowed to do this.  Returns the uid of the target
   4611      * if the URI permission grant should be performed; returns -1 if it is not
   4612      * needed (for example targetPkg already has permission to access the URI).
   4613      */
   4614     int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
   4615             Uri uri, int modeFlags) {
   4616         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   4617                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   4618         if (modeFlags == 0) {
   4619             return -1;
   4620         }
   4621 
   4622         if (targetPkg != null) {
   4623             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4624                     "Checking grant " + targetPkg + " permission to " + uri);
   4625         }
   4626 
   4627         final IPackageManager pm = AppGlobals.getPackageManager();
   4628 
   4629         // If this is not a content: uri, we can't do anything with it.
   4630         if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
   4631             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4632                     "Can't grant URI permission for non-content URI: " + uri);
   4633             return -1;
   4634         }
   4635 
   4636         String name = uri.getAuthority();
   4637         ProviderInfo pi = null;
   4638         ContentProviderRecord cpr = mProvidersByName.get(name);
   4639         if (cpr != null) {
   4640             pi = cpr.info;
   4641         } else {
   4642             try {
   4643                 pi = pm.resolveContentProvider(name,
   4644                         PackageManager.GET_URI_PERMISSION_PATTERNS);
   4645             } catch (RemoteException ex) {
   4646             }
   4647         }
   4648         if (pi == null) {
   4649             Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
   4650             return -1;
   4651         }
   4652 
   4653         int targetUid;
   4654         if (targetPkg != null) {
   4655             try {
   4656                 targetUid = pm.getPackageUid(targetPkg);
   4657                 if (targetUid < 0) {
   4658                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4659                             "Can't grant URI permission no uid for: " + targetPkg);
   4660                     return -1;
   4661                 }
   4662             } catch (RemoteException ex) {
   4663                 return -1;
   4664             }
   4665         } else {
   4666             targetUid = -1;
   4667         }
   4668 
   4669         if (targetUid >= 0) {
   4670             // First...  does the target actually need this permission?
   4671             if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
   4672                 // No need to grant the target this permission.
   4673                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4674                         "Target " + targetPkg + " already has full permission to " + uri);
   4675                 return -1;
   4676             }
   4677         } else {
   4678             // First...  there is no target package, so can anyone access it?
   4679             boolean allowed = pi.exported;
   4680             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   4681                 if (pi.readPermission != null) {
   4682                     allowed = false;
   4683                 }
   4684             }
   4685             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   4686                 if (pi.writePermission != null) {
   4687                     allowed = false;
   4688                 }
   4689             }
   4690             if (allowed) {
   4691                 return -1;
   4692             }
   4693         }
   4694 
   4695         // Second...  is the provider allowing granting of URI permissions?
   4696         if (!pi.grantUriPermissions) {
   4697             throw new SecurityException("Provider " + pi.packageName
   4698                     + "/" + pi.name
   4699                     + " does not allow granting of Uri permissions (uri "
   4700                     + uri + ")");
   4701         }
   4702         if (pi.uriPermissionPatterns != null) {
   4703             final int N = pi.uriPermissionPatterns.length;
   4704             boolean allowed = false;
   4705             for (int i=0; i<N; i++) {
   4706                 if (pi.uriPermissionPatterns[i] != null
   4707                         && pi.uriPermissionPatterns[i].match(uri.getPath())) {
   4708                     allowed = true;
   4709                     break;
   4710                 }
   4711             }
   4712             if (!allowed) {
   4713                 throw new SecurityException("Provider " + pi.packageName
   4714                         + "/" + pi.name
   4715                         + " does not allow granting of permission to path of Uri "
   4716                         + uri);
   4717             }
   4718         }
   4719 
   4720         // Third...  does the caller itself have permission to access
   4721         // this uri?
   4722         if (callingUid != Process.myUid()) {
   4723             if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
   4724                 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
   4725                     throw new SecurityException("Uid " + callingUid
   4726                             + " does not have permission to uri " + uri);
   4727                 }
   4728             }
   4729         }
   4730 
   4731         return targetUid;
   4732     }
   4733 
   4734     public int checkGrantUriPermission(int callingUid, String targetPkg,
   4735             Uri uri, int modeFlags) {
   4736         synchronized(this) {
   4737             return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
   4738         }
   4739     }
   4740 
   4741     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
   4742             Uri uri, int modeFlags, UriPermissionOwner owner) {
   4743         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   4744                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   4745         if (modeFlags == 0) {
   4746             return;
   4747         }
   4748 
   4749         // So here we are: the caller has the assumed permission
   4750         // to the uri, and the target doesn't.  Let's now give this to
   4751         // the target.
   4752 
   4753         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4754                 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
   4755 
   4756         HashMap<Uri, UriPermission> targetUris
   4757                 = mGrantedUriPermissions.get(targetUid);
   4758         if (targetUris == null) {
   4759             targetUris = new HashMap<Uri, UriPermission>();
   4760             mGrantedUriPermissions.put(targetUid, targetUris);
   4761         }
   4762 
   4763         UriPermission perm = targetUris.get(uri);
   4764         if (perm == null) {
   4765             perm = new UriPermission(targetUid, uri);
   4766             targetUris.put(uri, perm);
   4767         }
   4768 
   4769         perm.modeFlags |= modeFlags;
   4770         if (owner == null) {
   4771             perm.globalModeFlags |= modeFlags;
   4772         } else {
   4773             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   4774                  perm.readOwners.add(owner);
   4775                  owner.addReadPermission(perm);
   4776             }
   4777             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   4778                  perm.writeOwners.add(owner);
   4779                  owner.addWritePermission(perm);
   4780             }
   4781         }
   4782     }
   4783 
   4784     void grantUriPermissionLocked(int callingUid,
   4785             String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
   4786         if (targetPkg == null) {
   4787             throw new NullPointerException("targetPkg");
   4788         }
   4789 
   4790         int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
   4791         if (targetUid < 0) {
   4792             return;
   4793         }
   4794 
   4795         grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
   4796     }
   4797 
   4798     /**
   4799      * Like checkGrantUriPermissionLocked, but takes an Intent.
   4800      */
   4801     int checkGrantUriPermissionFromIntentLocked(int callingUid,
   4802             String targetPkg, Intent intent) {
   4803         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4804                 "Checking URI perm to " + (intent != null ? intent.getData() : null)
   4805                 + " from " + intent + "; flags=0x"
   4806                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
   4807 
   4808         if (targetPkg == null) {
   4809             throw new NullPointerException("targetPkg");
   4810         }
   4811 
   4812         if (intent == null) {
   4813             return -1;
   4814         }
   4815         Uri data = intent.getData();
   4816         if (data == null) {
   4817             return -1;
   4818         }
   4819         return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
   4820                 intent.getFlags());
   4821     }
   4822 
   4823     /**
   4824      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
   4825      */
   4826     void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
   4827             String targetPkg, Intent intent, UriPermissionOwner owner) {
   4828         grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
   4829                 intent.getFlags(), owner);
   4830     }
   4831 
   4832     void grantUriPermissionFromIntentLocked(int callingUid,
   4833             String targetPkg, Intent intent, UriPermissionOwner owner) {
   4834         int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
   4835         if (targetUid < 0) {
   4836             return;
   4837         }
   4838 
   4839         grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
   4840     }
   4841 
   4842     public void grantUriPermission(IApplicationThread caller, String targetPkg,
   4843             Uri uri, int modeFlags) {
   4844         synchronized(this) {
   4845             final ProcessRecord r = getRecordForAppLocked(caller);
   4846             if (r == null) {
   4847                 throw new SecurityException("Unable to find app for caller "
   4848                         + caller
   4849                         + " when granting permission to uri " + uri);
   4850             }
   4851             if (targetPkg == null) {
   4852                 throw new IllegalArgumentException("null target");
   4853             }
   4854             if (uri == null) {
   4855                 throw new IllegalArgumentException("null uri");
   4856             }
   4857 
   4858             grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
   4859                     null);
   4860         }
   4861     }
   4862 
   4863     void removeUriPermissionIfNeededLocked(UriPermission perm) {
   4864         if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
   4865                 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
   4866             HashMap<Uri, UriPermission> perms
   4867                     = mGrantedUriPermissions.get(perm.uid);
   4868             if (perms != null) {
   4869                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4870                         "Removing " + perm.uid + " permission to " + perm.uri);
   4871                 perms.remove(perm.uri);
   4872                 if (perms.size() == 0) {
   4873                     mGrantedUriPermissions.remove(perm.uid);
   4874                 }
   4875             }
   4876         }
   4877     }
   4878 
   4879     private void revokeUriPermissionLocked(int callingUid, Uri uri,
   4880             int modeFlags) {
   4881         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   4882                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   4883         if (modeFlags == 0) {
   4884             return;
   4885         }
   4886 
   4887         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4888                 "Revoking all granted permissions to " + uri);
   4889 
   4890         final IPackageManager pm = AppGlobals.getPackageManager();
   4891 
   4892         final String authority = uri.getAuthority();
   4893         ProviderInfo pi = null;
   4894         ContentProviderRecord cpr = mProvidersByName.get(authority);
   4895         if (cpr != null) {
   4896             pi = cpr.info;
   4897         } else {
   4898             try {
   4899                 pi = pm.resolveContentProvider(authority,
   4900                         PackageManager.GET_URI_PERMISSION_PATTERNS);
   4901             } catch (RemoteException ex) {
   4902             }
   4903         }
   4904         if (pi == null) {
   4905             Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
   4906             return;
   4907         }
   4908 
   4909         // Does the caller have this permission on the URI?
   4910         if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
   4911             // Right now, if you are not the original owner of the permission,
   4912             // you are not allowed to revoke it.
   4913             //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
   4914                 throw new SecurityException("Uid " + callingUid
   4915                         + " does not have permission to uri " + uri);
   4916             //}
   4917         }
   4918 
   4919         // Go through all of the permissions and remove any that match.
   4920         final List<String> SEGMENTS = uri.getPathSegments();
   4921         if (SEGMENTS != null) {
   4922             final int NS = SEGMENTS.size();
   4923             int N = mGrantedUriPermissions.size();
   4924             for (int i=0; i<N; i++) {
   4925                 HashMap<Uri, UriPermission> perms
   4926                         = mGrantedUriPermissions.valueAt(i);
   4927                 Iterator<UriPermission> it = perms.values().iterator();
   4928             toploop:
   4929                 while (it.hasNext()) {
   4930                     UriPermission perm = it.next();
   4931                     Uri targetUri = perm.uri;
   4932                     if (!authority.equals(targetUri.getAuthority())) {
   4933                         continue;
   4934                     }
   4935                     List<String> targetSegments = targetUri.getPathSegments();
   4936                     if (targetSegments == null) {
   4937                         continue;
   4938                     }
   4939                     if (targetSegments.size() < NS) {
   4940                         continue;
   4941                     }
   4942                     for (int j=0; j<NS; j++) {
   4943                         if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
   4944                             continue toploop;
   4945                         }
   4946                     }
   4947                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4948                             "Revoking " + perm.uid + " permission to " + perm.uri);
   4949                     perm.clearModes(modeFlags);
   4950                     if (perm.modeFlags == 0) {
   4951                         it.remove();
   4952                     }
   4953                 }
   4954                 if (perms.size() == 0) {
   4955                     mGrantedUriPermissions.remove(
   4956                             mGrantedUriPermissions.keyAt(i));
   4957                     N--;
   4958                     i--;
   4959                 }
   4960             }
   4961         }
   4962     }
   4963 
   4964     public void revokeUriPermission(IApplicationThread caller, Uri uri,
   4965             int modeFlags) {
   4966         synchronized(this) {
   4967             final ProcessRecord r = getRecordForAppLocked(caller);
   4968             if (r == null) {
   4969                 throw new SecurityException("Unable to find app for caller "
   4970                         + caller
   4971                         + " when revoking permission to uri " + uri);
   4972             }
   4973             if (uri == null) {
   4974                 Slog.w(TAG, "revokeUriPermission: null uri");
   4975                 return;
   4976             }
   4977 
   4978             modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   4979                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   4980             if (modeFlags == 0) {
   4981                 return;
   4982             }
   4983 
   4984             final IPackageManager pm = AppGlobals.getPackageManager();
   4985 
   4986             final String authority = uri.getAuthority();
   4987             ProviderInfo pi = null;
   4988             ContentProviderRecord cpr = mProvidersByName.get(authority);
   4989             if (cpr != null) {
   4990                 pi = cpr.info;
   4991             } else {
   4992                 try {
   4993                     pi = pm.resolveContentProvider(authority,
   4994                             PackageManager.GET_URI_PERMISSION_PATTERNS);
   4995                 } catch (RemoteException ex) {
   4996                 }
   4997             }
   4998             if (pi == null) {
   4999                 Slog.w(TAG, "No content provider found for permission revoke: "
   5000                         + uri.toSafeString());
   5001                 return;
   5002             }
   5003 
   5004             revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
   5005         }
   5006     }
   5007 
   5008     @Override
   5009     public IBinder newUriPermissionOwner(String name) {
   5010         synchronized(this) {
   5011             UriPermissionOwner owner = new UriPermissionOwner(this, name);
   5012             return owner.getExternalTokenLocked();
   5013         }
   5014     }
   5015 
   5016     @Override
   5017     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
   5018             Uri uri, int modeFlags) {
   5019         synchronized(this) {
   5020             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   5021             if (owner == null) {
   5022                 throw new IllegalArgumentException("Unknown owner: " + token);
   5023             }
   5024             if (fromUid != Binder.getCallingUid()) {
   5025                 if (Binder.getCallingUid() != Process.myUid()) {
   5026                     // Only system code can grant URI permissions on behalf
   5027                     // of other users.
   5028                     throw new SecurityException("nice try");
   5029                 }
   5030             }
   5031             if (targetPkg == null) {
   5032                 throw new IllegalArgumentException("null target");
   5033             }
   5034             if (uri == null) {
   5035                 throw new IllegalArgumentException("null uri");
   5036             }
   5037 
   5038             grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
   5039         }
   5040     }
   5041 
   5042     @Override
   5043     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
   5044         synchronized(this) {
   5045             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   5046             if (owner == null) {
   5047                 throw new IllegalArgumentException("Unknown owner: " + token);
   5048             }
   5049 
   5050             if (uri == null) {
   5051                 owner.removeUriPermissionsLocked(mode);
   5052             } else {
   5053                 owner.removeUriPermissionLocked(uri, mode);
   5054             }
   5055         }
   5056     }
   5057 
   5058     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
   5059         synchronized (this) {
   5060             ProcessRecord app =
   5061                 who != null ? getRecordForAppLocked(who) : null;
   5062             if (app == null) return;
   5063 
   5064             Message msg = Message.obtain();
   5065             msg.what = WAIT_FOR_DEBUGGER_MSG;
   5066             msg.obj = app;
   5067             msg.arg1 = waiting ? 1 : 0;
   5068             mHandler.sendMessage(msg);
   5069         }
   5070     }
   5071 
   5072     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
   5073         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
   5074         final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
   5075         outInfo.availMem = Process.getFreeMemory();
   5076         outInfo.threshold = homeAppMem;
   5077         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
   5078         outInfo.hiddenAppThreshold = hiddenAppMem;
   5079         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
   5080                 ProcessList.SERVICE_ADJ);
   5081         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
   5082                 ProcessList.VISIBLE_APP_ADJ);
   5083         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
   5084                 ProcessList.FOREGROUND_APP_ADJ);
   5085     }
   5086 
   5087     // =========================================================
   5088     // TASK MANAGEMENT
   5089     // =========================================================
   5090 
   5091     public List getTasks(int maxNum, int flags,
   5092                          IThumbnailReceiver receiver) {
   5093         ArrayList list = new ArrayList();
   5094 
   5095         PendingThumbnailsRecord pending = null;
   5096         IApplicationThread topThumbnail = null;
   5097         ActivityRecord topRecord = null;
   5098 
   5099         synchronized(this) {
   5100             if (localLOGV) Slog.v(
   5101                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
   5102                 + ", receiver=" + receiver);
   5103 
   5104             if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
   5105                     != PackageManager.PERMISSION_GRANTED) {
   5106                 if (receiver != null) {
   5107                     // If the caller wants to wait for pending thumbnails,
   5108                     // it ain't gonna get them.
   5109                     try {
   5110                         receiver.finished();
   5111                     } catch (RemoteException ex) {
   5112                     }
   5113                 }
   5114                 String msg = "Permission Denial: getTasks() from pid="
   5115                         + Binder.getCallingPid()
   5116                         + ", uid=" + Binder.getCallingUid()
   5117                         + " requires " + android.Manifest.permission.GET_TASKS;
   5118                 Slog.w(TAG, msg);
   5119                 throw new SecurityException(msg);
   5120             }
   5121 
   5122             int pos = mMainStack.mHistory.size()-1;
   5123             ActivityRecord next =
   5124                 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
   5125             ActivityRecord top = null;
   5126             TaskRecord curTask = null;
   5127             int numActivities = 0;
   5128             int numRunning = 0;
   5129             while (pos >= 0 && maxNum > 0) {
   5130                 final ActivityRecord r = next;
   5131                 pos--;
   5132                 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
   5133 
   5134                 // Initialize state for next task if needed.
   5135                 if (top == null ||
   5136                         (top.state == ActivityState.INITIALIZING
   5137                             && top.task == r.task)) {
   5138                     top = r;
   5139                     curTask = r.task;
   5140                     numActivities = numRunning = 0;
   5141                 }
   5142 
   5143                 // Add 'r' into the current task.
   5144                 numActivities++;
   5145                 if (r.app != null && r.app.thread != null) {
   5146                     numRunning++;
   5147                 }
   5148 
   5149                 if (localLOGV) Slog.v(
   5150                     TAG, r.intent.getComponent().flattenToShortString()
   5151                     + ": task=" + r.task);
   5152 
   5153                 // If the next one is a different task, generate a new
   5154                 // TaskInfo entry for what we have.
   5155                 if (next == null || next.task != curTask) {
   5156                     ActivityManager.RunningTaskInfo ci
   5157                             = new ActivityManager.RunningTaskInfo();
   5158                     ci.id = curTask.taskId;
   5159                     ci.baseActivity = r.intent.getComponent();
   5160                     ci.topActivity = top.intent.getComponent();
   5161                     if (top.thumbHolder != null) {
   5162                         ci.description = top.thumbHolder.lastDescription;
   5163                     }
   5164                     ci.numActivities = numActivities;
   5165                     ci.numRunning = numRunning;
   5166                     //System.out.println(
   5167                     //    "#" + maxNum + ": " + " descr=" + ci.description);
   5168                     if (ci.thumbnail == null && receiver != null) {
   5169                         if (localLOGV) Slog.v(
   5170                             TAG, "State=" + top.state + "Idle=" + top.idle
   5171                             + " app=" + top.app
   5172                             + " thr=" + (top.app != null ? top.app.thread : null));
   5173                         if (top.state == ActivityState.RESUMED
   5174                                 || top.state == ActivityState.PAUSING) {
   5175                             if (top.idle && top.app != null
   5176                                 && top.app.thread != null) {
   5177                                 topRecord = top;
   5178                                 topThumbnail = top.app.thread;
   5179                             } else {
   5180                                 top.thumbnailNeeded = true;
   5181                             }
   5182                         }
   5183                         if (pending == null) {
   5184                             pending = new PendingThumbnailsRecord(receiver);
   5185                         }
   5186                         pending.pendingRecords.add(top);
   5187                     }
   5188                     list.add(ci);
   5189                     maxNum--;
   5190                     top = null;
   5191                 }
   5192             }
   5193 
   5194             if (pending != null) {
   5195                 mPendingThumbnails.add(pending);
   5196             }
   5197         }
   5198 
   5199         if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
   5200 
   5201         if (topThumbnail != null) {
   5202             if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
   5203             try {
   5204                 topThumbnail.requestThumbnail(topRecord.appToken);
   5205             } catch (Exception e) {
   5206                 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
   5207                 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
   5208             }
   5209         }
   5210 
   5211         if (pending == null && receiver != null) {
   5212             // In this case all thumbnails were available and the client
   5213             // is being asked to be told when the remaining ones come in...
   5214             // which is unusually, since the top-most currently running
   5215             // activity should never have a canned thumbnail!  Oh well.
   5216             try {
   5217                 receiver.finished();
   5218             } catch (RemoteException ex) {
   5219             }
   5220         }
   5221 
   5222         return list;
   5223     }
   5224 
   5225     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
   5226             int flags) {
   5227         synchronized (this) {
   5228             enforceCallingPermission(android.Manifest.permission.GET_TASKS,
   5229                     "getRecentTasks()");
   5230 
   5231             IPackageManager pm = AppGlobals.getPackageManager();
   5232 
   5233             final int N = mRecentTasks.size();
   5234             ArrayList<ActivityManager.RecentTaskInfo> res
   5235                     = new ArrayList<ActivityManager.RecentTaskInfo>(
   5236                             maxNum < N ? maxNum : N);
   5237             for (int i=0; i<N && maxNum > 0; i++) {
   5238                 TaskRecord tr = mRecentTasks.get(i);
   5239                 // Return the entry if desired by the caller.  We always return
   5240                 // the first entry, because callers always expect this to be the
   5241                 // forground app.  We may filter others if the caller has
   5242                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
   5243                 // we should exclude the entry.
   5244                 if (i == 0
   5245                         || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
   5246                         || (tr.intent == null)
   5247                         || ((tr.intent.getFlags()
   5248                                 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
   5249                     ActivityManager.RecentTaskInfo rti
   5250                             = new ActivityManager.RecentTaskInfo();
   5251                     rti.id = tr.numActivities > 0 ? tr.taskId : -1;
   5252                     rti.persistentId = tr.taskId;
   5253                     rti.baseIntent = new Intent(
   5254                             tr.intent != null ? tr.intent : tr.affinityIntent);
   5255                     rti.origActivity = tr.origActivity;
   5256                     rti.description = tr.lastDescription;
   5257 
   5258                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
   5259                         // Check whether this activity is currently available.
   5260                         try {
   5261                             if (rti.origActivity != null) {
   5262                                 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
   5263                                     continue;
   5264                                 }
   5265                             } else if (rti.baseIntent != null) {
   5266                                 if (pm.queryIntentActivities(rti.baseIntent,
   5267                                         null, 0) == null) {
   5268                                     continue;
   5269                                 }
   5270                             }
   5271                         } catch (RemoteException e) {
   5272                             // Will never happen.
   5273                         }
   5274                     }
   5275 
   5276                     res.add(rti);
   5277                     maxNum--;
   5278                 }
   5279             }
   5280             return res;
   5281         }
   5282     }
   5283 
   5284     private TaskRecord taskForIdLocked(int id) {
   5285         final int N = mRecentTasks.size();
   5286         for (int i=0; i<N; i++) {
   5287             TaskRecord tr = mRecentTasks.get(i);
   5288             if (tr.taskId == id) {
   5289                 return tr;
   5290             }
   5291         }
   5292         return null;
   5293     }
   5294 
   5295     public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
   5296         synchronized (this) {
   5297             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
   5298                     "getTaskThumbnails()");
   5299             TaskRecord tr = taskForIdLocked(id);
   5300             if (tr != null) {
   5301                 return mMainStack.getTaskThumbnailsLocked(tr);
   5302             }
   5303         }
   5304         return null;
   5305     }
   5306 
   5307     public boolean removeSubTask(int taskId, int subTaskIndex) {
   5308         synchronized (this) {
   5309             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
   5310                     "removeSubTask()");
   5311             long ident = Binder.clearCallingIdentity();
   5312             try {
   5313                 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
   5314             } finally {
   5315                 Binder.restoreCallingIdentity(ident);
   5316             }
   5317         }
   5318     }
   5319 
   5320     private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
   5321         TaskRecord tr = root.task;
   5322         Intent baseIntent = new Intent(
   5323                 tr.intent != null ? tr.intent : tr.affinityIntent);
   5324         ComponentName component = baseIntent.getComponent();
   5325         if (component == null) {
   5326             Slog.w(TAG, "Now component for base intent of task: " + tr);
   5327             return;
   5328         }
   5329 
   5330         // Find any running services associated with this app.
   5331         ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
   5332         for (ServiceRecord sr : mServices.values()) {
   5333             if (sr.packageName.equals(component.getPackageName())) {
   5334                 services.add(sr);
   5335             }
   5336         }
   5337 
   5338         // Take care of any running services associated with the app.
   5339         for (int i=0; i<services.size(); i++) {
   5340             ServiceRecord sr = services.get(i);
   5341             if (sr.startRequested) {
   5342                 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
   5343                     Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
   5344                     stopServiceLocked(sr);
   5345                 } else {
   5346                     sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
   5347                             sr.makeNextStartId(), baseIntent, -1));
   5348                     if (sr.app != null && sr.app.thread != null) {
   5349                         sendServiceArgsLocked(sr, false);
   5350                     }
   5351                 }
   5352             }
   5353         }
   5354 
   5355         if (killProcesses) {
   5356             // Find any running processes associated with this app.
   5357             ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   5358             SparseArray<ProcessRecord> appProcs
   5359                     = mProcessNames.getMap().get(component.getPackageName());
   5360             if (appProcs != null) {
   5361                 for (int i=0; i<appProcs.size(); i++) {
   5362                     procs.add(appProcs.valueAt(i));
   5363                 }
   5364             }
   5365 
   5366             // Kill the running processes.
   5367             for (int i=0; i<procs.size(); i++) {
   5368                 ProcessRecord pr = procs.get(i);
   5369                 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
   5370                     Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
   5371                     EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
   5372                             pr.processName, pr.setAdj, "remove task");
   5373                     Process.killProcessQuiet(pr.pid);
   5374                 } else {
   5375                     pr.waitingToKill = "remove task";
   5376                 }
   5377             }
   5378         }
   5379     }
   5380 
   5381     public boolean removeTask(int taskId, int flags) {
   5382         synchronized (this) {
   5383             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
   5384                     "removeTask()");
   5385             long ident = Binder.clearCallingIdentity();
   5386             try {
   5387                 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
   5388                 if (r != null) {
   5389                     mRecentTasks.remove(r.task);
   5390                     cleanUpRemovedTaskLocked(r,
   5391                             (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
   5392                     return true;
   5393                 } else {
   5394                     TaskRecord tr = null;
   5395                     int i=0;
   5396                     while (i < mRecentTasks.size()) {
   5397                         TaskRecord t = mRecentTasks.get(i);
   5398                         if (t.taskId == taskId) {
   5399                             tr = t;
   5400                             break;
   5401                         }
   5402                         i++;
   5403                     }
   5404                     if (tr != null) {
   5405                         if (tr.numActivities <= 0) {
   5406                             // Caller is just removing a recent task that is
   5407                             // not actively running.  That is easy!
   5408                             mRecentTasks.remove(i);
   5409                         } else {
   5410                             Slog.w(TAG, "removeTask: task " + taskId
   5411                                     + " does not have activities to remove, "
   5412                                     + " but numActivities=" + tr.numActivities
   5413                                     + ": " + tr);
   5414                         }
   5415                     }
   5416                 }
   5417             } finally {
   5418                 Binder.restoreCallingIdentity(ident);
   5419             }
   5420         }
   5421         return false;
   5422     }
   5423 
   5424     private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
   5425         int j;
   5426         TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
   5427         TaskRecord jt = startTask;
   5428 
   5429         // First look backwards
   5430         for (j=startIndex-1; j>=0; j--) {
   5431             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
   5432             if (r.task != jt) {
   5433                 jt = r.task;
   5434                 if (affinity.equals(jt.affinity)) {
   5435                     return j;
   5436                 }
   5437             }
   5438         }
   5439 
   5440         // Now look forwards
   5441         final int N = mMainStack.mHistory.size();
   5442         jt = startTask;
   5443         for (j=startIndex+1; j<N; j++) {
   5444             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
   5445             if (r.task != jt) {
   5446                 if (affinity.equals(jt.affinity)) {
   5447                     return j;
   5448                 }
   5449                 jt = r.task;
   5450             }
   5451         }
   5452 
   5453         // Might it be at the top?
   5454         if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
   5455             return N-1;
   5456         }
   5457 
   5458         return -1;
   5459     }
   5460 
   5461     /**
   5462      * TODO: Add mController hook
   5463      */
   5464     public void moveTaskToFront(int task, int flags) {
   5465         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   5466                 "moveTaskToFront()");
   5467 
   5468         synchronized(this) {
   5469             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   5470                     Binder.getCallingUid(), "Task to front")) {
   5471                 return;
   5472             }
   5473             final long origId = Binder.clearCallingIdentity();
   5474             try {
   5475                 TaskRecord tr = taskForIdLocked(task);
   5476                 if (tr != null) {
   5477                     if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
   5478                         mMainStack.mUserLeaving = true;
   5479                     }
   5480                     if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
   5481                         // Caller wants the home activity moved with it.  To accomplish this,
   5482                         // we'll just move the home task to the top first.
   5483                         mMainStack.moveHomeToFrontLocked();
   5484                     }
   5485                     mMainStack.moveTaskToFrontLocked(tr, null);
   5486                     return;
   5487                 }
   5488                 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
   5489                     ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
   5490                     if (hr.task.taskId == task) {
   5491                         if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
   5492                             mMainStack.mUserLeaving = true;
   5493                         }
   5494                         if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
   5495                             // Caller wants the home activity moved with it.  To accomplish this,
   5496                             // we'll just move the home task to the top first.
   5497                             mMainStack.moveHomeToFrontLocked();
   5498                         }
   5499                         mMainStack.moveTaskToFrontLocked(hr.task, null);
   5500                         return;
   5501                     }
   5502                 }
   5503             } finally {
   5504                 Binder.restoreCallingIdentity(origId);
   5505             }
   5506         }
   5507     }
   5508 
   5509     public void moveTaskToBack(int task) {
   5510         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   5511                 "moveTaskToBack()");
   5512 
   5513         synchronized(this) {
   5514             if (mMainStack.mResumedActivity != null
   5515                     && mMainStack.mResumedActivity.task.taskId == task) {
   5516                 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   5517                         Binder.getCallingUid(), "Task to back")) {
   5518                     return;
   5519                 }
   5520             }
   5521             final long origId = Binder.clearCallingIdentity();
   5522             mMainStack.moveTaskToBackLocked(task, null);
   5523             Binder.restoreCallingIdentity(origId);
   5524         }
   5525     }
   5526 
   5527     /**
   5528      * Moves an activity, and all of the other activities within the same task, to the bottom
   5529      * of the history stack.  The activity's order within the task is unchanged.
   5530      *
   5531      * @param token A reference to the activity we wish to move
   5532      * @param nonRoot If false then this only works if the activity is the root
   5533      *                of a task; if true it will work for any activity in a task.
   5534      * @return Returns true if the move completed, false if not.
   5535      */
   5536     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
   5537         synchronized(this) {
   5538             final long origId = Binder.clearCallingIdentity();
   5539             int taskId = getTaskForActivityLocked(token, !nonRoot);
   5540             if (taskId >= 0) {
   5541                 return mMainStack.moveTaskToBackLocked(taskId, null);
   5542             }
   5543             Binder.restoreCallingIdentity(origId);
   5544         }
   5545         return false;
   5546     }
   5547 
   5548     public void moveTaskBackwards(int task) {
   5549         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   5550                 "moveTaskBackwards()");
   5551 
   5552         synchronized(this) {
   5553             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   5554                     Binder.getCallingUid(), "Task backwards")) {
   5555                 return;
   5556             }
   5557             final long origId = Binder.clearCallingIdentity();
   5558             moveTaskBackwardsLocked(task);
   5559             Binder.restoreCallingIdentity(origId);
   5560         }
   5561     }
   5562 
   5563     private final void moveTaskBackwardsLocked(int task) {
   5564         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
   5565     }
   5566 
   5567     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
   5568         synchronized(this) {
   5569             return getTaskForActivityLocked(token, onlyRoot);
   5570         }
   5571     }
   5572 
   5573     int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
   5574         final int N = mMainStack.mHistory.size();
   5575         TaskRecord lastTask = null;
   5576         for (int i=0; i<N; i++) {
   5577             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   5578             if (r.appToken == token) {
   5579                 if (!onlyRoot || lastTask != r.task) {
   5580                     return r.task.taskId;
   5581                 }
   5582                 return -1;
   5583             }
   5584             lastTask = r.task;
   5585         }
   5586 
   5587         return -1;
   5588     }
   5589 
   5590     public void finishOtherInstances(IBinder token, ComponentName className) {
   5591         synchronized(this) {
   5592             final long origId = Binder.clearCallingIdentity();
   5593 
   5594             int N = mMainStack.mHistory.size();
   5595             TaskRecord lastTask = null;
   5596             for (int i=0; i<N; i++) {
   5597                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   5598                 if (r.realActivity.equals(className)
   5599                         && r.appToken != token && lastTask != r.task) {
   5600                     if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
   5601                             null, "others")) {
   5602                         i--;
   5603                         N--;
   5604                     }
   5605                 }
   5606                 lastTask = r.task;
   5607             }
   5608 
   5609             Binder.restoreCallingIdentity(origId);
   5610         }
   5611     }
   5612 
   5613     // =========================================================
   5614     // THUMBNAILS
   5615     // =========================================================
   5616 
   5617     public void reportThumbnail(IBinder token,
   5618             Bitmap thumbnail, CharSequence description) {
   5619         //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
   5620         final long origId = Binder.clearCallingIdentity();
   5621         sendPendingThumbnail(null, token, thumbnail, description, true);
   5622         Binder.restoreCallingIdentity(origId);
   5623     }
   5624 
   5625     final void sendPendingThumbnail(ActivityRecord r, IBinder token,
   5626             Bitmap thumbnail, CharSequence description, boolean always) {
   5627         TaskRecord task = null;
   5628         ArrayList receivers = null;
   5629 
   5630         //System.out.println("Send pending thumbnail: " + r);
   5631 
   5632         synchronized(this) {
   5633             if (r == null) {
   5634                 r = mMainStack.isInStackLocked(token);
   5635                 if (r == null) {
   5636                     return;
   5637                 }
   5638             }
   5639             if (thumbnail == null && r.thumbHolder != null) {
   5640                 thumbnail = r.thumbHolder.lastThumbnail;
   5641                 description = r.thumbHolder.lastDescription;
   5642             }
   5643             if (thumbnail == null && !always) {
   5644                 // If there is no thumbnail, and this entry is not actually
   5645                 // going away, then abort for now and pick up the next
   5646                 // thumbnail we get.
   5647                 return;
   5648             }
   5649             task = r.task;
   5650 
   5651             int N = mPendingThumbnails.size();
   5652             int i=0;
   5653             while (i<N) {
   5654                 PendingThumbnailsRecord pr =
   5655                     (PendingThumbnailsRecord)mPendingThumbnails.get(i);
   5656                 //System.out.println("Looking in " + pr.pendingRecords);
   5657                 if (pr.pendingRecords.remove(r)) {
   5658                     if (receivers == null) {
   5659                         receivers = new ArrayList();
   5660                     }
   5661                     receivers.add(pr);
   5662                     if (pr.pendingRecords.size() == 0) {
   5663                         pr.finished = true;
   5664                         mPendingThumbnails.remove(i);
   5665                         N--;
   5666                         continue;
   5667                     }
   5668                 }
   5669                 i++;
   5670             }
   5671         }
   5672 
   5673         if (receivers != null) {
   5674             final int N = receivers.size();
   5675             for (int i=0; i<N; i++) {
   5676                 try {
   5677                     PendingThumbnailsRecord pr =
   5678                         (PendingThumbnailsRecord)receivers.get(i);
   5679                     pr.receiver.newThumbnail(
   5680                         task != null ? task.taskId : -1, thumbnail, description);
   5681                     if (pr.finished) {
   5682                         pr.receiver.finished();
   5683                     }
   5684                 } catch (Exception e) {
   5685                     Slog.w(TAG, "Exception thrown when sending thumbnail", e);
   5686                 }
   5687             }
   5688         }
   5689     }
   5690 
   5691     // =========================================================
   5692     // CONTENT PROVIDERS
   5693     // =========================================================
   5694 
   5695     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
   5696         List<ProviderInfo> providers = null;
   5697         try {
   5698             providers = AppGlobals.getPackageManager().
   5699                 queryContentProviders(app.processName, app.info.uid,
   5700                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
   5701         } catch (RemoteException ex) {
   5702         }
   5703         if (providers != null) {
   5704             final int N = providers.size();
   5705             for (int i=0; i<N; i++) {
   5706                 ProviderInfo cpi =
   5707                     (ProviderInfo)providers.get(i);
   5708                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   5709                 ContentProviderRecord cpr = mProvidersByClass.get(comp);
   5710                 if (cpr == null) {
   5711                     cpr = new ContentProviderRecord(cpi, app.info, comp);
   5712                     mProvidersByClass.put(comp, cpr);
   5713                 }
   5714                 app.pubProviders.put(cpi.name, cpr);
   5715                 app.addPackage(cpi.applicationInfo.packageName);
   5716                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
   5717             }
   5718         }
   5719         return providers;
   5720     }
   5721 
   5722     private final String checkContentProviderPermissionLocked(
   5723             ProviderInfo cpi, ProcessRecord r) {
   5724         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
   5725         final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
   5726         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
   5727                 cpi.applicationInfo.uid, cpi.exported)
   5728                 == PackageManager.PERMISSION_GRANTED) {
   5729             return null;
   5730         }
   5731         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
   5732                 cpi.applicationInfo.uid, cpi.exported)
   5733                 == PackageManager.PERMISSION_GRANTED) {
   5734             return null;
   5735         }
   5736 
   5737         PathPermission[] pps = cpi.pathPermissions;
   5738         if (pps != null) {
   5739             int i = pps.length;
   5740             while (i > 0) {
   5741                 i--;
   5742                 PathPermission pp = pps[i];
   5743                 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
   5744                         cpi.applicationInfo.uid, cpi.exported)
   5745                         == PackageManager.PERMISSION_GRANTED) {
   5746                     return null;
   5747                 }
   5748                 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
   5749                         cpi.applicationInfo.uid, cpi.exported)
   5750                         == PackageManager.PERMISSION_GRANTED) {
   5751                     return null;
   5752                 }
   5753             }
   5754         }
   5755 
   5756         HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   5757         if (perms != null) {
   5758             for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
   5759                 if (uri.getKey().getAuthority().equals(cpi.authority)) {
   5760                     return null;
   5761                 }
   5762             }
   5763         }
   5764 
   5765         String msg;
   5766         if (!cpi.exported) {
   5767             msg = "Permission Denial: opening provider " + cpi.name
   5768                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   5769                     + ", uid=" + callingUid + ") that is not exported from uid "
   5770                     + cpi.applicationInfo.uid;
   5771         } else {
   5772             msg = "Permission Denial: opening provider " + cpi.name
   5773                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   5774                     + ", uid=" + callingUid + ") requires "
   5775                     + cpi.readPermission + " or " + cpi.writePermission;
   5776         }
   5777         Slog.w(TAG, msg);
   5778         return msg;
   5779     }
   5780 
   5781     boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
   5782         if (r != null) {
   5783             Integer cnt = r.conProviders.get(cpr);
   5784             if (DEBUG_PROVIDER) Slog.v(TAG,
   5785                     "Adding provider requested by "
   5786                     + r.processName + " from process "
   5787                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   5788                     + " cnt=" + (cnt == null ? 1 : cnt));
   5789             if (cnt == null) {
   5790                 cpr.clients.add(r);
   5791                 r.conProviders.put(cpr, new Integer(1));
   5792                 return true;
   5793             } else {
   5794                 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
   5795             }
   5796         } else {
   5797             cpr.externals++;
   5798         }
   5799         return false;
   5800     }
   5801 
   5802     boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
   5803         if (r != null) {
   5804             Integer cnt = r.conProviders.get(cpr);
   5805             if (DEBUG_PROVIDER) Slog.v(TAG,
   5806                     "Removing provider requested by "
   5807                     + r.processName + " from process "
   5808                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   5809                     + " cnt=" + cnt);
   5810             if (cnt == null || cnt.intValue() <= 1) {
   5811                 cpr.clients.remove(r);
   5812                 r.conProviders.remove(cpr);
   5813                 return true;
   5814             } else {
   5815                 r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
   5816             }
   5817         } else {
   5818             cpr.externals++;
   5819         }
   5820         return false;
   5821     }
   5822 
   5823     private final ContentProviderHolder getContentProviderImpl(
   5824         IApplicationThread caller, String name) {
   5825         ContentProviderRecord cpr;
   5826         ProviderInfo cpi = null;
   5827 
   5828         synchronized(this) {
   5829             ProcessRecord r = null;
   5830             if (caller != null) {
   5831                 r = getRecordForAppLocked(caller);
   5832                 if (r == null) {
   5833                     throw new SecurityException(
   5834                             "Unable to find app for caller " + caller
   5835                           + " (pid=" + Binder.getCallingPid()
   5836                           + ") when getting content provider " + name);
   5837                 }
   5838             }
   5839 
   5840             // First check if this content provider has been published...
   5841             cpr = mProvidersByName.get(name);
   5842             boolean providerRunning = cpr != null;
   5843             if (providerRunning) {
   5844                 cpi = cpr.info;
   5845                 String msg;
   5846                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
   5847                     throw new SecurityException(msg);
   5848                 }
   5849 
   5850                 if (r != null && cpr.canRunHere(r)) {
   5851                     // This provider has been published or is in the process
   5852                     // of being published...  but it is also allowed to run
   5853                     // in the caller's process, so don't make a connection
   5854                     // and just let the caller instantiate its own instance.
   5855                     if (cpr.provider != null) {
   5856                         // don't give caller the provider object, it needs
   5857                         // to make its own.
   5858                         cpr = new ContentProviderRecord(cpr);
   5859                     }
   5860                     return cpr;
   5861                 }
   5862 
   5863                 final long origId = Binder.clearCallingIdentity();
   5864 
   5865                 // In this case the provider instance already exists, so we can
   5866                 // return it right away.
   5867                 final boolean countChanged = incProviderCount(r, cpr);
   5868                 if (countChanged) {
   5869                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   5870                         // If this is a perceptible app accessing the provider,
   5871                         // make sure to count it as being accessed and thus
   5872                         // back up on the LRU list.  This is good because
   5873                         // content providers are often expensive to start.
   5874                         updateLruProcessLocked(cpr.proc, false, true);
   5875                     }
   5876                 }
   5877 
   5878                 if (cpr.proc != null) {
   5879                     if (false) {
   5880                         if (cpr.name.flattenToShortString().equals(
   5881                                 "com.android.providers.calendar/.CalendarProvider2")) {
   5882                             Slog.v(TAG, "****************** KILLING "
   5883                                 + cpr.name.flattenToShortString());
   5884                             Process.killProcess(cpr.proc.pid);
   5885                         }
   5886                     }
   5887                     boolean success = updateOomAdjLocked(cpr.proc);
   5888                     if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
   5889                     // NOTE: there is still a race here where a signal could be
   5890                     // pending on the process even though we managed to update its
   5891                     // adj level.  Not sure what to do about this, but at least
   5892                     // the race is now smaller.
   5893                     if (!success) {
   5894                         // Uh oh...  it looks like the provider's process
   5895                         // has been killed on us.  We need to wait for a new
   5896                         // process to be started, and make sure its death
   5897                         // doesn't kill our process.
   5898                         Slog.i(TAG,
   5899                                 "Existing provider " + cpr.name.flattenToShortString()
   5900                                 + " is crashing; detaching " + r);
   5901                         boolean lastRef = decProviderCount(r, cpr);
   5902                         appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
   5903                         if (!lastRef) {
   5904                             // This wasn't the last ref our process had on
   5905                             // the provider...  we have now been killed, bail.
   5906                             return null;
   5907                         }
   5908                         providerRunning = false;
   5909                     }
   5910                 }
   5911 
   5912                 Binder.restoreCallingIdentity(origId);
   5913             }
   5914 
   5915             if (!providerRunning) {
   5916                 try {
   5917                     cpi = AppGlobals.getPackageManager().
   5918                         resolveContentProvider(name,
   5919                                 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
   5920                 } catch (RemoteException ex) {
   5921                 }
   5922                 if (cpi == null) {
   5923                     return null;
   5924                 }
   5925 
   5926                 String msg;
   5927                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
   5928                     throw new SecurityException(msg);
   5929                 }
   5930 
   5931                 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
   5932                         && !cpi.processName.equals("system")) {
   5933                     // If this content provider does not run in the system
   5934                     // process, and the system is not yet ready to run other
   5935                     // processes, then fail fast instead of hanging.
   5936                     throw new IllegalArgumentException(
   5937                             "Attempt to launch content provider before system ready");
   5938                 }
   5939 
   5940                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   5941                 cpr = mProvidersByClass.get(comp);
   5942                 final boolean firstClass = cpr == null;
   5943                 if (firstClass) {
   5944                     try {
   5945                         ApplicationInfo ai =
   5946                             AppGlobals.getPackageManager().
   5947                                 getApplicationInfo(
   5948                                         cpi.applicationInfo.packageName,
   5949                                         STOCK_PM_FLAGS);
   5950                         if (ai == null) {
   5951                             Slog.w(TAG, "No package info for content provider "
   5952                                     + cpi.name);
   5953                             return null;
   5954                         }
   5955                         cpr = new ContentProviderRecord(cpi, ai, comp);
   5956                     } catch (RemoteException ex) {
   5957                         // pm is in same process, this will never happen.
   5958                     }
   5959                 }
   5960 
   5961                 if (r != null && cpr.canRunHere(r)) {
   5962                     // If this is a multiprocess provider, then just return its
   5963                     // info and allow the caller to instantiate it.  Only do
   5964                     // this if the provider is the same user as the caller's
   5965                     // process, or can run as root (so can be in any process).
   5966                     return cpr;
   5967                 }
   5968 
   5969                 if (DEBUG_PROVIDER) {
   5970                     RuntimeException e = new RuntimeException("here");
   5971                     Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
   5972                           + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
   5973                 }
   5974 
   5975                 // This is single process, and our app is now connecting to it.
   5976                 // See if we are already in the process of launching this
   5977                 // provider.
   5978                 final int N = mLaunchingProviders.size();
   5979                 int i;
   5980                 for (i=0; i<N; i++) {
   5981                     if (mLaunchingProviders.get(i) == cpr) {
   5982                         break;
   5983                     }
   5984                 }
   5985 
   5986                 // If the provider is not already being launched, then get it
   5987                 // started.
   5988                 if (i >= N) {
   5989                     final long origId = Binder.clearCallingIdentity();
   5990 
   5991                     try {
   5992                         // Content provider is now in use, its package can't be stopped.
   5993                         try {
   5994                             AppGlobals.getPackageManager().setPackageStoppedState(
   5995                                     cpr.appInfo.packageName, false);
   5996                         } catch (RemoteException e) {
   5997                         } catch (IllegalArgumentException e) {
   5998                             Slog.w(TAG, "Failed trying to unstop package "
   5999                                     + cpr.appInfo.packageName + ": " + e);
   6000                         }
   6001 
   6002                         ProcessRecord proc = startProcessLocked(cpi.processName,
   6003                                 cpr.appInfo, false, 0, "content provider",
   6004                                 new ComponentName(cpi.applicationInfo.packageName,
   6005                                         cpi.name), false);
   6006                         if (proc == null) {
   6007                             Slog.w(TAG, "Unable to launch app "
   6008                                     + cpi.applicationInfo.packageName + "/"
   6009                                     + cpi.applicationInfo.uid + " for provider "
   6010                                     + name + ": process is bad");
   6011                             return null;
   6012                         }
   6013                         cpr.launchingApp = proc;
   6014                         mLaunchingProviders.add(cpr);
   6015                     } finally {
   6016                         Binder.restoreCallingIdentity(origId);
   6017                     }
   6018                 }
   6019 
   6020                 // Make sure the provider is published (the same provider class
   6021                 // may be published under multiple names).
   6022                 if (firstClass) {
   6023                     mProvidersByClass.put(comp, cpr);
   6024                 }
   6025                 mProvidersByName.put(name, cpr);
   6026                 incProviderCount(r, cpr);
   6027             }
   6028         }
   6029 
   6030         // Wait for the provider to be published...
   6031         synchronized (cpr) {
   6032             while (cpr.provider == null) {
   6033                 if (cpr.launchingApp == null) {
   6034                     Slog.w(TAG, "Unable to launch app "
   6035                             + cpi.applicationInfo.packageName + "/"
   6036                             + cpi.applicationInfo.uid + " for provider "
   6037                             + name + ": launching app became null");
   6038                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
   6039                             cpi.applicationInfo.packageName,
   6040                             cpi.applicationInfo.uid, name);
   6041                     return null;
   6042                 }
   6043                 try {
   6044                     cpr.wait();
   6045                 } catch (InterruptedException ex) {
   6046                 }
   6047             }
   6048         }
   6049         return cpr;
   6050     }
   6051 
   6052     public final ContentProviderHolder getContentProvider(
   6053             IApplicationThread caller, String name) {
   6054         if (caller == null) {
   6055             String msg = "null IApplicationThread when getting content provider "
   6056                     + name;
   6057             Slog.w(TAG, msg);
   6058             throw new SecurityException(msg);
   6059         }
   6060 
   6061         return getContentProviderImpl(caller, name);
   6062     }
   6063 
   6064     private ContentProviderHolder getContentProviderExternal(String name) {
   6065         return getContentProviderImpl(null, name);
   6066     }
   6067 
   6068     /**
   6069      * Drop a content provider from a ProcessRecord's bookkeeping
   6070      * @param cpr
   6071      */
   6072     public void removeContentProvider(IApplicationThread caller, String name) {
   6073         synchronized (this) {
   6074             ContentProviderRecord cpr = mProvidersByName.get(name);
   6075             if(cpr == null) {
   6076                 // remove from mProvidersByClass
   6077                 if (DEBUG_PROVIDER) Slog.v(TAG, name +
   6078                         " provider not found in providers list");
   6079                 return;
   6080             }
   6081             final ProcessRecord r = getRecordForAppLocked(caller);
   6082             if (r == null) {
   6083                 throw new SecurityException(
   6084                         "Unable to find app for caller " + caller +
   6085                         " when removing content provider " + name);
   6086             }
   6087             //update content provider record entry info
   6088             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
   6089             ContentProviderRecord localCpr = mProvidersByClass.get(comp);
   6090             if (localCpr.proc == r) {
   6091                 //should not happen. taken care of as a local provider
   6092                 Slog.w(TAG, "removeContentProvider called on local provider: "
   6093                         + cpr.info.name + " in process " + r.processName);
   6094                 return;
   6095             } else {
   6096                 if (decProviderCount(r, localCpr)) {
   6097                     updateOomAdjLocked();
   6098                 }
   6099             }
   6100         }
   6101     }
   6102 
   6103     private void removeContentProviderExternal(String name) {
   6104         synchronized (this) {
   6105             ContentProviderRecord cpr = mProvidersByName.get(name);
   6106             if(cpr == null) {
   6107                 //remove from mProvidersByClass
   6108                 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
   6109                 return;
   6110             }
   6111 
   6112             //update content provider record entry info
   6113             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
   6114             ContentProviderRecord localCpr = mProvidersByClass.get(comp);
   6115             localCpr.externals--;
   6116             if (localCpr.externals < 0) {
   6117                 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
   6118             }
   6119             updateOomAdjLocked();
   6120         }
   6121     }
   6122 
   6123     public final void publishContentProviders(IApplicationThread caller,
   6124             List<ContentProviderHolder> providers) {
   6125         if (providers == null) {
   6126             return;
   6127         }
   6128 
   6129         synchronized(this) {
   6130             final ProcessRecord r = getRecordForAppLocked(caller);
   6131             if (r == null) {
   6132                 throw new SecurityException(
   6133                         "Unable to find app for caller " + caller
   6134                       + " (pid=" + Binder.getCallingPid()
   6135                       + ") when publishing content providers");
   6136             }
   6137 
   6138             final long origId = Binder.clearCallingIdentity();
   6139 
   6140             final int N = providers.size();
   6141             for (int i=0; i<N; i++) {
   6142                 ContentProviderHolder src = providers.get(i);
   6143                 if (src == null || src.info == null || src.provider == null) {
   6144                     continue;
   6145                 }
   6146                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
   6147                 if (dst != null) {
   6148                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
   6149                     mProvidersByClass.put(comp, dst);
   6150                     String names[] = dst.info.authority.split(";");
   6151                     for (int j = 0; j < names.length; j++) {
   6152                         mProvidersByName.put(names[j], dst);
   6153                     }
   6154 
   6155                     int NL = mLaunchingProviders.size();
   6156                     int j;
   6157                     for (j=0; j<NL; j++) {
   6158                         if (mLaunchingProviders.get(j) == dst) {
   6159                             mLaunchingProviders.remove(j);
   6160                             j--;
   6161                             NL--;
   6162                         }
   6163                     }
   6164                     synchronized (dst) {
   6165                         dst.provider = src.provider;
   6166                         dst.proc = r;
   6167                         dst.notifyAll();
   6168                     }
   6169                     updateOomAdjLocked(r);
   6170                 }
   6171             }
   6172 
   6173             Binder.restoreCallingIdentity(origId);
   6174         }
   6175     }
   6176 
   6177     public static final void installSystemProviders() {
   6178         List<ProviderInfo> providers;
   6179         synchronized (mSelf) {
   6180             ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
   6181             providers = mSelf.generateApplicationProvidersLocked(app);
   6182             if (providers != null) {
   6183                 for (int i=providers.size()-1; i>=0; i--) {
   6184                     ProviderInfo pi = (ProviderInfo)providers.get(i);
   6185                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   6186                         Slog.w(TAG, "Not installing system proc provider " + pi.name
   6187                                 + ": not system .apk");
   6188                         providers.remove(i);
   6189                     }
   6190                 }
   6191             }
   6192         }
   6193         if (providers != null) {
   6194             mSystemThread.installSystemProviders(providers);
   6195         }
   6196 
   6197         mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
   6198 
   6199         mSelf.mUsageStatsService.monitorPackages();
   6200     }
   6201 
   6202     /**
   6203      * Allows app to retrieve the MIME type of a URI without having permission
   6204      * to access its content provider.
   6205      *
   6206      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
   6207      *
   6208      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
   6209      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
   6210      */
   6211     public String getProviderMimeType(Uri uri) {
   6212         final String name = uri.getAuthority();
   6213         final long ident = Binder.clearCallingIdentity();
   6214         ContentProviderHolder holder = null;
   6215 
   6216         try {
   6217             holder = getContentProviderExternal(name);
   6218             if (holder != null) {
   6219                 return holder.provider.getType(uri);
   6220             }
   6221         } catch (RemoteException e) {
   6222             Log.w(TAG, "Content provider dead retrieving " + uri, e);
   6223             return null;
   6224         } finally {
   6225             if (holder != null) {
   6226                 removeContentProviderExternal(name);
   6227             }
   6228             Binder.restoreCallingIdentity(ident);
   6229         }
   6230 
   6231         return null;
   6232     }
   6233 
   6234     // =========================================================
   6235     // GLOBAL MANAGEMENT
   6236     // =========================================================
   6237 
   6238     final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
   6239             ApplicationInfo info, String customProcess) {
   6240         String proc = customProcess != null ? customProcess : info.processName;
   6241         BatteryStatsImpl.Uid.Proc ps = null;
   6242         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   6243         synchronized (stats) {
   6244             ps = stats.getProcessStatsLocked(info.uid, proc);
   6245         }
   6246         return new ProcessRecord(ps, thread, info, proc);
   6247     }
   6248 
   6249     final ProcessRecord addAppLocked(ApplicationInfo info) {
   6250         ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
   6251 
   6252         if (app == null) {
   6253             app = newProcessRecordLocked(null, info, null);
   6254             mProcessNames.put(info.processName, info.uid, app);
   6255             updateLruProcessLocked(app, true, true);
   6256         }
   6257 
   6258         // This package really, really can not be stopped.
   6259         try {
   6260             AppGlobals.getPackageManager().setPackageStoppedState(
   6261                     info.packageName, false);
   6262         } catch (RemoteException e) {
   6263         } catch (IllegalArgumentException e) {
   6264             Slog.w(TAG, "Failed trying to unstop package "
   6265                     + info.packageName + ": " + e);
   6266         }
   6267 
   6268         if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
   6269                 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
   6270             app.persistent = true;
   6271             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
   6272         }
   6273         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
   6274             mPersistentStartingProcesses.add(app);
   6275             startProcessLocked(app, "added application", app.processName);
   6276         }
   6277 
   6278         return app;
   6279     }
   6280 
   6281     public void unhandledBack() {
   6282         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
   6283                 "unhandledBack()");
   6284 
   6285         synchronized(this) {
   6286             int count = mMainStack.mHistory.size();
   6287             if (DEBUG_SWITCH) Slog.d(
   6288                 TAG, "Performing unhandledBack(): stack size = " + count);
   6289             if (count > 1) {
   6290                 final long origId = Binder.clearCallingIdentity();
   6291                 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
   6292                         count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
   6293                 Binder.restoreCallingIdentity(origId);
   6294             }
   6295         }
   6296     }
   6297 
   6298     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
   6299         String name = uri.getAuthority();
   6300         ContentProviderHolder cph = getContentProviderExternal(name);
   6301         ParcelFileDescriptor pfd = null;
   6302         if (cph != null) {
   6303             // We record the binder invoker's uid in thread-local storage before
   6304             // going to the content provider to open the file.  Later, in the code
   6305             // that handles all permissions checks, we look for this uid and use
   6306             // that rather than the Activity Manager's own uid.  The effect is that
   6307             // we do the check against the caller's permissions even though it looks
   6308             // to the content provider like the Activity Manager itself is making
   6309             // the request.
   6310             sCallerIdentity.set(new Identity(
   6311                     Binder.getCallingPid(), Binder.getCallingUid()));
   6312             try {
   6313                 pfd = cph.provider.openFile(uri, "r");
   6314             } catch (FileNotFoundException e) {
   6315                 // do nothing; pfd will be returned null
   6316             } finally {
   6317                 // Ensure that whatever happens, we clean up the identity state
   6318                 sCallerIdentity.remove();
   6319             }
   6320 
   6321             // We've got the fd now, so we're done with the provider.
   6322             removeContentProviderExternal(name);
   6323         } else {
   6324             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
   6325         }
   6326         return pfd;
   6327     }
   6328 
   6329     // Actually is sleeping or shutting down or whatever else in the future
   6330     // is an inactive state.
   6331     public boolean isSleeping() {
   6332         return mSleeping || mShuttingDown;
   6333     }
   6334 
   6335     public void goingToSleep() {
   6336         synchronized(this) {
   6337             mSleeping = true;
   6338             mWindowManager.setEventDispatching(false);
   6339 
   6340             mMainStack.stopIfSleepingLocked();
   6341 
   6342             // Initialize the wake times of all processes.
   6343             checkExcessivePowerUsageLocked(false);
   6344             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   6345             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   6346             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   6347         }
   6348     }
   6349 
   6350     public boolean shutdown(int timeout) {
   6351         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
   6352                 != PackageManager.PERMISSION_GRANTED) {
   6353             throw new SecurityException("Requires permission "
   6354                     + android.Manifest.permission.SHUTDOWN);
   6355         }
   6356 
   6357         boolean timedout = false;
   6358 
   6359         synchronized(this) {
   6360             mShuttingDown = true;
   6361             mWindowManager.setEventDispatching(false);
   6362 
   6363             if (mMainStack.mResumedActivity != null) {
   6364                 mMainStack.stopIfSleepingLocked();
   6365                 final long endTime = System.currentTimeMillis() + timeout;
   6366                 while (mMainStack.mResumedActivity != null
   6367                         || mMainStack.mPausingActivity != null) {
   6368                     long delay = endTime - System.currentTimeMillis();
   6369                     if (delay <= 0) {
   6370                         Slog.w(TAG, "Activity manager shutdown timed out");
   6371                         timedout = true;
   6372                         break;
   6373                     }
   6374                     try {
   6375                         this.wait();
   6376                     } catch (InterruptedException e) {
   6377                     }
   6378                 }
   6379             }
   6380         }
   6381 
   6382         mUsageStatsService.shutdown();
   6383         mBatteryStatsService.shutdown();
   6384 
   6385         return timedout;
   6386     }
   6387 
   6388     public final void activitySlept(IBinder token) {
   6389         if (localLOGV) Slog.v(
   6390             TAG, "Activity slept: token=" + token);
   6391 
   6392         ActivityRecord r = null;
   6393 
   6394         final long origId = Binder.clearCallingIdentity();
   6395 
   6396         synchronized (this) {
   6397             r = mMainStack.isInStackLocked(token);
   6398             if (r != null) {
   6399                 mMainStack.activitySleptLocked(r);
   6400             }
   6401         }
   6402 
   6403         Binder.restoreCallingIdentity(origId);
   6404     }
   6405 
   6406     public void wakingUp() {
   6407         synchronized(this) {
   6408             mWindowManager.setEventDispatching(true);
   6409             mSleeping = false;
   6410             mMainStack.awakeFromSleepingLocked();
   6411             mMainStack.resumeTopActivityLocked(null);
   6412         }
   6413     }
   6414 
   6415     public void stopAppSwitches() {
   6416         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   6417                 != PackageManager.PERMISSION_GRANTED) {
   6418             throw new SecurityException("Requires permission "
   6419                     + android.Manifest.permission.STOP_APP_SWITCHES);
   6420         }
   6421 
   6422         synchronized(this) {
   6423             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
   6424                     + APP_SWITCH_DELAY_TIME;
   6425             mDidAppSwitch = false;
   6426             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   6427             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   6428             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
   6429         }
   6430     }
   6431 
   6432     public void resumeAppSwitches() {
   6433         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   6434                 != PackageManager.PERMISSION_GRANTED) {
   6435             throw new SecurityException("Requires permission "
   6436                     + android.Manifest.permission.STOP_APP_SWITCHES);
   6437         }
   6438 
   6439         synchronized(this) {
   6440             // Note that we don't execute any pending app switches... we will
   6441             // let those wait until either the timeout, or the next start
   6442             // activity request.
   6443             mAppSwitchesAllowedTime = 0;
   6444         }
   6445     }
   6446 
   6447     boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
   6448             String name) {
   6449         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
   6450             return true;
   6451         }
   6452 
   6453         final int perm = checkComponentPermission(
   6454                 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
   6455                 callingUid, -1, true);
   6456         if (perm == PackageManager.PERMISSION_GRANTED) {
   6457             return true;
   6458         }
   6459 
   6460         Slog.w(TAG, name + " request from " + callingUid + " stopped");
   6461         return false;
   6462     }
   6463 
   6464     public void setDebugApp(String packageName, boolean waitForDebugger,
   6465             boolean persistent) {
   6466         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
   6467                 "setDebugApp()");
   6468 
   6469         // Note that this is not really thread safe if there are multiple
   6470         // callers into it at the same time, but that's not a situation we
   6471         // care about.
   6472         if (persistent) {
   6473             final ContentResolver resolver = mContext.getContentResolver();
   6474             Settings.System.putString(
   6475                 resolver, Settings.System.DEBUG_APP,
   6476                 packageName);
   6477             Settings.System.putInt(
   6478                 resolver, Settings.System.WAIT_FOR_DEBUGGER,
   6479                 waitForDebugger ? 1 : 0);
   6480         }
   6481 
   6482         synchronized (this) {
   6483             if (!persistent) {
   6484                 mOrigDebugApp = mDebugApp;
   6485                 mOrigWaitForDebugger = mWaitForDebugger;
   6486             }
   6487             mDebugApp = packageName;
   6488             mWaitForDebugger = waitForDebugger;
   6489             mDebugTransient = !persistent;
   6490             if (packageName != null) {
   6491                 final long origId = Binder.clearCallingIdentity();
   6492                 forceStopPackageLocked(packageName, -1, false, false, true, true);
   6493                 Binder.restoreCallingIdentity(origId);
   6494             }
   6495         }
   6496     }
   6497 
   6498     void setProfileApp(ApplicationInfo app, String processName, String profileFile,
   6499             ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
   6500         synchronized (this) {
   6501             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   6502             if (!isDebuggable) {
   6503                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   6504                     throw new SecurityException("Process not debuggable: " + app.packageName);
   6505                 }
   6506             }
   6507             mProfileApp = processName;
   6508             mProfileFile = profileFile;
   6509             if (mProfileFd != null) {
   6510                 try {
   6511                     mProfileFd.close();
   6512                 } catch (IOException e) {
   6513                 }
   6514                 mProfileFd = null;
   6515             }
   6516             mProfileFd = profileFd;
   6517             mProfileType = 0;
   6518             mAutoStopProfiler = autoStopProfiler;
   6519         }
   6520     }
   6521 
   6522     public void setAlwaysFinish(boolean enabled) {
   6523         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
   6524                 "setAlwaysFinish()");
   6525 
   6526         Settings.System.putInt(
   6527                 mContext.getContentResolver(),
   6528                 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
   6529 
   6530         synchronized (this) {
   6531             mAlwaysFinishActivities = enabled;
   6532         }
   6533     }
   6534 
   6535     public void setActivityController(IActivityController controller) {
   6536         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   6537                 "setActivityController()");
   6538         synchronized (this) {
   6539             mController = controller;
   6540         }
   6541     }
   6542 
   6543     public boolean isUserAMonkey() {
   6544         // For now the fact that there is a controller implies
   6545         // we have a monkey.
   6546         synchronized (this) {
   6547             return mController != null;
   6548         }
   6549     }
   6550 
   6551     public void registerActivityWatcher(IActivityWatcher watcher) {
   6552         synchronized (this) {
   6553             mWatchers.register(watcher);
   6554         }
   6555     }
   6556 
   6557     public void unregisterActivityWatcher(IActivityWatcher watcher) {
   6558         synchronized (this) {
   6559             mWatchers.unregister(watcher);
   6560         }
   6561     }
   6562 
   6563     public void registerProcessObserver(IProcessObserver observer) {
   6564         mProcessObservers.register(observer);
   6565     }
   6566 
   6567     public void unregisterProcessObserver(IProcessObserver observer) {
   6568         mProcessObservers.unregister(observer);
   6569     }
   6570 
   6571     public void setImmersive(IBinder token, boolean immersive) {
   6572         synchronized(this) {
   6573             ActivityRecord r = mMainStack.isInStackLocked(token);
   6574             if (r == null) {
   6575                 throw new IllegalArgumentException();
   6576             }
   6577             r.immersive = immersive;
   6578         }
   6579     }
   6580 
   6581     public boolean isImmersive(IBinder token) {
   6582         synchronized (this) {
   6583             ActivityRecord r = mMainStack.isInStackLocked(token);
   6584             if (r == null) {
   6585                 throw new IllegalArgumentException();
   6586             }
   6587             return r.immersive;
   6588         }
   6589     }
   6590 
   6591     public boolean isTopActivityImmersive() {
   6592         synchronized (this) {
   6593             ActivityRecord r = mMainStack.topRunningActivityLocked(null);
   6594             return (r != null) ? r.immersive : false;
   6595         }
   6596     }
   6597 
   6598     public final void enterSafeMode() {
   6599         synchronized(this) {
   6600             // It only makes sense to do this before the system is ready
   6601             // and started launching other packages.
   6602             if (!mSystemReady) {
   6603                 try {
   6604                     AppGlobals.getPackageManager().enterSafeMode();
   6605                 } catch (RemoteException e) {
   6606                 }
   6607             }
   6608         }
   6609     }
   6610 
   6611     public final void showSafeModeOverlay() {
   6612         View v = LayoutInflater.from(mContext).inflate(
   6613                 com.android.internal.R.layout.safe_mode, null);
   6614         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
   6615         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
   6616         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
   6617         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
   6618         lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
   6619         lp.format = v.getBackground().getOpacity();
   6620         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
   6621                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
   6622         ((WindowManager)mContext.getSystemService(
   6623                 Context.WINDOW_SERVICE)).addView(v, lp);
   6624     }
   6625 
   6626     public void noteWakeupAlarm(IIntentSender sender) {
   6627         if (!(sender instanceof PendingIntentRecord)) {
   6628             return;
   6629         }
   6630         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   6631         synchronized (stats) {
   6632             if (mBatteryStatsService.isOnBattery()) {
   6633                 mBatteryStatsService.enforceCallingPermission();
   6634                 PendingIntentRecord rec = (PendingIntentRecord)sender;
   6635                 int MY_UID = Binder.getCallingUid();
   6636                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
   6637                 BatteryStatsImpl.Uid.Pkg pkg =
   6638                     stats.getPackageStatsLocked(uid, rec.key.packageName);
   6639                 pkg.incWakeupsLocked();
   6640             }
   6641         }
   6642     }
   6643 
   6644     public boolean killPids(int[] pids, String pReason, boolean secure) {
   6645         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   6646             throw new SecurityException("killPids only available to the system");
   6647         }
   6648         String reason = (pReason == null) ? "Unknown" : pReason;
   6649         // XXX Note: don't acquire main activity lock here, because the window
   6650         // manager calls in with its locks held.
   6651 
   6652         boolean killed = false;
   6653         synchronized (mPidsSelfLocked) {
   6654             int[] types = new int[pids.length];
   6655             int worstType = 0;
   6656             for (int i=0; i<pids.length; i++) {
   6657                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   6658                 if (proc != null) {
   6659                     int type = proc.setAdj;
   6660                     types[i] = type;
   6661                     if (type > worstType) {
   6662                         worstType = type;
   6663                     }
   6664                 }
   6665             }
   6666 
   6667             // If the worst oom_adj is somewhere in the hidden proc LRU range,
   6668             // then constrain it so we will kill all hidden procs.
   6669             if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
   6670                     && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
   6671                 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
   6672             }
   6673 
   6674             // If this is not a secure call, don't let it kill processes that
   6675             // are important.
   6676             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
   6677                 worstType = ProcessList.SERVICE_ADJ;
   6678             }
   6679 
   6680             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
   6681             for (int i=0; i<pids.length; i++) {
   6682                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   6683                 if (proc == null) {
   6684                     continue;
   6685                 }
   6686                 int adj = proc.setAdj;
   6687                 if (adj >= worstType && !proc.killedBackground) {
   6688                     Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
   6689                     EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
   6690                             proc.processName, adj, reason);
   6691                     killed = true;
   6692                     proc.killedBackground = true;
   6693                     Process.killProcessQuiet(pids[i]);
   6694                 }
   6695             }
   6696         }
   6697         return killed;
   6698     }
   6699 
   6700     public final void startRunning(String pkg, String cls, String action,
   6701             String data) {
   6702         synchronized(this) {
   6703             if (mStartRunning) {
   6704                 return;
   6705             }
   6706             mStartRunning = true;
   6707             mTopComponent = pkg != null && cls != null
   6708                     ? new ComponentName(pkg, cls) : null;
   6709             mTopAction = action != null ? action : Intent.ACTION_MAIN;
   6710             mTopData = data;
   6711             if (!mSystemReady) {
   6712                 return;
   6713             }
   6714         }
   6715 
   6716         systemReady(null);
   6717     }
   6718 
   6719     private void retrieveSettings() {
   6720         final ContentResolver resolver = mContext.getContentResolver();
   6721         String debugApp = Settings.System.getString(
   6722             resolver, Settings.System.DEBUG_APP);
   6723         boolean waitForDebugger = Settings.System.getInt(
   6724             resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
   6725         boolean alwaysFinishActivities = Settings.System.getInt(
   6726             resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
   6727 
   6728         Configuration configuration = new Configuration();
   6729         Settings.System.getConfiguration(resolver, configuration);
   6730 
   6731         synchronized (this) {
   6732             mDebugApp = mOrigDebugApp = debugApp;
   6733             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
   6734             mAlwaysFinishActivities = alwaysFinishActivities;
   6735             // This happens before any activities are started, so we can
   6736             // change mConfiguration in-place.
   6737             updateConfigurationLocked(configuration, null, false, true);
   6738             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
   6739         }
   6740     }
   6741 
   6742     public boolean testIsSystemReady() {
   6743         // no need to synchronize(this) just to read & return the value
   6744         return mSystemReady;
   6745     }
   6746 
   6747     private static File getCalledPreBootReceiversFile() {
   6748         File dataDir = Environment.getDataDirectory();
   6749         File systemDir = new File(dataDir, "system");
   6750         File fname = new File(systemDir, "called_pre_boots.dat");
   6751         return fname;
   6752     }
   6753 
   6754     static final int LAST_DONE_VERSION = 10000;
   6755 
   6756     private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
   6757         ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
   6758         File file = getCalledPreBootReceiversFile();
   6759         FileInputStream fis = null;
   6760         try {
   6761             fis = new FileInputStream(file);
   6762             DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
   6763             int fvers = dis.readInt();
   6764             if (fvers == LAST_DONE_VERSION) {
   6765                 String vers = dis.readUTF();
   6766                 String codename = dis.readUTF();
   6767                 String build = dis.readUTF();
   6768                 if (android.os.Build.VERSION.RELEASE.equals(vers)
   6769                         && android.os.Build.VERSION.CODENAME.equals(codename)
   6770                         && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
   6771                     int num = dis.readInt();
   6772                     while (num > 0) {
   6773                         num--;
   6774                         String pkg = dis.readUTF();
   6775                         String cls = dis.readUTF();
   6776                         lastDoneReceivers.add(new ComponentName(pkg, cls));
   6777                     }
   6778                 }
   6779             }
   6780         } catch (FileNotFoundException e) {
   6781         } catch (IOException e) {
   6782             Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
   6783         } finally {
   6784             if (fis != null) {
   6785                 try {
   6786                     fis.close();
   6787                 } catch (IOException e) {
   6788                 }
   6789             }
   6790         }
   6791         return lastDoneReceivers;
   6792     }
   6793 
   6794     private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
   6795         File file = getCalledPreBootReceiversFile();
   6796         FileOutputStream fos = null;
   6797         DataOutputStream dos = null;
   6798         try {
   6799             Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
   6800             fos = new FileOutputStream(file);
   6801             dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
   6802             dos.writeInt(LAST_DONE_VERSION);
   6803             dos.writeUTF(android.os.Build.VERSION.RELEASE);
   6804             dos.writeUTF(android.os.Build.VERSION.CODENAME);
   6805             dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
   6806             dos.writeInt(list.size());
   6807             for (int i=0; i<list.size(); i++) {
   6808                 dos.writeUTF(list.get(i).getPackageName());
   6809                 dos.writeUTF(list.get(i).getClassName());
   6810             }
   6811         } catch (IOException e) {
   6812             Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
   6813             file.delete();
   6814         } finally {
   6815             FileUtils.sync(fos);
   6816             if (dos != null) {
   6817                 try {
   6818                     dos.close();
   6819                 } catch (IOException e) {
   6820                     // TODO Auto-generated catch block
   6821                     e.printStackTrace();
   6822                 }
   6823             }
   6824         }
   6825     }
   6826 
   6827     public void systemReady(final Runnable goingCallback) {
   6828         synchronized(this) {
   6829             if (mSystemReady) {
   6830                 if (goingCallback != null) goingCallback.run();
   6831                 return;
   6832             }
   6833 
   6834             // Check to see if there are any update receivers to run.
   6835             if (!mDidUpdate) {
   6836                 if (mWaitingUpdate) {
   6837                     return;
   6838                 }
   6839                 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
   6840                 List<ResolveInfo> ris = null;
   6841                 try {
   6842                     ris = AppGlobals.getPackageManager().queryIntentReceivers(
   6843                                 intent, null, 0);
   6844                 } catch (RemoteException e) {
   6845                 }
   6846                 if (ris != null) {
   6847                     for (int i=ris.size()-1; i>=0; i--) {
   6848                         if ((ris.get(i).activityInfo.applicationInfo.flags
   6849                                 &ApplicationInfo.FLAG_SYSTEM) == 0) {
   6850                             ris.remove(i);
   6851                         }
   6852                     }
   6853                     intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
   6854 
   6855                     ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
   6856 
   6857                     final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
   6858                     for (int i=0; i<ris.size(); i++) {
   6859                         ActivityInfo ai = ris.get(i).activityInfo;
   6860                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
   6861                         if (lastDoneReceivers.contains(comp)) {
   6862                             ris.remove(i);
   6863                             i--;
   6864                         }
   6865                     }
   6866 
   6867                     for (int i=0; i<ris.size(); i++) {
   6868                         ActivityInfo ai = ris.get(i).activityInfo;
   6869                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
   6870                         doneReceivers.add(comp);
   6871                         intent.setComponent(comp);
   6872                         IIntentReceiver finisher = null;
   6873                         if (i == ris.size()-1) {
   6874                             finisher = new IIntentReceiver.Stub() {
   6875                                 public void performReceive(Intent intent, int resultCode,
   6876                                         String data, Bundle extras, boolean ordered,
   6877                                         boolean sticky) {
   6878                                     // The raw IIntentReceiver interface is called
   6879                                     // with the AM lock held, so redispatch to
   6880                                     // execute our code without the lock.
   6881                                     mHandler.post(new Runnable() {
   6882                                         public void run() {
   6883                                             synchronized (ActivityManagerService.this) {
   6884                                                 mDidUpdate = true;
   6885                                             }
   6886                                             writeLastDonePreBootReceivers(doneReceivers);
   6887                                             showBootMessage(mContext.getText(
   6888                                                     R.string.android_upgrading_complete),
   6889                                                     false);
   6890                                             systemReady(goingCallback);
   6891                                         }
   6892                                     });
   6893                                 }
   6894                             };
   6895                         }
   6896                         Slog.i(TAG, "Sending system update to: " + intent.getComponent());
   6897                         broadcastIntentLocked(null, null, intent, null, finisher,
   6898                                 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
   6899                         if (finisher != null) {
   6900                             mWaitingUpdate = true;
   6901                         }
   6902                     }
   6903                 }
   6904                 if (mWaitingUpdate) {
   6905                     return;
   6906                 }
   6907                 mDidUpdate = true;
   6908             }
   6909 
   6910             mSystemReady = true;
   6911             if (!mStartRunning) {
   6912                 return;
   6913             }
   6914         }
   6915 
   6916         ArrayList<ProcessRecord> procsToKill = null;
   6917         synchronized(mPidsSelfLocked) {
   6918             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
   6919                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   6920                 if (!isAllowedWhileBooting(proc.info)){
   6921                     if (procsToKill == null) {
   6922                         procsToKill = new ArrayList<ProcessRecord>();
   6923                     }
   6924                     procsToKill.add(proc);
   6925                 }
   6926             }
   6927         }
   6928 
   6929         synchronized(this) {
   6930             if (procsToKill != null) {
   6931                 for (int i=procsToKill.size()-1; i>=0; i--) {
   6932                     ProcessRecord proc = procsToKill.get(i);
   6933                     Slog.i(TAG, "Removing system update proc: " + proc);
   6934                     removeProcessLocked(proc, true, false, "system update done");
   6935                 }
   6936             }
   6937 
   6938             // Now that we have cleaned up any update processes, we
   6939             // are ready to start launching real processes and know that
   6940             // we won't trample on them any more.
   6941             mProcessesReady = true;
   6942         }
   6943 
   6944         Slog.i(TAG, "System now ready");
   6945         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
   6946             SystemClock.uptimeMillis());
   6947 
   6948         synchronized(this) {
   6949             // Make sure we have no pre-ready processes sitting around.
   6950 
   6951             if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
   6952                 ResolveInfo ri = mContext.getPackageManager()
   6953                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
   6954                                 STOCK_PM_FLAGS);
   6955                 CharSequence errorMsg = null;
   6956                 if (ri != null) {
   6957                     ActivityInfo ai = ri.activityInfo;
   6958                     ApplicationInfo app = ai.applicationInfo;
   6959                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   6960                         mTopAction = Intent.ACTION_FACTORY_TEST;
   6961                         mTopData = null;
   6962                         mTopComponent = new ComponentName(app.packageName,
   6963                                 ai.name);
   6964                     } else {
   6965                         errorMsg = mContext.getResources().getText(
   6966                                 com.android.internal.R.string.factorytest_not_system);
   6967                     }
   6968                 } else {
   6969                     errorMsg = mContext.getResources().getText(
   6970                             com.android.internal.R.string.factorytest_no_action);
   6971                 }
   6972                 if (errorMsg != null) {
   6973                     mTopAction = null;
   6974                     mTopData = null;
   6975                     mTopComponent = null;
   6976                     Message msg = Message.obtain();
   6977                     msg.what = SHOW_FACTORY_ERROR_MSG;
   6978                     msg.getData().putCharSequence("msg", errorMsg);
   6979                     mHandler.sendMessage(msg);
   6980                 }
   6981             }
   6982         }
   6983 
   6984         retrieveSettings();
   6985 
   6986         if (goingCallback != null) goingCallback.run();
   6987 
   6988         synchronized (this) {
   6989             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   6990                 try {
   6991                     List apps = AppGlobals.getPackageManager().
   6992                         getPersistentApplications(STOCK_PM_FLAGS);
   6993                     if (apps != null) {
   6994                         int N = apps.size();
   6995                         int i;
   6996                         for (i=0; i<N; i++) {
   6997                             ApplicationInfo info
   6998                                 = (ApplicationInfo)apps.get(i);
   6999                             if (info != null &&
   7000                                     !info.packageName.equals("android")) {
   7001                                 addAppLocked(info);
   7002                             }
   7003                         }
   7004                     }
   7005                 } catch (RemoteException ex) {
   7006                     // pm is in same process, this will never happen.
   7007                 }
   7008             }
   7009 
   7010             // Start up initial activity.
   7011             mBooting = true;
   7012 
   7013             try {
   7014                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
   7015                     Message msg = Message.obtain();
   7016                     msg.what = SHOW_UID_ERROR_MSG;
   7017                     mHandler.sendMessage(msg);
   7018                 }
   7019             } catch (RemoteException e) {
   7020             }
   7021 
   7022             mMainStack.resumeTopActivityLocked(null);
   7023         }
   7024     }
   7025 
   7026     private boolean makeAppCrashingLocked(ProcessRecord app,
   7027             String shortMsg, String longMsg, String stackTrace) {
   7028         app.crashing = true;
   7029         app.crashingReport = generateProcessError(app,
   7030                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
   7031         startAppProblemLocked(app);
   7032         app.stopFreezingAllLocked();
   7033         return handleAppCrashLocked(app);
   7034     }
   7035 
   7036     private void makeAppNotRespondingLocked(ProcessRecord app,
   7037             String activity, String shortMsg, String longMsg) {
   7038         app.notResponding = true;
   7039         app.notRespondingReport = generateProcessError(app,
   7040                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
   7041                 activity, shortMsg, longMsg, null);
   7042         startAppProblemLocked(app);
   7043         app.stopFreezingAllLocked();
   7044     }
   7045 
   7046     /**
   7047      * Generate a process error record, suitable for attachment to a ProcessRecord.
   7048      *
   7049      * @param app The ProcessRecord in which the error occurred.
   7050      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
   7051      *                      ActivityManager.AppErrorStateInfo
   7052      * @param activity The activity associated with the crash, if known.
   7053      * @param shortMsg Short message describing the crash.
   7054      * @param longMsg Long message describing the crash.
   7055      * @param stackTrace Full crash stack trace, may be null.
   7056      *
   7057      * @return Returns a fully-formed AppErrorStateInfo record.
   7058      */
   7059     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
   7060             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
   7061         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
   7062 
   7063         report.condition = condition;
   7064         report.processName = app.processName;
   7065         report.pid = app.pid;
   7066         report.uid = app.info.uid;
   7067         report.tag = activity;
   7068         report.shortMsg = shortMsg;
   7069         report.longMsg = longMsg;
   7070         report.stackTrace = stackTrace;
   7071 
   7072         return report;
   7073     }
   7074 
   7075     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
   7076         synchronized (this) {
   7077             app.crashing = false;
   7078             app.crashingReport = null;
   7079             app.notResponding = false;
   7080             app.notRespondingReport = null;
   7081             if (app.anrDialog == fromDialog) {
   7082                 app.anrDialog = null;
   7083             }
   7084             if (app.waitDialog == fromDialog) {
   7085                 app.waitDialog = null;
   7086             }
   7087             if (app.pid > 0 && app.pid != MY_PID) {
   7088                 handleAppCrashLocked(app);
   7089                 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
   7090                 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   7091                         app.processName, app.setAdj, "user's request after error");
   7092                 Process.killProcessQuiet(app.pid);
   7093             }
   7094         }
   7095     }
   7096 
   7097     private boolean handleAppCrashLocked(ProcessRecord app) {
   7098         long now = SystemClock.uptimeMillis();
   7099 
   7100         Long crashTime = mProcessCrashTimes.get(app.info.processName,
   7101                 app.info.uid);
   7102         if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
   7103             // This process loses!
   7104             Slog.w(TAG, "Process " + app.info.processName
   7105                     + " has crashed too many times: killing!");
   7106             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
   7107                     app.info.processName, app.info.uid);
   7108             for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
   7109                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   7110                 if (r.app == app) {
   7111                     Slog.w(TAG, "  Force finishing activity "
   7112                         + r.intent.getComponent().flattenToShortString());
   7113                     r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
   7114                 }
   7115             }
   7116             if (!app.persistent) {
   7117                 // We don't want to start this process again until the user
   7118                 // explicitly does so...  but for persistent process, we really
   7119                 // need to keep it running.  If a persistent process is actually
   7120                 // repeatedly crashing, then badness for everyone.
   7121                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
   7122                         app.info.processName);
   7123                 mBadProcesses.put(app.info.processName, app.info.uid, now);
   7124                 app.bad = true;
   7125                 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
   7126                 app.removed = true;
   7127                 // Don't let services in this process be restarted and potentially
   7128                 // annoy the user repeatedly.  Unless it is persistent, since those
   7129                 // processes run critical code.
   7130                 removeProcessLocked(app, false, false, "crash");
   7131                 mMainStack.resumeTopActivityLocked(null);
   7132                 return false;
   7133             }
   7134             mMainStack.resumeTopActivityLocked(null);
   7135         } else {
   7136             ActivityRecord r = mMainStack.topRunningActivityLocked(null);
   7137             if (r.app == app) {
   7138                 // If the top running activity is from this crashing
   7139                 // process, then terminate it to avoid getting in a loop.
   7140                 Slog.w(TAG, "  Force finishing activity "
   7141                         + r.intent.getComponent().flattenToShortString());
   7142                 int index = mMainStack.indexOfActivityLocked(r);
   7143                 r.stack.finishActivityLocked(r, index,
   7144                         Activity.RESULT_CANCELED, null, "crashed");
   7145                 // Also terminate any activities below it that aren't yet
   7146                 // stopped, to avoid a situation where one will get
   7147                 // re-start our crashing activity once it gets resumed again.
   7148                 index--;
   7149                 if (index >= 0) {
   7150                     r = (ActivityRecord)mMainStack.mHistory.get(index);
   7151                     if (r.state == ActivityState.RESUMED
   7152                             || r.state == ActivityState.PAUSING
   7153                             || r.state == ActivityState.PAUSED) {
   7154                         if (!r.isHomeActivity || mHomeProcess != r.app) {
   7155                             Slog.w(TAG, "  Force finishing activity "
   7156                                     + r.intent.getComponent().flattenToShortString());
   7157                             r.stack.finishActivityLocked(r, index,
   7158                                     Activity.RESULT_CANCELED, null, "crashed");
   7159                         }
   7160                     }
   7161                 }
   7162             }
   7163         }
   7164 
   7165         // Bump up the crash count of any services currently running in the proc.
   7166         if (app.services.size() != 0) {
   7167             // Any services running in the application need to be placed
   7168             // back in the pending list.
   7169             Iterator<ServiceRecord> it = app.services.iterator();
   7170             while (it.hasNext()) {
   7171                 ServiceRecord sr = it.next();
   7172                 sr.crashCount++;
   7173             }
   7174         }
   7175 
   7176         // If the crashing process is what we consider to be the "home process" and it has been
   7177         // replaced by a third-party app, clear the package preferred activities from packages
   7178         // with a home activity running in the process to prevent a repeatedly crashing app
   7179         // from blocking the user to manually clear the list.
   7180         if (app == mHomeProcess && mHomeProcess.activities.size() > 0
   7181                     && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
   7182             Iterator it = mHomeProcess.activities.iterator();
   7183             while (it.hasNext()) {
   7184                 ActivityRecord r = (ActivityRecord)it.next();
   7185                 if (r.isHomeActivity) {
   7186                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
   7187                     try {
   7188                         ActivityThread.getPackageManager()
   7189                                 .clearPackagePreferredActivities(r.packageName);
   7190                     } catch (RemoteException c) {
   7191                         // pm is in same process, this will never happen.
   7192                     }
   7193                 }
   7194             }
   7195         }
   7196 
   7197         mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
   7198         return true;
   7199     }
   7200 
   7201     void startAppProblemLocked(ProcessRecord app) {
   7202         app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
   7203                 mContext, app.info.packageName, app.info.flags);
   7204         skipCurrentReceiverLocked(app);
   7205     }
   7206 
   7207     void skipCurrentReceiverLocked(ProcessRecord app) {
   7208         boolean reschedule = false;
   7209         BroadcastRecord r = app.curReceiver;
   7210         if (r != null) {
   7211             // The current broadcast is waiting for this app's receiver
   7212             // to be finished.  Looks like that's not going to happen, so
   7213             // let the broadcast continue.
   7214             logBroadcastReceiverDiscardLocked(r);
   7215             finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
   7216                     r.resultExtras, r.resultAbort, true);
   7217             reschedule = true;
   7218         }
   7219         r = mPendingBroadcast;
   7220         if (r != null && r.curApp == app) {
   7221             if (DEBUG_BROADCAST) Slog.v(TAG,
   7222                     "skip & discard pending app " + r);
   7223             logBroadcastReceiverDiscardLocked(r);
   7224             finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
   7225                     r.resultExtras, r.resultAbort, true);
   7226             reschedule = true;
   7227         }
   7228         if (reschedule) {
   7229             scheduleBroadcastsLocked();
   7230         }
   7231     }
   7232 
   7233     /**
   7234      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
   7235      * The application process will exit immediately after this call returns.
   7236      * @param app object of the crashing app, null for the system server
   7237      * @param crashInfo describing the exception
   7238      */
   7239     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
   7240         ProcessRecord r = findAppProcess(app, "Crash");
   7241         final String processName = app == null ? "system_server"
   7242                 : (r == null ? "unknown" : r.processName);
   7243 
   7244         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
   7245                 processName,
   7246                 r == null ? -1 : r.info.flags,
   7247                 crashInfo.exceptionClassName,
   7248                 crashInfo.exceptionMessage,
   7249                 crashInfo.throwFileName,
   7250                 crashInfo.throwLineNumber);
   7251 
   7252         addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
   7253 
   7254         crashApplication(r, crashInfo);
   7255     }
   7256 
   7257     public void handleApplicationStrictModeViolation(
   7258             IBinder app,
   7259             int violationMask,
   7260             StrictMode.ViolationInfo info) {
   7261         ProcessRecord r = findAppProcess(app, "StrictMode");
   7262         if (r == null) {
   7263             return;
   7264         }
   7265 
   7266         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
   7267             Integer stackFingerprint = info.hashCode();
   7268             boolean logIt = true;
   7269             synchronized (mAlreadyLoggedViolatedStacks) {
   7270                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
   7271                     logIt = false;
   7272                     // TODO: sub-sample into EventLog for these, with
   7273                     // the info.durationMillis?  Then we'd get
   7274                     // the relative pain numbers, without logging all
   7275                     // the stack traces repeatedly.  We'd want to do
   7276                     // likewise in the client code, which also does
   7277                     // dup suppression, before the Binder call.
   7278                 } else {
   7279                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
   7280                         mAlreadyLoggedViolatedStacks.clear();
   7281                     }
   7282                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
   7283                 }
   7284             }
   7285             if (logIt) {
   7286                 logStrictModeViolationToDropBox(r, info);
   7287             }
   7288         }
   7289 
   7290         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
   7291             AppErrorResult result = new AppErrorResult();
   7292             synchronized (this) {
   7293                 final long origId = Binder.clearCallingIdentity();
   7294 
   7295                 Message msg = Message.obtain();
   7296                 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
   7297                 HashMap<String, Object> data = new HashMap<String, Object>();
   7298                 data.put("result", result);
   7299                 data.put("app", r);
   7300                 data.put("violationMask", violationMask);
   7301                 data.put("info", info);
   7302                 msg.obj = data;
   7303                 mHandler.sendMessage(msg);
   7304 
   7305                 Binder.restoreCallingIdentity(origId);
   7306             }
   7307             int res = result.get();
   7308             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
   7309         }
   7310     }
   7311 
   7312     // Depending on the policy in effect, there could be a bunch of
   7313     // these in quick succession so we try to batch these together to
   7314     // minimize disk writes, number of dropbox entries, and maximize
   7315     // compression, by having more fewer, larger records.
   7316     private void logStrictModeViolationToDropBox(
   7317             ProcessRecord process,
   7318             StrictMode.ViolationInfo info) {
   7319         if (info == null) {
   7320             return;
   7321         }
   7322         final boolean isSystemApp = process == null ||
   7323                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
   7324                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
   7325         final String processName = process == null ? "unknown" : process.processName;
   7326         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
   7327         final DropBoxManager dbox = (DropBoxManager)
   7328                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   7329 
   7330         // Exit early if the dropbox isn't configured to accept this report type.
   7331         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   7332 
   7333         boolean bufferWasEmpty;
   7334         boolean needsFlush;
   7335         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
   7336         synchronized (sb) {
   7337             bufferWasEmpty = sb.length() == 0;
   7338             appendDropBoxProcessHeaders(process, processName, sb);
   7339             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   7340             sb.append("System-App: ").append(isSystemApp).append("\n");
   7341             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
   7342             if (info.violationNumThisLoop != 0) {
   7343                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
   7344             }
   7345             if (info.numAnimationsRunning != 0) {
   7346                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
   7347             }
   7348             if (info.broadcastIntentAction != null) {
   7349                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
   7350             }
   7351             if (info.durationMillis != -1) {
   7352                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
   7353             }
   7354             if (info.numInstances != -1) {
   7355                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
   7356             }
   7357             if (info.tags != null) {
   7358                 for (String tag : info.tags) {
   7359                     sb.append("Span-Tag: ").append(tag).append("\n");
   7360                 }
   7361             }
   7362             sb.append("\n");
   7363             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
   7364                 sb.append(info.crashInfo.stackTrace);
   7365             }
   7366             sb.append("\n");
   7367 
   7368             // Only buffer up to ~64k.  Various logging bits truncate
   7369             // things at 128k.
   7370             needsFlush = (sb.length() > 64 * 1024);
   7371         }
   7372 
   7373         // Flush immediately if the buffer's grown too large, or this
   7374         // is a non-system app.  Non-system apps are isolated with a
   7375         // different tag & policy and not batched.
   7376         //
   7377         // Batching is useful during internal testing with
   7378         // StrictMode settings turned up high.  Without batching,
   7379         // thousands of separate files could be created on boot.
   7380         if (!isSystemApp || needsFlush) {
   7381             new Thread("Error dump: " + dropboxTag) {
   7382                 @Override
   7383                 public void run() {
   7384                     String report;
   7385                     synchronized (sb) {
   7386                         report = sb.toString();
   7387                         sb.delete(0, sb.length());
   7388                         sb.trimToSize();
   7389                     }
   7390                     if (report.length() != 0) {
   7391                         dbox.addText(dropboxTag, report);
   7392                     }
   7393                 }
   7394             }.start();
   7395             return;
   7396         }
   7397 
   7398         // System app batching:
   7399         if (!bufferWasEmpty) {
   7400             // An existing dropbox-writing thread is outstanding, so
   7401             // we don't need to start it up.  The existing thread will
   7402             // catch the buffer appends we just did.
   7403             return;
   7404         }
   7405 
   7406         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
   7407         // (After this point, we shouldn't access AMS internal data structures.)
   7408         new Thread("Error dump: " + dropboxTag) {
   7409             @Override
   7410             public void run() {
   7411                 // 5 second sleep to let stacks arrive and be batched together
   7412                 try {
   7413                     Thread.sleep(5000);  // 5 seconds
   7414                 } catch (InterruptedException e) {}
   7415 
   7416                 String errorReport;
   7417                 synchronized (mStrictModeBuffer) {
   7418                     errorReport = mStrictModeBuffer.toString();
   7419                     if (errorReport.length() == 0) {
   7420                         return;
   7421                     }
   7422                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
   7423                     mStrictModeBuffer.trimToSize();
   7424                 }
   7425                 dbox.addText(dropboxTag, errorReport);
   7426             }
   7427         }.start();
   7428     }
   7429 
   7430     /**
   7431      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
   7432      * @param app object of the crashing app, null for the system server
   7433      * @param tag reported by the caller
   7434      * @param crashInfo describing the context of the error
   7435      * @return true if the process should exit immediately (WTF is fatal)
   7436      */
   7437     public boolean handleApplicationWtf(IBinder app, String tag,
   7438             ApplicationErrorReport.CrashInfo crashInfo) {
   7439         ProcessRecord r = findAppProcess(app, "WTF");
   7440         final String processName = app == null ? "system_server"
   7441                 : (r == null ? "unknown" : r.processName);
   7442 
   7443         EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
   7444                 processName,
   7445                 r == null ? -1 : r.info.flags,
   7446                 tag, crashInfo.exceptionMessage);
   7447 
   7448         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
   7449 
   7450         if (r != null && r.pid != Process.myPid() &&
   7451                 Settings.Secure.getInt(mContext.getContentResolver(),
   7452                         Settings.Secure.WTF_IS_FATAL, 0) != 0) {
   7453             crashApplication(r, crashInfo);
   7454             return true;
   7455         } else {
   7456             return false;
   7457         }
   7458     }
   7459 
   7460     /**
   7461      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
   7462      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
   7463      */
   7464     private ProcessRecord findAppProcess(IBinder app, String reason) {
   7465         if (app == null) {
   7466             return null;
   7467         }
   7468 
   7469         synchronized (this) {
   7470             for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   7471                 final int NA = apps.size();
   7472                 for (int ia=0; ia<NA; ia++) {
   7473                     ProcessRecord p = apps.valueAt(ia);
   7474                     if (p.thread != null && p.thread.asBinder() == app) {
   7475                         return p;
   7476                     }
   7477                 }
   7478             }
   7479 
   7480             Slog.w(TAG, "Can't find mystery application for " + reason
   7481                     + " from pid=" + Binder.getCallingPid()
   7482                     + " uid=" + Binder.getCallingUid() + ": " + app);
   7483             return null;
   7484         }
   7485     }
   7486 
   7487     /**
   7488      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
   7489      * to append various headers to the dropbox log text.
   7490      */
   7491     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
   7492             StringBuilder sb) {
   7493         // Watchdog thread ends up invoking this function (with
   7494         // a null ProcessRecord) to add the stack file to dropbox.
   7495         // Do not acquire a lock on this (am) in such cases, as it
   7496         // could cause a potential deadlock, if and when watchdog
   7497         // is invoked due to unavailability of lock on am and it
   7498         // would prevent watchdog from killing system_server.
   7499         if (process == null) {
   7500             sb.append("Process: ").append(processName).append("\n");
   7501             return;
   7502         }
   7503         // Note: ProcessRecord 'process' is guarded by the service
   7504         // instance.  (notably process.pkgList, which could otherwise change
   7505         // concurrently during execution of this method)
   7506         synchronized (this) {
   7507             sb.append("Process: ").append(processName).append("\n");
   7508             int flags = process.info.flags;
   7509             IPackageManager pm = AppGlobals.getPackageManager();
   7510             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
   7511             for (String pkg : process.pkgList) {
   7512                 sb.append("Package: ").append(pkg);
   7513                 try {
   7514                     PackageInfo pi = pm.getPackageInfo(pkg, 0);
   7515                     if (pi != null) {
   7516                         sb.append(" v").append(pi.versionCode);
   7517                         if (pi.versionName != null) {
   7518                             sb.append(" (").append(pi.versionName).append(")");
   7519                         }
   7520                     }
   7521                 } catch (RemoteException e) {
   7522                     Slog.e(TAG, "Error getting package info: " + pkg, e);
   7523                 }
   7524                 sb.append("\n");
   7525             }
   7526         }
   7527     }
   7528 
   7529     private static String processClass(ProcessRecord process) {
   7530         if (process == null || process.pid == MY_PID) {
   7531             return "system_server";
   7532         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   7533             return "system_app";
   7534         } else {
   7535             return "data_app";
   7536         }
   7537     }
   7538 
   7539     /**
   7540      * Write a description of an error (crash, WTF, ANR) to the drop box.
   7541      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
   7542      * @param process which caused the error, null means the system server
   7543      * @param activity which triggered the error, null if unknown
   7544      * @param parent activity related to the error, null if unknown
   7545      * @param subject line related to the error, null if absent
   7546      * @param report in long form describing the error, null if absent
   7547      * @param logFile to include in the report, null if none
   7548      * @param crashInfo giving an application stack trace, null if absent
   7549      */
   7550     public void addErrorToDropBox(String eventType,
   7551             ProcessRecord process, String processName, ActivityRecord activity,
   7552             ActivityRecord parent, String subject,
   7553             final String report, final File logFile,
   7554             final ApplicationErrorReport.CrashInfo crashInfo) {
   7555         // NOTE -- this must never acquire the ActivityManagerService lock,
   7556         // otherwise the watchdog may be prevented from resetting the system.
   7557 
   7558         final String dropboxTag = processClass(process) + "_" + eventType;
   7559         final DropBoxManager dbox = (DropBoxManager)
   7560                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   7561 
   7562         // Exit early if the dropbox isn't configured to accept this report type.
   7563         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   7564 
   7565         final StringBuilder sb = new StringBuilder(1024);
   7566         appendDropBoxProcessHeaders(process, processName, sb);
   7567         if (activity != null) {
   7568             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
   7569         }
   7570         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
   7571             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
   7572         }
   7573         if (parent != null && parent != activity) {
   7574             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
   7575         }
   7576         if (subject != null) {
   7577             sb.append("Subject: ").append(subject).append("\n");
   7578         }
   7579         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   7580         if (Debug.isDebuggerConnected()) {
   7581             sb.append("Debugger: Connected\n");
   7582         }
   7583         sb.append("\n");
   7584 
   7585         // Do the rest in a worker thread to avoid blocking the caller on I/O
   7586         // (After this point, we shouldn't access AMS internal data structures.)
   7587         Thread worker = new Thread("Error dump: " + dropboxTag) {
   7588             @Override
   7589             public void run() {
   7590                 if (report != null) {
   7591                     sb.append(report);
   7592                 }
   7593                 if (logFile != null) {
   7594                     try {
   7595                         sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
   7596                     } catch (IOException e) {
   7597                         Slog.e(TAG, "Error reading " + logFile, e);
   7598                     }
   7599                 }
   7600                 if (crashInfo != null && crashInfo.stackTrace != null) {
   7601                     sb.append(crashInfo.stackTrace);
   7602                 }
   7603 
   7604                 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
   7605                 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
   7606                 if (lines > 0) {
   7607                     sb.append("\n");
   7608 
   7609                     // Merge several logcat streams, and take the last N lines
   7610                     InputStreamReader input = null;
   7611                     try {
   7612                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
   7613                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
   7614                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
   7615 
   7616                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
   7617                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
   7618                         input = new InputStreamReader(logcat.getInputStream());
   7619 
   7620                         int num;
   7621                         char[] buf = new char[8192];
   7622                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
   7623                     } catch (IOException e) {
   7624                         Slog.e(TAG, "Error running logcat", e);
   7625                     } finally {
   7626                         if (input != null) try { input.close(); } catch (IOException e) {}
   7627                     }
   7628                 }
   7629 
   7630                 dbox.addText(dropboxTag, sb.toString());
   7631             }
   7632         };
   7633 
   7634         if (process == null || process.pid == MY_PID) {
   7635             worker.run();  // We may be about to die -- need to run this synchronously
   7636         } else {
   7637             worker.start();
   7638         }
   7639     }
   7640 
   7641     /**
   7642      * Bring up the "unexpected error" dialog box for a crashing app.
   7643      * Deal with edge cases (intercepts from instrumented applications,
   7644      * ActivityController, error intent receivers, that sort of thing).
   7645      * @param r the application crashing
   7646      * @param crashInfo describing the failure
   7647      */
   7648     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
   7649         long timeMillis = System.currentTimeMillis();
   7650         String shortMsg = crashInfo.exceptionClassName;
   7651         String longMsg = crashInfo.exceptionMessage;
   7652         String stackTrace = crashInfo.stackTrace;
   7653         if (shortMsg != null && longMsg != null) {
   7654             longMsg = shortMsg + ": " + longMsg;
   7655         } else if (shortMsg != null) {
   7656             longMsg = shortMsg;
   7657         }
   7658 
   7659         AppErrorResult result = new AppErrorResult();
   7660         synchronized (this) {
   7661             if (mController != null) {
   7662                 try {
   7663                     String name = r != null ? r.processName : null;
   7664                     int pid = r != null ? r.pid : Binder.getCallingPid();
   7665                     if (!mController.appCrashed(name, pid,
   7666                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
   7667                         Slog.w(TAG, "Force-killing crashed app " + name
   7668                                 + " at watcher's request");
   7669                         Process.killProcess(pid);
   7670                         return;
   7671                     }
   7672                 } catch (RemoteException e) {
   7673                     mController = null;
   7674                 }
   7675             }
   7676 
   7677             final long origId = Binder.clearCallingIdentity();
   7678 
   7679             // If this process is running instrumentation, finish it.
   7680             if (r != null && r.instrumentationClass != null) {
   7681                 Slog.w(TAG, "Error in app " + r.processName
   7682                       + " running instrumentation " + r.instrumentationClass + ":");
   7683                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
   7684                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
   7685                 Bundle info = new Bundle();
   7686                 info.putString("shortMsg", shortMsg);
   7687                 info.putString("longMsg", longMsg);
   7688                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
   7689                 Binder.restoreCallingIdentity(origId);
   7690                 return;
   7691             }
   7692 
   7693             // If we can't identify the process or it's already exceeded its crash quota,
   7694             // quit right away without showing a crash dialog.
   7695             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
   7696                 Binder.restoreCallingIdentity(origId);
   7697                 return;
   7698             }
   7699 
   7700             Message msg = Message.obtain();
   7701             msg.what = SHOW_ERROR_MSG;
   7702             HashMap data = new HashMap();
   7703             data.put("result", result);
   7704             data.put("app", r);
   7705             msg.obj = data;
   7706             mHandler.sendMessage(msg);
   7707 
   7708             Binder.restoreCallingIdentity(origId);
   7709         }
   7710 
   7711         int res = result.get();
   7712 
   7713         Intent appErrorIntent = null;
   7714         synchronized (this) {
   7715             if (r != null) {
   7716                 mProcessCrashTimes.put(r.info.processName, r.info.uid,
   7717                         SystemClock.uptimeMillis());
   7718             }
   7719             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
   7720                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
   7721             }
   7722         }
   7723 
   7724         if (appErrorIntent != null) {
   7725             try {
   7726                 mContext.startActivity(appErrorIntent);
   7727             } catch (ActivityNotFoundException e) {
   7728                 Slog.w(TAG, "bug report receiver dissappeared", e);
   7729             }
   7730         }
   7731     }
   7732 
   7733     Intent createAppErrorIntentLocked(ProcessRecord r,
   7734             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   7735         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
   7736         if (report == null) {
   7737             return null;
   7738         }
   7739         Intent result = new Intent(Intent.ACTION_APP_ERROR);
   7740         result.setComponent(r.errorReportReceiver);
   7741         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
   7742         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   7743         return result;
   7744     }
   7745 
   7746     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
   7747             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   7748         if (r.errorReportReceiver == null) {
   7749             return null;
   7750         }
   7751 
   7752         if (!r.crashing && !r.notResponding) {
   7753             return null;
   7754         }
   7755 
   7756         ApplicationErrorReport report = new ApplicationErrorReport();
   7757         report.packageName = r.info.packageName;
   7758         report.installerPackageName = r.errorReportReceiver.getPackageName();
   7759         report.processName = r.processName;
   7760         report.time = timeMillis;
   7761         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   7762 
   7763         if (r.crashing) {
   7764             report.type = ApplicationErrorReport.TYPE_CRASH;
   7765             report.crashInfo = crashInfo;
   7766         } else if (r.notResponding) {
   7767             report.type = ApplicationErrorReport.TYPE_ANR;
   7768             report.anrInfo = new ApplicationErrorReport.AnrInfo();
   7769 
   7770             report.anrInfo.activity = r.notRespondingReport.tag;
   7771             report.anrInfo.cause = r.notRespondingReport.shortMsg;
   7772             report.anrInfo.info = r.notRespondingReport.longMsg;
   7773         }
   7774 
   7775         return report;
   7776     }
   7777 
   7778     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
   7779         // assume our apps are happy - lazy create the list
   7780         List<ActivityManager.ProcessErrorStateInfo> errList = null;
   7781 
   7782         synchronized (this) {
   7783 
   7784             // iterate across all processes
   7785             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   7786                 ProcessRecord app = mLruProcesses.get(i);
   7787                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
   7788                     // This one's in trouble, so we'll generate a report for it
   7789                     // crashes are higher priority (in case there's a crash *and* an anr)
   7790                     ActivityManager.ProcessErrorStateInfo report = null;
   7791                     if (app.crashing) {
   7792                         report = app.crashingReport;
   7793                     } else if (app.notResponding) {
   7794                         report = app.notRespondingReport;
   7795                     }
   7796 
   7797                     if (report != null) {
   7798                         if (errList == null) {
   7799                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
   7800                         }
   7801                         errList.add(report);
   7802                     } else {
   7803                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
   7804                                 " crashing = " + app.crashing +
   7805                                 " notResponding = " + app.notResponding);
   7806                     }
   7807                 }
   7808             }
   7809         }
   7810 
   7811         return errList;
   7812     }
   7813 
   7814     static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
   7815         if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   7816             if (currApp != null) {
   7817                 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
   7818             }
   7819             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   7820         } else if (adj >= ProcessList.SERVICE_B_ADJ) {
   7821             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   7822         } else if (adj >= ProcessList.HOME_APP_ADJ) {
   7823             if (currApp != null) {
   7824                 currApp.lru = 0;
   7825             }
   7826             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   7827         } else if (adj >= ProcessList.SERVICE_ADJ) {
   7828             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   7829         } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   7830             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
   7831         } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   7832             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
   7833         } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
   7834             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
   7835         } else {
   7836             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
   7837         }
   7838     }
   7839 
   7840     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
   7841         // Lazy instantiation of list
   7842         List<ActivityManager.RunningAppProcessInfo> runList = null;
   7843         synchronized (this) {
   7844             // Iterate across all processes
   7845             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   7846                 ProcessRecord app = mLruProcesses.get(i);
   7847                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
   7848                     // Generate process state info for running application
   7849                     ActivityManager.RunningAppProcessInfo currApp =
   7850                         new ActivityManager.RunningAppProcessInfo(app.processName,
   7851                                 app.pid, app.getPackageList());
   7852                     currApp.uid = app.info.uid;
   7853                     if (mHeavyWeightProcess == app) {
   7854                         currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
   7855                     }
   7856                     if (app.persistent) {
   7857                         currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
   7858                     }
   7859                     int adj = app.curAdj;
   7860                     currApp.importance = oomAdjToImportance(adj, currApp);
   7861                     currApp.importanceReasonCode = app.adjTypeCode;
   7862                     if (app.adjSource instanceof ProcessRecord) {
   7863                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
   7864                         currApp.importanceReasonImportance = oomAdjToImportance(
   7865                                 app.adjSourceOom, null);
   7866                     } else if (app.adjSource instanceof ActivityRecord) {
   7867                         ActivityRecord r = (ActivityRecord)app.adjSource;
   7868                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
   7869                     }
   7870                     if (app.adjTarget instanceof ComponentName) {
   7871                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
   7872                     }
   7873                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
   7874                     //        + " lru=" + currApp.lru);
   7875                     if (runList == null) {
   7876                         runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
   7877                     }
   7878                     runList.add(currApp);
   7879                 }
   7880             }
   7881         }
   7882         return runList;
   7883     }
   7884 
   7885     public List<ApplicationInfo> getRunningExternalApplications() {
   7886         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
   7887         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
   7888         if (runningApps != null && runningApps.size() > 0) {
   7889             Set<String> extList = new HashSet<String>();
   7890             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
   7891                 if (app.pkgList != null) {
   7892                     for (String pkg : app.pkgList) {
   7893                         extList.add(pkg);
   7894                     }
   7895                 }
   7896             }
   7897             IPackageManager pm = AppGlobals.getPackageManager();
   7898             for (String pkg : extList) {
   7899                 try {
   7900                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
   7901                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
   7902                         retList.add(info);
   7903                     }
   7904                 } catch (RemoteException e) {
   7905                 }
   7906             }
   7907         }
   7908         return retList;
   7909     }
   7910 
   7911     @Override
   7912     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   7913         if (checkCallingPermission(android.Manifest.permission.DUMP)
   7914                 != PackageManager.PERMISSION_GRANTED) {
   7915             pw.println("Permission Denial: can't dump ActivityManager from from pid="
   7916                     + Binder.getCallingPid()
   7917                     + ", uid=" + Binder.getCallingUid()
   7918                     + " without permission "
   7919                     + android.Manifest.permission.DUMP);
   7920             return;
   7921         }
   7922 
   7923         boolean dumpAll = false;
   7924         boolean dumpClient = false;
   7925         String dumpPackage = null;
   7926 
   7927         int opti = 0;
   7928         while (opti < args.length) {
   7929             String opt = args[opti];
   7930             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   7931                 break;
   7932             }
   7933             opti++;
   7934             if ("-a".equals(opt)) {
   7935                 dumpAll = true;
   7936             } else if ("-c".equals(opt)) {
   7937                 dumpClient = true;
   7938             } else if ("-h".equals(opt)) {
   7939                 pw.println("Activity manager dump options:");
   7940                 pw.println("  [-a] [-c] [-h] [cmd] ...");
   7941                 pw.println("  cmd may be one of:");
   7942                 pw.println("    a[ctivities]: activity stack state");
   7943                 pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
   7944                 pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
   7945                 pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
   7946                 pw.println("    o[om]: out of memory management");
   7947                 pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
   7948                 pw.println("    s[ervices] [COMP_SPEC ...]: service state");
   7949                 pw.println("    service [COMP_SPEC]: service client-side state");
   7950                 pw.println("    package [PACKAGE_NAME]: all state related to given package");
   7951                 pw.println("    all: dump all activities");
   7952                 pw.println("    top: dump the top activity");
   7953                 pw.println("  cmd may also be a COMP_SPEC to dump activities.");
   7954                 pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
   7955                 pw.println("    a partial substring in a component name, a");
   7956                 pw.println("    hex object identifier.");
   7957                 pw.println("  -a: include all available server state.");
   7958                 pw.println("  -c: include client state.");
   7959                 return;
   7960             } else {
   7961                 pw.println("Unknown argument: " + opt + "; use -h for help");
   7962             }
   7963         }
   7964 
   7965         // Is the caller requesting to dump a particular piece of data?
   7966         if (opti < args.length) {
   7967             String cmd = args[opti];
   7968             opti++;
   7969             if ("activities".equals(cmd) || "a".equals(cmd)) {
   7970                 synchronized (this) {
   7971                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
   7972                 }
   7973                 return;
   7974             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
   7975                 String[] newArgs;
   7976                 String name;
   7977                 if (opti >= args.length) {
   7978                     name = null;
   7979                     newArgs = EMPTY_STRING_ARRAY;
   7980                 } else {
   7981                     name = args[opti];
   7982                     opti++;
   7983                     newArgs = new String[args.length - opti];
   7984                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   7985                             args.length - opti);
   7986                 }
   7987                 synchronized (this) {
   7988                     dumpBroadcastsLocked(fd, pw, args, opti, true, name);
   7989                 }
   7990                 return;
   7991             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
   7992                 String[] newArgs;
   7993                 String name;
   7994                 if (opti >= args.length) {
   7995                     name = null;
   7996                     newArgs = EMPTY_STRING_ARRAY;
   7997                 } else {
   7998                     name = args[opti];
   7999                     opti++;
   8000                     newArgs = new String[args.length - opti];
   8001                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   8002                             args.length - opti);
   8003                 }
   8004                 synchronized (this) {
   8005                     dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
   8006                 }
   8007                 return;
   8008             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
   8009                 String[] newArgs;
   8010                 String name;
   8011                 if (opti >= args.length) {
   8012                     name = null;
   8013                     newArgs = EMPTY_STRING_ARRAY;
   8014                 } else {
   8015                     name = args[opti];
   8016                     opti++;
   8017                     newArgs = new String[args.length - opti];
   8018                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   8019                             args.length - opti);
   8020                 }
   8021                 synchronized (this) {
   8022                     dumpProcessesLocked(fd, pw, args, opti, true, name);
   8023                 }
   8024                 return;
   8025             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
   8026                 synchronized (this) {
   8027                     dumpOomLocked(fd, pw, args, opti, true);
   8028                 }
   8029                 return;
   8030             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
   8031                 synchronized (this) {
   8032                     dumpProvidersLocked(fd, pw, args, opti, true, null);
   8033                 }
   8034                 return;
   8035             } else if ("service".equals(cmd)) {
   8036                 String[] newArgs;
   8037                 String name;
   8038                 if (opti >= args.length) {
   8039                     name = null;
   8040                     newArgs = EMPTY_STRING_ARRAY;
   8041                 } else {
   8042                     name = args[opti];
   8043                     opti++;
   8044                     newArgs = new String[args.length - opti];
   8045                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   8046                             args.length - opti);
   8047                 }
   8048                 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
   8049                     pw.println("No services match: " + name);
   8050                     pw.println("Use -h for help.");
   8051                 }
   8052                 return;
   8053             } else if ("package".equals(cmd)) {
   8054                 String[] newArgs;
   8055                 if (opti >= args.length) {
   8056                     pw.println("package: no package name specified");
   8057                     pw.println("Use -h for help.");
   8058                     return;
   8059                 } else {
   8060                     dumpPackage = args[opti];
   8061                     opti++;
   8062                     newArgs = new String[args.length - opti];
   8063                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   8064                             args.length - opti);
   8065                     args = newArgs;
   8066                     opti = 0;
   8067                 }
   8068             } else if ("services".equals(cmd) || "s".equals(cmd)) {
   8069                 synchronized (this) {
   8070                     dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
   8071                 }
   8072                 return;
   8073             } else {
   8074                 // Dumping a single activity?
   8075                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
   8076                     pw.println("Bad activity command, or no activities match: " + cmd);
   8077                     pw.println("Use -h for help.");
   8078                 }
   8079                 return;
   8080             }
   8081         }
   8082 
   8083         // No piece of data specified, dump everything.
   8084         synchronized (this) {
   8085             boolean needSep;
   8086             needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   8087             if (needSep) {
   8088                 pw.println(" ");
   8089             }
   8090             if (dumpAll) {
   8091                 pw.println("-------------------------------------------------------------------------------");
   8092             }
   8093             needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   8094             if (needSep) {
   8095                 pw.println(" ");
   8096             }
   8097             if (dumpAll) {
   8098                 pw.println("-------------------------------------------------------------------------------");
   8099             }
   8100             needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   8101             if (needSep) {
   8102                 pw.println(" ");
   8103             }
   8104             if (dumpAll) {
   8105                 pw.println("-------------------------------------------------------------------------------");
   8106             }
   8107             needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   8108             if (needSep) {
   8109                 pw.println(" ");
   8110             }
   8111             if (dumpAll) {
   8112                 pw.println("-------------------------------------------------------------------------------");
   8113             }
   8114             needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   8115             if (needSep) {
   8116                 pw.println(" ");
   8117             }
   8118             if (dumpAll) {
   8119                 pw.println("-------------------------------------------------------------------------------");
   8120             }
   8121             dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   8122         }
   8123     }
   8124 
   8125     boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   8126             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   8127         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
   8128         pw.println("  Main stack:");
   8129         dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
   8130                 dumpPackage);
   8131         pw.println(" ");
   8132         pw.println("  Running activities (most recent first):");
   8133         dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
   8134                 dumpPackage);
   8135         if (mMainStack.mWaitingVisibleActivities.size() > 0) {
   8136             pw.println(" ");
   8137             pw.println("  Activities waiting for another to become visible:");
   8138             dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
   8139                     !dumpAll, false, dumpPackage);
   8140         }
   8141         if (mMainStack.mStoppingActivities.size() > 0) {
   8142             pw.println(" ");
   8143             pw.println("  Activities waiting to stop:");
   8144             dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
   8145                     !dumpAll, false, dumpPackage);
   8146         }
   8147         if (mMainStack.mGoingToSleepActivities.size() > 0) {
   8148             pw.println(" ");
   8149             pw.println("  Activities waiting to sleep:");
   8150             dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
   8151                     !dumpAll, false, dumpPackage);
   8152         }
   8153         if (mMainStack.mFinishingActivities.size() > 0) {
   8154             pw.println(" ");
   8155             pw.println("  Activities waiting to finish:");
   8156             dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
   8157                     !dumpAll, false, dumpPackage);
   8158         }
   8159 
   8160         pw.println(" ");
   8161         if (mMainStack.mPausingActivity != null) {
   8162             pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
   8163         }
   8164         pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
   8165         pw.println("  mFocusedActivity: " + mFocusedActivity);
   8166         if (dumpAll) {
   8167             pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
   8168             pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
   8169             pw.println("  mDismissKeyguardOnNextActivity: "
   8170                     + mMainStack.mDismissKeyguardOnNextActivity);
   8171         }
   8172 
   8173         if (mRecentTasks.size() > 0) {
   8174             pw.println();
   8175             pw.println("  Recent tasks:");
   8176 
   8177             final int N = mRecentTasks.size();
   8178             for (int i=0; i<N; i++) {
   8179                 TaskRecord tr = mRecentTasks.get(i);
   8180                 if (dumpPackage != null) {
   8181                     if (tr.realActivity == null ||
   8182                             !dumpPackage.equals(tr.realActivity)) {
   8183                         continue;
   8184                     }
   8185                 }
   8186                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
   8187                         pw.println(tr);
   8188                 if (dumpAll) {
   8189                     mRecentTasks.get(i).dump(pw, "    ");
   8190                 }
   8191             }
   8192         }
   8193 
   8194         if (dumpAll) {
   8195             pw.println(" ");
   8196             pw.println("  mCurTask: " + mCurTask);
   8197         }
   8198 
   8199         return true;
   8200     }
   8201 
   8202     boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   8203             int opti, boolean dumpAll, String dumpPackage) {
   8204         boolean needSep = false;
   8205         int numPers = 0;
   8206 
   8207         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
   8208 
   8209         if (dumpAll) {
   8210             for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
   8211                 final int NA = procs.size();
   8212                 for (int ia=0; ia<NA; ia++) {
   8213                     ProcessRecord r = procs.valueAt(ia);
   8214                     if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   8215                         continue;
   8216                     }
   8217                     if (!needSep) {
   8218                         pw.println("  All known processes:");
   8219                         needSep = true;
   8220                     }
   8221                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
   8222                         pw.print(" UID "); pw.print(procs.keyAt(ia));
   8223                         pw.print(" "); pw.println(r);
   8224                     r.dump(pw, "    ");
   8225                     if (r.persistent) {
   8226                         numPers++;
   8227                     }
   8228                 }
   8229             }
   8230         }
   8231 
   8232         if (mLruProcesses.size() > 0) {
   8233             if (needSep) pw.println(" ");
   8234             needSep = true;
   8235             pw.println("  Process LRU list (sorted by oom_adj):");
   8236             dumpProcessOomList(pw, this, mLruProcesses, "    ",
   8237                     "Proc", "PERS", false, dumpPackage);
   8238             needSep = true;
   8239         }
   8240 
   8241         if (dumpAll) {
   8242             synchronized (mPidsSelfLocked) {
   8243                 boolean printed = false;
   8244                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   8245                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
   8246                     if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   8247                         continue;
   8248                     }
   8249                     if (!printed) {
   8250                         if (needSep) pw.println(" ");
   8251                         needSep = true;
   8252                         pw.println("  PID mappings:");
   8253                         printed = true;
   8254                     }
   8255                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
   8256                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
   8257                 }
   8258             }
   8259         }
   8260 
   8261         if (mForegroundProcesses.size() > 0) {
   8262             synchronized (mPidsSelfLocked) {
   8263                 boolean printed = false;
   8264                 for (int i=0; i<mForegroundProcesses.size(); i++) {
   8265                     ProcessRecord r = mPidsSelfLocked.get(
   8266                             mForegroundProcesses.valueAt(i).pid);
   8267                     if (dumpPackage != null && (r == null
   8268                             || !dumpPackage.equals(r.info.packageName))) {
   8269                         continue;
   8270                     }
   8271                     if (!printed) {
   8272                         if (needSep) pw.println(" ");
   8273                         needSep = true;
   8274                         pw.println("  Foreground Processes:");
   8275                         printed = true;
   8276                     }
   8277                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
   8278                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
   8279                 }
   8280             }
   8281         }
   8282 
   8283         if (mPersistentStartingProcesses.size() > 0) {
   8284             if (needSep) pw.println(" ");
   8285             needSep = true;
   8286             pw.println("  Persisent processes that are starting:");
   8287             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
   8288                     "Starting Norm", "Restarting PERS", dumpPackage);
   8289         }
   8290 
   8291         if (mRemovedProcesses.size() > 0) {
   8292             if (needSep) pw.println(" ");
   8293             needSep = true;
   8294             pw.println("  Processes that are being removed:");
   8295             dumpProcessList(pw, this, mRemovedProcesses, "    ",
   8296                     "Removed Norm", "Removed PERS", dumpPackage);
   8297         }
   8298 
   8299         if (mProcessesOnHold.size() > 0) {
   8300             if (needSep) pw.println(" ");
   8301             needSep = true;
   8302             pw.println("  Processes that are on old until the system is ready:");
   8303             dumpProcessList(pw, this, mProcessesOnHold, "    ",
   8304                     "OnHold Norm", "OnHold PERS", dumpPackage);
   8305         }
   8306 
   8307         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
   8308 
   8309         if (mProcessCrashTimes.getMap().size() > 0) {
   8310             boolean printed = false;
   8311             long now = SystemClock.uptimeMillis();
   8312             for (Map.Entry<String, SparseArray<Long>> procs
   8313                     : mProcessCrashTimes.getMap().entrySet()) {
   8314                 String pname = procs.getKey();
   8315                 SparseArray<Long> uids = procs.getValue();
   8316                 final int N = uids.size();
   8317                 for (int i=0; i<N; i++) {
   8318                     int puid = uids.keyAt(i);
   8319                     ProcessRecord r = mProcessNames.get(pname, puid);
   8320                     if (dumpPackage != null && (r == null
   8321                             || !dumpPackage.equals(r.info.packageName))) {
   8322                         continue;
   8323                     }
   8324                     if (!printed) {
   8325                         if (needSep) pw.println(" ");
   8326                         needSep = true;
   8327                         pw.println("  Time since processes crashed:");
   8328                         printed = true;
   8329                     }
   8330                     pw.print("    Process "); pw.print(pname);
   8331                             pw.print(" uid "); pw.print(puid);
   8332                             pw.print(": last crashed ");
   8333                             pw.print((now-uids.valueAt(i)));
   8334                             pw.println(" ms ago");
   8335                 }
   8336             }
   8337         }
   8338 
   8339         if (mBadProcesses.getMap().size() > 0) {
   8340             boolean printed = false;
   8341             for (Map.Entry<String, SparseArray<Long>> procs
   8342                     : mBadProcesses.getMap().entrySet()) {
   8343                 String pname = procs.getKey();
   8344                 SparseArray<Long> uids = procs.getValue();
   8345                 final int N = uids.size();
   8346                 for (int i=0; i<N; i++) {
   8347                     int puid = uids.keyAt(i);
   8348                     ProcessRecord r = mProcessNames.get(pname, puid);
   8349                     if (dumpPackage != null && (r == null
   8350                             || !dumpPackage.equals(r.info.packageName))) {
   8351                         continue;
   8352                     }
   8353                     if (!printed) {
   8354                         if (needSep) pw.println(" ");
   8355                         needSep = true;
   8356                         pw.println("  Bad processes:");
   8357                     }
   8358                     pw.print("    Bad process "); pw.print(pname);
   8359                             pw.print(" uid "); pw.print(puid);
   8360                             pw.print(": crashed at time ");
   8361                             pw.println(uids.valueAt(i));
   8362                 }
   8363             }
   8364         }
   8365 
   8366         pw.println();
   8367         pw.println("  mHomeProcess: " + mHomeProcess);
   8368         pw.println("  mPreviousProcess: " + mPreviousProcess);
   8369         if (dumpAll) {
   8370             StringBuilder sb = new StringBuilder(128);
   8371             sb.append("  mPreviousProcessVisibleTime: ");
   8372             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
   8373             pw.println(sb);
   8374         }
   8375         if (mHeavyWeightProcess != null) {
   8376             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   8377         }
   8378         pw.println("  mConfiguration: " + mConfiguration);
   8379         if (dumpAll) {
   8380             pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
   8381             if (mCompatModePackages.getPackages().size() > 0) {
   8382                 boolean printed = false;
   8383                 for (Map.Entry<String, Integer> entry
   8384                         : mCompatModePackages.getPackages().entrySet()) {
   8385                     String pkg = entry.getKey();
   8386                     int mode = entry.getValue();
   8387                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
   8388                         continue;
   8389                     }
   8390                     if (!printed) {
   8391                         pw.println("  mScreenCompatPackages:");
   8392                         printed = true;
   8393                     }
   8394                     pw.print("    "); pw.print(pkg); pw.print(": ");
   8395                             pw.print(mode); pw.println();
   8396                 }
   8397             }
   8398         }
   8399         pw.println("  mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
   8400         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
   8401                 || mOrigWaitForDebugger) {
   8402             pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
   8403                     + " mDebugTransient=" + mDebugTransient
   8404                     + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
   8405         }
   8406         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
   8407                 || mProfileFd != null) {
   8408             pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
   8409             pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
   8410             pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
   8411                     + mAutoStopProfiler);
   8412         }
   8413         if (mAlwaysFinishActivities || mController != null) {
   8414             pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
   8415                     + " mController=" + mController);
   8416         }
   8417         if (dumpAll) {
   8418             pw.println("  Total persistent processes: " + numPers);
   8419             pw.println("  mStartRunning=" + mStartRunning
   8420                     + " mProcessesReady=" + mProcessesReady
   8421                     + " mSystemReady=" + mSystemReady);
   8422             pw.println("  mBooting=" + mBooting
   8423                     + " mBooted=" + mBooted
   8424                     + " mFactoryTest=" + mFactoryTest);
   8425             pw.print("  mLastPowerCheckRealtime=");
   8426                     TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
   8427                     pw.println("");
   8428             pw.print("  mLastPowerCheckUptime=");
   8429                     TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
   8430                     pw.println("");
   8431             pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
   8432             pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
   8433             pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
   8434             pw.println("  mNumServiceProcs=" + mNumServiceProcs
   8435                     + " mNewNumServiceProcs=" + mNewNumServiceProcs);
   8436         }
   8437 
   8438         return true;
   8439     }
   8440 
   8441     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
   8442             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
   8443         if (mProcessesToGc.size() > 0) {
   8444             boolean printed = false;
   8445             long now = SystemClock.uptimeMillis();
   8446             for (int i=0; i<mProcessesToGc.size(); i++) {
   8447                 ProcessRecord proc = mProcessesToGc.get(i);
   8448                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
   8449                     continue;
   8450                 }
   8451                 if (!printed) {
   8452                     if (needSep) pw.println(" ");
   8453                     needSep = true;
   8454                     pw.println("  Processes that are waiting to GC:");
   8455                     printed = true;
   8456                 }
   8457                 pw.print("    Process "); pw.println(proc);
   8458                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
   8459                         pw.print(", last gced=");
   8460                         pw.print(now-proc.lastRequestedGc);
   8461                         pw.print(" ms ago, last lowMem=");
   8462                         pw.print(now-proc.lastLowMemory);
   8463                         pw.println(" ms ago");
   8464 
   8465             }
   8466         }
   8467         return needSep;
   8468     }
   8469 
   8470     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   8471             int opti, boolean dumpAll) {
   8472         boolean needSep = false;
   8473 
   8474         if (mLruProcesses.size() > 0) {
   8475             if (needSep) pw.println(" ");
   8476             needSep = true;
   8477             pw.println("  OOM levels:");
   8478             pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
   8479             pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
   8480             pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
   8481             pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
   8482             pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
   8483             pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
   8484             pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
   8485             pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
   8486             pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
   8487             pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
   8488             pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
   8489             pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
   8490             pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
   8491 
   8492             if (needSep) pw.println(" ");
   8493             needSep = true;
   8494             pw.println("  Process OOM control:");
   8495             dumpProcessOomList(pw, this, mLruProcesses, "    ",
   8496                     "Proc", "PERS", true, null);
   8497             needSep = true;
   8498         }
   8499 
   8500         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
   8501 
   8502         pw.println();
   8503         pw.println("  mHomeProcess: " + mHomeProcess);
   8504         pw.println("  mPreviousProcess: " + mPreviousProcess);
   8505         if (mHeavyWeightProcess != null) {
   8506             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   8507         }
   8508 
   8509         return true;
   8510     }
   8511 
   8512     /**
   8513      * There are three ways to call this:
   8514      *  - no service specified: dump all the services
   8515      *  - a flattened component name that matched an existing service was specified as the
   8516      *    first arg: dump that one service
   8517      *  - the first arg isn't the flattened component name of an existing service:
   8518      *    dump all services whose component contains the first arg as a substring
   8519      */
   8520     protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   8521             int opti, boolean dumpAll) {
   8522         ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
   8523 
   8524         if ("all".equals(name)) {
   8525             synchronized (this) {
   8526                 for (ServiceRecord r1 : mServices.values()) {
   8527                     services.add(r1);
   8528                 }
   8529             }
   8530         } else {
   8531             ComponentName componentName = name != null
   8532                     ? ComponentName.unflattenFromString(name) : null;
   8533             int objectId = 0;
   8534             if (componentName == null) {
   8535                 // Not a '/' separated full component name; maybe an object ID?
   8536                 try {
   8537                     objectId = Integer.parseInt(name, 16);
   8538                     name = null;
   8539                     componentName = null;
   8540                 } catch (RuntimeException e) {
   8541                 }
   8542             }
   8543 
   8544             synchronized (this) {
   8545                 for (ServiceRecord r1 : mServices.values()) {
   8546                     if (componentName != null) {
   8547                         if (r1.name.equals(componentName)) {
   8548                             services.add(r1);
   8549                         }
   8550                     } else if (name != null) {
   8551                         if (r1.name.flattenToString().contains(name)) {
   8552                             services.add(r1);
   8553                         }
   8554                     } else if (System.identityHashCode(r1) == objectId) {
   8555                         services.add(r1);
   8556                     }
   8557                 }
   8558             }
   8559         }
   8560 
   8561         if (services.size() <= 0) {
   8562             return false;
   8563         }
   8564 
   8565         boolean needSep = false;
   8566         for (int i=0; i<services.size(); i++) {
   8567             if (needSep) {
   8568                 pw.println();
   8569             }
   8570             needSep = true;
   8571             dumpService("", fd, pw, services.get(i), args, dumpAll);
   8572         }
   8573         return true;
   8574     }
   8575 
   8576     /**
   8577      * Invokes IApplicationThread.dumpService() on the thread of the specified service if
   8578      * there is a thread associated with the service.
   8579      */
   8580     private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
   8581             final ServiceRecord r, String[] args, boolean dumpAll) {
   8582         String innerPrefix = prefix + "  ";
   8583         synchronized (this) {
   8584             pw.print(prefix); pw.print("SERVICE ");
   8585                     pw.print(r.shortName); pw.print(" ");
   8586                     pw.print(Integer.toHexString(System.identityHashCode(r)));
   8587                     pw.print(" pid=");
   8588                     if (r.app != null) pw.println(r.app.pid);
   8589                     else pw.println("(not running)");
   8590             if (dumpAll) {
   8591                 r.dump(pw, innerPrefix);
   8592             }
   8593         }
   8594         if (r.app != null && r.app.thread != null) {
   8595             pw.print(prefix); pw.println("  Client:");
   8596             pw.flush();
   8597             try {
   8598                 TransferPipe tp = new TransferPipe();
   8599                 try {
   8600                     r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
   8601                     tp.setBufferPrefix(prefix + "    ");
   8602                     tp.go(fd);
   8603                 } finally {
   8604                     tp.kill();
   8605                 }
   8606             } catch (IOException e) {
   8607                 pw.println(prefix + "    Failure while dumping the service: " + e);
   8608             } catch (RemoteException e) {
   8609                 pw.println(prefix + "    Got a RemoteException while dumping the service");
   8610             }
   8611         }
   8612     }
   8613 
   8614     static class ItemMatcher {
   8615         ArrayList<ComponentName> components;
   8616         ArrayList<String> strings;
   8617         ArrayList<Integer> objects;
   8618         boolean all;
   8619 
   8620         ItemMatcher() {
   8621             all = true;
   8622         }
   8623 
   8624         void build(String name) {
   8625             ComponentName componentName = ComponentName.unflattenFromString(name);
   8626             if (componentName != null) {
   8627                 if (components == null) {
   8628                     components = new ArrayList<ComponentName>();
   8629                 }
   8630                 components.add(componentName);
   8631                 all = false;
   8632             } else {
   8633                 int objectId = 0;
   8634                 // Not a '/' separated full component name; maybe an object ID?
   8635                 try {
   8636                     objectId = Integer.parseInt(name, 16);
   8637                     if (objects == null) {
   8638                         objects = new ArrayList<Integer>();
   8639                     }
   8640                     objects.add(objectId);
   8641                     all = false;
   8642                 } catch (RuntimeException e) {
   8643                     // Not an integer; just do string match.
   8644                     if (strings == null) {
   8645                         strings = new ArrayList<String>();
   8646                     }
   8647                     strings.add(name);
   8648                     all = false;
   8649                 }
   8650             }
   8651         }
   8652 
   8653         int build(String[] args, int opti) {
   8654             for (; opti<args.length; opti++) {
   8655                 String name = args[opti];
   8656                 if ("--".equals(name)) {
   8657                     return opti+1;
   8658                 }
   8659                 build(name);
   8660             }
   8661             return opti;
   8662         }
   8663 
   8664         boolean match(Object object, ComponentName comp) {
   8665             if (all) {
   8666                 return true;
   8667             }
   8668             if (components != null) {
   8669                 for (int i=0; i<components.size(); i++) {
   8670                     if (components.get(i).equals(comp)) {
   8671                         return true;
   8672                     }
   8673                 }
   8674             }
   8675             if (objects != null) {
   8676                 for (int i=0; i<objects.size(); i++) {
   8677                     if (System.identityHashCode(object) == objects.get(i)) {
   8678                         return true;
   8679                     }
   8680                 }
   8681             }
   8682             if (strings != null) {
   8683                 String flat = comp.flattenToString();
   8684                 for (int i=0; i<strings.size(); i++) {
   8685                     if (flat.contains(strings.get(i))) {
   8686                         return true;
   8687                     }
   8688                 }
   8689             }
   8690             return false;
   8691         }
   8692     }
   8693 
   8694     /**
   8695      * There are three things that cmd can be:
   8696      *  - a flattened component name that matches an existing activity
   8697      *  - the cmd arg isn't the flattened component name of an existing activity:
   8698      *    dump all activity whose component contains the cmd as a substring
   8699      *  - A hex number of the ActivityRecord object instance.
   8700      */
   8701     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   8702             int opti, boolean dumpAll) {
   8703         ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
   8704 
   8705         if ("all".equals(name)) {
   8706             synchronized (this) {
   8707                 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
   8708                     activities.add(r1);
   8709                 }
   8710             }
   8711         } else if ("top".equals(name)) {
   8712             synchronized (this) {
   8713                 final int N = mMainStack.mHistory.size();
   8714                 if (N > 0) {
   8715                     activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
   8716                 }
   8717             }
   8718         } else {
   8719             ItemMatcher matcher = new ItemMatcher();
   8720             matcher.build(name);
   8721 
   8722             synchronized (this) {
   8723                 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
   8724                     if (matcher.match(r1, r1.intent.getComponent())) {
   8725                         activities.add(r1);
   8726                     }
   8727                 }
   8728             }
   8729         }
   8730 
   8731         if (activities.size() <= 0) {
   8732             return false;
   8733         }
   8734 
   8735         String[] newArgs = new String[args.length - opti];
   8736         if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   8737 
   8738         TaskRecord lastTask = null;
   8739         boolean needSep = false;
   8740         for (int i=activities.size()-1; i>=0; i--) {
   8741             ActivityRecord r = (ActivityRecord)activities.get(i);
   8742             if (needSep) {
   8743                 pw.println();
   8744             }
   8745             needSep = true;
   8746             synchronized (this) {
   8747                 if (lastTask != r.task) {
   8748                     lastTask = r.task;
   8749                     pw.print("TASK "); pw.print(lastTask.affinity);
   8750                             pw.print(" id="); pw.println(lastTask.taskId);
   8751                     if (dumpAll) {
   8752                         lastTask.dump(pw, "  ");
   8753                     }
   8754                 }
   8755             }
   8756             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
   8757         }
   8758         return true;
   8759     }
   8760 
   8761     /**
   8762      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
   8763      * there is a thread associated with the activity.
   8764      */
   8765     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
   8766             final ActivityRecord r, String[] args, boolean dumpAll) {
   8767         String innerPrefix = prefix + "  ";
   8768         synchronized (this) {
   8769             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
   8770                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
   8771                     pw.print(" pid=");
   8772                     if (r.app != null) pw.println(r.app.pid);
   8773                     else pw.println("(not running)");
   8774             if (dumpAll) {
   8775                 r.dump(pw, innerPrefix);
   8776             }
   8777         }
   8778         if (r.app != null && r.app.thread != null) {
   8779             // flush anything that is already in the PrintWriter since the thread is going
   8780             // to write to the file descriptor directly
   8781             pw.flush();
   8782             try {
   8783                 TransferPipe tp = new TransferPipe();
   8784                 try {
   8785                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
   8786                             r.appToken, innerPrefix, args);
   8787                     tp.go(fd);
   8788                 } finally {
   8789                     tp.kill();
   8790                 }
   8791             } catch (IOException e) {
   8792                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   8793             } catch (RemoteException e) {
   8794                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   8795             }
   8796         }
   8797     }
   8798 
   8799     boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   8800             int opti, boolean dumpAll, String dumpPackage) {
   8801         boolean needSep = false;
   8802 
   8803         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
   8804         if (dumpAll) {
   8805             if (mRegisteredReceivers.size() > 0) {
   8806                 boolean printed = false;
   8807                 Iterator it = mRegisteredReceivers.values().iterator();
   8808                 while (it.hasNext()) {
   8809                     ReceiverList r = (ReceiverList)it.next();
   8810                     if (dumpPackage != null && (r.app == null ||
   8811                             !dumpPackage.equals(r.app.info.packageName))) {
   8812                         continue;
   8813                     }
   8814                     if (!printed) {
   8815                         pw.println("  Registered Receivers:");
   8816                         needSep = true;
   8817                         printed = true;
   8818                     }
   8819                     pw.print("  * "); pw.println(r);
   8820                     r.dump(pw, "    ");
   8821                 }
   8822             }
   8823 
   8824             if (mReceiverResolver.dump(pw, needSep ?
   8825                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
   8826                     "    ", dumpPackage, false)) {
   8827                 needSep = true;
   8828             }
   8829         }
   8830 
   8831         if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
   8832                 || mPendingBroadcast != null) {
   8833             boolean printed = false;
   8834             for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
   8835                 BroadcastRecord br = mParallelBroadcasts.get(i);
   8836                 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
   8837                     continue;
   8838                 }
   8839                 if (!printed) {
   8840                     if (needSep) {
   8841                         pw.println();
   8842                     }
   8843                     needSep = true;
   8844                     pw.println("  Active broadcasts:");
   8845                 }
   8846                 pw.println("  Broadcast #" + i + ":");
   8847                 br.dump(pw, "    ");
   8848             }
   8849             printed = false;
   8850             for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
   8851                 BroadcastRecord br = mOrderedBroadcasts.get(i);
   8852                 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
   8853                     continue;
   8854                 }
   8855                 if (!printed) {
   8856                     if (needSep) {
   8857                         pw.println();
   8858                     }
   8859                     needSep = true;
   8860                     pw.println("  Active ordered broadcasts:");
   8861                 }
   8862                 pw.println("  Ordered Broadcast #" + i + ":");
   8863                 mOrderedBroadcasts.get(i).dump(pw, "    ");
   8864             }
   8865             if (dumpPackage == null || (mPendingBroadcast != null
   8866                     && dumpPackage.equals(mPendingBroadcast.callerPackage))) {
   8867                 if (needSep) {
   8868                     pw.println();
   8869                 }
   8870                 pw.println("  Pending broadcast:");
   8871                 if (mPendingBroadcast != null) {
   8872                     mPendingBroadcast.dump(pw, "    ");
   8873                 } else {
   8874                     pw.println("    (null)");
   8875                 }
   8876                 needSep = true;
   8877             }
   8878         }
   8879 
   8880         boolean printed = false;
   8881         for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
   8882             BroadcastRecord r = mBroadcastHistory[i];
   8883             if (r == null) {
   8884                 break;
   8885             }
   8886             if (dumpPackage != null && !dumpPackage.equals(r.callerPackage)) {
   8887                 continue;
   8888             }
   8889             if (!printed) {
   8890                 if (needSep) {
   8891                     pw.println();
   8892                 }
   8893                 needSep = true;
   8894                 pw.println("  Historical broadcasts:");
   8895                 printed = true;
   8896             }
   8897             if (dumpAll) {
   8898                 pw.print("  Historical Broadcast #"); pw.print(i); pw.println(":");
   8899                 r.dump(pw, "    ");
   8900             } else {
   8901                 if (i >= 50) {
   8902                     pw.println("  ...");
   8903                     break;
   8904                 }
   8905                 pw.print("  #"); pw.print(i); pw.print(": "); pw.println(r);
   8906             }
   8907         }
   8908         needSep = true;
   8909 
   8910         if (mStickyBroadcasts != null && dumpPackage == null) {
   8911             if (needSep) {
   8912                 pw.println();
   8913             }
   8914             needSep = true;
   8915             pw.println("  Sticky broadcasts:");
   8916             StringBuilder sb = new StringBuilder(128);
   8917             for (Map.Entry<String, ArrayList<Intent>> ent
   8918                     : mStickyBroadcasts.entrySet()) {
   8919                 pw.print("  * Sticky action "); pw.print(ent.getKey());
   8920                 if (dumpAll) {
   8921                     pw.println(":");
   8922                     ArrayList<Intent> intents = ent.getValue();
   8923                     final int N = intents.size();
   8924                     for (int i=0; i<N; i++) {
   8925                         sb.setLength(0);
   8926                         sb.append("    Intent: ");
   8927                         intents.get(i).toShortString(sb, false, true, false);
   8928                         pw.println(sb.toString());
   8929                         Bundle bundle = intents.get(i).getExtras();
   8930                         if (bundle != null) {
   8931                             pw.print("      ");
   8932                             pw.println(bundle.toString());
   8933                         }
   8934                     }
   8935                 } else {
   8936                     pw.println("");
   8937                 }
   8938             }
   8939             needSep = true;
   8940         }
   8941 
   8942         if (dumpAll) {
   8943             pw.println();
   8944             pw.println("  mBroadcastsScheduled=" + mBroadcastsScheduled);
   8945             pw.println("  mHandler:");
   8946             mHandler.dump(new PrintWriterPrinter(pw), "    ");
   8947             needSep = true;
   8948         }
   8949 
   8950         return needSep;
   8951     }
   8952 
   8953     boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   8954             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   8955         boolean needSep = false;
   8956 
   8957         ItemMatcher matcher = new ItemMatcher();
   8958         matcher.build(args, opti);
   8959 
   8960         pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
   8961         if (mServices.size() > 0) {
   8962             boolean printed = false;
   8963             long nowReal = SystemClock.elapsedRealtime();
   8964             Iterator<ServiceRecord> it = mServices.values().iterator();
   8965             needSep = false;
   8966             while (it.hasNext()) {
   8967                 ServiceRecord r = it.next();
   8968                 if (!matcher.match(r, r.name)) {
   8969                     continue;
   8970                 }
   8971                 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
   8972                     continue;
   8973                 }
   8974                 if (!printed) {
   8975                     pw.println("  Active services:");
   8976                     printed = true;
   8977                 }
   8978                 if (needSep) {
   8979                     pw.println();
   8980                 }
   8981                 pw.print("  * "); pw.println(r);
   8982                 if (dumpAll) {
   8983                     r.dump(pw, "    ");
   8984                     needSep = true;
   8985                 } else {
   8986                     pw.print("    app="); pw.println(r.app);
   8987                     pw.print("    created=");
   8988                         TimeUtils.formatDuration(r.createTime, nowReal, pw);
   8989                         pw.print(" started="); pw.print(r.startRequested);
   8990                         pw.print(" connections="); pw.println(r.connections.size());
   8991                     if (r.connections.size() > 0) {
   8992                         pw.println("    Connections:");
   8993                         for (ArrayList<ConnectionRecord> clist : r.connections.values()) {
   8994                             for (int i=0; i<clist.size(); i++) {
   8995                                 ConnectionRecord conn = clist.get(i);
   8996                                 pw.print("      ");
   8997                                 pw.print(conn.binding.intent.intent.getIntent().toShortString(
   8998                                         false, false, false));
   8999                                 pw.print(" -> ");
   9000                                 ProcessRecord proc = conn.binding.client;
   9001                                 pw.println(proc != null ? proc.toShortString() : "null");
   9002                             }
   9003                         }
   9004                     }
   9005                 }
   9006                 if (dumpClient && r.app != null && r.app.thread != null) {
   9007                     pw.println("    Client:");
   9008                     pw.flush();
   9009                     try {
   9010                         TransferPipe tp = new TransferPipe();
   9011                         try {
   9012                             r.app.thread.dumpService(
   9013                                     tp.getWriteFd().getFileDescriptor(), r, args);
   9014                             tp.setBufferPrefix("      ");
   9015                             // Short timeout, since blocking here can
   9016                             // deadlock with the application.
   9017                             tp.go(fd, 2000);
   9018                         } finally {
   9019                             tp.kill();
   9020                         }
   9021                     } catch (IOException e) {
   9022                         pw.println("      Failure while dumping the service: " + e);
   9023                     } catch (RemoteException e) {
   9024                         pw.println("      Got a RemoteException while dumping the service");
   9025                     }
   9026                     needSep = true;
   9027                 }
   9028             }
   9029             needSep = printed;
   9030         }
   9031 
   9032         if (mPendingServices.size() > 0) {
   9033             boolean printed = false;
   9034             for (int i=0; i<mPendingServices.size(); i++) {
   9035                 ServiceRecord r = mPendingServices.get(i);
   9036                 if (!matcher.match(r, r.name)) {
   9037                     continue;
   9038                 }
   9039                 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
   9040                     continue;
   9041                 }
   9042                 if (!printed) {
   9043                     if (needSep) pw.println(" ");
   9044                     needSep = true;
   9045                     pw.println("  Pending services:");
   9046                     printed = true;
   9047                 }
   9048                 pw.print("  * Pending "); pw.println(r);
   9049                 r.dump(pw, "    ");
   9050             }
   9051             needSep = true;
   9052         }
   9053 
   9054         if (mRestartingServices.size() > 0) {
   9055             boolean printed = false;
   9056             for (int i=0; i<mRestartingServices.size(); i++) {
   9057                 ServiceRecord r = mRestartingServices.get(i);
   9058                 if (!matcher.match(r, r.name)) {
   9059                     continue;
   9060                 }
   9061                 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
   9062                     continue;
   9063                 }
   9064                 if (!printed) {
   9065                     if (needSep) pw.println(" ");
   9066                     needSep = true;
   9067                     pw.println("  Restarting services:");
   9068                     printed = true;
   9069                 }
   9070                 pw.print("  * Restarting "); pw.println(r);
   9071                 r.dump(pw, "    ");
   9072             }
   9073             needSep = true;
   9074         }
   9075 
   9076         if (mStoppingServices.size() > 0) {
   9077             boolean printed = false;
   9078             for (int i=0; i<mStoppingServices.size(); i++) {
   9079                 ServiceRecord r = mStoppingServices.get(i);
   9080                 if (!matcher.match(r, r.name)) {
   9081                     continue;
   9082                 }
   9083                 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
   9084                     continue;
   9085                 }
   9086                 if (!printed) {
   9087                     if (needSep) pw.println(" ");
   9088                     needSep = true;
   9089                     pw.println("  Stopping services:");
   9090                     printed = true;
   9091                 }
   9092                 pw.print("  * Stopping "); pw.println(r);
   9093                 r.dump(pw, "    ");
   9094             }
   9095             needSep = true;
   9096         }
   9097 
   9098         if (dumpAll) {
   9099             if (mServiceConnections.size() > 0) {
   9100                 boolean printed = false;
   9101                 Iterator<ArrayList<ConnectionRecord>> it
   9102                         = mServiceConnections.values().iterator();
   9103                 while (it.hasNext()) {
   9104                     ArrayList<ConnectionRecord> r = it.next();
   9105                     for (int i=0; i<r.size(); i++) {
   9106                         ConnectionRecord cr = r.get(i);
   9107                         if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
   9108                             continue;
   9109                         }
   9110                         if (dumpPackage != null && (cr.binding.client == null
   9111                                 || !dumpPackage.equals(cr.binding.client.info.packageName))) {
   9112                             continue;
   9113                         }
   9114                         if (!printed) {
   9115                             if (needSep) pw.println(" ");
   9116                             needSep = true;
   9117                             pw.println("  Connection bindings to services:");
   9118                             printed = true;
   9119                         }
   9120                         pw.print("  * "); pw.println(cr);
   9121                         cr.dump(pw, "    ");
   9122                     }
   9123                 }
   9124                 needSep = true;
   9125             }
   9126         }
   9127 
   9128         return needSep;
   9129     }
   9130 
   9131     boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   9132             int opti, boolean dumpAll, String dumpPackage) {
   9133         boolean needSep = false;
   9134 
   9135         ItemMatcher matcher = new ItemMatcher();
   9136         matcher.build(args, opti);
   9137 
   9138         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
   9139         if (mProvidersByClass.size() > 0) {
   9140             boolean printed = false;
   9141             Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it
   9142                     = mProvidersByClass.entrySet().iterator();
   9143             while (it.hasNext()) {
   9144                 Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
   9145                 ContentProviderRecord r = e.getValue();
   9146                 ComponentName comp = e.getKey();
   9147                 String cls = comp.getClassName();
   9148                 int end = cls.lastIndexOf('.');
   9149                 if (end > 0 && end < (cls.length()-2)) {
   9150                     cls = cls.substring(end+1);
   9151                 }
   9152                 if (!matcher.match(r, comp)) {
   9153                     continue;
   9154                 }
   9155                 if (dumpPackage != null && !dumpPackage.equals(comp.getPackageName())) {
   9156                     continue;
   9157                 }
   9158                 if (!printed) {
   9159                     if (needSep) pw.println(" ");
   9160                     needSep = true;
   9161                     pw.println("  Published content providers (by class):");
   9162                     printed = true;
   9163                 }
   9164                 pw.print("  * "); pw.print(cls); pw.print(" (");
   9165                         pw.print(comp.flattenToShortString()); pw.println(")");
   9166                 if (dumpAll) {
   9167                     r.dump(pw, "      ");
   9168                 } else {
   9169                     if (r.proc != null) {
   9170                         pw.print("      "); pw.println(r.proc);
   9171                     } else {
   9172                         pw.println();
   9173                     }
   9174                     if (r.clients.size() > 0) {
   9175                         pw.println("      Clients:");
   9176                         for (ProcessRecord cproc : r.clients) {
   9177                             pw.print("        - "); pw.println(cproc);
   9178                         }
   9179                     }
   9180                 }
   9181             }
   9182         }
   9183 
   9184         if (dumpAll) {
   9185             if (mProvidersByName.size() > 0) {
   9186                 boolean printed = false;
   9187                 Iterator<Map.Entry<String, ContentProviderRecord>> it
   9188                         = mProvidersByName.entrySet().iterator();
   9189                 while (it.hasNext()) {
   9190                     Map.Entry<String, ContentProviderRecord> e = it.next();
   9191                     ContentProviderRecord r = e.getValue();
   9192                     if (!matcher.match(r, r.name)) {
   9193                         continue;
   9194                     }
   9195                     if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
   9196                         continue;
   9197                     }
   9198                     if (!printed) {
   9199                         if (needSep) pw.println(" ");
   9200                         needSep = true;
   9201                         pw.println("  Authority to provider mappings:");
   9202                         printed = true;
   9203                     }
   9204                     pw.print("  "); pw.print(e.getKey()); pw.println(":");
   9205                     pw.print("    "); pw.println(r);
   9206                 }
   9207             }
   9208         }
   9209 
   9210         if (mLaunchingProviders.size() > 0) {
   9211             boolean printed = false;
   9212             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
   9213                 ContentProviderRecord r = mLaunchingProviders.get(i);
   9214                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
   9215                     continue;
   9216                 }
   9217                 if (!printed) {
   9218                     if (needSep) pw.println(" ");
   9219                     needSep = true;
   9220                     pw.println("  Launching content providers:");
   9221                     printed = true;
   9222                 }
   9223                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
   9224                         pw.println(r);
   9225             }
   9226         }
   9227 
   9228         if (mGrantedUriPermissions.size() > 0) {
   9229             if (needSep) pw.println();
   9230             needSep = true;
   9231             pw.println("Granted Uri Permissions:");
   9232             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
   9233                 int uid = mGrantedUriPermissions.keyAt(i);
   9234                 HashMap<Uri, UriPermission> perms
   9235                         = mGrantedUriPermissions.valueAt(i);
   9236                 pw.print("  * UID "); pw.print(uid);
   9237                         pw.println(" holds:");
   9238                 for (UriPermission perm : perms.values()) {
   9239                     pw.print("    "); pw.println(perm);
   9240                     if (dumpAll) {
   9241                         perm.dump(pw, "      ");
   9242                     }
   9243                 }
   9244             }
   9245             needSep = true;
   9246         }
   9247 
   9248         return needSep;
   9249     }
   9250 
   9251     boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   9252             int opti, boolean dumpAll, String dumpPackage) {
   9253         boolean needSep = false;
   9254 
   9255         if (mIntentSenderRecords.size() > 0) {
   9256             boolean printed = false;
   9257             Iterator<WeakReference<PendingIntentRecord>> it
   9258                     = mIntentSenderRecords.values().iterator();
   9259             while (it.hasNext()) {
   9260                 WeakReference<PendingIntentRecord> ref = it.next();
   9261                 PendingIntentRecord rec = ref != null ? ref.get(): null;
   9262                 if (dumpPackage != null && (rec == null
   9263                         || !dumpPackage.equals(rec.key.packageName))) {
   9264                     continue;
   9265                 }
   9266                 if (!printed) {
   9267                     pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
   9268                     printed = true;
   9269                 }
   9270                 needSep = true;
   9271                 if (rec != null) {
   9272                     pw.print("  * "); pw.println(rec);
   9273                     if (dumpAll) {
   9274                         rec.dump(pw, "    ");
   9275                     }
   9276                 } else {
   9277                     pw.print("  * "); pw.println(ref);
   9278                 }
   9279             }
   9280         }
   9281 
   9282         return needSep;
   9283     }
   9284 
   9285     private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
   9286             String prefix, String label, boolean complete, boolean brief, boolean client,
   9287             String dumpPackage) {
   9288         TaskRecord lastTask = null;
   9289         boolean needNL = false;
   9290         final String innerPrefix = prefix + "      ";
   9291         final String[] args = new String[0];
   9292         for (int i=list.size()-1; i>=0; i--) {
   9293             final ActivityRecord r = (ActivityRecord)list.get(i);
   9294             if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
   9295                 continue;
   9296             }
   9297             final boolean full = !brief && (complete || !r.isInHistory());
   9298             if (needNL) {
   9299                 pw.println(" ");
   9300                 needNL = false;
   9301             }
   9302             if (lastTask != r.task) {
   9303                 lastTask = r.task;
   9304                 pw.print(prefix);
   9305                 pw.print(full ? "* " : "  ");
   9306                 pw.println(lastTask);
   9307                 if (full) {
   9308                     lastTask.dump(pw, prefix + "  ");
   9309                 } else if (complete) {
   9310                     // Complete + brief == give a summary.  Isn't that obvious?!?
   9311                     if (lastTask.intent != null) {
   9312                         pw.print(prefix); pw.print("  ");
   9313                                 pw.println(lastTask.intent.toInsecureString());
   9314                     }
   9315                 }
   9316             }
   9317             pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
   9318             pw.print(" #"); pw.print(i); pw.print(": ");
   9319             pw.println(r);
   9320             if (full) {
   9321                 r.dump(pw, innerPrefix);
   9322             } else if (complete) {
   9323                 // Complete + brief == give a summary.  Isn't that obvious?!?
   9324                 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
   9325                 if (r.app != null) {
   9326                     pw.print(innerPrefix); pw.println(r.app);
   9327                 }
   9328             }
   9329             if (client && r.app != null && r.app.thread != null) {
   9330                 // flush anything that is already in the PrintWriter since the thread is going
   9331                 // to write to the file descriptor directly
   9332                 pw.flush();
   9333                 try {
   9334                     TransferPipe tp = new TransferPipe();
   9335                     try {
   9336                         r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
   9337                                 r.appToken, innerPrefix, args);
   9338                         // Short timeout, since blocking here can
   9339                         // deadlock with the application.
   9340                         tp.go(fd, 2000);
   9341                     } finally {
   9342                         tp.kill();
   9343                     }
   9344                 } catch (IOException e) {
   9345                     pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   9346                 } catch (RemoteException e) {
   9347                     pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   9348                 }
   9349                 needNL = true;
   9350             }
   9351         }
   9352     }
   9353 
   9354     private static String buildOomTag(String prefix, String space, int val, int base) {
   9355         if (val == base) {
   9356             if (space == null) return prefix;
   9357             return prefix + "  ";
   9358         }
   9359         return prefix + "+" + Integer.toString(val-base);
   9360     }
   9361 
   9362     private static final int dumpProcessList(PrintWriter pw,
   9363             ActivityManagerService service, List list,
   9364             String prefix, String normalLabel, String persistentLabel,
   9365             String dumpPackage) {
   9366         int numPers = 0;
   9367         final int N = list.size()-1;
   9368         for (int i=N; i>=0; i--) {
   9369             ProcessRecord r = (ProcessRecord)list.get(i);
   9370             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   9371                 continue;
   9372             }
   9373             pw.println(String.format("%s%s #%2d: %s",
   9374                     prefix, (r.persistent ? persistentLabel : normalLabel),
   9375                     i, r.toString()));
   9376             if (r.persistent) {
   9377                 numPers++;
   9378             }
   9379         }
   9380         return numPers;
   9381     }
   9382 
   9383     private static final boolean dumpProcessOomList(PrintWriter pw,
   9384             ActivityManagerService service, List<ProcessRecord> origList,
   9385             String prefix, String normalLabel, String persistentLabel,
   9386             boolean inclDetails, String dumpPackage) {
   9387 
   9388         ArrayList<Pair<ProcessRecord, Integer>> list
   9389                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
   9390         for (int i=0; i<origList.size(); i++) {
   9391             ProcessRecord r = origList.get(i);
   9392             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   9393                 continue;
   9394             }
   9395             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
   9396         }
   9397 
   9398         if (list.size() <= 0) {
   9399             return false;
   9400         }
   9401 
   9402         Comparator<Pair<ProcessRecord, Integer>> comparator
   9403                 = new Comparator<Pair<ProcessRecord, Integer>>() {
   9404             @Override
   9405             public int compare(Pair<ProcessRecord, Integer> object1,
   9406                     Pair<ProcessRecord, Integer> object2) {
   9407                 if (object1.first.setAdj != object2.first.setAdj) {
   9408                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
   9409                 }
   9410                 if (object1.second.intValue() != object2.second.intValue()) {
   9411                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
   9412                 }
   9413                 return 0;
   9414             }
   9415         };
   9416 
   9417         Collections.sort(list, comparator);
   9418 
   9419         final long curRealtime = SystemClock.elapsedRealtime();
   9420         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
   9421         final long curUptime = SystemClock.uptimeMillis();
   9422         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
   9423 
   9424         for (int i=list.size()-1; i>=0; i--) {
   9425             ProcessRecord r = list.get(i).first;
   9426             String oomAdj;
   9427             if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   9428                 oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
   9429             } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
   9430                 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
   9431             } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
   9432                 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
   9433             } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
   9434                 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
   9435             } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
   9436                 oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
   9437             } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
   9438                 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
   9439             } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   9440                 oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
   9441             } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   9442                 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
   9443             } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
   9444                 oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
   9445             } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
   9446                 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
   9447             } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
   9448                 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
   9449             } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
   9450                 oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
   9451             } else {
   9452                 oomAdj = Integer.toString(r.setAdj);
   9453             }
   9454             String schedGroup;
   9455             switch (r.setSchedGroup) {
   9456                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
   9457                     schedGroup = "B";
   9458                     break;
   9459                 case Process.THREAD_GROUP_DEFAULT:
   9460                     schedGroup = "F";
   9461                     break;
   9462                 default:
   9463                     schedGroup = Integer.toString(r.setSchedGroup);
   9464                     break;
   9465             }
   9466             String foreground;
   9467             if (r.foregroundActivities) {
   9468                 foreground = "A";
   9469             } else if (r.foregroundServices) {
   9470                 foreground = "S";
   9471             } else {
   9472                 foreground = " ";
   9473             }
   9474             pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
   9475                     prefix, (r.persistent ? persistentLabel : normalLabel),
   9476                     (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
   9477                     foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
   9478             if (r.adjSource != null || r.adjTarget != null) {
   9479                 pw.print(prefix);
   9480                 pw.print("    ");
   9481                 if (r.adjTarget instanceof ComponentName) {
   9482                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
   9483                 } else if (r.adjTarget != null) {
   9484                     pw.print(r.adjTarget.toString());
   9485                 } else {
   9486                     pw.print("{null}");
   9487                 }
   9488                 pw.print("<=");
   9489                 if (r.adjSource instanceof ProcessRecord) {
   9490                     pw.print("Proc{");
   9491                     pw.print(((ProcessRecord)r.adjSource).toShortString());
   9492                     pw.println("}");
   9493                 } else if (r.adjSource != null) {
   9494                     pw.println(r.adjSource.toString());
   9495                 } else {
   9496                     pw.println("{null}");
   9497                 }
   9498             }
   9499             if (inclDetails) {
   9500                 pw.print(prefix);
   9501                 pw.print("    ");
   9502                 pw.print("oom: max="); pw.print(r.maxAdj);
   9503                 pw.print(" hidden="); pw.print(r.hiddenAdj);
   9504                 pw.print(" curRaw="); pw.print(r.curRawAdj);
   9505                 pw.print(" setRaw="); pw.print(r.setRawAdj);
   9506                 pw.print(" cur="); pw.print(r.curAdj);
   9507                 pw.print(" set="); pw.println(r.setAdj);
   9508                 pw.print(prefix);
   9509                 pw.print("    ");
   9510                 pw.print("keeping="); pw.print(r.keeping);
   9511                 pw.print(" hidden="); pw.print(r.hidden);
   9512                 pw.print(" empty="); pw.print(r.empty);
   9513                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
   9514 
   9515                 if (!r.keeping) {
   9516                     if (r.lastWakeTime != 0) {
   9517                         long wtime;
   9518                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
   9519                         synchronized (stats) {
   9520                             wtime = stats.getProcessWakeTime(r.info.uid,
   9521                                     r.pid, curRealtime);
   9522                         }
   9523                         long timeUsed = wtime - r.lastWakeTime;
   9524                         pw.print(prefix);
   9525                         pw.print("    ");
   9526                         pw.print("keep awake over ");
   9527                         TimeUtils.formatDuration(realtimeSince, pw);
   9528                         pw.print(" used ");
   9529                         TimeUtils.formatDuration(timeUsed, pw);
   9530                         pw.print(" (");
   9531                         pw.print((timeUsed*100)/realtimeSince);
   9532                         pw.println("%)");
   9533                     }
   9534                     if (r.lastCpuTime != 0) {
   9535                         long timeUsed = r.curCpuTime - r.lastCpuTime;
   9536                         pw.print(prefix);
   9537                         pw.print("    ");
   9538                         pw.print("run cpu over ");
   9539                         TimeUtils.formatDuration(uptimeSince, pw);
   9540                         pw.print(" used ");
   9541                         TimeUtils.formatDuration(timeUsed, pw);
   9542                         pw.print(" (");
   9543                         pw.print((timeUsed*100)/uptimeSince);
   9544                         pw.println("%)");
   9545                     }
   9546                 }
   9547             }
   9548         }
   9549         return true;
   9550     }
   9551 
   9552     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
   9553         ArrayList<ProcessRecord> procs;
   9554         synchronized (this) {
   9555             if (args != null && args.length > start
   9556                     && args[start].charAt(0) != '-') {
   9557                 procs = new ArrayList<ProcessRecord>();
   9558                 int pid = -1;
   9559                 try {
   9560                     pid = Integer.parseInt(args[start]);
   9561                 } catch (NumberFormatException e) {
   9562 
   9563                 }
   9564                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   9565                     ProcessRecord proc = mLruProcesses.get(i);
   9566                     if (proc.pid == pid) {
   9567                         procs.add(proc);
   9568                     } else if (proc.processName.equals(args[start])) {
   9569                         procs.add(proc);
   9570                     }
   9571                 }
   9572                 if (procs.size() <= 0) {
   9573                     pw.println("No process found for: " + args[start]);
   9574                     return null;
   9575                 }
   9576             } else {
   9577                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
   9578             }
   9579         }
   9580         return procs;
   9581     }
   9582 
   9583     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
   9584             PrintWriter pw, String[] args) {
   9585         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
   9586         if (procs == null) {
   9587             return;
   9588         }
   9589 
   9590         long uptime = SystemClock.uptimeMillis();
   9591         long realtime = SystemClock.elapsedRealtime();
   9592         pw.println("Applications Graphics Acceleration Info:");
   9593         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   9594 
   9595         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   9596             ProcessRecord r = procs.get(i);
   9597             if (r.thread != null) {
   9598                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
   9599                 pw.flush();
   9600                 try {
   9601                     TransferPipe tp = new TransferPipe();
   9602                     try {
   9603                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
   9604                         tp.go(fd);
   9605                     } finally {
   9606                         tp.kill();
   9607                     }
   9608                 } catch (IOException e) {
   9609                     pw.println("Failure while dumping the app: " + r);
   9610                     pw.flush();
   9611                 } catch (RemoteException e) {
   9612                     pw.println("Got a RemoteException while dumping the app " + r);
   9613                     pw.flush();
   9614                 }
   9615             }
   9616         }
   9617     }
   9618 
   9619     final static class MemItem {
   9620         final String label;
   9621         final String shortLabel;
   9622         final long pss;
   9623         final int id;
   9624         ArrayList<MemItem> subitems;
   9625 
   9626         public MemItem(String _label, String _shortLabel, long _pss, int _id) {
   9627             label = _label;
   9628             shortLabel = _shortLabel;
   9629             pss = _pss;
   9630             id = _id;
   9631         }
   9632     }
   9633 
   9634     static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
   9635             boolean sort) {
   9636         if (sort) {
   9637             Collections.sort(items, new Comparator<MemItem>() {
   9638                 @Override
   9639                 public int compare(MemItem lhs, MemItem rhs) {
   9640                     if (lhs.pss < rhs.pss) {
   9641                         return 1;
   9642                     } else if (lhs.pss > rhs.pss) {
   9643                         return -1;
   9644                     }
   9645                     return 0;
   9646                 }
   9647             });
   9648         }
   9649 
   9650         for (int i=0; i<items.size(); i++) {
   9651             MemItem mi = items.get(i);
   9652             pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
   9653             if (mi.subitems != null) {
   9654                 dumpMemItems(pw, prefix + "           ", mi.subitems, true);
   9655             }
   9656         }
   9657     }
   9658 
   9659     // These are in KB.
   9660     static final long[] DUMP_MEM_BUCKETS = new long[] {
   9661         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
   9662         120*1024, 160*1024, 200*1024,
   9663         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
   9664         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
   9665     };
   9666 
   9667     static final void appendMemBucket(StringBuilder out, long memKB, String label,
   9668             boolean stackLike) {
   9669         int start = label.lastIndexOf('.');
   9670         if (start >= 0) start++;
   9671         else start = 0;
   9672         int end = label.length();
   9673         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
   9674             if (DUMP_MEM_BUCKETS[i] >= memKB) {
   9675                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
   9676                 out.append(bucket);
   9677                 out.append(stackLike ? "MB." : "MB ");
   9678                 out.append(label, start, end);
   9679                 return;
   9680             }
   9681         }
   9682         out.append(memKB/1024);
   9683         out.append(stackLike ? "MB." : "MB ");
   9684         out.append(label, start, end);
   9685     }
   9686 
   9687     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
   9688             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
   9689             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
   9690             ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
   9691             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
   9692     };
   9693     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
   9694             "System", "Persistent", "Foreground",
   9695             "Visible", "Perceptible", "Heavy Weight",
   9696             "Backup", "A Services", "Home", "Previous",
   9697             "B Services", "Background"
   9698     };
   9699 
   9700     final void dumpApplicationMemoryUsage(FileDescriptor fd,
   9701             PrintWriter pw, String prefix, String[] args, boolean brief,
   9702             PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
   9703         boolean dumpAll = false;
   9704         boolean oomOnly = false;
   9705 
   9706         int opti = 0;
   9707         while (opti < args.length) {
   9708             String opt = args[opti];
   9709             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   9710                 break;
   9711             }
   9712             opti++;
   9713             if ("-a".equals(opt)) {
   9714                 dumpAll = true;
   9715             } else if ("--oom".equals(opt)) {
   9716                 oomOnly = true;
   9717             } else if ("-h".equals(opt)) {
   9718                 pw.println("meminfo dump options: [-a] [--oom] [process]");
   9719                 pw.println("  -a: include all available information for each process.");
   9720                 pw.println("  --oom: only show processes organized by oom adj.");
   9721                 pw.println("If [process] is specified it can be the name or ");
   9722                 pw.println("pid of a specific process to dump.");
   9723                 return;
   9724             } else {
   9725                 pw.println("Unknown argument: " + opt + "; use -h for help");
   9726             }
   9727         }
   9728 
   9729         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
   9730         if (procs == null) {
   9731             return;
   9732         }
   9733 
   9734         final boolean isCheckinRequest = scanArgs(args, "--checkin");
   9735         long uptime = SystemClock.uptimeMillis();
   9736         long realtime = SystemClock.elapsedRealtime();
   9737 
   9738         if (procs.size() == 1 || isCheckinRequest) {
   9739             dumpAll = true;
   9740         }
   9741 
   9742         if (isCheckinRequest) {
   9743             // short checkin version
   9744             pw.println(uptime + "," + realtime);
   9745             pw.flush();
   9746         } else {
   9747             pw.println("Applications Memory Usage (kB):");
   9748             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   9749         }
   9750 
   9751         String[] innerArgs = new String[args.length-opti];
   9752         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
   9753 
   9754         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
   9755         long nativePss=0, dalvikPss=0, otherPss=0;
   9756         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
   9757 
   9758         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
   9759         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
   9760                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
   9761 
   9762         long totalPss = 0;
   9763 
   9764         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   9765             ProcessRecord r = procs.get(i);
   9766             if (r.thread != null) {
   9767                 if (!isCheckinRequest && dumpAll) {
   9768                     pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
   9769                     pw.flush();
   9770                 }
   9771                 Debug.MemoryInfo mi = null;
   9772                 if (dumpAll) {
   9773                     try {
   9774                         mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
   9775                     } catch (RemoteException e) {
   9776                         if (!isCheckinRequest) {
   9777                             pw.println("Got RemoteException!");
   9778                             pw.flush();
   9779                         }
   9780                     }
   9781                 } else {
   9782                     mi = new Debug.MemoryInfo();
   9783                     Debug.getMemoryInfo(r.pid, mi);
   9784                 }
   9785 
   9786                 if (!isCheckinRequest && mi != null) {
   9787                     long myTotalPss = mi.getTotalPss();
   9788                     totalPss += myTotalPss;
   9789                     MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
   9790                             r.processName, myTotalPss, 0);
   9791                     procMems.add(pssItem);
   9792 
   9793                     nativePss += mi.nativePss;
   9794                     dalvikPss += mi.dalvikPss;
   9795                     otherPss += mi.otherPss;
   9796                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   9797                         long mem = mi.getOtherPss(j);
   9798                         miscPss[j] += mem;
   9799                         otherPss -= mem;
   9800                     }
   9801 
   9802                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
   9803                         if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
   9804                                 || oomIndex == (oomPss.length-1)) {
   9805                             oomPss[oomIndex] += myTotalPss;
   9806                             if (oomProcs[oomIndex] == null) {
   9807                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
   9808                             }
   9809                             oomProcs[oomIndex].add(pssItem);
   9810                             break;
   9811                         }
   9812                     }
   9813                 }
   9814             }
   9815         }
   9816 
   9817         if (!isCheckinRequest && procs.size() > 1) {
   9818             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
   9819 
   9820             catMems.add(new MemItem("Native", "Native", nativePss, -1));
   9821             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
   9822             catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
   9823             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   9824                 String label = Debug.MemoryInfo.getOtherLabel(j);
   9825                 catMems.add(new MemItem(label, label, miscPss[j], j));
   9826             }
   9827 
   9828             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
   9829             for (int j=0; j<oomPss.length; j++) {
   9830                 if (oomPss[j] != 0) {
   9831                     String label = DUMP_MEM_OOM_LABEL[j];
   9832                     MemItem item = new MemItem(label, label, oomPss[j],
   9833                             DUMP_MEM_OOM_ADJ[j]);
   9834                     item.subitems = oomProcs[j];
   9835                     oomMems.add(item);
   9836                 }
   9837             }
   9838 
   9839             if (outTag != null || outStack != null) {
   9840                 if (outTag != null) {
   9841                     appendMemBucket(outTag, totalPss, "total", false);
   9842                 }
   9843                 if (outStack != null) {
   9844                     appendMemBucket(outStack, totalPss, "total", true);
   9845                 }
   9846                 boolean firstLine = true;
   9847                 for (int i=0; i<oomMems.size(); i++) {
   9848                     MemItem miCat = oomMems.get(i);
   9849                     if (miCat.subitems == null || miCat.subitems.size() < 1) {
   9850                         continue;
   9851                     }
   9852                     if (miCat.id < ProcessList.SERVICE_ADJ
   9853                             || miCat.id == ProcessList.HOME_APP_ADJ
   9854                             || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
   9855                         if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
   9856                             outTag.append(" / ");
   9857                         }
   9858                         if (outStack != null) {
   9859                             if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
   9860                                 if (firstLine) {
   9861                                     outStack.append(":");
   9862                                     firstLine = false;
   9863                                 }
   9864                                 outStack.append("\n\t at ");
   9865                             } else {
   9866                                 outStack.append("$");
   9867                             }
   9868                         }
   9869                         for (int j=0; j<miCat.subitems.size(); j++) {
   9870                             MemItem mi = miCat.subitems.get(j);
   9871                             if (j > 0) {
   9872                                 if (outTag != null) {
   9873                                     outTag.append(" ");
   9874                                 }
   9875                                 if (outStack != null) {
   9876                                     outStack.append("$");
   9877                                 }
   9878                             }
   9879                             if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
   9880                                 appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
   9881                             }
   9882                             if (outStack != null) {
   9883                                 appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
   9884                             }
   9885                         }
   9886                         if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
   9887                             outStack.append("(");
   9888                             for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
   9889                                 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
   9890                                     outStack.append(DUMP_MEM_OOM_LABEL[k]);
   9891                                     outStack.append(":");
   9892                                     outStack.append(DUMP_MEM_OOM_ADJ[k]);
   9893                                 }
   9894                             }
   9895                             outStack.append(")");
   9896                         }
   9897                     }
   9898                 }
   9899             }
   9900 
   9901             if (!brief && !oomOnly) {
   9902                 pw.println();
   9903                 pw.println("Total PSS by process:");
   9904                 dumpMemItems(pw, "  ", procMems, true);
   9905                 pw.println();
   9906             }
   9907             pw.println("Total PSS by OOM adjustment:");
   9908             dumpMemItems(pw, "  ", oomMems, false);
   9909             if (!oomOnly) {
   9910                 PrintWriter out = categoryPw != null ? categoryPw : pw;
   9911                 out.println();
   9912                 out.println("Total PSS by category:");
   9913                 dumpMemItems(out, "  ", catMems, true);
   9914             }
   9915             pw.println();
   9916             pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
   9917         }
   9918     }
   9919 
   9920     /**
   9921      * Searches array of arguments for the specified string
   9922      * @param args array of argument strings
   9923      * @param value value to search for
   9924      * @return true if the value is contained in the array
   9925      */
   9926     private static boolean scanArgs(String[] args, String value) {
   9927         if (args != null) {
   9928             for (String arg : args) {
   9929                 if (value.equals(arg)) {
   9930                     return true;
   9931                 }
   9932             }
   9933         }
   9934         return false;
   9935     }
   9936 
   9937     private final void killServicesLocked(ProcessRecord app,
   9938             boolean allowRestart) {
   9939         // Report disconnected services.
   9940         if (false) {
   9941             // XXX we are letting the client link to the service for
   9942             // death notifications.
   9943             if (app.services.size() > 0) {
   9944                 Iterator<ServiceRecord> it = app.services.iterator();
   9945                 while (it.hasNext()) {
   9946                     ServiceRecord r = it.next();
   9947                     if (r.connections.size() > 0) {
   9948                         Iterator<ArrayList<ConnectionRecord>> jt
   9949                                 = r.connections.values().iterator();
   9950                         while (jt.hasNext()) {
   9951                             ArrayList<ConnectionRecord> cl = jt.next();
   9952                             for (int i=0; i<cl.size(); i++) {
   9953                                 ConnectionRecord c = cl.get(i);
   9954                                 if (c.binding.client != app) {
   9955                                     try {
   9956                                         //c.conn.connected(r.className, null);
   9957                                     } catch (Exception e) {
   9958                                         // todo: this should be asynchronous!
   9959                                         Slog.w(TAG, "Exception thrown disconnected servce "
   9960                                               + r.shortName
   9961                                               + " from app " + app.processName, e);
   9962                                     }
   9963                                 }
   9964                             }
   9965                         }
   9966                     }
   9967                 }
   9968             }
   9969         }
   9970 
   9971         // Clean up any connections this application has to other services.
   9972         if (app.connections.size() > 0) {
   9973             Iterator<ConnectionRecord> it = app.connections.iterator();
   9974             while (it.hasNext()) {
   9975                 ConnectionRecord r = it.next();
   9976                 removeConnectionLocked(r, app, null);
   9977             }
   9978         }
   9979         app.connections.clear();
   9980 
   9981         if (app.services.size() != 0) {
   9982             // Any services running in the application need to be placed
   9983             // back in the pending list.
   9984             Iterator<ServiceRecord> it = app.services.iterator();
   9985             while (it.hasNext()) {
   9986                 ServiceRecord sr = it.next();
   9987                 synchronized (sr.stats.getBatteryStats()) {
   9988                     sr.stats.stopLaunchedLocked();
   9989                 }
   9990                 sr.app = null;
   9991                 sr.executeNesting = 0;
   9992                 if (mStoppingServices.remove(sr)) {
   9993                     if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
   9994                 }
   9995 
   9996                 boolean hasClients = sr.bindings.size() > 0;
   9997                 if (hasClients) {
   9998                     Iterator<IntentBindRecord> bindings
   9999                             = sr.bindings.values().iterator();
   10000                     while (bindings.hasNext()) {
   10001                         IntentBindRecord b = bindings.next();
   10002                         if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
   10003                                 + ": shouldUnbind=" + b.hasBound);
   10004                         b.binder = null;
   10005                         b.requested = b.received = b.hasBound = false;
   10006                     }
   10007                 }
   10008 
   10009                 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
   10010                         &ApplicationInfo.FLAG_PERSISTENT) == 0) {
   10011                     Slog.w(TAG, "Service crashed " + sr.crashCount
   10012                             + " times, stopping: " + sr);
   10013                     EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
   10014                             sr.crashCount, sr.shortName, app.pid);
   10015                     bringDownServiceLocked(sr, true);
   10016                 } else if (!allowRestart) {
   10017                     bringDownServiceLocked(sr, true);
   10018                 } else {
   10019                     boolean canceled = scheduleServiceRestartLocked(sr, true);
   10020 
   10021                     // Should the service remain running?  Note that in the
   10022                     // extreme case of so many attempts to deliver a command
   10023                     // that it failed we also will stop it here.
   10024                     if (sr.startRequested && (sr.stopIfKilled || canceled)) {
   10025                         if (sr.pendingStarts.size() == 0) {
   10026                             sr.startRequested = false;
   10027                             if (!hasClients) {
   10028                                 // Whoops, no reason to restart!
   10029                                 bringDownServiceLocked(sr, true);
   10030                             }
   10031                         }
   10032                     }
   10033                 }
   10034             }
   10035 
   10036             if (!allowRestart) {
   10037                 app.services.clear();
   10038             }
   10039         }
   10040 
   10041         // Make sure we have no more records on the stopping list.
   10042         int i = mStoppingServices.size();
   10043         while (i > 0) {
   10044             i--;
   10045             ServiceRecord sr = mStoppingServices.get(i);
   10046             if (sr.app == app) {
   10047                 mStoppingServices.remove(i);
   10048                 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
   10049             }
   10050         }
   10051 
   10052         app.executingServices.clear();
   10053     }
   10054 
   10055     private final void removeDyingProviderLocked(ProcessRecord proc,
   10056             ContentProviderRecord cpr) {
   10057         synchronized (cpr) {
   10058             cpr.launchingApp = null;
   10059             cpr.notifyAll();
   10060         }
   10061 
   10062         mProvidersByClass.remove(cpr.name);
   10063         String names[] = cpr.info.authority.split(";");
   10064         for (int j = 0; j < names.length; j++) {
   10065             mProvidersByName.remove(names[j]);
   10066         }
   10067 
   10068         Iterator<ProcessRecord> cit = cpr.clients.iterator();
   10069         while (cit.hasNext()) {
   10070             ProcessRecord capp = cit.next();
   10071             if (!capp.persistent && capp.thread != null
   10072                     && capp.pid != 0
   10073                     && capp.pid != MY_PID) {
   10074                 Slog.i(TAG, "Kill " + capp.processName
   10075                         + " (pid " + capp.pid + "): provider " + cpr.info.name
   10076                         + " in dying process " + (proc != null ? proc.processName : "??"));
   10077                 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
   10078                         capp.processName, capp.setAdj, "dying provider "
   10079                                 + cpr.name.toShortString());
   10080                 Process.killProcessQuiet(capp.pid);
   10081             }
   10082         }
   10083 
   10084         mLaunchingProviders.remove(cpr);
   10085     }
   10086 
   10087     /**
   10088      * Main code for cleaning up a process when it has gone away.  This is
   10089      * called both as a result of the process dying, or directly when stopping
   10090      * a process when running in single process mode.
   10091      */
   10092     private final void cleanUpApplicationRecordLocked(ProcessRecord app,
   10093             boolean restarting, boolean allowRestart, int index) {
   10094         if (index >= 0) {
   10095             mLruProcesses.remove(index);
   10096         }
   10097 
   10098         mProcessesToGc.remove(app);
   10099 
   10100         // Dismiss any open dialogs.
   10101         if (app.crashDialog != null) {
   10102             app.crashDialog.dismiss();
   10103             app.crashDialog = null;
   10104         }
   10105         if (app.anrDialog != null) {
   10106             app.anrDialog.dismiss();
   10107             app.anrDialog = null;
   10108         }
   10109         if (app.waitDialog != null) {
   10110             app.waitDialog.dismiss();
   10111             app.waitDialog = null;
   10112         }
   10113 
   10114         app.crashing = false;
   10115         app.notResponding = false;
   10116 
   10117         app.resetPackageList();
   10118         app.unlinkDeathRecipient();
   10119         app.thread = null;
   10120         app.forcingToForeground = null;
   10121         app.foregroundServices = false;
   10122         app.foregroundActivities = false;
   10123         app.hasShownUi = false;
   10124         app.hasAboveClient = false;
   10125 
   10126         killServicesLocked(app, allowRestart);
   10127 
   10128         boolean restart = false;
   10129 
   10130         int NL = mLaunchingProviders.size();
   10131 
   10132         // Remove published content providers.
   10133         if (!app.pubProviders.isEmpty()) {
   10134             Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
   10135             while (it.hasNext()) {
   10136                 ContentProviderRecord cpr = it.next();
   10137                 cpr.provider = null;
   10138                 cpr.proc = null;
   10139 
   10140                 // See if someone is waiting for this provider...  in which
   10141                 // case we don't remove it, but just let it restart.
   10142                 int i = 0;
   10143                 if (!app.bad && allowRestart) {
   10144                     for (; i<NL; i++) {
   10145                         if (mLaunchingProviders.get(i) == cpr) {
   10146                             restart = true;
   10147                             break;
   10148                         }
   10149                     }
   10150                 } else {
   10151                     i = NL;
   10152                 }
   10153 
   10154                 if (i >= NL) {
   10155                     removeDyingProviderLocked(app, cpr);
   10156                     NL = mLaunchingProviders.size();
   10157                 }
   10158             }
   10159             app.pubProviders.clear();
   10160         }
   10161 
   10162         // Take care of any launching providers waiting for this process.
   10163         if (checkAppInLaunchingProvidersLocked(app, false)) {
   10164             restart = true;
   10165         }
   10166 
   10167         // Unregister from connected content providers.
   10168         if (!app.conProviders.isEmpty()) {
   10169             Iterator it = app.conProviders.keySet().iterator();
   10170             while (it.hasNext()) {
   10171                 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
   10172                 cpr.clients.remove(app);
   10173             }
   10174             app.conProviders.clear();
   10175         }
   10176 
   10177         // At this point there may be remaining entries in mLaunchingProviders
   10178         // where we were the only one waiting, so they are no longer of use.
   10179         // Look for these and clean up if found.
   10180         // XXX Commented out for now.  Trying to figure out a way to reproduce
   10181         // the actual situation to identify what is actually going on.
   10182         if (false) {
   10183             for (int i=0; i<NL; i++) {
   10184                 ContentProviderRecord cpr = (ContentProviderRecord)
   10185                         mLaunchingProviders.get(i);
   10186                 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
   10187                     synchronized (cpr) {
   10188                         cpr.launchingApp = null;
   10189                         cpr.notifyAll();
   10190                     }
   10191                 }
   10192             }
   10193         }
   10194 
   10195         skipCurrentReceiverLocked(app);
   10196 
   10197         // Unregister any receivers.
   10198         if (app.receivers.size() > 0) {
   10199             Iterator<ReceiverList> it = app.receivers.iterator();
   10200             while (it.hasNext()) {
   10201                 removeReceiverLocked(it.next());
   10202             }
   10203             app.receivers.clear();
   10204         }
   10205 
   10206         // If the app is undergoing backup, tell the backup manager about it
   10207         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
   10208             if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
   10209             try {
   10210                 IBackupManager bm = IBackupManager.Stub.asInterface(
   10211                         ServiceManager.getService(Context.BACKUP_SERVICE));
   10212                 bm.agentDisconnected(app.info.packageName);
   10213             } catch (RemoteException e) {
   10214                 // can't happen; backup manager is local
   10215             }
   10216         }
   10217 
   10218         mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
   10219 
   10220         // If the caller is restarting this app, then leave it in its
   10221         // current lists and let the caller take care of it.
   10222         if (restarting) {
   10223             return;
   10224         }
   10225 
   10226         if (!app.persistent) {
   10227             if (DEBUG_PROCESSES) Slog.v(TAG,
   10228                     "Removing non-persistent process during cleanup: " + app);
   10229             mProcessNames.remove(app.processName, app.info.uid);
   10230             if (mHeavyWeightProcess == app) {
   10231                 mHeavyWeightProcess = null;
   10232                 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
   10233             }
   10234         } else if (!app.removed) {
   10235             // This app is persistent, so we need to keep its record around.
   10236             // If it is not already on the pending app list, add it there
   10237             // and start a new process for it.
   10238             if (mPersistentStartingProcesses.indexOf(app) < 0) {
   10239                 mPersistentStartingProcesses.add(app);
   10240                 restart = true;
   10241             }
   10242         }
   10243         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   10244                 "Clean-up removing on hold: " + app);
   10245         mProcessesOnHold.remove(app);
   10246 
   10247         if (app == mHomeProcess) {
   10248             mHomeProcess = null;
   10249         }
   10250         if (app == mPreviousProcess) {
   10251             mPreviousProcess = null;
   10252         }
   10253 
   10254         if (restart) {
   10255             // We have components that still need to be running in the
   10256             // process, so re-launch it.
   10257             mProcessNames.put(app.processName, app.info.uid, app);
   10258             startProcessLocked(app, "restart", app.processName);
   10259         } else if (app.pid > 0 && app.pid != MY_PID) {
   10260             // Goodbye!
   10261             synchronized (mPidsSelfLocked) {
   10262                 mPidsSelfLocked.remove(app.pid);
   10263                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   10264             }
   10265             app.setPid(0);
   10266         }
   10267     }
   10268 
   10269     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
   10270         // Look through the content providers we are waiting to have launched,
   10271         // and if any run in this process then either schedule a restart of
   10272         // the process or kill the client waiting for it if this process has
   10273         // gone bad.
   10274         int NL = mLaunchingProviders.size();
   10275         boolean restart = false;
   10276         for (int i=0; i<NL; i++) {
   10277             ContentProviderRecord cpr = mLaunchingProviders.get(i);
   10278             if (cpr.launchingApp == app) {
   10279                 if (!alwaysBad && !app.bad) {
   10280                     restart = true;
   10281                 } else {
   10282                     removeDyingProviderLocked(app, cpr);
   10283                     NL = mLaunchingProviders.size();
   10284                 }
   10285             }
   10286         }
   10287         return restart;
   10288     }
   10289 
   10290     // =========================================================
   10291     // SERVICES
   10292     // =========================================================
   10293 
   10294     ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
   10295         ActivityManager.RunningServiceInfo info =
   10296             new ActivityManager.RunningServiceInfo();
   10297         info.service = r.name;
   10298         if (r.app != null) {
   10299             info.pid = r.app.pid;
   10300         }
   10301         info.uid = r.appInfo.uid;
   10302         info.process = r.processName;
   10303         info.foreground = r.isForeground;
   10304         info.activeSince = r.createTime;
   10305         info.started = r.startRequested;
   10306         info.clientCount = r.connections.size();
   10307         info.crashCount = r.crashCount;
   10308         info.lastActivityTime = r.lastActivity;
   10309         if (r.isForeground) {
   10310             info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
   10311         }
   10312         if (r.startRequested) {
   10313             info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
   10314         }
   10315         if (r.app != null && r.app.pid == MY_PID) {
   10316             info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
   10317         }
   10318         if (r.app != null && r.app.persistent) {
   10319             info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
   10320         }
   10321 
   10322         for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
   10323             for (int i=0; i<connl.size(); i++) {
   10324                 ConnectionRecord conn = connl.get(i);
   10325                 if (conn.clientLabel != 0) {
   10326                     info.clientPackage = conn.binding.client.info.packageName;
   10327                     info.clientLabel = conn.clientLabel;
   10328                     return info;
   10329                 }
   10330             }
   10331         }
   10332         return info;
   10333     }
   10334 
   10335     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
   10336             int flags) {
   10337         synchronized (this) {
   10338             ArrayList<ActivityManager.RunningServiceInfo> res
   10339                     = new ArrayList<ActivityManager.RunningServiceInfo>();
   10340 
   10341             if (mServices.size() > 0) {
   10342                 Iterator<ServiceRecord> it = mServices.values().iterator();
   10343                 while (it.hasNext() && res.size() < maxNum) {
   10344                     res.add(makeRunningServiceInfoLocked(it.next()));
   10345                 }
   10346             }
   10347 
   10348             for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
   10349                 ServiceRecord r = mRestartingServices.get(i);
   10350                 ActivityManager.RunningServiceInfo info =
   10351                         makeRunningServiceInfoLocked(r);
   10352                 info.restarting = r.nextRestartTime;
   10353                 res.add(info);
   10354             }
   10355 
   10356             return res;
   10357         }
   10358     }
   10359 
   10360     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
   10361         synchronized (this) {
   10362             ServiceRecord r = mServices.get(name);
   10363             if (r != null) {
   10364                 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
   10365                     for (int i=0; i<conn.size(); i++) {
   10366                         if (conn.get(i).clientIntent != null) {
   10367                             return conn.get(i).clientIntent;
   10368                         }
   10369                     }
   10370                 }
   10371             }
   10372         }
   10373         return null;
   10374     }
   10375 
   10376     private final ServiceRecord findServiceLocked(ComponentName name,
   10377             IBinder token) {
   10378         ServiceRecord r = mServices.get(name);
   10379         return r == token ? r : null;
   10380     }
   10381 
   10382     private final class ServiceLookupResult {
   10383         final ServiceRecord record;
   10384         final String permission;
   10385 
   10386         ServiceLookupResult(ServiceRecord _record, String _permission) {
   10387             record = _record;
   10388             permission = _permission;
   10389         }
   10390     };
   10391 
   10392     private ServiceLookupResult findServiceLocked(Intent service,
   10393             String resolvedType) {
   10394         ServiceRecord r = null;
   10395         if (service.getComponent() != null) {
   10396             r = mServices.get(service.getComponent());
   10397         }
   10398         if (r == null) {
   10399             Intent.FilterComparison filter = new Intent.FilterComparison(service);
   10400             r = mServicesByIntent.get(filter);
   10401         }
   10402 
   10403         if (r == null) {
   10404             try {
   10405                 ResolveInfo rInfo =
   10406                     AppGlobals.getPackageManager().resolveService(
   10407                             service, resolvedType, 0);
   10408                 ServiceInfo sInfo =
   10409                     rInfo != null ? rInfo.serviceInfo : null;
   10410                 if (sInfo == null) {
   10411                     return null;
   10412                 }
   10413 
   10414                 ComponentName name = new ComponentName(
   10415                         sInfo.applicationInfo.packageName, sInfo.name);
   10416                 r = mServices.get(name);
   10417             } catch (RemoteException ex) {
   10418                 // pm is in same process, this will never happen.
   10419             }
   10420         }
   10421         if (r != null) {
   10422             int callingPid = Binder.getCallingPid();
   10423             int callingUid = Binder.getCallingUid();
   10424             if (checkComponentPermission(r.permission,
   10425                     callingPid, callingUid, r.appInfo.uid, r.exported)
   10426                     != PackageManager.PERMISSION_GRANTED) {
   10427                 if (!r.exported) {
   10428                     Slog.w(TAG, "Permission Denial: Accessing service " + r.name
   10429                             + " from pid=" + callingPid
   10430                             + ", uid=" + callingUid
   10431                             + " that is not exported from uid " + r.appInfo.uid);
   10432                     return new ServiceLookupResult(null, "not exported from uid "
   10433                             + r.appInfo.uid);
   10434                 }
   10435                 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
   10436                         + " from pid=" + callingPid
   10437                         + ", uid=" + callingUid
   10438                         + " requires " + r.permission);
   10439                 return new ServiceLookupResult(null, r.permission);
   10440             }
   10441             return new ServiceLookupResult(r, null);
   10442         }
   10443         return null;
   10444     }
   10445 
   10446     private class ServiceRestarter implements Runnable {
   10447         private ServiceRecord mService;
   10448 
   10449         void setService(ServiceRecord service) {
   10450             mService = service;
   10451         }
   10452 
   10453         public void run() {
   10454             synchronized(ActivityManagerService.this) {
   10455                 performServiceRestartLocked(mService);
   10456             }
   10457         }
   10458     }
   10459 
   10460     private ServiceLookupResult retrieveServiceLocked(Intent service,
   10461             String resolvedType, int callingPid, int callingUid) {
   10462         ServiceRecord r = null;
   10463         if (service.getComponent() != null) {
   10464             r = mServices.get(service.getComponent());
   10465         }
   10466         Intent.FilterComparison filter = new Intent.FilterComparison(service);
   10467         r = mServicesByIntent.get(filter);
   10468         if (r == null) {
   10469             try {
   10470                 ResolveInfo rInfo =
   10471                     AppGlobals.getPackageManager().resolveService(
   10472                             service, resolvedType, STOCK_PM_FLAGS);
   10473                 ServiceInfo sInfo =
   10474                     rInfo != null ? rInfo.serviceInfo : null;
   10475                 if (sInfo == null) {
   10476                     Slog.w(TAG, "Unable to start service " + service +
   10477                           ": not found");
   10478                     return null;
   10479                 }
   10480 
   10481                 ComponentName name = new ComponentName(
   10482                         sInfo.applicationInfo.packageName, sInfo.name);
   10483                 r = mServices.get(name);
   10484                 if (r == null) {
   10485                     filter = new Intent.FilterComparison(service.cloneFilter());
   10486                     ServiceRestarter res = new ServiceRestarter();
   10487                     BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   10488                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   10489                     synchronized (stats) {
   10490                         ss = stats.getServiceStatsLocked(
   10491                                 sInfo.applicationInfo.uid, sInfo.packageName,
   10492                                 sInfo.name);
   10493                     }
   10494                     r = new ServiceRecord(this, ss, name, filter, sInfo, res);
   10495                     res.setService(r);
   10496                     mServices.put(name, r);
   10497                     mServicesByIntent.put(filter, r);
   10498 
   10499                     // Make sure this component isn't in the pending list.
   10500                     int N = mPendingServices.size();
   10501                     for (int i=0; i<N; i++) {
   10502                         ServiceRecord pr = mPendingServices.get(i);
   10503                         if (pr.name.equals(name)) {
   10504                             mPendingServices.remove(i);
   10505                             i--;
   10506                             N--;
   10507                         }
   10508                     }
   10509                 }
   10510             } catch (RemoteException ex) {
   10511                 // pm is in same process, this will never happen.
   10512             }
   10513         }
   10514         if (r != null) {
   10515             if (checkComponentPermission(r.permission,
   10516                     callingPid, callingUid, r.appInfo.uid, r.exported)
   10517                     != PackageManager.PERMISSION_GRANTED) {
   10518                 if (!r.exported) {
   10519                     Slog.w(TAG, "Permission Denial: Accessing service " + r.name
   10520                             + " from pid=" + callingPid
   10521                             + ", uid=" + callingUid
   10522                             + " that is not exported from uid " + r.appInfo.uid);
   10523                     return new ServiceLookupResult(null, "not exported from uid "
   10524                             + r.appInfo.uid);
   10525                 }
   10526                 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
   10527                         + " from pid=" + callingPid
   10528                         + ", uid=" + callingUid
   10529                         + " requires " + r.permission);
   10530                 return new ServiceLookupResult(null, r.permission);
   10531             }
   10532             return new ServiceLookupResult(r, null);
   10533         }
   10534         return null;
   10535     }
   10536 
   10537     private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
   10538         if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
   10539                 + why + " of " + r + " in app " + r.app);
   10540         else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
   10541                 + why + " of " + r.shortName);
   10542         long now = SystemClock.uptimeMillis();
   10543         if (r.executeNesting == 0 && r.app != null) {
   10544             if (r.app.executingServices.size() == 0) {
   10545                 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   10546                 msg.obj = r.app;
   10547                 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
   10548             }
   10549             r.app.executingServices.add(r);
   10550         }
   10551         r.executeNesting++;
   10552         r.executingStart = now;
   10553     }
   10554 
   10555     private final void sendServiceArgsLocked(ServiceRecord r,
   10556             boolean oomAdjusted) {
   10557         final int N = r.pendingStarts.size();
   10558         if (N == 0) {
   10559             return;
   10560         }
   10561 
   10562         while (r.pendingStarts.size() > 0) {
   10563             try {
   10564                 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
   10565                 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
   10566                         + r + " " + r.intent + " args=" + si.intent);
   10567                 if (si.intent == null && N > 1) {
   10568                     // If somehow we got a dummy null intent in the middle,
   10569                     // then skip it.  DO NOT skip a null intent when it is
   10570                     // the only one in the list -- this is to support the
   10571                     // onStartCommand(null) case.
   10572                     continue;
   10573                 }
   10574                 si.deliveredTime = SystemClock.uptimeMillis();
   10575                 r.deliveredStarts.add(si);
   10576                 si.deliveryCount++;
   10577                 if (si.targetPermissionUid >= 0 && si.intent != null) {
   10578                     grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
   10579                             r.packageName, si.intent, si.getUriPermissionsLocked());
   10580                 }
   10581                 bumpServiceExecutingLocked(r, "start");
   10582                 if (!oomAdjusted) {
   10583                     oomAdjusted = true;
   10584                     updateOomAdjLocked(r.app);
   10585                 }
   10586                 int flags = 0;
   10587                 if (si.deliveryCount > 0) {
   10588                     flags |= Service.START_FLAG_RETRY;
   10589                 }
   10590                 if (si.doneExecutingCount > 0) {
   10591                     flags |= Service.START_FLAG_REDELIVERY;
   10592                 }
   10593                 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
   10594             } catch (RemoteException e) {
   10595                 // Remote process gone...  we'll let the normal cleanup take
   10596                 // care of this.
   10597                 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
   10598                 break;
   10599             } catch (Exception e) {
   10600                 Slog.w(TAG, "Unexpected exception", e);
   10601                 break;
   10602             }
   10603         }
   10604     }
   10605 
   10606     private final boolean requestServiceBindingLocked(ServiceRecord r,
   10607             IntentBindRecord i, boolean rebind) {
   10608         if (r.app == null || r.app.thread == null) {
   10609             // If service is not currently running, can't yet bind.
   10610             return false;
   10611         }
   10612         if ((!i.requested || rebind) && i.apps.size() > 0) {
   10613             try {
   10614                 bumpServiceExecutingLocked(r, "bind");
   10615                 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
   10616                 if (!rebind) {
   10617                     i.requested = true;
   10618                 }
   10619                 i.hasBound = true;
   10620                 i.doRebind = false;
   10621             } catch (RemoteException e) {
   10622                 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
   10623                 return false;
   10624             }
   10625         }
   10626         return true;
   10627     }
   10628 
   10629     private final void requestServiceBindingsLocked(ServiceRecord r) {
   10630         Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
   10631         while (bindings.hasNext()) {
   10632             IntentBindRecord i = bindings.next();
   10633             if (!requestServiceBindingLocked(r, i, false)) {
   10634                 break;
   10635             }
   10636         }
   10637     }
   10638 
   10639     private final void realStartServiceLocked(ServiceRecord r,
   10640             ProcessRecord app) throws RemoteException {
   10641         if (app.thread == null) {
   10642             throw new RemoteException();
   10643         }
   10644 
   10645         r.app = app;
   10646         r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
   10647 
   10648         app.services.add(r);
   10649         bumpServiceExecutingLocked(r, "create");
   10650         updateLruProcessLocked(app, true, true);
   10651 
   10652         boolean created = false;
   10653         try {
   10654             mStringBuilder.setLength(0);
   10655             r.intent.getIntent().toShortString(mStringBuilder, true, false, true);
   10656             EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
   10657                     System.identityHashCode(r), r.shortName,
   10658                     mStringBuilder.toString(), r.app.pid);
   10659             synchronized (r.stats.getBatteryStats()) {
   10660                 r.stats.startLaunchedLocked();
   10661             }
   10662             ensurePackageDexOpt(r.serviceInfo.packageName);
   10663             app.thread.scheduleCreateService(r, r.serviceInfo,
   10664                     compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
   10665             r.postNotification();
   10666             created = true;
   10667         } finally {
   10668             if (!created) {
   10669                 app.services.remove(r);
   10670                 scheduleServiceRestartLocked(r, false);
   10671             }
   10672         }
   10673 
   10674         requestServiceBindingsLocked(r);
   10675 
   10676         // If the service is in the started state, and there are no
   10677         // pending arguments, then fake up one so its onStartCommand() will
   10678         // be called.
   10679         if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
   10680             r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
   10681                     null, -1));
   10682         }
   10683 
   10684         sendServiceArgsLocked(r, true);
   10685     }
   10686 
   10687     private final boolean scheduleServiceRestartLocked(ServiceRecord r,
   10688             boolean allowCancel) {
   10689         boolean canceled = false;
   10690 
   10691         final long now = SystemClock.uptimeMillis();
   10692         long minDuration = SERVICE_RESTART_DURATION;
   10693         long resetTime = SERVICE_RESET_RUN_DURATION;
   10694 
   10695         if ((r.serviceInfo.applicationInfo.flags
   10696                 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
   10697             minDuration /= 4;
   10698         }
   10699 
   10700         // Any delivered but not yet finished starts should be put back
   10701         // on the pending list.
   10702         final int N = r.deliveredStarts.size();
   10703         if (N > 0) {
   10704             for (int i=N-1; i>=0; i--) {
   10705                 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
   10706                 si.removeUriPermissionsLocked();
   10707                 if (si.intent == null) {
   10708                     // We'll generate this again if needed.
   10709                 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
   10710                         && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
   10711                     r.pendingStarts.add(0, si);
   10712                     long dur = SystemClock.uptimeMillis() - si.deliveredTime;
   10713                     dur *= 2;
   10714                     if (minDuration < dur) minDuration = dur;
   10715                     if (resetTime < dur) resetTime = dur;
   10716                 } else {
   10717                     Slog.w(TAG, "Canceling start item " + si.intent + " in service "
   10718                             + r.name);
   10719                     canceled = true;
   10720                 }
   10721             }
   10722             r.deliveredStarts.clear();
   10723         }
   10724 
   10725         r.totalRestartCount++;
   10726         if (r.restartDelay == 0) {
   10727             r.restartCount++;
   10728             r.restartDelay = minDuration;
   10729         } else {
   10730             // If it has been a "reasonably long time" since the service
   10731             // was started, then reset our restart duration back to
   10732             // the beginning, so we don't infinitely increase the duration
   10733             // on a service that just occasionally gets killed (which is
   10734             // a normal case, due to process being killed to reclaim memory).
   10735             if (now > (r.restartTime+resetTime)) {
   10736                 r.restartCount = 1;
   10737                 r.restartDelay = minDuration;
   10738             } else {
   10739                 if ((r.serviceInfo.applicationInfo.flags
   10740                         &ApplicationInfo.FLAG_PERSISTENT) != 0) {
   10741                     // Services in peristent processes will restart much more
   10742                     // quickly, since they are pretty important.  (Think SystemUI).
   10743                     r.restartDelay += minDuration/2;
   10744                 } else {
   10745                     r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
   10746                     if (r.restartDelay < minDuration) {
   10747                         r.restartDelay = minDuration;
   10748                     }
   10749                 }
   10750             }
   10751         }
   10752 
   10753         r.nextRestartTime = now + r.restartDelay;
   10754 
   10755         // Make sure that we don't end up restarting a bunch of services
   10756         // all at the same time.
   10757         boolean repeat;
   10758         do {
   10759             repeat = false;
   10760             for (int i=mRestartingServices.size()-1; i>=0; i--) {
   10761                 ServiceRecord r2 = mRestartingServices.get(i);
   10762                 if (r2 != r && r.nextRestartTime
   10763                         >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
   10764                         && r.nextRestartTime
   10765                         < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
   10766                     r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
   10767                     r.restartDelay = r.nextRestartTime - now;
   10768                     repeat = true;
   10769                     break;
   10770                 }
   10771             }
   10772         } while (repeat);
   10773 
   10774         if (!mRestartingServices.contains(r)) {
   10775             mRestartingServices.add(r);
   10776         }
   10777 
   10778         r.cancelNotification();
   10779 
   10780         mHandler.removeCallbacks(r.restarter);
   10781         mHandler.postAtTime(r.restarter, r.nextRestartTime);
   10782         r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
   10783         Slog.w(TAG, "Scheduling restart of crashed service "
   10784                 + r.shortName + " in " + r.restartDelay + "ms");
   10785         EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
   10786                 r.shortName, r.restartDelay);
   10787 
   10788         return canceled;
   10789     }
   10790 
   10791     final void performServiceRestartLocked(ServiceRecord r) {
   10792         if (!mRestartingServices.contains(r)) {
   10793             return;
   10794         }
   10795         bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
   10796     }
   10797 
   10798     private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
   10799         if (r.restartDelay == 0) {
   10800             return false;
   10801         }
   10802         r.resetRestartCounter();
   10803         mRestartingServices.remove(r);
   10804         mHandler.removeCallbacks(r.restarter);
   10805         return true;
   10806     }
   10807 
   10808     private final boolean bringUpServiceLocked(ServiceRecord r,
   10809             int intentFlags, boolean whileRestarting) {
   10810         //Slog.i(TAG, "Bring up service:");
   10811         //r.dump("  ");
   10812 
   10813         if (r.app != null && r.app.thread != null) {
   10814             sendServiceArgsLocked(r, false);
   10815             return true;
   10816         }
   10817 
   10818         if (!whileRestarting && r.restartDelay > 0) {
   10819             // If waiting for a restart, then do nothing.
   10820             return true;
   10821         }
   10822 
   10823         if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
   10824 
   10825         // We are now bringing the service up, so no longer in the
   10826         // restarting state.
   10827         mRestartingServices.remove(r);
   10828 
   10829         // Service is now being launched, its package can't be stopped.
   10830         try {
   10831             AppGlobals.getPackageManager().setPackageStoppedState(
   10832                     r.packageName, false);
   10833         } catch (RemoteException e) {
   10834         } catch (IllegalArgumentException e) {
   10835             Slog.w(TAG, "Failed trying to unstop package "
   10836                     + r.packageName + ": " + e);
   10837         }
   10838 
   10839         final String appName = r.processName;
   10840         ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
   10841         if (app != null && app.thread != null) {
   10842             try {
   10843                 app.addPackage(r.appInfo.packageName);
   10844                 realStartServiceLocked(r, app);
   10845                 return true;
   10846             } catch (RemoteException e) {
   10847                 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
   10848             }
   10849 
   10850             // If a dead object exception was thrown -- fall through to
   10851             // restart the application.
   10852         }
   10853 
   10854         // Not running -- get it started, and enqueue this service record
   10855         // to be executed when the app comes up.
   10856         if (startProcessLocked(appName, r.appInfo, true, intentFlags,
   10857                 "service", r.name, false) == null) {
   10858             Slog.w(TAG, "Unable to launch app "
   10859                     + r.appInfo.packageName + "/"
   10860                     + r.appInfo.uid + " for service "
   10861                     + r.intent.getIntent() + ": process is bad");
   10862             bringDownServiceLocked(r, true);
   10863             return false;
   10864         }
   10865 
   10866         if (!mPendingServices.contains(r)) {
   10867             mPendingServices.add(r);
   10868         }
   10869 
   10870         return true;
   10871     }
   10872 
   10873     private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
   10874         //Slog.i(TAG, "Bring down service:");
   10875         //r.dump("  ");
   10876 
   10877         // Does it still need to run?
   10878         if (!force && r.startRequested) {
   10879             return;
   10880         }
   10881         if (r.connections.size() > 0) {
   10882             if (!force) {
   10883                 // XXX should probably keep a count of the number of auto-create
   10884                 // connections directly in the service.
   10885                 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
   10886                 while (it.hasNext()) {
   10887                     ArrayList<ConnectionRecord> cr = it.next();
   10888                     for (int i=0; i<cr.size(); i++) {
   10889                         if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
   10890                             return;
   10891                         }
   10892                     }
   10893                 }
   10894             }
   10895 
   10896             // Report to all of the connections that the service is no longer
   10897             // available.
   10898             Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
   10899             while (it.hasNext()) {
   10900                 ArrayList<ConnectionRecord> c = it.next();
   10901                 for (int i=0; i<c.size(); i++) {
   10902                     ConnectionRecord cr = c.get(i);
   10903                     // There is still a connection to the service that is
   10904                     // being brought down.  Mark it as dead.
   10905                     cr.serviceDead = true;
   10906                     try {
   10907                         cr.conn.connected(r.name, null);
   10908                     } catch (Exception e) {
   10909                         Slog.w(TAG, "Failure disconnecting service " + r.name +
   10910                               " to connection " + c.get(i).conn.asBinder() +
   10911                               " (in " + c.get(i).binding.client.processName + ")", e);
   10912                     }
   10913                 }
   10914             }
   10915         }
   10916 
   10917         // Tell the service that it has been unbound.
   10918         if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
   10919             Iterator<IntentBindRecord> it = r.bindings.values().iterator();
   10920             while (it.hasNext()) {
   10921                 IntentBindRecord ibr = it.next();
   10922                 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
   10923                         + ": hasBound=" + ibr.hasBound);
   10924                 if (r.app != null && r.app.thread != null && ibr.hasBound) {
   10925                     try {
   10926                         bumpServiceExecutingLocked(r, "bring down unbind");
   10927                         updateOomAdjLocked(r.app);
   10928                         ibr.hasBound = false;
   10929                         r.app.thread.scheduleUnbindService(r,
   10930                                 ibr.intent.getIntent());
   10931                     } catch (Exception e) {
   10932                         Slog.w(TAG, "Exception when unbinding service "
   10933                                 + r.shortName, e);
   10934                         serviceDoneExecutingLocked(r, true);
   10935                     }
   10936                 }
   10937             }
   10938         }
   10939 
   10940         if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
   10941         EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
   10942                 System.identityHashCode(r), r.shortName,
   10943                 (r.app != null) ? r.app.pid : -1);
   10944 
   10945         mServices.remove(r.name);
   10946         mServicesByIntent.remove(r.intent);
   10947         r.totalRestartCount = 0;
   10948         unscheduleServiceRestartLocked(r);
   10949 
   10950         // Also make sure it is not on the pending list.
   10951         int N = mPendingServices.size();
   10952         for (int i=0; i<N; i++) {
   10953             if (mPendingServices.get(i) == r) {
   10954                 mPendingServices.remove(i);
   10955                 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
   10956                 i--;
   10957                 N--;
   10958             }
   10959         }
   10960 
   10961         r.cancelNotification();
   10962         r.isForeground = false;
   10963         r.foregroundId = 0;
   10964         r.foregroundNoti = null;
   10965 
   10966         // Clear start entries.
   10967         r.clearDeliveredStartsLocked();
   10968         r.pendingStarts.clear();
   10969 
   10970         if (r.app != null) {
   10971             synchronized (r.stats.getBatteryStats()) {
   10972                 r.stats.stopLaunchedLocked();
   10973             }
   10974             r.app.services.remove(r);
   10975             if (r.app.thread != null) {
   10976                 try {
   10977                     bumpServiceExecutingLocked(r, "stop");
   10978                     mStoppingServices.add(r);
   10979                     updateOomAdjLocked(r.app);
   10980                     r.app.thread.scheduleStopService(r);
   10981                 } catch (Exception e) {
   10982                     Slog.w(TAG, "Exception when stopping service "
   10983                             + r.shortName, e);
   10984                     serviceDoneExecutingLocked(r, true);
   10985                 }
   10986                 updateServiceForegroundLocked(r.app, false);
   10987             } else {
   10988                 if (DEBUG_SERVICE) Slog.v(
   10989                     TAG, "Removed service that has no process: " + r);
   10990             }
   10991         } else {
   10992             if (DEBUG_SERVICE) Slog.v(
   10993                 TAG, "Removed service that is not running: " + r);
   10994         }
   10995 
   10996         if (r.bindings.size() > 0) {
   10997             r.bindings.clear();
   10998         }
   10999 
   11000         if (r.restarter instanceof ServiceRestarter) {
   11001            ((ServiceRestarter)r.restarter).setService(null);
   11002         }
   11003     }
   11004 
   11005     ComponentName startServiceLocked(IApplicationThread caller,
   11006             Intent service, String resolvedType,
   11007             int callingPid, int callingUid) {
   11008         synchronized(this) {
   11009             if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
   11010                     + " type=" + resolvedType + " args=" + service.getExtras());
   11011 
   11012             if (caller != null) {
   11013                 final ProcessRecord callerApp = getRecordForAppLocked(caller);
   11014                 if (callerApp == null) {
   11015                     throw new SecurityException(
   11016                             "Unable to find app for caller " + caller
   11017                             + " (pid=" + Binder.getCallingPid()
   11018                             + ") when starting service " + service);
   11019                 }
   11020             }
   11021 
   11022             ServiceLookupResult res =
   11023                 retrieveServiceLocked(service, resolvedType,
   11024                         callingPid, callingUid);
   11025             if (res == null) {
   11026                 return null;
   11027             }
   11028             if (res.record == null) {
   11029                 return new ComponentName("!", res.permission != null
   11030                         ? res.permission : "private to package");
   11031             }
   11032             ServiceRecord r = res.record;
   11033             int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
   11034                     callingUid, r.packageName, service);
   11035             if (unscheduleServiceRestartLocked(r)) {
   11036                 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
   11037             }
   11038             r.startRequested = true;
   11039             r.callStart = false;
   11040             r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
   11041                     service, targetPermissionUid));
   11042             r.lastActivity = SystemClock.uptimeMillis();
   11043             synchronized (r.stats.getBatteryStats()) {
   11044                 r.stats.startRunningLocked();
   11045             }
   11046             if (!bringUpServiceLocked(r, service.getFlags(), false)) {
   11047                 return new ComponentName("!", "Service process is bad");
   11048             }
   11049             return r.name;
   11050         }
   11051     }
   11052 
   11053     public ComponentName startService(IApplicationThread caller, Intent service,
   11054             String resolvedType) {
   11055         // Refuse possible leaked file descriptors
   11056         if (service != null && service.hasFileDescriptors() == true) {
   11057             throw new IllegalArgumentException("File descriptors passed in Intent");
   11058         }
   11059 
   11060         synchronized(this) {
   11061             final int callingPid = Binder.getCallingPid();
   11062             final int callingUid = Binder.getCallingUid();
   11063             final long origId = Binder.clearCallingIdentity();
   11064             ComponentName res = startServiceLocked(caller, service,
   11065                     resolvedType, callingPid, callingUid);
   11066             Binder.restoreCallingIdentity(origId);
   11067             return res;
   11068         }
   11069     }
   11070 
   11071     ComponentName startServiceInPackage(int uid,
   11072             Intent service, String resolvedType) {
   11073         synchronized(this) {
   11074             final long origId = Binder.clearCallingIdentity();
   11075             ComponentName res = startServiceLocked(null, service,
   11076                     resolvedType, -1, uid);
   11077             Binder.restoreCallingIdentity(origId);
   11078             return res;
   11079         }
   11080     }
   11081 
   11082     private void stopServiceLocked(ServiceRecord service) {
   11083         synchronized (service.stats.getBatteryStats()) {
   11084             service.stats.stopRunningLocked();
   11085         }
   11086         service.startRequested = false;
   11087         service.callStart = false;
   11088         bringDownServiceLocked(service, false);
   11089     }
   11090 
   11091     public int stopService(IApplicationThread caller, Intent service,
   11092             String resolvedType) {
   11093         // Refuse possible leaked file descriptors
   11094         if (service != null && service.hasFileDescriptors() == true) {
   11095             throw new IllegalArgumentException("File descriptors passed in Intent");
   11096         }
   11097 
   11098         synchronized(this) {
   11099             if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
   11100                     + " type=" + resolvedType);
   11101 
   11102             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   11103             if (caller != null && callerApp == null) {
   11104                 throw new SecurityException(
   11105                         "Unable to find app for caller " + caller
   11106                         + " (pid=" + Binder.getCallingPid()
   11107                         + ") when stopping service " + service);
   11108             }
   11109 
   11110             // If this service is active, make sure it is stopped.
   11111             ServiceLookupResult r = findServiceLocked(service, resolvedType);
   11112             if (r != null) {
   11113                 if (r.record != null) {
   11114                     final long origId = Binder.clearCallingIdentity();
   11115                     try {
   11116                         stopServiceLocked(r.record);
   11117                     } finally {
   11118                         Binder.restoreCallingIdentity(origId);
   11119                     }
   11120                     return 1;
   11121                 }
   11122                 return -1;
   11123             }
   11124         }
   11125 
   11126         return 0;
   11127     }
   11128 
   11129     public IBinder peekService(Intent service, String resolvedType) {
   11130         // Refuse possible leaked file descriptors
   11131         if (service != null && service.hasFileDescriptors() == true) {
   11132             throw new IllegalArgumentException("File descriptors passed in Intent");
   11133         }
   11134 
   11135         IBinder ret = null;
   11136 
   11137         synchronized(this) {
   11138             ServiceLookupResult r = findServiceLocked(service, resolvedType);
   11139 
   11140             if (r != null) {
   11141                 // r.record is null if findServiceLocked() failed the caller permission check
   11142                 if (r.record == null) {
   11143                     throw new SecurityException(
   11144                             "Permission Denial: Accessing service " + r.record.name
   11145                             + " from pid=" + Binder.getCallingPid()
   11146                             + ", uid=" + Binder.getCallingUid()
   11147                             + " requires " + r.permission);
   11148                 }
   11149                 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
   11150                 if (ib != null) {
   11151                     ret = ib.binder;
   11152                 }
   11153             }
   11154         }
   11155 
   11156         return ret;
   11157     }
   11158 
   11159     public boolean stopServiceToken(ComponentName className, IBinder token,
   11160             int startId) {
   11161         synchronized(this) {
   11162             if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
   11163                     + " " + token + " startId=" + startId);
   11164             ServiceRecord r = findServiceLocked(className, token);
   11165             if (r != null) {
   11166                 if (startId >= 0) {
   11167                     // Asked to only stop if done with all work.  Note that
   11168                     // to avoid leaks, we will take this as dropping all
   11169                     // start items up to and including this one.
   11170                     ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
   11171                     if (si != null) {
   11172                         while (r.deliveredStarts.size() > 0) {
   11173                             ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
   11174                             cur.removeUriPermissionsLocked();
   11175                             if (cur == si) {
   11176                                 break;
   11177                             }
   11178                         }
   11179                     }
   11180 
   11181                     if (r.getLastStartId() != startId) {
   11182                         return false;
   11183                     }
   11184 
   11185                     if (r.deliveredStarts.size() > 0) {
   11186                         Slog.w(TAG, "stopServiceToken startId " + startId
   11187                                 + " is last, but have " + r.deliveredStarts.size()
   11188                                 + " remaining args");
   11189                     }
   11190                 }
   11191 
   11192                 synchronized (r.stats.getBatteryStats()) {
   11193                     r.stats.stopRunningLocked();
   11194                     r.startRequested = false;
   11195                     r.callStart = false;
   11196                 }
   11197                 final long origId = Binder.clearCallingIdentity();
   11198                 bringDownServiceLocked(r, false);
   11199                 Binder.restoreCallingIdentity(origId);
   11200                 return true;
   11201             }
   11202         }
   11203         return false;
   11204     }
   11205 
   11206     public void setServiceForeground(ComponentName className, IBinder token,
   11207             int id, Notification notification, boolean removeNotification) {
   11208         final long origId = Binder.clearCallingIdentity();
   11209         try {
   11210         synchronized(this) {
   11211             ServiceRecord r = findServiceLocked(className, token);
   11212             if (r != null) {
   11213                 if (id != 0) {
   11214                     if (notification == null) {
   11215                         throw new IllegalArgumentException("null notification");
   11216                     }
   11217                     if (r.foregroundId != id) {
   11218                         r.cancelNotification();
   11219                         r.foregroundId = id;
   11220                     }
   11221                     notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
   11222                     r.foregroundNoti = notification;
   11223                     r.isForeground = true;
   11224                     r.postNotification();
   11225                     if (r.app != null) {
   11226                         updateServiceForegroundLocked(r.app, true);
   11227                     }
   11228                 } else {
   11229                     if (r.isForeground) {
   11230                         r.isForeground = false;
   11231                         if (r.app != null) {
   11232                             updateLruProcessLocked(r.app, false, true);
   11233                             updateServiceForegroundLocked(r.app, true);
   11234                         }
   11235                     }
   11236                     if (removeNotification) {
   11237                         r.cancelNotification();
   11238                         r.foregroundId = 0;
   11239                         r.foregroundNoti = null;
   11240                     }
   11241                 }
   11242             }
   11243         }
   11244         } finally {
   11245             Binder.restoreCallingIdentity(origId);
   11246         }
   11247     }
   11248 
   11249     public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
   11250         boolean anyForeground = false;
   11251         for (ServiceRecord sr : proc.services) {
   11252             if (sr.isForeground) {
   11253                 anyForeground = true;
   11254                 break;
   11255             }
   11256         }
   11257         if (anyForeground != proc.foregroundServices) {
   11258             proc.foregroundServices = anyForeground;
   11259             if (oomAdj) {
   11260                 updateOomAdjLocked();
   11261             }
   11262         }
   11263     }
   11264 
   11265     public int bindService(IApplicationThread caller, IBinder token,
   11266             Intent service, String resolvedType,
   11267             IServiceConnection connection, int flags) {
   11268         // Refuse possible leaked file descriptors
   11269         if (service != null && service.hasFileDescriptors() == true) {
   11270             throw new IllegalArgumentException("File descriptors passed in Intent");
   11271         }
   11272 
   11273         synchronized(this) {
   11274             if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
   11275                     + " type=" + resolvedType + " conn=" + connection.asBinder()
   11276                     + " flags=0x" + Integer.toHexString(flags));
   11277             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   11278             if (callerApp == null) {
   11279                 throw new SecurityException(
   11280                         "Unable to find app for caller " + caller
   11281                         + " (pid=" + Binder.getCallingPid()
   11282                         + ") when binding service " + service);
   11283             }
   11284 
   11285             ActivityRecord activity = null;
   11286             if (token != null) {
   11287                 activity = mMainStack.isInStackLocked(token);
   11288                 if (activity == null) {
   11289                     Slog.w(TAG, "Binding with unknown activity: " + token);
   11290                     return 0;
   11291                 }
   11292             }
   11293 
   11294             int clientLabel = 0;
   11295             PendingIntent clientIntent = null;
   11296 
   11297             if (callerApp.info.uid == Process.SYSTEM_UID) {
   11298                 // Hacky kind of thing -- allow system stuff to tell us
   11299                 // what they are, so we can report this elsewhere for
   11300                 // others to know why certain services are running.
   11301                 try {
   11302                     clientIntent = (PendingIntent)service.getParcelableExtra(
   11303                             Intent.EXTRA_CLIENT_INTENT);
   11304                 } catch (RuntimeException e) {
   11305                 }
   11306                 if (clientIntent != null) {
   11307                     clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
   11308                     if (clientLabel != 0) {
   11309                         // There are no useful extras in the intent, trash them.
   11310                         // System code calling with this stuff just needs to know
   11311                         // this will happen.
   11312                         service = service.cloneFilter();
   11313                     }
   11314                 }
   11315             }
   11316 
   11317             ServiceLookupResult res =
   11318                 retrieveServiceLocked(service, resolvedType,
   11319                         Binder.getCallingPid(), Binder.getCallingUid());
   11320             if (res == null) {
   11321                 return 0;
   11322             }
   11323             if (res.record == null) {
   11324                 return -1;
   11325             }
   11326             ServiceRecord s = res.record;
   11327 
   11328             final long origId = Binder.clearCallingIdentity();
   11329 
   11330             if (unscheduleServiceRestartLocked(s)) {
   11331                 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
   11332                         + s);
   11333             }
   11334 
   11335             AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
   11336             ConnectionRecord c = new ConnectionRecord(b, activity,
   11337                     connection, flags, clientLabel, clientIntent);
   11338 
   11339             IBinder binder = connection.asBinder();
   11340             ArrayList<ConnectionRecord> clist = s.connections.get(binder);
   11341             if (clist == null) {
   11342                 clist = new ArrayList<ConnectionRecord>();
   11343                 s.connections.put(binder, clist);
   11344             }
   11345             clist.add(c);
   11346             b.connections.add(c);
   11347             if (activity != null) {
   11348                 if (activity.connections == null) {
   11349                     activity.connections = new HashSet<ConnectionRecord>();
   11350                 }
   11351                 activity.connections.add(c);
   11352             }
   11353             b.client.connections.add(c);
   11354             if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
   11355                 b.client.hasAboveClient = true;
   11356             }
   11357             clist = mServiceConnections.get(binder);
   11358             if (clist == null) {
   11359                 clist = new ArrayList<ConnectionRecord>();
   11360                 mServiceConnections.put(binder, clist);
   11361             }
   11362             clist.add(c);
   11363 
   11364             if ((flags&Context.BIND_AUTO_CREATE) != 0) {
   11365                 s.lastActivity = SystemClock.uptimeMillis();
   11366                 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
   11367                     return 0;
   11368                 }
   11369             }
   11370 
   11371             if (s.app != null) {
   11372                 // This could have made the service more important.
   11373                 updateOomAdjLocked(s.app);
   11374             }
   11375 
   11376             if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
   11377                     + ": received=" + b.intent.received
   11378                     + " apps=" + b.intent.apps.size()
   11379                     + " doRebind=" + b.intent.doRebind);
   11380 
   11381             if (s.app != null && b.intent.received) {
   11382                 // Service is already running, so we can immediately
   11383                 // publish the connection.
   11384                 try {
   11385                     c.conn.connected(s.name, b.intent.binder);
   11386                 } catch (Exception e) {
   11387                     Slog.w(TAG, "Failure sending service " + s.shortName
   11388                             + " to connection " + c.conn.asBinder()
   11389                             + " (in " + c.binding.client.processName + ")", e);
   11390                 }
   11391 
   11392                 // If this is the first app connected back to this binding,
   11393                 // and the service had previously asked to be told when
   11394                 // rebound, then do so.
   11395                 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
   11396                     requestServiceBindingLocked(s, b.intent, true);
   11397                 }
   11398             } else if (!b.intent.requested) {
   11399                 requestServiceBindingLocked(s, b.intent, false);
   11400             }
   11401 
   11402             Binder.restoreCallingIdentity(origId);
   11403         }
   11404 
   11405         return 1;
   11406     }
   11407 
   11408     void removeConnectionLocked(
   11409         ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
   11410         IBinder binder = c.conn.asBinder();
   11411         AppBindRecord b = c.binding;
   11412         ServiceRecord s = b.service;
   11413         ArrayList<ConnectionRecord> clist = s.connections.get(binder);
   11414         if (clist != null) {
   11415             clist.remove(c);
   11416             if (clist.size() == 0) {
   11417                 s.connections.remove(binder);
   11418             }
   11419         }
   11420         b.connections.remove(c);
   11421         if (c.activity != null && c.activity != skipAct) {
   11422             if (c.activity.connections != null) {
   11423                 c.activity.connections.remove(c);
   11424             }
   11425         }
   11426         if (b.client != skipApp) {
   11427             b.client.connections.remove(c);
   11428             if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
   11429                 b.client.updateHasAboveClientLocked();
   11430             }
   11431         }
   11432         clist = mServiceConnections.get(binder);
   11433         if (clist != null) {
   11434             clist.remove(c);
   11435             if (clist.size() == 0) {
   11436                 mServiceConnections.remove(binder);
   11437             }
   11438         }
   11439 
   11440         if (b.connections.size() == 0) {
   11441             b.intent.apps.remove(b.client);
   11442         }
   11443 
   11444         if (!c.serviceDead) {
   11445             if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
   11446                     + ": shouldUnbind=" + b.intent.hasBound);
   11447             if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
   11448                     && b.intent.hasBound) {
   11449                 try {
   11450                     bumpServiceExecutingLocked(s, "unbind");
   11451                     updateOomAdjLocked(s.app);
   11452                     b.intent.hasBound = false;
   11453                     // Assume the client doesn't want to know about a rebind;
   11454                     // we will deal with that later if it asks for one.
   11455                     b.intent.doRebind = false;
   11456                     s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
   11457                 } catch (Exception e) {
   11458                     Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
   11459                     serviceDoneExecutingLocked(s, true);
   11460                 }
   11461             }
   11462 
   11463             if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
   11464                 bringDownServiceLocked(s, false);
   11465             }
   11466         }
   11467     }
   11468 
   11469     public boolean unbindService(IServiceConnection connection) {
   11470         synchronized (this) {
   11471             IBinder binder = connection.asBinder();
   11472             if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
   11473             ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
   11474             if (clist == null) {
   11475                 Slog.w(TAG, "Unbind failed: could not find connection for "
   11476                       + connection.asBinder());
   11477                 return false;
   11478             }
   11479 
   11480             final long origId = Binder.clearCallingIdentity();
   11481 
   11482             while (clist.size() > 0) {
   11483                 ConnectionRecord r = clist.get(0);
   11484                 removeConnectionLocked(r, null, null);
   11485 
   11486                 if (r.binding.service.app != null) {
   11487                     // This could have made the service less important.
   11488                     updateOomAdjLocked(r.binding.service.app);
   11489                 }
   11490             }
   11491 
   11492             Binder.restoreCallingIdentity(origId);
   11493         }
   11494 
   11495         return true;
   11496     }
   11497 
   11498     public void publishService(IBinder token, Intent intent, IBinder service) {
   11499         // Refuse possible leaked file descriptors
   11500         if (intent != null && intent.hasFileDescriptors() == true) {
   11501             throw new IllegalArgumentException("File descriptors passed in Intent");
   11502         }
   11503 
   11504         synchronized(this) {
   11505             if (!(token instanceof ServiceRecord)) {
   11506                 throw new IllegalArgumentException("Invalid service token");
   11507             }
   11508             ServiceRecord r = (ServiceRecord)token;
   11509 
   11510             final long origId = Binder.clearCallingIdentity();
   11511 
   11512             if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
   11513                     + " " + intent + ": " + service);
   11514             if (r != null) {
   11515                 Intent.FilterComparison filter
   11516                         = new Intent.FilterComparison(intent);
   11517                 IntentBindRecord b = r.bindings.get(filter);
   11518                 if (b != null && !b.received) {
   11519                     b.binder = service;
   11520                     b.requested = true;
   11521                     b.received = true;
   11522                     if (r.connections.size() > 0) {
   11523                         Iterator<ArrayList<ConnectionRecord>> it
   11524                                 = r.connections.values().iterator();
   11525                         while (it.hasNext()) {
   11526                             ArrayList<ConnectionRecord> clist = it.next();
   11527                             for (int i=0; i<clist.size(); i++) {
   11528                                 ConnectionRecord c = clist.get(i);
   11529                                 if (!filter.equals(c.binding.intent.intent)) {
   11530                                     if (DEBUG_SERVICE) Slog.v(
   11531                                             TAG, "Not publishing to: " + c);
   11532                                     if (DEBUG_SERVICE) Slog.v(
   11533                                             TAG, "Bound intent: " + c.binding.intent.intent);
   11534                                     if (DEBUG_SERVICE) Slog.v(
   11535                                             TAG, "Published intent: " + intent);
   11536                                     continue;
   11537                                 }
   11538                                 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
   11539                                 try {
   11540                                     c.conn.connected(r.name, service);
   11541                                 } catch (Exception e) {
   11542                                     Slog.w(TAG, "Failure sending service " + r.name +
   11543                                           " to connection " + c.conn.asBinder() +
   11544                                           " (in " + c.binding.client.processName + ")", e);
   11545                                 }
   11546                             }
   11547                         }
   11548                     }
   11549                 }
   11550 
   11551                 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
   11552 
   11553                 Binder.restoreCallingIdentity(origId);
   11554             }
   11555         }
   11556     }
   11557 
   11558     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
   11559         // Refuse possible leaked file descriptors
   11560         if (intent != null && intent.hasFileDescriptors() == true) {
   11561             throw new IllegalArgumentException("File descriptors passed in Intent");
   11562         }
   11563 
   11564         synchronized(this) {
   11565             if (!(token instanceof ServiceRecord)) {
   11566                 throw new IllegalArgumentException("Invalid service token");
   11567             }
   11568             ServiceRecord r = (ServiceRecord)token;
   11569 
   11570             final long origId = Binder.clearCallingIdentity();
   11571 
   11572             if (r != null) {
   11573                 Intent.FilterComparison filter
   11574                         = new Intent.FilterComparison(intent);
   11575                 IntentBindRecord b = r.bindings.get(filter);
   11576                 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
   11577                         + " at " + b + ": apps="
   11578                         + (b != null ? b.apps.size() : 0));
   11579 
   11580                 boolean inStopping = mStoppingServices.contains(r);
   11581                 if (b != null) {
   11582                     if (b.apps.size() > 0 && !inStopping) {
   11583                         // Applications have already bound since the last
   11584                         // unbind, so just rebind right here.
   11585                         requestServiceBindingLocked(r, b, true);
   11586                     } else {
   11587                         // Note to tell the service the next time there is
   11588                         // a new client.
   11589                         b.doRebind = true;
   11590                     }
   11591                 }
   11592 
   11593                 serviceDoneExecutingLocked(r, inStopping);
   11594 
   11595                 Binder.restoreCallingIdentity(origId);
   11596             }
   11597         }
   11598     }
   11599 
   11600     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
   11601         synchronized(this) {
   11602             if (!(token instanceof ServiceRecord)) {
   11603                 throw new IllegalArgumentException("Invalid service token");
   11604             }
   11605             ServiceRecord r = (ServiceRecord)token;
   11606             boolean inStopping = mStoppingServices.contains(token);
   11607             if (r != null) {
   11608                 if (r != token) {
   11609                     Slog.w(TAG, "Done executing service " + r.name
   11610                           + " with incorrect token: given " + token
   11611                           + ", expected " + r);
   11612                     return;
   11613                 }
   11614 
   11615                 if (type == 1) {
   11616                     // This is a call from a service start...  take care of
   11617                     // book-keeping.
   11618                     r.callStart = true;
   11619                     switch (res) {
   11620                         case Service.START_STICKY_COMPATIBILITY:
   11621                         case Service.START_STICKY: {
   11622                             // We are done with the associated start arguments.
   11623                             r.findDeliveredStart(startId, true);
   11624                             // Don't stop if killed.
   11625                             r.stopIfKilled = false;
   11626                             break;
   11627                         }
   11628                         case Service.START_NOT_STICKY: {
   11629                             // We are done with the associated start arguments.
   11630                             r.findDeliveredStart(startId, true);
   11631                             if (r.getLastStartId() == startId) {
   11632                                 // There is no more work, and this service
   11633                                 // doesn't want to hang around if killed.
   11634                                 r.stopIfKilled = true;
   11635                             }
   11636                             break;
   11637                         }
   11638                         case Service.START_REDELIVER_INTENT: {
   11639                             // We'll keep this item until they explicitly
   11640                             // call stop for it, but keep track of the fact
   11641                             // that it was delivered.
   11642                             ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
   11643                             if (si != null) {
   11644                                 si.deliveryCount = 0;
   11645                                 si.doneExecutingCount++;
   11646                                 // Don't stop if killed.
   11647                                 r.stopIfKilled = true;
   11648                             }
   11649                             break;
   11650                         }
   11651                         case Service.START_TASK_REMOVED_COMPLETE: {
   11652                             // Special processing for onTaskRemoved().  Don't
   11653                             // impact normal onStartCommand() processing.
   11654                             r.findDeliveredStart(startId, true);
   11655                             break;
   11656                         }
   11657                         default:
   11658                             throw new IllegalArgumentException(
   11659                                     "Unknown service start result: " + res);
   11660                     }
   11661                     if (res == Service.START_STICKY_COMPATIBILITY) {
   11662                         r.callStart = false;
   11663                     }
   11664                 }
   11665 
   11666                 final long origId = Binder.clearCallingIdentity();
   11667                 serviceDoneExecutingLocked(r, inStopping);
   11668                 Binder.restoreCallingIdentity(origId);
   11669             } else {
   11670                 Slog.w(TAG, "Done executing unknown service from pid "
   11671                         + Binder.getCallingPid());
   11672             }
   11673         }
   11674     }
   11675 
   11676     public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
   11677         if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
   11678                 + ": nesting=" + r.executeNesting
   11679                 + ", inStopping=" + inStopping + ", app=" + r.app);
   11680         else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
   11681         r.executeNesting--;
   11682         if (r.executeNesting <= 0 && r.app != null) {
   11683             if (DEBUG_SERVICE) Slog.v(TAG,
   11684                     "Nesting at 0 of " + r.shortName);
   11685             r.app.executingServices.remove(r);
   11686             if (r.app.executingServices.size() == 0) {
   11687                 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
   11688                         "No more executingServices of " + r.shortName);
   11689                 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
   11690             }
   11691             if (inStopping) {
   11692                 if (DEBUG_SERVICE) Slog.v(TAG,
   11693                         "doneExecuting remove stopping " + r);
   11694                 mStoppingServices.remove(r);
   11695                 r.bindings.clear();
   11696             }
   11697             updateOomAdjLocked(r.app);
   11698         }
   11699     }
   11700 
   11701     void serviceTimeout(ProcessRecord proc) {
   11702         String anrMessage = null;
   11703 
   11704         synchronized(this) {
   11705             if (proc.executingServices.size() == 0 || proc.thread == null) {
   11706                 return;
   11707             }
   11708             long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
   11709             Iterator<ServiceRecord> it = proc.executingServices.iterator();
   11710             ServiceRecord timeout = null;
   11711             long nextTime = 0;
   11712             while (it.hasNext()) {
   11713                 ServiceRecord sr = it.next();
   11714                 if (sr.executingStart < maxTime) {
   11715                     timeout = sr;
   11716                     break;
   11717                 }
   11718                 if (sr.executingStart > nextTime) {
   11719                     nextTime = sr.executingStart;
   11720                 }
   11721             }
   11722             if (timeout != null && mLruProcesses.contains(proc)) {
   11723                 Slog.w(TAG, "Timeout executing service: " + timeout);
   11724                 anrMessage = "Executing service " + timeout.shortName;
   11725             } else {
   11726                 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   11727                 msg.obj = proc;
   11728                 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
   11729             }
   11730         }
   11731 
   11732         if (anrMessage != null) {
   11733             appNotResponding(proc, null, null, anrMessage);
   11734         }
   11735     }
   11736 
   11737     // =========================================================
   11738     // BACKUP AND RESTORE
   11739     // =========================================================
   11740 
   11741     // Cause the target app to be launched if necessary and its backup agent
   11742     // instantiated.  The backup agent will invoke backupAgentCreated() on the
   11743     // activity manager to announce its creation.
   11744     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
   11745         if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
   11746         enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
   11747 
   11748         synchronized(this) {
   11749             // !!! TODO: currently no check here that we're already bound
   11750             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   11751             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   11752             synchronized (stats) {
   11753                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
   11754             }
   11755 
   11756             // Backup agent is now in use, its package can't be stopped.
   11757             try {
   11758                 AppGlobals.getPackageManager().setPackageStoppedState(
   11759                         app.packageName, false);
   11760             } catch (RemoteException e) {
   11761             } catch (IllegalArgumentException e) {
   11762                 Slog.w(TAG, "Failed trying to unstop package "
   11763                         + app.packageName + ": " + e);
   11764             }
   11765 
   11766             BackupRecord r = new BackupRecord(ss, app, backupMode);
   11767             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
   11768                     ? new ComponentName(app.packageName, app.backupAgentName)
   11769                     : new ComponentName("android", "FullBackupAgent");
   11770             // startProcessLocked() returns existing proc's record if it's already running
   11771             ProcessRecord proc = startProcessLocked(app.processName, app,
   11772                     false, 0, "backup", hostingName, false);
   11773             if (proc == null) {
   11774                 Slog.e(TAG, "Unable to start backup agent process " + r);
   11775                 return false;
   11776             }
   11777 
   11778             r.app = proc;
   11779             mBackupTarget = r;
   11780             mBackupAppName = app.packageName;
   11781 
   11782             // Try not to kill the process during backup
   11783             updateOomAdjLocked(proc);
   11784 
   11785             // If the process is already attached, schedule the creation of the backup agent now.
   11786             // If it is not yet live, this will be done when it attaches to the framework.
   11787             if (proc.thread != null) {
   11788                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
   11789                 try {
   11790                     proc.thread.scheduleCreateBackupAgent(app,
   11791                             compatibilityInfoForPackageLocked(app), backupMode);
   11792                 } catch (RemoteException e) {
   11793                     // Will time out on the backup manager side
   11794                 }
   11795             } else {
   11796                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
   11797             }
   11798             // Invariants: at this point, the target app process exists and the application
   11799             // is either already running or in the process of coming up.  mBackupTarget and
   11800             // mBackupAppName describe the app, so that when it binds back to the AM we
   11801             // know that it's scheduled for a backup-agent operation.
   11802         }
   11803 
   11804         return true;
   11805     }
   11806 
   11807     // A backup agent has just come up
   11808     public void backupAgentCreated(String agentPackageName, IBinder agent) {
   11809         if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
   11810                 + " = " + agent);
   11811 
   11812         synchronized(this) {
   11813             if (!agentPackageName.equals(mBackupAppName)) {
   11814                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
   11815                 return;
   11816             }
   11817         }
   11818 
   11819         long oldIdent = Binder.clearCallingIdentity();
   11820         try {
   11821             IBackupManager bm = IBackupManager.Stub.asInterface(
   11822                     ServiceManager.getService(Context.BACKUP_SERVICE));
   11823             bm.agentConnected(agentPackageName, agent);
   11824         } catch (RemoteException e) {
   11825             // can't happen; the backup manager service is local
   11826         } catch (Exception e) {
   11827             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
   11828             e.printStackTrace();
   11829         } finally {
   11830             Binder.restoreCallingIdentity(oldIdent);
   11831         }
   11832     }
   11833 
   11834     // done with this agent
   11835     public void unbindBackupAgent(ApplicationInfo appInfo) {
   11836         if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
   11837         if (appInfo == null) {
   11838             Slog.w(TAG, "unbind backup agent for null app");
   11839             return;
   11840         }
   11841 
   11842         synchronized(this) {
   11843             if (mBackupAppName == null) {
   11844                 Slog.w(TAG, "Unbinding backup agent with no active backup");
   11845                 return;
   11846             }
   11847 
   11848             if (!mBackupAppName.equals(appInfo.packageName)) {
   11849                 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
   11850                 return;
   11851             }
   11852 
   11853             ProcessRecord proc = mBackupTarget.app;
   11854             mBackupTarget = null;
   11855             mBackupAppName = null;
   11856 
   11857             // Not backing this app up any more; reset its OOM adjustment
   11858             updateOomAdjLocked(proc);
   11859 
   11860             // If the app crashed during backup, 'thread' will be null here
   11861             if (proc.thread != null) {
   11862                 try {
   11863                     proc.thread.scheduleDestroyBackupAgent(appInfo,
   11864                             compatibilityInfoForPackageLocked(appInfo));
   11865                 } catch (Exception e) {
   11866                     Slog.e(TAG, "Exception when unbinding backup agent:");
   11867                     e.printStackTrace();
   11868                 }
   11869             }
   11870         }
   11871     }
   11872     // =========================================================
   11873     // BROADCASTS
   11874     // =========================================================
   11875 
   11876     private final List getStickiesLocked(String action, IntentFilter filter,
   11877             List cur) {
   11878         final ContentResolver resolver = mContext.getContentResolver();
   11879         final ArrayList<Intent> list = mStickyBroadcasts.get(action);
   11880         if (list == null) {
   11881             return cur;
   11882         }
   11883         int N = list.size();
   11884         for (int i=0; i<N; i++) {
   11885             Intent intent = list.get(i);
   11886             if (filter.match(resolver, intent, true, TAG) >= 0) {
   11887                 if (cur == null) {
   11888                     cur = new ArrayList<Intent>();
   11889                 }
   11890                 cur.add(intent);
   11891             }
   11892         }
   11893         return cur;
   11894     }
   11895 
   11896     private final void scheduleBroadcastsLocked() {
   11897         if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
   11898                 + mBroadcastsScheduled);
   11899 
   11900         if (mBroadcastsScheduled) {
   11901             return;
   11902         }
   11903         mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
   11904         mBroadcastsScheduled = true;
   11905     }
   11906 
   11907     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
   11908             IIntentReceiver receiver, IntentFilter filter, String permission) {
   11909         synchronized(this) {
   11910             ProcessRecord callerApp = null;
   11911             if (caller != null) {
   11912                 callerApp = getRecordForAppLocked(caller);
   11913                 if (callerApp == null) {
   11914                     throw new SecurityException(
   11915                             "Unable to find app for caller " + caller
   11916                             + " (pid=" + Binder.getCallingPid()
   11917                             + ") when registering receiver " + receiver);
   11918                 }
   11919                 if (callerApp.info.uid != Process.SYSTEM_UID &&
   11920                         !callerApp.pkgList.contains(callerPackage)) {
   11921                     throw new SecurityException("Given caller package " + callerPackage
   11922                             + " is not running in process " + callerApp);
   11923                 }
   11924             } else {
   11925                 callerPackage = null;
   11926             }
   11927 
   11928             List allSticky = null;
   11929 
   11930             // Look for any matching sticky broadcasts...
   11931             Iterator actions = filter.actionsIterator();
   11932             if (actions != null) {
   11933                 while (actions.hasNext()) {
   11934                     String action = (String)actions.next();
   11935                     allSticky = getStickiesLocked(action, filter, allSticky);
   11936                 }
   11937             } else {
   11938                 allSticky = getStickiesLocked(null, filter, allSticky);
   11939             }
   11940 
   11941             // The first sticky in the list is returned directly back to
   11942             // the client.
   11943             Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
   11944 
   11945             if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
   11946                     + ": " + sticky);
   11947 
   11948             if (receiver == null) {
   11949                 return sticky;
   11950             }
   11951 
   11952             ReceiverList rl
   11953                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   11954             if (rl == null) {
   11955                 rl = new ReceiverList(this, callerApp,
   11956                         Binder.getCallingPid(),
   11957                         Binder.getCallingUid(), receiver);
   11958                 if (rl.app != null) {
   11959                     rl.app.receivers.add(rl);
   11960                 } else {
   11961                     try {
   11962                         receiver.asBinder().linkToDeath(rl, 0);
   11963                     } catch (RemoteException e) {
   11964                         return sticky;
   11965                     }
   11966                     rl.linkedToDeath = true;
   11967                 }
   11968                 mRegisteredReceivers.put(receiver.asBinder(), rl);
   11969             }
   11970             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
   11971             rl.add(bf);
   11972             if (!bf.debugCheck()) {
   11973                 Slog.w(TAG, "==> For Dynamic broadast");
   11974             }
   11975             mReceiverResolver.addFilter(bf);
   11976 
   11977             // Enqueue broadcasts for all existing stickies that match
   11978             // this filter.
   11979             if (allSticky != null) {
   11980                 ArrayList receivers = new ArrayList();
   11981                 receivers.add(bf);
   11982 
   11983                 int N = allSticky.size();
   11984                 for (int i=0; i<N; i++) {
   11985                     Intent intent = (Intent)allSticky.get(i);
   11986                     BroadcastRecord r = new BroadcastRecord(intent, null,
   11987                             null, -1, -1, null, receivers, null, 0, null, null,
   11988                             false, true, true);
   11989                     if (mParallelBroadcasts.size() == 0) {
   11990                         scheduleBroadcastsLocked();
   11991                     }
   11992                     mParallelBroadcasts.add(r);
   11993                 }
   11994             }
   11995 
   11996             return sticky;
   11997         }
   11998     }
   11999 
   12000     public void unregisterReceiver(IIntentReceiver receiver) {
   12001         if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
   12002 
   12003         boolean doNext = false;
   12004 
   12005         synchronized(this) {
   12006             ReceiverList rl
   12007                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   12008             if (rl != null) {
   12009                 if (rl.curBroadcast != null) {
   12010                     BroadcastRecord r = rl.curBroadcast;
   12011                     doNext = finishReceiverLocked(
   12012                         receiver.asBinder(), r.resultCode, r.resultData,
   12013                         r.resultExtras, r.resultAbort, true);
   12014                 }
   12015 
   12016                 if (rl.app != null) {
   12017                     rl.app.receivers.remove(rl);
   12018                 }
   12019                 removeReceiverLocked(rl);
   12020                 if (rl.linkedToDeath) {
   12021                     rl.linkedToDeath = false;
   12022                     rl.receiver.asBinder().unlinkToDeath(rl, 0);
   12023                 }
   12024             }
   12025         }
   12026 
   12027         if (!doNext) {
   12028             return;
   12029         }
   12030 
   12031         final long origId = Binder.clearCallingIdentity();
   12032         processNextBroadcast(false);
   12033         trimApplications();
   12034         Binder.restoreCallingIdentity(origId);
   12035     }
   12036 
   12037     void removeReceiverLocked(ReceiverList rl) {
   12038         mRegisteredReceivers.remove(rl.receiver.asBinder());
   12039         int N = rl.size();
   12040         for (int i=0; i<N; i++) {
   12041             mReceiverResolver.removeFilter(rl.get(i));
   12042         }
   12043     }
   12044 
   12045     private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
   12046         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   12047             ProcessRecord r = mLruProcesses.get(i);
   12048             if (r.thread != null) {
   12049                 try {
   12050                     r.thread.dispatchPackageBroadcast(cmd, packages);
   12051                 } catch (RemoteException ex) {
   12052                 }
   12053             }
   12054         }
   12055     }
   12056 
   12057     private final int broadcastIntentLocked(ProcessRecord callerApp,
   12058             String callerPackage, Intent intent, String resolvedType,
   12059             IIntentReceiver resultTo, int resultCode, String resultData,
   12060             Bundle map, String requiredPermission,
   12061             boolean ordered, boolean sticky, int callingPid, int callingUid) {
   12062         intent = new Intent(intent);
   12063 
   12064         // By default broadcasts do not go to stopped apps.
   12065         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
   12066 
   12067         if (DEBUG_BROADCAST_LIGHT) Slog.v(
   12068             TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
   12069             + " ordered=" + ordered);
   12070         if ((resultTo != null) && !ordered) {
   12071             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
   12072         }
   12073 
   12074         // Handle special intents: if this broadcast is from the package
   12075         // manager about a package being removed, we need to remove all of
   12076         // its activities from the history stack.
   12077         final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
   12078                 intent.getAction());
   12079         if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
   12080                 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
   12081                 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
   12082                 || uidRemoved) {
   12083             if (checkComponentPermission(
   12084                     android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
   12085                     callingPid, callingUid, -1, true)
   12086                     == PackageManager.PERMISSION_GRANTED) {
   12087                 if (uidRemoved) {
   12088                     final Bundle intentExtras = intent.getExtras();
   12089                     final int uid = intentExtras != null
   12090                             ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
   12091                     if (uid >= 0) {
   12092                         BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
   12093                         synchronized (bs) {
   12094                             bs.removeUidStatsLocked(uid);
   12095                         }
   12096                     }
   12097                 } else {
   12098                     // If resources are unvailble just force stop all
   12099                     // those packages and flush the attribute cache as well.
   12100                     if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
   12101                         String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   12102                         if (list != null && (list.length > 0)) {
   12103                             for (String pkg : list) {
   12104                                 forceStopPackageLocked(pkg, -1, false, true, true, false);
   12105                             }
   12106                             sendPackageBroadcastLocked(
   12107                                     IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
   12108                         }
   12109                     } else {
   12110                         Uri data = intent.getData();
   12111                         String ssp;
   12112                         if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   12113                             if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
   12114                                 forceStopPackageLocked(ssp,
   12115                                         intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
   12116                             }
   12117                             if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
   12118                                 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
   12119                                         new String[] {ssp});
   12120                             }
   12121                         }
   12122                     }
   12123                 }
   12124             } else {
   12125                 String msg = "Permission Denial: " + intent.getAction()
   12126                         + " broadcast from " + callerPackage + " (pid=" + callingPid
   12127                         + ", uid=" + callingUid + ")"
   12128                         + " requires "
   12129                         + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
   12130                 Slog.w(TAG, msg);
   12131                 throw new SecurityException(msg);
   12132             }
   12133 
   12134         // Special case for adding a package: by default turn on compatibility
   12135         // mode.
   12136         } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
   12137             Uri data = intent.getData();
   12138             String ssp;
   12139             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   12140                 mCompatModePackages.handlePackageAddedLocked(ssp,
   12141                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
   12142             }
   12143         }
   12144 
   12145         /*
   12146          * If this is the time zone changed action, queue up a message that will reset the timezone
   12147          * of all currently running processes. This message will get queued up before the broadcast
   12148          * happens.
   12149          */
   12150         if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
   12151             mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
   12152         }
   12153 
   12154         if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
   12155             mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
   12156         }
   12157 
   12158         if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
   12159             ProxyProperties proxy = intent.getParcelableExtra("proxy");
   12160             mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
   12161         }
   12162 
   12163         /*
   12164          * Prevent non-system code (defined here to be non-persistent
   12165          * processes) from sending protected broadcasts.
   12166          */
   12167         if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
   12168                 || callingUid == Process.SHELL_UID || callingUid == 0) {
   12169             // Always okay.
   12170         } else if (callerApp == null || !callerApp.persistent) {
   12171             try {
   12172                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
   12173                         intent.getAction())) {
   12174                     String msg = "Permission Denial: not allowed to send broadcast "
   12175                             + intent.getAction() + " from pid="
   12176                             + callingPid + ", uid=" + callingUid;
   12177                     Slog.w(TAG, msg);
   12178                     throw new SecurityException(msg);
   12179                 }
   12180             } catch (RemoteException e) {
   12181                 Slog.w(TAG, "Remote exception", e);
   12182                 return BROADCAST_SUCCESS;
   12183             }
   12184         }
   12185 
   12186         // Add to the sticky list if requested.
   12187         if (sticky) {
   12188             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
   12189                     callingPid, callingUid)
   12190                     != PackageManager.PERMISSION_GRANTED) {
   12191                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
   12192                         + callingPid + ", uid=" + callingUid
   12193                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   12194                 Slog.w(TAG, msg);
   12195                 throw new SecurityException(msg);
   12196             }
   12197             if (requiredPermission != null) {
   12198                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
   12199                         + " and enforce permission " + requiredPermission);
   12200                 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
   12201             }
   12202             if (intent.getComponent() != null) {
   12203                 throw new SecurityException(
   12204                         "Sticky broadcasts can't target a specific component");
   12205             }
   12206             ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
   12207             if (list == null) {
   12208                 list = new ArrayList<Intent>();
   12209                 mStickyBroadcasts.put(intent.getAction(), list);
   12210             }
   12211             int N = list.size();
   12212             int i;
   12213             for (i=0; i<N; i++) {
   12214                 if (intent.filterEquals(list.get(i))) {
   12215                     // This sticky already exists, replace it.
   12216                     list.set(i, new Intent(intent));
   12217                     break;
   12218                 }
   12219             }
   12220             if (i >= N) {
   12221                 list.add(new Intent(intent));
   12222             }
   12223         }
   12224 
   12225         // Figure out who all will receive this broadcast.
   12226         List receivers = null;
   12227         List<BroadcastFilter> registeredReceivers = null;
   12228         try {
   12229             if (intent.getComponent() != null) {
   12230                 // Broadcast is going to one specific receiver class...
   12231                 ActivityInfo ai = AppGlobals.getPackageManager().
   12232                     getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
   12233                 if (ai != null) {
   12234                     receivers = new ArrayList();
   12235                     ResolveInfo ri = new ResolveInfo();
   12236                     ri.activityInfo = ai;
   12237                     receivers.add(ri);
   12238                 }
   12239             } else {
   12240                 // Need to resolve the intent to interested receivers...
   12241                 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
   12242                          == 0) {
   12243                     receivers =
   12244                         AppGlobals.getPackageManager().queryIntentReceivers(
   12245                                 intent, resolvedType, STOCK_PM_FLAGS);
   12246                 }
   12247                 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
   12248             }
   12249         } catch (RemoteException ex) {
   12250             // pm is in same process, this will never happen.
   12251         }
   12252 
   12253         final boolean replacePending =
   12254                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
   12255 
   12256         if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
   12257                 + " replacePending=" + replacePending);
   12258 
   12259         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
   12260         if (!ordered && NR > 0) {
   12261             // If we are not serializing this broadcast, then send the
   12262             // registered receivers separately so they don't wait for the
   12263             // components to be launched.
   12264             BroadcastRecord r = new BroadcastRecord(intent, callerApp,
   12265                     callerPackage, callingPid, callingUid, requiredPermission,
   12266                     registeredReceivers, resultTo, resultCode, resultData, map,
   12267                     ordered, sticky, false);
   12268             if (DEBUG_BROADCAST) Slog.v(
   12269                     TAG, "Enqueueing parallel broadcast " + r
   12270                     + ": prev had " + mParallelBroadcasts.size());
   12271             boolean replaced = false;
   12272             if (replacePending) {
   12273                 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
   12274                     if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
   12275                         if (DEBUG_BROADCAST) Slog.v(TAG,
   12276                                 "***** DROPPING PARALLEL: " + intent);
   12277                         mParallelBroadcasts.set(i, r);
   12278                         replaced = true;
   12279                         break;
   12280                     }
   12281                 }
   12282             }
   12283             if (!replaced) {
   12284                 mParallelBroadcasts.add(r);
   12285                 scheduleBroadcastsLocked();
   12286             }
   12287             registeredReceivers = null;
   12288             NR = 0;
   12289         }
   12290 
   12291         // Merge into one list.
   12292         int ir = 0;
   12293         if (receivers != null) {
   12294             // A special case for PACKAGE_ADDED: do not allow the package
   12295             // being added to see this broadcast.  This prevents them from
   12296             // using this as a back door to get run as soon as they are
   12297             // installed.  Maybe in the future we want to have a special install
   12298             // broadcast or such for apps, but we'd like to deliberately make
   12299             // this decision.
   12300             String skipPackages[] = null;
   12301             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
   12302                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
   12303                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
   12304                 Uri data = intent.getData();
   12305                 if (data != null) {
   12306                     String pkgName = data.getSchemeSpecificPart();
   12307                     if (pkgName != null) {
   12308                         skipPackages = new String[] { pkgName };
   12309                     }
   12310                 }
   12311             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
   12312                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   12313             }
   12314             if (skipPackages != null && (skipPackages.length > 0)) {
   12315                 for (String skipPackage : skipPackages) {
   12316                     if (skipPackage != null) {
   12317                         int NT = receivers.size();
   12318                         for (int it=0; it<NT; it++) {
   12319                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
   12320                             if (curt.activityInfo.packageName.equals(skipPackage)) {
   12321                                 receivers.remove(it);
   12322                                 it--;
   12323                                 NT--;
   12324                             }
   12325                         }
   12326                     }
   12327                 }
   12328             }
   12329 
   12330             int NT = receivers != null ? receivers.size() : 0;
   12331             int it = 0;
   12332             ResolveInfo curt = null;
   12333             BroadcastFilter curr = null;
   12334             while (it < NT && ir < NR) {
   12335                 if (curt == null) {
   12336                     curt = (ResolveInfo)receivers.get(it);
   12337                 }
   12338                 if (curr == null) {
   12339                     curr = registeredReceivers.get(ir);
   12340                 }
   12341                 if (curr.getPriority() >= curt.priority) {
   12342                     // Insert this broadcast record into the final list.
   12343                     receivers.add(it, curr);
   12344                     ir++;
   12345                     curr = null;
   12346                     it++;
   12347                     NT++;
   12348                 } else {
   12349                     // Skip to the next ResolveInfo in the final list.
   12350                     it++;
   12351                     curt = null;
   12352                 }
   12353             }
   12354         }
   12355         while (ir < NR) {
   12356             if (receivers == null) {
   12357                 receivers = new ArrayList();
   12358             }
   12359             receivers.add(registeredReceivers.get(ir));
   12360             ir++;
   12361         }
   12362 
   12363         if ((receivers != null && receivers.size() > 0)
   12364                 || resultTo != null) {
   12365             BroadcastRecord r = new BroadcastRecord(intent, callerApp,
   12366                     callerPackage, callingPid, callingUid, requiredPermission,
   12367                     receivers, resultTo, resultCode, resultData, map, ordered,
   12368                     sticky, false);
   12369             if (DEBUG_BROADCAST) Slog.v(
   12370                     TAG, "Enqueueing ordered broadcast " + r
   12371                     + ": prev had " + mOrderedBroadcasts.size());
   12372             if (DEBUG_BROADCAST) {
   12373                 int seq = r.intent.getIntExtra("seq", -1);
   12374                 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
   12375             }
   12376             boolean replaced = false;
   12377             if (replacePending) {
   12378                 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
   12379                     if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
   12380                         if (DEBUG_BROADCAST) Slog.v(TAG,
   12381                                 "***** DROPPING ORDERED: " + intent);
   12382                         mOrderedBroadcasts.set(i, r);
   12383                         replaced = true;
   12384                         break;
   12385                     }
   12386                 }
   12387             }
   12388             if (!replaced) {
   12389                 mOrderedBroadcasts.add(r);
   12390                 scheduleBroadcastsLocked();
   12391             }
   12392         }
   12393 
   12394         return BROADCAST_SUCCESS;
   12395     }
   12396 
   12397     final Intent verifyBroadcastLocked(Intent intent) {
   12398         // Refuse possible leaked file descriptors
   12399         if (intent != null && intent.hasFileDescriptors() == true) {
   12400             throw new IllegalArgumentException("File descriptors passed in Intent");
   12401         }
   12402 
   12403         int flags = intent.getFlags();
   12404 
   12405         if (!mProcessesReady) {
   12406             // if the caller really truly claims to know what they're doing, go
   12407             // ahead and allow the broadcast without launching any receivers
   12408             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
   12409                 intent = new Intent(intent);
   12410                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   12411             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
   12412                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
   12413                         + " before boot completion");
   12414                 throw new IllegalStateException("Cannot broadcast before boot completed");
   12415             }
   12416         }
   12417 
   12418         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   12419             throw new IllegalArgumentException(
   12420                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   12421         }
   12422 
   12423         return intent;
   12424     }
   12425 
   12426     public final int broadcastIntent(IApplicationThread caller,
   12427             Intent intent, String resolvedType, IIntentReceiver resultTo,
   12428             int resultCode, String resultData, Bundle map,
   12429             String requiredPermission, boolean serialized, boolean sticky) {
   12430         synchronized(this) {
   12431             intent = verifyBroadcastLocked(intent);
   12432 
   12433             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   12434             final int callingPid = Binder.getCallingPid();
   12435             final int callingUid = Binder.getCallingUid();
   12436             final long origId = Binder.clearCallingIdentity();
   12437             int res = broadcastIntentLocked(callerApp,
   12438                     callerApp != null ? callerApp.info.packageName : null,
   12439                     intent, resolvedType, resultTo,
   12440                     resultCode, resultData, map, requiredPermission, serialized,
   12441                     sticky, callingPid, callingUid);
   12442             Binder.restoreCallingIdentity(origId);
   12443             return res;
   12444         }
   12445     }
   12446 
   12447     int broadcastIntentInPackage(String packageName, int uid,
   12448             Intent intent, String resolvedType, IIntentReceiver resultTo,
   12449             int resultCode, String resultData, Bundle map,
   12450             String requiredPermission, boolean serialized, boolean sticky) {
   12451         synchronized(this) {
   12452             intent = verifyBroadcastLocked(intent);
   12453 
   12454             final long origId = Binder.clearCallingIdentity();
   12455             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
   12456                     resultTo, resultCode, resultData, map, requiredPermission,
   12457                     serialized, sticky, -1, uid);
   12458             Binder.restoreCallingIdentity(origId);
   12459             return res;
   12460         }
   12461     }
   12462 
   12463     public final void unbroadcastIntent(IApplicationThread caller,
   12464             Intent intent) {
   12465         // Refuse possible leaked file descriptors
   12466         if (intent != null && intent.hasFileDescriptors() == true) {
   12467             throw new IllegalArgumentException("File descriptors passed in Intent");
   12468         }
   12469 
   12470         synchronized(this) {
   12471             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
   12472                     != PackageManager.PERMISSION_GRANTED) {
   12473                 String msg = "Permission Denial: unbroadcastIntent() from pid="
   12474                         + Binder.getCallingPid()
   12475                         + ", uid=" + Binder.getCallingUid()
   12476                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   12477                 Slog.w(TAG, msg);
   12478                 throw new SecurityException(msg);
   12479             }
   12480             ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
   12481             if (list != null) {
   12482                 int N = list.size();
   12483                 int i;
   12484                 for (i=0; i<N; i++) {
   12485                     if (intent.filterEquals(list.get(i))) {
   12486                         list.remove(i);
   12487                         break;
   12488                     }
   12489                 }
   12490             }
   12491         }
   12492     }
   12493 
   12494     private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
   12495             String resultData, Bundle resultExtras, boolean resultAbort,
   12496             boolean explicit) {
   12497         if (mOrderedBroadcasts.size() == 0) {
   12498             if (explicit) {
   12499                 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
   12500             }
   12501             return false;
   12502         }
   12503         BroadcastRecord r = mOrderedBroadcasts.get(0);
   12504         if (r.receiver == null) {
   12505             if (explicit) {
   12506                 Slog.w(TAG, "finishReceiver called but none active");
   12507             }
   12508             return false;
   12509         }
   12510         if (r.receiver != receiver) {
   12511             Slog.w(TAG, "finishReceiver called but active receiver is different");
   12512             return false;
   12513         }
   12514         int state = r.state;
   12515         r.state = BroadcastRecord.IDLE;
   12516         if (state == BroadcastRecord.IDLE) {
   12517             if (explicit) {
   12518                 Slog.w(TAG, "finishReceiver called but state is IDLE");
   12519             }
   12520         }
   12521         r.receiver = null;
   12522         r.intent.setComponent(null);
   12523         if (r.curApp != null) {
   12524             r.curApp.curReceiver = null;
   12525         }
   12526         if (r.curFilter != null) {
   12527             r.curFilter.receiverList.curBroadcast = null;
   12528         }
   12529         r.curFilter = null;
   12530         r.curApp = null;
   12531         r.curComponent = null;
   12532         r.curReceiver = null;
   12533         mPendingBroadcast = null;
   12534 
   12535         r.resultCode = resultCode;
   12536         r.resultData = resultData;
   12537         r.resultExtras = resultExtras;
   12538         r.resultAbort = resultAbort;
   12539 
   12540         // We will process the next receiver right now if this is finishing
   12541         // an app receiver (which is always asynchronous) or after we have
   12542         // come back from calling a receiver.
   12543         return state == BroadcastRecord.APP_RECEIVE
   12544                 || state == BroadcastRecord.CALL_DONE_RECEIVE;
   12545     }
   12546 
   12547     public void finishReceiver(IBinder who, int resultCode, String resultData,
   12548             Bundle resultExtras, boolean resultAbort) {
   12549         if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
   12550 
   12551         // Refuse possible leaked file descriptors
   12552         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
   12553             throw new IllegalArgumentException("File descriptors passed in Bundle");
   12554         }
   12555 
   12556         boolean doNext;
   12557 
   12558         final long origId = Binder.clearCallingIdentity();
   12559 
   12560         synchronized(this) {
   12561             doNext = finishReceiverLocked(
   12562                 who, resultCode, resultData, resultExtras, resultAbort, true);
   12563         }
   12564 
   12565         if (doNext) {
   12566             processNextBroadcast(false);
   12567         }
   12568         trimApplications();
   12569 
   12570         Binder.restoreCallingIdentity(origId);
   12571     }
   12572 
   12573     private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
   12574         if (r.nextReceiver > 0) {
   12575             Object curReceiver = r.receivers.get(r.nextReceiver-1);
   12576             if (curReceiver instanceof BroadcastFilter) {
   12577                 BroadcastFilter bf = (BroadcastFilter) curReceiver;
   12578                 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
   12579                         System.identityHashCode(r),
   12580                         r.intent.getAction(),
   12581                         r.nextReceiver - 1,
   12582                         System.identityHashCode(bf));
   12583             } else {
   12584                 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
   12585                         System.identityHashCode(r),
   12586                         r.intent.getAction(),
   12587                         r.nextReceiver - 1,
   12588                         ((ResolveInfo)curReceiver).toString());
   12589             }
   12590         } else {
   12591             Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
   12592                     + r);
   12593             EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
   12594                     System.identityHashCode(r),
   12595                     r.intent.getAction(),
   12596                     r.nextReceiver,
   12597                     "NONE");
   12598         }
   12599     }
   12600 
   12601     private final void setBroadcastTimeoutLocked(long timeoutTime) {
   12602         if (! mPendingBroadcastTimeoutMessage) {
   12603             Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
   12604             mHandler.sendMessageAtTime(msg, timeoutTime);
   12605             mPendingBroadcastTimeoutMessage = true;
   12606         }
   12607     }
   12608 
   12609     private final void cancelBroadcastTimeoutLocked() {
   12610         if (mPendingBroadcastTimeoutMessage) {
   12611             mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
   12612             mPendingBroadcastTimeoutMessage = false;
   12613         }
   12614     }
   12615 
   12616     private final void broadcastTimeoutLocked(boolean fromMsg) {
   12617         if (fromMsg) {
   12618             mPendingBroadcastTimeoutMessage = false;
   12619         }
   12620 
   12621         if (mOrderedBroadcasts.size() == 0) {
   12622             return;
   12623         }
   12624 
   12625         long now = SystemClock.uptimeMillis();
   12626         BroadcastRecord r = mOrderedBroadcasts.get(0);
   12627         if (fromMsg) {
   12628             if (mDidDexOpt) {
   12629                 // Delay timeouts until dexopt finishes.
   12630                 mDidDexOpt = false;
   12631                 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
   12632                 setBroadcastTimeoutLocked(timeoutTime);
   12633                 return;
   12634             }
   12635             if (! mProcessesReady) {
   12636                 // Only process broadcast timeouts if the system is ready. That way
   12637                 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
   12638                 // to do heavy lifting for system up.
   12639                 return;
   12640             }
   12641 
   12642             long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
   12643             if (timeoutTime > now) {
   12644                 // We can observe premature timeouts because we do not cancel and reset the
   12645                 // broadcast timeout message after each receiver finishes.  Instead, we set up
   12646                 // an initial timeout then kick it down the road a little further as needed
   12647                 // when it expires.
   12648                 if (DEBUG_BROADCAST) Slog.v(TAG,
   12649                         "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
   12650                         + timeoutTime);
   12651                 setBroadcastTimeoutLocked(timeoutTime);
   12652                 return;
   12653             }
   12654         }
   12655 
   12656         Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
   12657                 + ", started " + (now - r.receiverTime) + "ms ago");
   12658         r.receiverTime = now;
   12659         r.anrCount++;
   12660 
   12661         // Current receiver has passed its expiration date.
   12662         if (r.nextReceiver <= 0) {
   12663             Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
   12664             return;
   12665         }
   12666 
   12667         ProcessRecord app = null;
   12668         String anrMessage = null;
   12669 
   12670         Object curReceiver = r.receivers.get(r.nextReceiver-1);
   12671         Slog.w(TAG, "Receiver during timeout: " + curReceiver);
   12672         logBroadcastReceiverDiscardLocked(r);
   12673         if (curReceiver instanceof BroadcastFilter) {
   12674             BroadcastFilter bf = (BroadcastFilter)curReceiver;
   12675             if (bf.receiverList.pid != 0
   12676                     && bf.receiverList.pid != MY_PID) {
   12677                 synchronized (this.mPidsSelfLocked) {
   12678                     app = this.mPidsSelfLocked.get(
   12679                             bf.receiverList.pid);
   12680                 }
   12681             }
   12682         } else {
   12683             app = r.curApp;
   12684         }
   12685 
   12686         if (app != null) {
   12687             anrMessage = "Broadcast of " + r.intent.toString();
   12688         }
   12689 
   12690         if (mPendingBroadcast == r) {
   12691             mPendingBroadcast = null;
   12692         }
   12693 
   12694         // Move on to the next receiver.
   12695         finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
   12696                 r.resultExtras, r.resultAbort, true);
   12697         scheduleBroadcastsLocked();
   12698 
   12699         if (anrMessage != null) {
   12700             // Post the ANR to the handler since we do not want to process ANRs while
   12701             // potentially holding our lock.
   12702             mHandler.post(new AppNotResponding(app, anrMessage));
   12703         }
   12704     }
   12705 
   12706     private final void processCurBroadcastLocked(BroadcastRecord r,
   12707             ProcessRecord app) throws RemoteException {
   12708         if (DEBUG_BROADCAST)  Slog.v(TAG,
   12709                 "Process cur broadcast " + r + " for app " + app);
   12710         if (app.thread == null) {
   12711             throw new RemoteException();
   12712         }
   12713         r.receiver = app.thread.asBinder();
   12714         r.curApp = app;
   12715         app.curReceiver = r;
   12716         updateLruProcessLocked(app, true, true);
   12717 
   12718         // Tell the application to launch this receiver.
   12719         r.intent.setComponent(r.curComponent);
   12720 
   12721         boolean started = false;
   12722         try {
   12723             if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
   12724                     "Delivering to component " + r.curComponent
   12725                     + ": " + r);
   12726             ensurePackageDexOpt(r.intent.getComponent().getPackageName());
   12727             app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
   12728                     compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
   12729                     r.resultCode, r.resultData, r.resultExtras, r.ordered);
   12730             if (DEBUG_BROADCAST)  Slog.v(TAG,
   12731                     "Process cur broadcast " + r + " DELIVERED for app " + app);
   12732             started = true;
   12733         } finally {
   12734             if (!started) {
   12735                 if (DEBUG_BROADCAST)  Slog.v(TAG,
   12736                         "Process cur broadcast " + r + ": NOT STARTED!");
   12737                 r.receiver = null;
   12738                 r.curApp = null;
   12739                 app.curReceiver = null;
   12740             }
   12741         }
   12742 
   12743     }
   12744 
   12745     static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
   12746             Intent intent, int resultCode, String data, Bundle extras,
   12747             boolean ordered, boolean sticky) throws RemoteException {
   12748         // Send the intent to the receiver asynchronously using one-way binder calls.
   12749         if (app != null && app.thread != null) {
   12750             // If we have an app thread, do the call through that so it is
   12751             // correctly ordered with other one-way calls.
   12752             app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
   12753                     data, extras, ordered, sticky);
   12754         } else {
   12755             receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
   12756         }
   12757     }
   12758 
   12759     private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
   12760             BroadcastFilter filter, boolean ordered) {
   12761         boolean skip = false;
   12762         if (filter.requiredPermission != null) {
   12763             int perm = checkComponentPermission(filter.requiredPermission,
   12764                     r.callingPid, r.callingUid, -1, true);
   12765             if (perm != PackageManager.PERMISSION_GRANTED) {
   12766                 Slog.w(TAG, "Permission Denial: broadcasting "
   12767                         + r.intent.toString()
   12768                         + " from " + r.callerPackage + " (pid="
   12769                         + r.callingPid + ", uid=" + r.callingUid + ")"
   12770                         + " requires " + filter.requiredPermission
   12771                         + " due to registered receiver " + filter);
   12772                 skip = true;
   12773             }
   12774         }
   12775         if (r.requiredPermission != null) {
   12776             int perm = checkComponentPermission(r.requiredPermission,
   12777                     filter.receiverList.pid, filter.receiverList.uid, -1, true);
   12778             if (perm != PackageManager.PERMISSION_GRANTED) {
   12779                 Slog.w(TAG, "Permission Denial: receiving "
   12780                         + r.intent.toString()
   12781                         + " to " + filter.receiverList.app
   12782                         + " (pid=" + filter.receiverList.pid
   12783                         + ", uid=" + filter.receiverList.uid + ")"
   12784                         + " requires " + r.requiredPermission
   12785                         + " due to sender " + r.callerPackage
   12786                         + " (uid " + r.callingUid + ")");
   12787                 skip = true;
   12788             }
   12789         }
   12790 
   12791         if (!skip) {
   12792             // If this is not being sent as an ordered broadcast, then we
   12793             // don't want to touch the fields that keep track of the current
   12794             // state of ordered broadcasts.
   12795             if (ordered) {
   12796                 r.receiver = filter.receiverList.receiver.asBinder();
   12797                 r.curFilter = filter;
   12798                 filter.receiverList.curBroadcast = r;
   12799                 r.state = BroadcastRecord.CALL_IN_RECEIVE;
   12800                 if (filter.receiverList.app != null) {
   12801                     // Bump hosting application to no longer be in background
   12802                     // scheduling class.  Note that we can't do that if there
   12803                     // isn't an app...  but we can only be in that case for
   12804                     // things that directly call the IActivityManager API, which
   12805                     // are already core system stuff so don't matter for this.
   12806                     r.curApp = filter.receiverList.app;
   12807                     filter.receiverList.app.curReceiver = r;
   12808                     updateOomAdjLocked();
   12809                 }
   12810             }
   12811             try {
   12812                 if (DEBUG_BROADCAST_LIGHT) {
   12813                     int seq = r.intent.getIntExtra("seq", -1);
   12814                     Slog.i(TAG, "Delivering to " + filter
   12815                             + " (seq=" + seq + "): " + r);
   12816                 }
   12817                 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
   12818                     new Intent(r.intent), r.resultCode,
   12819                     r.resultData, r.resultExtras, r.ordered, r.initialSticky);
   12820                 if (ordered) {
   12821                     r.state = BroadcastRecord.CALL_DONE_RECEIVE;
   12822                 }
   12823             } catch (RemoteException e) {
   12824                 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
   12825                 if (ordered) {
   12826                     r.receiver = null;
   12827                     r.curFilter = null;
   12828                     filter.receiverList.curBroadcast = null;
   12829                     if (filter.receiverList.app != null) {
   12830                         filter.receiverList.app.curReceiver = null;
   12831                     }
   12832                 }
   12833             }
   12834         }
   12835     }
   12836 
   12837     private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
   12838         if (r.callingUid < 0) {
   12839             // This was from a registerReceiver() call; ignore it.
   12840             return;
   12841         }
   12842         System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
   12843                 MAX_BROADCAST_HISTORY-1);
   12844         r.finishTime = SystemClock.uptimeMillis();
   12845         mBroadcastHistory[0] = r;
   12846     }
   12847 
   12848     private final void processNextBroadcast(boolean fromMsg) {
   12849         synchronized(this) {
   12850             BroadcastRecord r;
   12851 
   12852             if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
   12853                     + mParallelBroadcasts.size() + " broadcasts, "
   12854                     + mOrderedBroadcasts.size() + " ordered broadcasts");
   12855 
   12856             updateCpuStats();
   12857 
   12858             if (fromMsg) {
   12859                 mBroadcastsScheduled = false;
   12860             }
   12861 
   12862             // First, deliver any non-serialized broadcasts right away.
   12863             while (mParallelBroadcasts.size() > 0) {
   12864                 r = mParallelBroadcasts.remove(0);
   12865                 r.dispatchTime = SystemClock.uptimeMillis();
   12866                 r.dispatchClockTime = System.currentTimeMillis();
   12867                 final int N = r.receivers.size();
   12868                 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
   12869                         + r);
   12870                 for (int i=0; i<N; i++) {
   12871                     Object target = r.receivers.get(i);
   12872                     if (DEBUG_BROADCAST)  Slog.v(TAG,
   12873                             "Delivering non-ordered to registered "
   12874                             + target + ": " + r);
   12875                     deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
   12876                 }
   12877                 addBroadcastToHistoryLocked(r);
   12878                 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
   12879                         + r);
   12880             }
   12881 
   12882             // Now take care of the next serialized one...
   12883 
   12884             // If we are waiting for a process to come up to handle the next
   12885             // broadcast, then do nothing at this point.  Just in case, we
   12886             // check that the process we're waiting for still exists.
   12887             if (mPendingBroadcast != null) {
   12888                 if (DEBUG_BROADCAST_LIGHT) {
   12889                     Slog.v(TAG, "processNextBroadcast: waiting for "
   12890                             + mPendingBroadcast.curApp);
   12891                 }
   12892 
   12893                 boolean isDead;
   12894                 synchronized (mPidsSelfLocked) {
   12895                     isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
   12896                 }
   12897                 if (!isDead) {
   12898                     // It's still alive, so keep waiting
   12899                     return;
   12900                 } else {
   12901                     Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
   12902                             + " died before responding to broadcast");
   12903                     mPendingBroadcast.state = BroadcastRecord.IDLE;
   12904                     mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
   12905                     mPendingBroadcast = null;
   12906                 }
   12907             }
   12908 
   12909             boolean looped = false;
   12910 
   12911             do {
   12912                 if (mOrderedBroadcasts.size() == 0) {
   12913                     // No more broadcasts pending, so all done!
   12914                     scheduleAppGcsLocked();
   12915                     if (looped) {
   12916                         // If we had finished the last ordered broadcast, then
   12917                         // make sure all processes have correct oom and sched
   12918                         // adjustments.
   12919                         updateOomAdjLocked();
   12920                     }
   12921                     return;
   12922                 }
   12923                 r = mOrderedBroadcasts.get(0);
   12924                 boolean forceReceive = false;
   12925 
   12926                 // Ensure that even if something goes awry with the timeout
   12927                 // detection, we catch "hung" broadcasts here, discard them,
   12928                 // and continue to make progress.
   12929                 //
   12930                 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
   12931                 // receivers don't get executed with timeouts. They're intended for
   12932                 // one time heavy lifting after system upgrades and can take
   12933                 // significant amounts of time.
   12934                 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
   12935                 if (mProcessesReady && r.dispatchTime > 0) {
   12936                     long now = SystemClock.uptimeMillis();
   12937                     if ((numReceivers > 0) &&
   12938                             (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
   12939                         Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
   12940                                 + " now=" + now
   12941                                 + " dispatchTime=" + r.dispatchTime
   12942                                 + " startTime=" + r.receiverTime
   12943                                 + " intent=" + r.intent
   12944                                 + " numReceivers=" + numReceivers
   12945                                 + " nextReceiver=" + r.nextReceiver
   12946                                 + " state=" + r.state);
   12947                         broadcastTimeoutLocked(false); // forcibly finish this broadcast
   12948                         forceReceive = true;
   12949                         r.state = BroadcastRecord.IDLE;
   12950                     }
   12951                 }
   12952 
   12953                 if (r.state != BroadcastRecord.IDLE) {
   12954                     if (DEBUG_BROADCAST) Slog.d(TAG,
   12955                             "processNextBroadcast() called when not idle (state="
   12956                             + r.state + ")");
   12957                     return;
   12958                 }
   12959 
   12960                 if (r.receivers == null || r.nextReceiver >= numReceivers
   12961                         || r.resultAbort || forceReceive) {
   12962                     // No more receivers for this broadcast!  Send the final
   12963                     // result if requested...
   12964                     if (r.resultTo != null) {
   12965                         try {
   12966                             if (DEBUG_BROADCAST) {
   12967                                 int seq = r.intent.getIntExtra("seq", -1);
   12968                                 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
   12969                                         + " seq=" + seq + " app=" + r.callerApp);
   12970                             }
   12971                             performReceiveLocked(r.callerApp, r.resultTo,
   12972                                 new Intent(r.intent), r.resultCode,
   12973                                 r.resultData, r.resultExtras, false, false);
   12974                             // Set this to null so that the reference
   12975                             // (local and remote) isnt kept in the mBroadcastHistory.
   12976                             r.resultTo = null;
   12977                         } catch (RemoteException e) {
   12978                             Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
   12979                         }
   12980                     }
   12981 
   12982                     if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
   12983                     cancelBroadcastTimeoutLocked();
   12984 
   12985                     if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
   12986                             + r);
   12987 
   12988                     // ... and on to the next...
   12989                     addBroadcastToHistoryLocked(r);
   12990                     mOrderedBroadcasts.remove(0);
   12991                     r = null;
   12992                     looped = true;
   12993                     continue;
   12994                 }
   12995             } while (r == null);
   12996 
   12997             // Get the next receiver...
   12998             int recIdx = r.nextReceiver++;
   12999 
   13000             // Keep track of when this receiver started, and make sure there
   13001             // is a timeout message pending to kill it if need be.
   13002             r.receiverTime = SystemClock.uptimeMillis();
   13003             if (recIdx == 0) {
   13004                 r.dispatchTime = r.receiverTime;
   13005                 r.dispatchClockTime = System.currentTimeMillis();
   13006                 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
   13007                         + r);
   13008             }
   13009             if (! mPendingBroadcastTimeoutMessage) {
   13010                 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
   13011                 if (DEBUG_BROADCAST) Slog.v(TAG,
   13012                         "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
   13013                 setBroadcastTimeoutLocked(timeoutTime);
   13014             }
   13015 
   13016             Object nextReceiver = r.receivers.get(recIdx);
   13017             if (nextReceiver instanceof BroadcastFilter) {
   13018                 // Simple case: this is a registered receiver who gets
   13019                 // a direct call.
   13020                 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
   13021                 if (DEBUG_BROADCAST)  Slog.v(TAG,
   13022                         "Delivering ordered to registered "
   13023                         + filter + ": " + r);
   13024                 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
   13025                 if (r.receiver == null || !r.ordered) {
   13026                     // The receiver has already finished, so schedule to
   13027                     // process the next one.
   13028                     if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
   13029                             + r.ordered + " receiver=" + r.receiver);
   13030                     r.state = BroadcastRecord.IDLE;
   13031                     scheduleBroadcastsLocked();
   13032                 }
   13033                 return;
   13034             }
   13035 
   13036             // Hard case: need to instantiate the receiver, possibly
   13037             // starting its application process to host it.
   13038 
   13039             ResolveInfo info =
   13040                 (ResolveInfo)nextReceiver;
   13041 
   13042             boolean skip = false;
   13043             int perm = checkComponentPermission(info.activityInfo.permission,
   13044                     r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
   13045                     info.activityInfo.exported);
   13046             if (perm != PackageManager.PERMISSION_GRANTED) {
   13047                 if (!info.activityInfo.exported) {
   13048                     Slog.w(TAG, "Permission Denial: broadcasting "
   13049                             + r.intent.toString()
   13050                             + " from " + r.callerPackage + " (pid=" + r.callingPid
   13051                             + ", uid=" + r.callingUid + ")"
   13052                             + " is not exported from uid " + info.activityInfo.applicationInfo.uid
   13053                             + " due to receiver " + info.activityInfo.packageName
   13054                             + "/" + info.activityInfo.name);
   13055                 } else {
   13056                     Slog.w(TAG, "Permission Denial: broadcasting "
   13057                             + r.intent.toString()
   13058                             + " from " + r.callerPackage + " (pid=" + r.callingPid
   13059                             + ", uid=" + r.callingUid + ")"
   13060                             + " requires " + info.activityInfo.permission
   13061                             + " due to receiver " + info.activityInfo.packageName
   13062                             + "/" + info.activityInfo.name);
   13063                 }
   13064                 skip = true;
   13065             }
   13066             if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
   13067                 r.requiredPermission != null) {
   13068                 try {
   13069                     perm = AppGlobals.getPackageManager().
   13070                             checkPermission(r.requiredPermission,
   13071                                     info.activityInfo.applicationInfo.packageName);
   13072                 } catch (RemoteException e) {
   13073                     perm = PackageManager.PERMISSION_DENIED;
   13074                 }
   13075                 if (perm != PackageManager.PERMISSION_GRANTED) {
   13076                     Slog.w(TAG, "Permission Denial: receiving "
   13077                             + r.intent + " to "
   13078                             + info.activityInfo.applicationInfo.packageName
   13079                             + " requires " + r.requiredPermission
   13080                             + " due to sender " + r.callerPackage
   13081                             + " (uid " + r.callingUid + ")");
   13082                     skip = true;
   13083                 }
   13084             }
   13085             if (r.curApp != null && r.curApp.crashing) {
   13086                 // If the target process is crashing, just skip it.
   13087                 if (DEBUG_BROADCAST)  Slog.v(TAG,
   13088                         "Skipping deliver ordered " + r + " to " + r.curApp
   13089                         + ": process crashing");
   13090                 skip = true;
   13091             }
   13092 
   13093             if (skip) {
   13094                 if (DEBUG_BROADCAST)  Slog.v(TAG,
   13095                         "Skipping delivery of ordered " + r + " for whatever reason");
   13096                 r.receiver = null;
   13097                 r.curFilter = null;
   13098                 r.state = BroadcastRecord.IDLE;
   13099                 scheduleBroadcastsLocked();
   13100                 return;
   13101             }
   13102 
   13103             r.state = BroadcastRecord.APP_RECEIVE;
   13104             String targetProcess = info.activityInfo.processName;
   13105             r.curComponent = new ComponentName(
   13106                     info.activityInfo.applicationInfo.packageName,
   13107                     info.activityInfo.name);
   13108             r.curReceiver = info.activityInfo;
   13109 
   13110             // Broadcast is being executed, its package can't be stopped.
   13111             try {
   13112                 AppGlobals.getPackageManager().setPackageStoppedState(
   13113                         r.curComponent.getPackageName(), false);
   13114             } catch (RemoteException e) {
   13115             } catch (IllegalArgumentException e) {
   13116                 Slog.w(TAG, "Failed trying to unstop package "
   13117                         + r.curComponent.getPackageName() + ": " + e);
   13118             }
   13119 
   13120             // Is this receiver's application already running?
   13121             ProcessRecord app = getProcessRecordLocked(targetProcess,
   13122                     info.activityInfo.applicationInfo.uid);
   13123             if (app != null && app.thread != null) {
   13124                 try {
   13125                     app.addPackage(info.activityInfo.packageName);
   13126                     processCurBroadcastLocked(r, app);
   13127                     return;
   13128                 } catch (RemoteException e) {
   13129                     Slog.w(TAG, "Exception when sending broadcast to "
   13130                           + r.curComponent, e);
   13131                 }
   13132 
   13133                 // If a dead object exception was thrown -- fall through to
   13134                 // restart the application.
   13135             }
   13136 
   13137             // Not running -- get it started, to be executed when the app comes up.
   13138             if (DEBUG_BROADCAST)  Slog.v(TAG,
   13139                     "Need to start app " + targetProcess + " for broadcast " + r);
   13140             if ((r.curApp=startProcessLocked(targetProcess,
   13141                     info.activityInfo.applicationInfo, true,
   13142                     r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
   13143                     "broadcast", r.curComponent,
   13144                     (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
   13145                             == null) {
   13146                 // Ah, this recipient is unavailable.  Finish it if necessary,
   13147                 // and mark the broadcast record as ready for the next.
   13148                 Slog.w(TAG, "Unable to launch app "
   13149                         + info.activityInfo.applicationInfo.packageName + "/"
   13150                         + info.activityInfo.applicationInfo.uid + " for broadcast "
   13151                         + r.intent + ": process is bad");
   13152                 logBroadcastReceiverDiscardLocked(r);
   13153                 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
   13154                         r.resultExtras, r.resultAbort, true);
   13155                 scheduleBroadcastsLocked();
   13156                 r.state = BroadcastRecord.IDLE;
   13157                 return;
   13158             }
   13159 
   13160             mPendingBroadcast = r;
   13161             mPendingBroadcastRecvIndex = recIdx;
   13162         }
   13163     }
   13164 
   13165     // =========================================================
   13166     // INSTRUMENTATION
   13167     // =========================================================
   13168 
   13169     public boolean startInstrumentation(ComponentName className,
   13170             String profileFile, int flags, Bundle arguments,
   13171             IInstrumentationWatcher watcher) {
   13172         // Refuse possible leaked file descriptors
   13173         if (arguments != null && arguments.hasFileDescriptors()) {
   13174             throw new IllegalArgumentException("File descriptors passed in Bundle");
   13175         }
   13176 
   13177         synchronized(this) {
   13178             InstrumentationInfo ii = null;
   13179             ApplicationInfo ai = null;
   13180             try {
   13181                 ii = mContext.getPackageManager().getInstrumentationInfo(
   13182                     className, STOCK_PM_FLAGS);
   13183                 ai = mContext.getPackageManager().getApplicationInfo(
   13184                     ii.targetPackage, STOCK_PM_FLAGS);
   13185             } catch (PackageManager.NameNotFoundException e) {
   13186             }
   13187             if (ii == null) {
   13188                 reportStartInstrumentationFailure(watcher, className,
   13189                         "Unable to find instrumentation info for: " + className);
   13190                 return false;
   13191             }
   13192             if (ai == null) {
   13193                 reportStartInstrumentationFailure(watcher, className,
   13194                         "Unable to find instrumentation target package: " + ii.targetPackage);
   13195                 return false;
   13196             }
   13197 
   13198             int match = mContext.getPackageManager().checkSignatures(
   13199                     ii.targetPackage, ii.packageName);
   13200             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
   13201                 String msg = "Permission Denial: starting instrumentation "
   13202                         + className + " from pid="
   13203                         + Binder.getCallingPid()
   13204                         + ", uid=" + Binder.getCallingPid()
   13205                         + " not allowed because package " + ii.packageName
   13206                         + " does not have a signature matching the target "
   13207                         + ii.targetPackage;
   13208                 reportStartInstrumentationFailure(watcher, className, msg);
   13209                 throw new SecurityException(msg);
   13210             }
   13211 
   13212             final long origId = Binder.clearCallingIdentity();
   13213             // Instrumentation can kill and relaunch even persistent processes
   13214             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
   13215             ProcessRecord app = addAppLocked(ai);
   13216             app.instrumentationClass = className;
   13217             app.instrumentationInfo = ai;
   13218             app.instrumentationProfileFile = profileFile;
   13219             app.instrumentationArguments = arguments;
   13220             app.instrumentationWatcher = watcher;
   13221             app.instrumentationResultClass = className;
   13222             Binder.restoreCallingIdentity(origId);
   13223         }
   13224 
   13225         return true;
   13226     }
   13227 
   13228     /**
   13229      * Report errors that occur while attempting to start Instrumentation.  Always writes the
   13230      * error to the logs, but if somebody is watching, send the report there too.  This enables
   13231      * the "am" command to report errors with more information.
   13232      *
   13233      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
   13234      * @param cn The component name of the instrumentation.
   13235      * @param report The error report.
   13236      */
   13237     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
   13238             ComponentName cn, String report) {
   13239         Slog.w(TAG, report);
   13240         try {
   13241             if (watcher != null) {
   13242                 Bundle results = new Bundle();
   13243                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
   13244                 results.putString("Error", report);
   13245                 watcher.instrumentationStatus(cn, -1, results);
   13246             }
   13247         } catch (RemoteException e) {
   13248             Slog.w(TAG, e);
   13249         }
   13250     }
   13251 
   13252     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
   13253         if (app.instrumentationWatcher != null) {
   13254             try {
   13255                 // NOTE:  IInstrumentationWatcher *must* be oneway here
   13256                 app.instrumentationWatcher.instrumentationFinished(
   13257                     app.instrumentationClass,
   13258                     resultCode,
   13259                     results);
   13260             } catch (RemoteException e) {
   13261             }
   13262         }
   13263         app.instrumentationWatcher = null;
   13264         app.instrumentationClass = null;
   13265         app.instrumentationInfo = null;
   13266         app.instrumentationProfileFile = null;
   13267         app.instrumentationArguments = null;
   13268 
   13269         forceStopPackageLocked(app.processName, -1, false, false, true, true);
   13270     }
   13271 
   13272     public void finishInstrumentation(IApplicationThread target,
   13273             int resultCode, Bundle results) {
   13274         // Refuse possible leaked file descriptors
   13275         if (results != null && results.hasFileDescriptors()) {
   13276             throw new IllegalArgumentException("File descriptors passed in Intent");
   13277         }
   13278 
   13279         synchronized(this) {
   13280             ProcessRecord app = getRecordForAppLocked(target);
   13281             if (app == null) {
   13282                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
   13283                 return;
   13284             }
   13285             final long origId = Binder.clearCallingIdentity();
   13286             finishInstrumentationLocked(app, resultCode, results);
   13287             Binder.restoreCallingIdentity(origId);
   13288         }
   13289     }
   13290 
   13291     // =========================================================
   13292     // CONFIGURATION
   13293     // =========================================================
   13294 
   13295     public ConfigurationInfo getDeviceConfigurationInfo() {
   13296         ConfigurationInfo config = new ConfigurationInfo();
   13297         synchronized (this) {
   13298             config.reqTouchScreen = mConfiguration.touchscreen;
   13299             config.reqKeyboardType = mConfiguration.keyboard;
   13300             config.reqNavigation = mConfiguration.navigation;
   13301             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
   13302                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
   13303                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
   13304             }
   13305             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
   13306                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
   13307                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
   13308             }
   13309             config.reqGlEsVersion = GL_ES_VERSION;
   13310         }
   13311         return config;
   13312     }
   13313 
   13314     public Configuration getConfiguration() {
   13315         Configuration ci;
   13316         synchronized(this) {
   13317             ci = new Configuration(mConfiguration);
   13318         }
   13319         return ci;
   13320     }
   13321 
   13322     public void updatePersistentConfiguration(Configuration values) {
   13323         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   13324                 "updateConfiguration()");
   13325         enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
   13326                 "updateConfiguration()");
   13327         if (values == null) {
   13328             throw new NullPointerException("Configuration must not be null");
   13329         }
   13330 
   13331         synchronized(this) {
   13332             final long origId = Binder.clearCallingIdentity();
   13333             updateConfigurationLocked(values, null, true, false);
   13334             Binder.restoreCallingIdentity(origId);
   13335         }
   13336     }
   13337 
   13338     public void updateConfiguration(Configuration values) {
   13339         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   13340                 "updateConfiguration()");
   13341 
   13342         synchronized(this) {
   13343             if (values == null && mWindowManager != null) {
   13344                 // sentinel: fetch the current configuration from the window manager
   13345                 values = mWindowManager.computeNewConfiguration();
   13346             }
   13347 
   13348             if (mWindowManager != null) {
   13349                 mProcessList.applyDisplaySize(mWindowManager);
   13350             }
   13351 
   13352             final long origId = Binder.clearCallingIdentity();
   13353             if (values != null) {
   13354                 Settings.System.clearConfiguration(values);
   13355             }
   13356             updateConfigurationLocked(values, null, false, false);
   13357             Binder.restoreCallingIdentity(origId);
   13358         }
   13359     }
   13360 
   13361     /**
   13362      * Do either or both things: (1) change the current configuration, and (2)
   13363      * make sure the given activity is running with the (now) current
   13364      * configuration.  Returns true if the activity has been left running, or
   13365      * false if <var>starting</var> is being destroyed to match the new
   13366      * configuration.
   13367      * @param persistent TODO
   13368      */
   13369     public boolean updateConfigurationLocked(Configuration values,
   13370             ActivityRecord starting, boolean persistent, boolean initLocale) {
   13371         int changes = 0;
   13372 
   13373         boolean kept = true;
   13374 
   13375         if (values != null) {
   13376             Configuration newConfig = new Configuration(mConfiguration);
   13377             changes = newConfig.updateFrom(values);
   13378             if (changes != 0) {
   13379                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
   13380                     Slog.i(TAG, "Updating configuration to: " + values);
   13381                 }
   13382 
   13383                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
   13384 
   13385                 if (values.locale != null && !initLocale) {
   13386                     saveLocaleLocked(values.locale,
   13387                                      !values.locale.equals(mConfiguration.locale),
   13388                                      values.userSetLocale);
   13389                 }
   13390 
   13391                 mConfigurationSeq++;
   13392                 if (mConfigurationSeq <= 0) {
   13393                     mConfigurationSeq = 1;
   13394                 }
   13395                 newConfig.seq = mConfigurationSeq;
   13396                 mConfiguration = newConfig;
   13397                 Slog.i(TAG, "Config changed: " + newConfig);
   13398 
   13399                 final Configuration configCopy = new Configuration(mConfiguration);
   13400 
   13401                 AttributeCache ac = AttributeCache.instance();
   13402                 if (ac != null) {
   13403                     ac.updateConfiguration(configCopy);
   13404                 }
   13405 
   13406                 // Make sure all resources in our process are updated
   13407                 // right now, so that anyone who is going to retrieve
   13408                 // resource values after we return will be sure to get
   13409                 // the new ones.  This is especially important during
   13410                 // boot, where the first config change needs to guarantee
   13411                 // all resources have that config before following boot
   13412                 // code is executed.
   13413                 mSystemThread.applyConfigurationToResources(configCopy);
   13414 
   13415                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
   13416                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
   13417                     msg.obj = new Configuration(configCopy);
   13418                     mHandler.sendMessage(msg);
   13419                 }
   13420 
   13421                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   13422                     ProcessRecord app = mLruProcesses.get(i);
   13423                     try {
   13424                         if (app.thread != null) {
   13425                             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
   13426                                     + app.processName + " new config " + mConfiguration);
   13427                             app.thread.scheduleConfigurationChanged(configCopy);
   13428                         }
   13429                     } catch (Exception e) {
   13430                     }
   13431                 }
   13432                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
   13433                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   13434                         | Intent.FLAG_RECEIVER_REPLACE_PENDING);
   13435                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
   13436                         null, false, false, MY_PID, Process.SYSTEM_UID);
   13437                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
   13438                     broadcastIntentLocked(null, null,
   13439                             new Intent(Intent.ACTION_LOCALE_CHANGED),
   13440                             null, null, 0, null, null,
   13441                             null, false, false, MY_PID, Process.SYSTEM_UID);
   13442                 }
   13443             }
   13444         }
   13445 
   13446         if (changes != 0 && starting == null) {
   13447             // If the configuration changed, and the caller is not already
   13448             // in the process of starting an activity, then find the top
   13449             // activity to check if its configuration needs to change.
   13450             starting = mMainStack.topRunningActivityLocked(null);
   13451         }
   13452 
   13453         if (starting != null) {
   13454             kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
   13455             // And we need to make sure at this point that all other activities
   13456             // are made visible with the correct configuration.
   13457             mMainStack.ensureActivitiesVisibleLocked(starting, changes);
   13458         }
   13459 
   13460         if (values != null && mWindowManager != null) {
   13461             mWindowManager.setNewConfiguration(mConfiguration);
   13462         }
   13463 
   13464         return kept;
   13465     }
   13466 
   13467     /**
   13468      * Save the locale.  You must be inside a synchronized (this) block.
   13469      */
   13470     private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
   13471         if(isDiff) {
   13472             SystemProperties.set("user.language", l.getLanguage());
   13473             SystemProperties.set("user.region", l.getCountry());
   13474         }
   13475 
   13476         if(isPersist) {
   13477             SystemProperties.set("persist.sys.language", l.getLanguage());
   13478             SystemProperties.set("persist.sys.country", l.getCountry());
   13479             SystemProperties.set("persist.sys.localevar", l.getVariant());
   13480         }
   13481     }
   13482 
   13483     // =========================================================
   13484     // LIFETIME MANAGEMENT
   13485     // =========================================================
   13486 
   13487     private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
   13488             ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
   13489         if (mAdjSeq == app.adjSeq) {
   13490             // This adjustment has already been computed.  If we are calling
   13491             // from the top, we may have already computed our adjustment with
   13492             // an earlier hidden adjustment that isn't really for us... if
   13493             // so, use the new hidden adjustment.
   13494             if (!recursed && app.hidden) {
   13495                 app.curAdj = app.curRawAdj = hiddenAdj;
   13496             }
   13497             return app.curRawAdj;
   13498         }
   13499 
   13500         if (app.thread == null) {
   13501             app.adjSeq = mAdjSeq;
   13502             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13503             return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
   13504         }
   13505 
   13506         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
   13507         app.adjSource = null;
   13508         app.adjTarget = null;
   13509         app.empty = false;
   13510         app.hidden = false;
   13511 
   13512         final int activitiesSize = app.activities.size();
   13513 
   13514         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   13515             // The max adjustment doesn't allow this app to be anything
   13516             // below foreground, so it is not worth doing work for it.
   13517             app.adjType = "fixed";
   13518             app.adjSeq = mAdjSeq;
   13519             app.curRawAdj = app.maxAdj;
   13520             app.foregroundActivities = false;
   13521             app.keeping = true;
   13522             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
   13523             // System process can do UI, and when they do we want to have
   13524             // them trim their memory after the user leaves the UI.  To
   13525             // facilitate this, here we need to determine whether or not it
   13526             // is currently showing UI.
   13527             app.systemNoUi = true;
   13528             if (app == TOP_APP) {
   13529                 app.systemNoUi = false;
   13530             } else if (activitiesSize > 0) {
   13531                 for (int j = 0; j < activitiesSize; j++) {
   13532                     final ActivityRecord r = app.activities.get(j);
   13533                     if (r.visible) {
   13534                         app.systemNoUi = false;
   13535                         break;
   13536                     }
   13537                 }
   13538             }
   13539             return (app.curAdj=app.maxAdj);
   13540         }
   13541 
   13542         final boolean hadForegroundActivities = app.foregroundActivities;
   13543 
   13544         app.foregroundActivities = false;
   13545         app.keeping = false;
   13546         app.systemNoUi = false;
   13547 
   13548         // Determine the importance of the process, starting with most
   13549         // important to least, and assign an appropriate OOM adjustment.
   13550         int adj;
   13551         int schedGroup;
   13552         if (app == TOP_APP) {
   13553             // The last app on the list is the foreground app.
   13554             adj = ProcessList.FOREGROUND_APP_ADJ;
   13555             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13556             app.adjType = "top-activity";
   13557             app.foregroundActivities = true;
   13558         } else if (app.instrumentationClass != null) {
   13559             // Don't want to kill running instrumentation.
   13560             adj = ProcessList.FOREGROUND_APP_ADJ;
   13561             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13562             app.adjType = "instrumentation";
   13563         } else if (app.curReceiver != null ||
   13564                 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
   13565             // An app that is currently receiving a broadcast also
   13566             // counts as being in the foreground.
   13567             adj = ProcessList.FOREGROUND_APP_ADJ;
   13568             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13569             app.adjType = "broadcast";
   13570         } else if (app.executingServices.size() > 0) {
   13571             // An app that is currently executing a service callback also
   13572             // counts as being in the foreground.
   13573             adj = ProcessList.FOREGROUND_APP_ADJ;
   13574             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13575             app.adjType = "exec-service";
   13576         } else if (activitiesSize > 0) {
   13577             // This app is in the background with paused activities.
   13578             // We inspect activities to potentially upgrade adjustment further below.
   13579             adj = hiddenAdj;
   13580             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13581             app.hidden = true;
   13582             app.adjType = "bg-activities";
   13583         } else {
   13584             // A very not-needed process.  If this is lower in the lru list,
   13585             // we will push it in to the empty bucket.
   13586             adj = hiddenAdj;
   13587             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13588             app.hidden = true;
   13589             app.empty = true;
   13590             app.adjType = "bg-empty";
   13591         }
   13592 
   13593         // Examine all activities if not already foreground.
   13594         if (!app.foregroundActivities && activitiesSize > 0) {
   13595             for (int j = 0; j < activitiesSize; j++) {
   13596                 final ActivityRecord r = app.activities.get(j);
   13597                 if (r.visible) {
   13598                     // App has a visible activity; only upgrade adjustment.
   13599                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   13600                         adj = ProcessList.VISIBLE_APP_ADJ;
   13601                         app.adjType = "visible";
   13602                     }
   13603                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   13604                     app.hidden = false;
   13605                     app.foregroundActivities = true;
   13606                     break;
   13607                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
   13608                         || r.state == ActivityState.STOPPING) {
   13609                     // Only upgrade adjustment.
   13610                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   13611                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   13612                         app.adjType = "stopping";
   13613                     }
   13614                     app.hidden = false;
   13615                     app.foregroundActivities = true;
   13616                 }
   13617             }
   13618         }
   13619 
   13620         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   13621             if (app.foregroundServices) {
   13622                 // The user is aware of this app, so make it visible.
   13623                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   13624                 app.hidden = false;
   13625                 app.adjType = "foreground-service";
   13626                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   13627             } else if (app.forcingToForeground != null) {
   13628                 // The user is aware of this app, so make it visible.
   13629                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   13630                 app.hidden = false;
   13631                 app.adjType = "force-foreground";
   13632                 app.adjSource = app.forcingToForeground;
   13633                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   13634             }
   13635         }
   13636 
   13637         if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
   13638             // We don't want to kill the current heavy-weight process.
   13639             adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
   13640             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13641             app.hidden = false;
   13642             app.adjType = "heavy";
   13643         }
   13644 
   13645         if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
   13646             // This process is hosting what we currently consider to be the
   13647             // home app, so we don't want to let it go into the background.
   13648             adj = ProcessList.HOME_APP_ADJ;
   13649             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13650             app.hidden = false;
   13651             app.adjType = "home";
   13652         }
   13653 
   13654         if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
   13655                 && app.activities.size() > 0) {
   13656             // This was the previous process that showed UI to the user.
   13657             // We want to try to keep it around more aggressively, to give
   13658             // a good experience around switching between two apps.
   13659             adj = ProcessList.PREVIOUS_APP_ADJ;
   13660             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13661             app.hidden = false;
   13662             app.adjType = "previous";
   13663         }
   13664 
   13665         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
   13666                 + " reason=" + app.adjType);
   13667 
   13668         // By default, we use the computed adjustment.  It may be changed if
   13669         // there are applications dependent on our services or providers, but
   13670         // this gives us a baseline and makes sure we don't get into an
   13671         // infinite recursion.
   13672         app.adjSeq = mAdjSeq;
   13673         app.curRawAdj = adj;
   13674 
   13675         if (mBackupTarget != null && app == mBackupTarget.app) {
   13676             // If possible we want to avoid killing apps while they're being backed up
   13677             if (adj > ProcessList.BACKUP_APP_ADJ) {
   13678                 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
   13679                 adj = ProcessList.BACKUP_APP_ADJ;
   13680                 app.adjType = "backup";
   13681                 app.hidden = false;
   13682             }
   13683         }
   13684 
   13685         if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   13686                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   13687             final long now = SystemClock.uptimeMillis();
   13688             // This process is more important if the top activity is
   13689             // bound to the service.
   13690             Iterator<ServiceRecord> jt = app.services.iterator();
   13691             while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
   13692                 ServiceRecord s = jt.next();
   13693                 if (s.startRequested) {
   13694                     if (app.hasShownUi && app != mHomeProcess) {
   13695                         // If this process has shown some UI, let it immediately
   13696                         // go to the LRU list because it may be pretty heavy with
   13697                         // UI stuff.  We'll tag it with a label just to help
   13698                         // debug and understand what is going on.
   13699                         if (adj > ProcessList.SERVICE_ADJ) {
   13700                             app.adjType = "started-bg-ui-services";
   13701                         }
   13702                     } else {
   13703                         if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
   13704                             // This service has seen some activity within
   13705                             // recent memory, so we will keep its process ahead
   13706                             // of the background processes.
   13707                             if (adj > ProcessList.SERVICE_ADJ) {
   13708                                 adj = ProcessList.SERVICE_ADJ;
   13709                                 app.adjType = "started-services";
   13710                                 app.hidden = false;
   13711                             }
   13712                         }
   13713                         // If we have let the service slide into the background
   13714                         // state, still have some text describing what it is doing
   13715                         // even though the service no longer has an impact.
   13716                         if (adj > ProcessList.SERVICE_ADJ) {
   13717                             app.adjType = "started-bg-services";
   13718                         }
   13719                     }
   13720                     // Don't kill this process because it is doing work; it
   13721                     // has said it is doing work.
   13722                     app.keeping = true;
   13723                 }
   13724                 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   13725                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   13726                     Iterator<ArrayList<ConnectionRecord>> kt
   13727                             = s.connections.values().iterator();
   13728                     while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
   13729                         ArrayList<ConnectionRecord> clist = kt.next();
   13730                         for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
   13731                             // XXX should compute this based on the max of
   13732                             // all connected clients.
   13733                             ConnectionRecord cr = clist.get(i);
   13734                             if (cr.binding.client == app) {
   13735                                 // Binding to ourself is not interesting.
   13736                                 continue;
   13737                             }
   13738                             if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
   13739                                 ProcessRecord client = cr.binding.client;
   13740                                 int clientAdj = adj;
   13741                                 int myHiddenAdj = hiddenAdj;
   13742                                 if (myHiddenAdj > client.hiddenAdj) {
   13743                                     if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
   13744                                         myHiddenAdj = client.hiddenAdj;
   13745                                     } else {
   13746                                         myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
   13747                                     }
   13748                                 }
   13749                                 clientAdj = computeOomAdjLocked(
   13750                                     client, myHiddenAdj, TOP_APP, true, doingAll);
   13751                                 String adjType = null;
   13752                                 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
   13753                                     // Not doing bind OOM management, so treat
   13754                                     // this guy more like a started service.
   13755                                     if (app.hasShownUi && app != mHomeProcess) {
   13756                                         // If this process has shown some UI, let it immediately
   13757                                         // go to the LRU list because it may be pretty heavy with
   13758                                         // UI stuff.  We'll tag it with a label just to help
   13759                                         // debug and understand what is going on.
   13760                                         if (adj > clientAdj) {
   13761                                             adjType = "bound-bg-ui-services";
   13762                                         }
   13763                                         app.hidden = false;
   13764                                         clientAdj = adj;
   13765                                     } else {
   13766                                         if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
   13767                                             // This service has not seen activity within
   13768                                             // recent memory, so allow it to drop to the
   13769                                             // LRU list if there is no other reason to keep
   13770                                             // it around.  We'll also tag it with a label just
   13771                                             // to help debug and undertand what is going on.
   13772                                             if (adj > clientAdj) {
   13773                                                 adjType = "bound-bg-services";
   13774                                             }
   13775                                             clientAdj = adj;
   13776                                         }
   13777                                     }
   13778                                 }
   13779                                 if (adj > clientAdj) {
   13780                                     // If this process has recently shown UI, and
   13781                                     // the process that is binding to it is less
   13782                                     // important than being visible, then we don't
   13783                                     // care about the binding as much as we care
   13784                                     // about letting this process get into the LRU
   13785                                     // list to be killed and restarted if needed for
   13786                                     // memory.
   13787                                     if (app.hasShownUi && app != mHomeProcess
   13788                                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   13789                                         adjType = "bound-bg-ui-services";
   13790                                     } else {
   13791                                         if ((cr.flags&(Context.BIND_ABOVE_CLIENT
   13792                                                 |Context.BIND_IMPORTANT)) != 0) {
   13793                                             adj = clientAdj;
   13794                                         } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
   13795                                                 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
   13796                                                 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   13797                                             adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   13798                                         } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
   13799                                             adj = clientAdj;
   13800                                         } else {
   13801                                             app.pendingUiClean = true;
   13802                                             if (adj > ProcessList.VISIBLE_APP_ADJ) {
   13803                                                 adj = ProcessList.VISIBLE_APP_ADJ;
   13804                                             }
   13805                                         }
   13806                                         if (!client.hidden) {
   13807                                             app.hidden = false;
   13808                                         }
   13809                                         if (client.keeping) {
   13810                                             app.keeping = true;
   13811                                         }
   13812                                         adjType = "service";
   13813                                     }
   13814                                 }
   13815                                 if (adjType != null) {
   13816                                     app.adjType = adjType;
   13817                                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   13818                                             .REASON_SERVICE_IN_USE;
   13819                                     app.adjSource = cr.binding.client;
   13820                                     app.adjSourceOom = clientAdj;
   13821                                     app.adjTarget = s.name;
   13822                                 }
   13823                                 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   13824                                     if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   13825                                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   13826                                     }
   13827                                 }
   13828                             }
   13829                             if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
   13830                                 ActivityRecord a = cr.activity;
   13831                                 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
   13832                                         (a.visible || a.state == ActivityState.RESUMED
   13833                                          || a.state == ActivityState.PAUSING)) {
   13834                                     adj = ProcessList.FOREGROUND_APP_ADJ;
   13835                                     if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   13836                                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   13837                                     }
   13838                                     app.hidden = false;
   13839                                     app.adjType = "service";
   13840                                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   13841                                             .REASON_SERVICE_IN_USE;
   13842                                     app.adjSource = a;
   13843                                     app.adjSourceOom = adj;
   13844                                     app.adjTarget = s.name;
   13845                                 }
   13846                             }
   13847                         }
   13848                     }
   13849                 }
   13850             }
   13851 
   13852             // Finally, if this process has active services running in it, we
   13853             // would like to avoid killing it unless it would prevent the current
   13854             // application from running.  By default we put the process in
   13855             // with the rest of the background processes; as we scan through
   13856             // its services we may bump it up from there.
   13857             if (adj > hiddenAdj) {
   13858                 adj = hiddenAdj;
   13859                 app.hidden = false;
   13860                 app.adjType = "bg-services";
   13861             }
   13862         }
   13863 
   13864         if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   13865                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   13866             Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
   13867             while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
   13868                     || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   13869                 ContentProviderRecord cpr = jt.next();
   13870                 if (cpr.clients.size() != 0) {
   13871                     Iterator<ProcessRecord> kt = cpr.clients.iterator();
   13872                     while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
   13873                         ProcessRecord client = kt.next();
   13874                         if (client == app) {
   13875                             // Being our own client is not interesting.
   13876                             continue;
   13877                         }
   13878                         int myHiddenAdj = hiddenAdj;
   13879                         if (myHiddenAdj > client.hiddenAdj) {
   13880                             if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
   13881                                 myHiddenAdj = client.hiddenAdj;
   13882                             } else {
   13883                                 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
   13884                             }
   13885                         }
   13886                         int clientAdj = computeOomAdjLocked(
   13887                             client, myHiddenAdj, TOP_APP, true, doingAll);
   13888                         if (adj > clientAdj) {
   13889                             if (app.hasShownUi && app != mHomeProcess
   13890                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   13891                                 app.adjType = "bg-ui-provider";
   13892                             } else {
   13893                                 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
   13894                                         ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
   13895                                 app.adjType = "provider";
   13896                             }
   13897                             if (!client.hidden) {
   13898                                 app.hidden = false;
   13899                             }
   13900                             if (client.keeping) {
   13901                                 app.keeping = true;
   13902                             }
   13903                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   13904                                     .REASON_PROVIDER_IN_USE;
   13905                             app.adjSource = client;
   13906                             app.adjSourceOom = clientAdj;
   13907                             app.adjTarget = cpr.name;
   13908                         }
   13909                         if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   13910                             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13911                         }
   13912                     }
   13913                 }
   13914                 // If the provider has external (non-framework) process
   13915                 // dependencies, ensure that its adjustment is at least
   13916                 // FOREGROUND_APP_ADJ.
   13917                 if (cpr.externals != 0) {
   13918                     if (adj > ProcessList.FOREGROUND_APP_ADJ) {
   13919                         adj = ProcessList.FOREGROUND_APP_ADJ;
   13920                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   13921                         app.hidden = false;
   13922                         app.keeping = true;
   13923                         app.adjType = "provider";
   13924                         app.adjTarget = cpr.name;
   13925                     }
   13926                 }
   13927             }
   13928         }
   13929 
   13930         app.curRawAdj = adj;
   13931 
   13932         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
   13933         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
   13934         if (adj > app.maxAdj) {
   13935             adj = app.maxAdj;
   13936             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   13937                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   13938             }
   13939         }
   13940         if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
   13941             app.keeping = true;
   13942         }
   13943 
   13944         if (app.hasAboveClient) {
   13945             // If this process has bound to any services with BIND_ABOVE_CLIENT,
   13946             // then we need to drop its adjustment to be lower than the service's
   13947             // in order to honor the request.  We want to drop it by one adjustment
   13948             // level...  but there is special meaning applied to various levels so
   13949             // we will skip some of them.
   13950             if (adj < ProcessList.FOREGROUND_APP_ADJ) {
   13951                 // System process will not get dropped, ever
   13952             } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
   13953                 adj = ProcessList.VISIBLE_APP_ADJ;
   13954             } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
   13955                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   13956             } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
   13957                 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
   13958             } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
   13959                 adj++;
   13960             }
   13961         }
   13962 
   13963         if (adj == ProcessList.SERVICE_ADJ) {
   13964             if (doingAll) {
   13965                 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
   13966                 mNewNumServiceProcs++;
   13967             }
   13968             if (app.serviceb) {
   13969                 adj = ProcessList.SERVICE_B_ADJ;
   13970             }
   13971         } else {
   13972             app.serviceb = false;
   13973         }
   13974 
   13975         app.curAdj = adj;
   13976         app.curSchedGroup = schedGroup;
   13977 
   13978         if (hadForegroundActivities != app.foregroundActivities) {
   13979             mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
   13980                     app.foregroundActivities).sendToTarget();
   13981         }
   13982 
   13983         return app.curRawAdj;
   13984     }
   13985 
   13986     /**
   13987      * Ask a given process to GC right now.
   13988      */
   13989     final void performAppGcLocked(ProcessRecord app) {
   13990         try {
   13991             app.lastRequestedGc = SystemClock.uptimeMillis();
   13992             if (app.thread != null) {
   13993                 if (app.reportLowMemory) {
   13994                     app.reportLowMemory = false;
   13995                     app.thread.scheduleLowMemory();
   13996                 } else {
   13997                     app.thread.processInBackground();
   13998                 }
   13999             }
   14000         } catch (Exception e) {
   14001             // whatever.
   14002         }
   14003     }
   14004 
   14005     /**
   14006      * Returns true if things are idle enough to perform GCs.
   14007      */
   14008     private final boolean canGcNowLocked() {
   14009         return mParallelBroadcasts.size() == 0
   14010                 && mOrderedBroadcasts.size() == 0
   14011                 && (mSleeping || (mMainStack.mResumedActivity != null &&
   14012                         mMainStack.mResumedActivity.idle));
   14013     }
   14014 
   14015     /**
   14016      * Perform GCs on all processes that are waiting for it, but only
   14017      * if things are idle.
   14018      */
   14019     final void performAppGcsLocked() {
   14020         final int N = mProcessesToGc.size();
   14021         if (N <= 0) {
   14022             return;
   14023         }
   14024         if (canGcNowLocked()) {
   14025             while (mProcessesToGc.size() > 0) {
   14026                 ProcessRecord proc = mProcessesToGc.remove(0);
   14027                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
   14028                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
   14029                             <= SystemClock.uptimeMillis()) {
   14030                         // To avoid spamming the system, we will GC processes one
   14031                         // at a time, waiting a few seconds between each.
   14032                         performAppGcLocked(proc);
   14033                         scheduleAppGcsLocked();
   14034                         return;
   14035                     } else {
   14036                         // It hasn't been long enough since we last GCed this
   14037                         // process...  put it in the list to wait for its time.
   14038                         addProcessToGcListLocked(proc);
   14039                         break;
   14040                     }
   14041                 }
   14042             }
   14043 
   14044             scheduleAppGcsLocked();
   14045         }
   14046     }
   14047 
   14048     /**
   14049      * If all looks good, perform GCs on all processes waiting for them.
   14050      */
   14051     final void performAppGcsIfAppropriateLocked() {
   14052         if (canGcNowLocked()) {
   14053             performAppGcsLocked();
   14054             return;
   14055         }
   14056         // Still not idle, wait some more.
   14057         scheduleAppGcsLocked();
   14058     }
   14059 
   14060     /**
   14061      * Schedule the execution of all pending app GCs.
   14062      */
   14063     final void scheduleAppGcsLocked() {
   14064         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
   14065 
   14066         if (mProcessesToGc.size() > 0) {
   14067             // Schedule a GC for the time to the next process.
   14068             ProcessRecord proc = mProcessesToGc.get(0);
   14069             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
   14070 
   14071             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
   14072             long now = SystemClock.uptimeMillis();
   14073             if (when < (now+GC_TIMEOUT)) {
   14074                 when = now + GC_TIMEOUT;
   14075             }
   14076             mHandler.sendMessageAtTime(msg, when);
   14077         }
   14078     }
   14079 
   14080     /**
   14081      * Add a process to the array of processes waiting to be GCed.  Keeps the
   14082      * list in sorted order by the last GC time.  The process can't already be
   14083      * on the list.
   14084      */
   14085     final void addProcessToGcListLocked(ProcessRecord proc) {
   14086         boolean added = false;
   14087         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
   14088             if (mProcessesToGc.get(i).lastRequestedGc <
   14089                     proc.lastRequestedGc) {
   14090                 added = true;
   14091                 mProcessesToGc.add(i+1, proc);
   14092                 break;
   14093             }
   14094         }
   14095         if (!added) {
   14096             mProcessesToGc.add(0, proc);
   14097         }
   14098     }
   14099 
   14100     /**
   14101      * Set up to ask a process to GC itself.  This will either do it
   14102      * immediately, or put it on the list of processes to gc the next
   14103      * time things are idle.
   14104      */
   14105     final void scheduleAppGcLocked(ProcessRecord app) {
   14106         long now = SystemClock.uptimeMillis();
   14107         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
   14108             return;
   14109         }
   14110         if (!mProcessesToGc.contains(app)) {
   14111             addProcessToGcListLocked(app);
   14112             scheduleAppGcsLocked();
   14113         }
   14114     }
   14115 
   14116     final void checkExcessivePowerUsageLocked(boolean doKills) {
   14117         updateCpuStatsNow();
   14118 
   14119         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   14120         boolean doWakeKills = doKills;
   14121         boolean doCpuKills = doKills;
   14122         if (mLastPowerCheckRealtime == 0) {
   14123             doWakeKills = false;
   14124         }
   14125         if (mLastPowerCheckUptime == 0) {
   14126             doCpuKills = false;
   14127         }
   14128         if (stats.isScreenOn()) {
   14129             doWakeKills = false;
   14130         }
   14131         final long curRealtime = SystemClock.elapsedRealtime();
   14132         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
   14133         final long curUptime = SystemClock.uptimeMillis();
   14134         final long uptimeSince = curUptime - mLastPowerCheckUptime;
   14135         mLastPowerCheckRealtime = curRealtime;
   14136         mLastPowerCheckUptime = curUptime;
   14137         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
   14138             doWakeKills = false;
   14139         }
   14140         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
   14141             doCpuKills = false;
   14142         }
   14143         int i = mLruProcesses.size();
   14144         while (i > 0) {
   14145             i--;
   14146             ProcessRecord app = mLruProcesses.get(i);
   14147             if (!app.keeping) {
   14148                 long wtime;
   14149                 synchronized (stats) {
   14150                     wtime = stats.getProcessWakeTime(app.info.uid,
   14151                             app.pid, curRealtime);
   14152                 }
   14153                 long wtimeUsed = wtime - app.lastWakeTime;
   14154                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
   14155                 if (DEBUG_POWER) {
   14156                     StringBuilder sb = new StringBuilder(128);
   14157                     sb.append("Wake for ");
   14158                     app.toShortString(sb);
   14159                     sb.append(": over ");
   14160                     TimeUtils.formatDuration(realtimeSince, sb);
   14161                     sb.append(" used ");
   14162                     TimeUtils.formatDuration(wtimeUsed, sb);
   14163                     sb.append(" (");
   14164                     sb.append((wtimeUsed*100)/realtimeSince);
   14165                     sb.append("%)");
   14166                     Slog.i(TAG, sb.toString());
   14167                     sb.setLength(0);
   14168                     sb.append("CPU for ");
   14169                     app.toShortString(sb);
   14170                     sb.append(": over ");
   14171                     TimeUtils.formatDuration(uptimeSince, sb);
   14172                     sb.append(" used ");
   14173                     TimeUtils.formatDuration(cputimeUsed, sb);
   14174                     sb.append(" (");
   14175                     sb.append((cputimeUsed*100)/uptimeSince);
   14176                     sb.append("%)");
   14177                     Slog.i(TAG, sb.toString());
   14178                 }
   14179                 // If a process has held a wake lock for more
   14180                 // than 50% of the time during this period,
   14181                 // that sounds pad.  Kill!
   14182                 if (doWakeKills && realtimeSince > 0
   14183                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
   14184                     synchronized (stats) {
   14185                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
   14186                                 realtimeSince, wtimeUsed);
   14187                     }
   14188                     Slog.w(TAG, "Excessive wake lock in " + app.processName
   14189                             + " (pid " + app.pid + "): held " + wtimeUsed
   14190                             + " during " + realtimeSince);
   14191                     EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   14192                             app.processName, app.setAdj, "excessive wake lock");
   14193                     Process.killProcessQuiet(app.pid);
   14194                 } else if (doCpuKills && uptimeSince > 0
   14195                         && ((cputimeUsed*100)/uptimeSince) >= 50) {
   14196                     synchronized (stats) {
   14197                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
   14198                                 uptimeSince, cputimeUsed);
   14199                     }
   14200                     Slog.w(TAG, "Excessive CPU in " + app.processName
   14201                             + " (pid " + app.pid + "): used " + cputimeUsed
   14202                             + " during " + uptimeSince);
   14203                     EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   14204                             app.processName, app.setAdj, "excessive cpu");
   14205                     Process.killProcessQuiet(app.pid);
   14206                 } else {
   14207                     app.lastWakeTime = wtime;
   14208                     app.lastCpuTime = app.curCpuTime;
   14209                 }
   14210             }
   14211         }
   14212     }
   14213 
   14214     private final boolean updateOomAdjLocked(
   14215             ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
   14216         app.hiddenAdj = hiddenAdj;
   14217 
   14218         if (app.thread == null) {
   14219             return false;
   14220         }
   14221 
   14222         final boolean wasKeeping = app.keeping;
   14223 
   14224         boolean success = true;
   14225 
   14226         computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
   14227 
   14228         if (app.curRawAdj != app.setRawAdj) {
   14229             if (false) {
   14230                 // Removing for now.  Forcing GCs is not so useful anymore
   14231                 // with Dalvik, and the new memory level hint facility is
   14232                 // better for what we need to do these days.
   14233                 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
   14234                         && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   14235                     // If this app is transitioning from foreground to
   14236                     // non-foreground, have it do a gc.
   14237                     scheduleAppGcLocked(app);
   14238                 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
   14239                         && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
   14240                     // Likewise do a gc when an app is moving in to the
   14241                     // background (such as a service stopping).
   14242                     scheduleAppGcLocked(app);
   14243                 }
   14244             }
   14245 
   14246             if (wasKeeping && !app.keeping) {
   14247                 // This app is no longer something we want to keep.  Note
   14248                 // its current wake lock time to later know to kill it if
   14249                 // it is not behaving well.
   14250                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   14251                 synchronized (stats) {
   14252                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
   14253                             app.pid, SystemClock.elapsedRealtime());
   14254                 }
   14255                 app.lastCpuTime = app.curCpuTime;
   14256             }
   14257 
   14258             app.setRawAdj = app.curRawAdj;
   14259         }
   14260 
   14261         if (app.curAdj != app.setAdj) {
   14262             if (Process.setOomAdj(app.pid, app.curAdj)) {
   14263                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
   14264                     TAG, "Set " + app.pid + " " + app.processName +
   14265                     " adj " + app.curAdj + ": " + app.adjType);
   14266                 app.setAdj = app.curAdj;
   14267             } else {
   14268                 success = false;
   14269                 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
   14270             }
   14271         }
   14272         if (app.setSchedGroup != app.curSchedGroup) {
   14273             app.setSchedGroup = app.curSchedGroup;
   14274             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   14275                     "Setting process group of " + app.processName
   14276                     + " to " + app.curSchedGroup);
   14277             if (app.waitingToKill != null &&
   14278                     app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
   14279                 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
   14280                 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   14281                         app.processName, app.setAdj, app.waitingToKill);
   14282                 Process.killProcessQuiet(app.pid);
   14283                 success = false;
   14284             } else {
   14285                 if (true) {
   14286                     long oldId = Binder.clearCallingIdentity();
   14287                     try {
   14288                         Process.setProcessGroup(app.pid, app.curSchedGroup);
   14289                     } catch (Exception e) {
   14290                         Slog.w(TAG, "Failed setting process group of " + app.pid
   14291                                 + " to " + app.curSchedGroup);
   14292                         e.printStackTrace();
   14293                     } finally {
   14294                         Binder.restoreCallingIdentity(oldId);
   14295                     }
   14296                 } else {
   14297                     if (app.thread != null) {
   14298                         try {
   14299                             app.thread.setSchedulingGroup(app.curSchedGroup);
   14300                         } catch (RemoteException e) {
   14301                         }
   14302                     }
   14303                 }
   14304             }
   14305         }
   14306         return success;
   14307     }
   14308 
   14309     private final ActivityRecord resumedAppLocked() {
   14310         ActivityRecord resumedActivity = mMainStack.mResumedActivity;
   14311         if (resumedActivity == null || resumedActivity.app == null) {
   14312             resumedActivity = mMainStack.mPausingActivity;
   14313             if (resumedActivity == null || resumedActivity.app == null) {
   14314                 resumedActivity = mMainStack.topRunningActivityLocked(null);
   14315             }
   14316         }
   14317         return resumedActivity;
   14318     }
   14319 
   14320     private final boolean updateOomAdjLocked(ProcessRecord app) {
   14321         final ActivityRecord TOP_ACT = resumedAppLocked();
   14322         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   14323         int curAdj = app.curAdj;
   14324         final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
   14325             && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
   14326 
   14327         mAdjSeq++;
   14328 
   14329         boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
   14330         final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
   14331             && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
   14332         if (nowHidden != wasHidden) {
   14333             // Changed to/from hidden state, so apps after it in the LRU
   14334             // list may also be changed.
   14335             updateOomAdjLocked();
   14336         }
   14337         return success;
   14338     }
   14339 
   14340     final void updateOomAdjLocked() {
   14341         final ActivityRecord TOP_ACT = resumedAppLocked();
   14342         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   14343 
   14344         if (false) {
   14345             RuntimeException e = new RuntimeException();
   14346             e.fillInStackTrace();
   14347             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
   14348         }
   14349 
   14350         mAdjSeq++;
   14351         mNewNumServiceProcs = 0;
   14352 
   14353         // Let's determine how many processes we have running vs.
   14354         // how many slots we have for background processes; we may want
   14355         // to put multiple processes in a slot of there are enough of
   14356         // them.
   14357         int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
   14358         int factor = (mLruProcesses.size()-4)/numSlots;
   14359         if (factor < 1) factor = 1;
   14360         int step = 0;
   14361         int numHidden = 0;
   14362 
   14363         // First update the OOM adjustment for each of the
   14364         // application processes based on their current state.
   14365         int i = mLruProcesses.size();
   14366         int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
   14367         while (i > 0) {
   14368             i--;
   14369             ProcessRecord app = mLruProcesses.get(i);
   14370             //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
   14371             updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
   14372             if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
   14373                 && app.curAdj == curHiddenAdj) {
   14374                 step++;
   14375                 if (step >= factor) {
   14376                     step = 0;
   14377                     curHiddenAdj++;
   14378                 }
   14379             }
   14380             if (!app.killedBackground) {
   14381                 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   14382                     numHidden++;
   14383                     if (numHidden > mProcessLimit) {
   14384                         Slog.i(TAG, "No longer want " + app.processName
   14385                                 + " (pid " + app.pid + "): hidden #" + numHidden);
   14386                         EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   14387                                 app.processName, app.setAdj, "too many background");
   14388                         app.killedBackground = true;
   14389                         Process.killProcessQuiet(app.pid);
   14390                     }
   14391                 }
   14392             }
   14393         }
   14394 
   14395         mNumServiceProcs = mNewNumServiceProcs;
   14396 
   14397         // Now determine the memory trimming level of background processes.
   14398         // Unfortunately we need to start at the back of the list to do this
   14399         // properly.  We only do this if the number of background apps we
   14400         // are managing to keep around is less than half the maximum we desire;
   14401         // if we are keeping a good number around, we'll let them use whatever
   14402         // memory they want.
   14403         if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
   14404             final int N = mLruProcesses.size();
   14405             factor = numHidden/3;
   14406             int minFactor = 2;
   14407             if (mHomeProcess != null) minFactor++;
   14408             if (mPreviousProcess != null) minFactor++;
   14409             if (factor < minFactor) factor = minFactor;
   14410             step = 0;
   14411             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
   14412             for (i=0; i<N; i++) {
   14413                 ProcessRecord app = mLruProcesses.get(i);
   14414                 if (app.curAdj >= ProcessList.HOME_APP_ADJ
   14415                         && app.curAdj != ProcessList.SERVICE_B_ADJ
   14416                         && !app.killedBackground) {
   14417                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
   14418                         try {
   14419                             app.thread.scheduleTrimMemory(curLevel);
   14420                         } catch (RemoteException e) {
   14421                         }
   14422                         if (false) {
   14423                             // For now we won't do this; our memory trimming seems
   14424                             // to be good enough at this point that destroying
   14425                             // activities causes more harm than good.
   14426                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
   14427                                     && app != mHomeProcess && app != mPreviousProcess) {
   14428                                 // For these apps we will also finish their activities
   14429                                 // to help them free memory.
   14430                                 mMainStack.destroyActivitiesLocked(app, false, "trim");
   14431                             }
   14432                         }
   14433                     }
   14434                     app.trimMemoryLevel = curLevel;
   14435                     step++;
   14436                     if (step >= factor) {
   14437                         switch (curLevel) {
   14438                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
   14439                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
   14440                                 break;
   14441                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
   14442                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   14443                                 break;
   14444                         }
   14445                     }
   14446                 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   14447                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
   14448                             && app.thread != null) {
   14449                         try {
   14450                             app.thread.scheduleTrimMemory(
   14451                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   14452                         } catch (RemoteException e) {
   14453                         }
   14454                     }
   14455                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   14456                 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
   14457                         && app.pendingUiClean) {
   14458                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
   14459                             && app.thread != null) {
   14460                         try {
   14461                             app.thread.scheduleTrimMemory(
   14462                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   14463                         } catch (RemoteException e) {
   14464                         }
   14465                     }
   14466                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
   14467                     app.pendingUiClean = false;
   14468                 } else {
   14469                     app.trimMemoryLevel = 0;
   14470                 }
   14471             }
   14472         } else {
   14473             final int N = mLruProcesses.size();
   14474             for (i=0; i<N; i++) {
   14475                 ProcessRecord app = mLruProcesses.get(i);
   14476                 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
   14477                         && app.pendingUiClean) {
   14478                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
   14479                             && app.thread != null) {
   14480                         try {
   14481                             app.thread.scheduleTrimMemory(
   14482                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   14483                         } catch (RemoteException e) {
   14484                         }
   14485                     }
   14486                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
   14487                     app.pendingUiClean = false;
   14488                 } else {
   14489                     app.trimMemoryLevel = 0;
   14490                 }
   14491             }
   14492         }
   14493 
   14494         if (mAlwaysFinishActivities) {
   14495             mMainStack.destroyActivitiesLocked(null, false, "always-finish");
   14496         }
   14497     }
   14498 
   14499     final void trimApplications() {
   14500         synchronized (this) {
   14501             int i;
   14502 
   14503             // First remove any unused application processes whose package
   14504             // has been removed.
   14505             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
   14506                 final ProcessRecord app = mRemovedProcesses.get(i);
   14507                 if (app.activities.size() == 0
   14508                         && app.curReceiver == null && app.services.size() == 0) {
   14509                     Slog.i(
   14510                         TAG, "Exiting empty application process "
   14511                         + app.processName + " ("
   14512                         + (app.thread != null ? app.thread.asBinder() : null)
   14513                         + ")\n");
   14514                     if (app.pid > 0 && app.pid != MY_PID) {
   14515                         EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   14516                                 app.processName, app.setAdj, "empty");
   14517                         Process.killProcessQuiet(app.pid);
   14518                     } else {
   14519                         try {
   14520                             app.thread.scheduleExit();
   14521                         } catch (Exception e) {
   14522                             // Ignore exceptions.
   14523                         }
   14524                     }
   14525                     cleanUpApplicationRecordLocked(app, false, true, -1);
   14526                     mRemovedProcesses.remove(i);
   14527 
   14528                     if (app.persistent) {
   14529                         if (app.persistent) {
   14530                             addAppLocked(app.info);
   14531                         }
   14532                     }
   14533                 }
   14534             }
   14535 
   14536             // Now update the oom adj for all processes.
   14537             updateOomAdjLocked();
   14538         }
   14539     }
   14540 
   14541     /** This method sends the specified signal to each of the persistent apps */
   14542     public void signalPersistentProcesses(int sig) throws RemoteException {
   14543         if (sig != Process.SIGNAL_USR1) {
   14544             throw new SecurityException("Only SIGNAL_USR1 is allowed");
   14545         }
   14546 
   14547         synchronized (this) {
   14548             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
   14549                     != PackageManager.PERMISSION_GRANTED) {
   14550                 throw new SecurityException("Requires permission "
   14551                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
   14552             }
   14553 
   14554             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   14555                 ProcessRecord r = mLruProcesses.get(i);
   14556                 if (r.thread != null && r.persistent) {
   14557                     Process.sendSignal(r.pid, sig);
   14558                 }
   14559             }
   14560         }
   14561     }
   14562 
   14563     private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
   14564         if (proc == null || proc == mProfileProc) {
   14565             proc = mProfileProc;
   14566             path = mProfileFile;
   14567             profileType = mProfileType;
   14568             clearProfilerLocked();
   14569         }
   14570         if (proc == null) {
   14571             return;
   14572         }
   14573         try {
   14574             proc.thread.profilerControl(false, path, null, profileType);
   14575         } catch (RemoteException e) {
   14576             throw new IllegalStateException("Process disappeared");
   14577         }
   14578     }
   14579 
   14580     private void clearProfilerLocked() {
   14581         if (mProfileFd != null) {
   14582             try {
   14583                 mProfileFd.close();
   14584             } catch (IOException e) {
   14585             }
   14586         }
   14587         mProfileApp = null;
   14588         mProfileProc = null;
   14589         mProfileFile = null;
   14590         mProfileType = 0;
   14591         mAutoStopProfiler = false;
   14592     }
   14593 
   14594     public boolean profileControl(String process, boolean start,
   14595             String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
   14596 
   14597         try {
   14598             synchronized (this) {
   14599                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   14600                 // its own permission.
   14601                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   14602                         != PackageManager.PERMISSION_GRANTED) {
   14603                     throw new SecurityException("Requires permission "
   14604                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   14605                 }
   14606 
   14607                 if (start && fd == null) {
   14608                     throw new IllegalArgumentException("null fd");
   14609                 }
   14610 
   14611                 ProcessRecord proc = null;
   14612                 if (process != null) {
   14613                     try {
   14614                         int pid = Integer.parseInt(process);
   14615                         synchronized (mPidsSelfLocked) {
   14616                             proc = mPidsSelfLocked.get(pid);
   14617                         }
   14618                     } catch (NumberFormatException e) {
   14619                     }
   14620 
   14621                     if (proc == null) {
   14622                         HashMap<String, SparseArray<ProcessRecord>> all
   14623                                 = mProcessNames.getMap();
   14624                         SparseArray<ProcessRecord> procs = all.get(process);
   14625                         if (procs != null && procs.size() > 0) {
   14626                             proc = procs.valueAt(0);
   14627                         }
   14628                     }
   14629                 }
   14630 
   14631                 if (start && (proc == null || proc.thread == null)) {
   14632                     throw new IllegalArgumentException("Unknown process: " + process);
   14633                 }
   14634 
   14635                 if (start) {
   14636                     stopProfilerLocked(null, null, 0);
   14637                     setProfileApp(proc.info, proc.processName, path, fd, false);
   14638                     mProfileProc = proc;
   14639                     mProfileType = profileType;
   14640                     try {
   14641                         fd = fd.dup();
   14642                     } catch (IOException e) {
   14643                         fd = null;
   14644                     }
   14645                     proc.thread.profilerControl(start, path, fd, profileType);
   14646                     fd = null;
   14647                     mProfileFd = null;
   14648                 } else {
   14649                     stopProfilerLocked(proc, path, profileType);
   14650                     if (fd != null) {
   14651                         try {
   14652                             fd.close();
   14653                         } catch (IOException e) {
   14654                         }
   14655                     }
   14656                 }
   14657 
   14658                 return true;
   14659             }
   14660         } catch (RemoteException e) {
   14661             throw new IllegalStateException("Process disappeared");
   14662         } finally {
   14663             if (fd != null) {
   14664                 try {
   14665                     fd.close();
   14666                 } catch (IOException e) {
   14667                 }
   14668             }
   14669         }
   14670     }
   14671 
   14672     public boolean dumpHeap(String process, boolean managed,
   14673             String path, ParcelFileDescriptor fd) throws RemoteException {
   14674 
   14675         try {
   14676             synchronized (this) {
   14677                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   14678                 // its own permission (same as profileControl).
   14679                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   14680                         != PackageManager.PERMISSION_GRANTED) {
   14681                     throw new SecurityException("Requires permission "
   14682                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   14683                 }
   14684 
   14685                 if (fd == null) {
   14686                     throw new IllegalArgumentException("null fd");
   14687                 }
   14688 
   14689                 ProcessRecord proc = null;
   14690                 try {
   14691                     int pid = Integer.parseInt(process);
   14692                     synchronized (mPidsSelfLocked) {
   14693                         proc = mPidsSelfLocked.get(pid);
   14694                     }
   14695                 } catch (NumberFormatException e) {
   14696                 }
   14697 
   14698                 if (proc == null) {
   14699                     HashMap<String, SparseArray<ProcessRecord>> all
   14700                             = mProcessNames.getMap();
   14701                     SparseArray<ProcessRecord> procs = all.get(process);
   14702                     if (procs != null && procs.size() > 0) {
   14703                         proc = procs.valueAt(0);
   14704                     }
   14705                 }
   14706 
   14707                 if (proc == null || proc.thread == null) {
   14708                     throw new IllegalArgumentException("Unknown process: " + process);
   14709                 }
   14710 
   14711                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   14712                 if (!isDebuggable) {
   14713                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   14714                         throw new SecurityException("Process not debuggable: " + proc);
   14715                     }
   14716                 }
   14717 
   14718                 proc.thread.dumpHeap(managed, path, fd);
   14719                 fd = null;
   14720                 return true;
   14721             }
   14722         } catch (RemoteException e) {
   14723             throw new IllegalStateException("Process disappeared");
   14724         } finally {
   14725             if (fd != null) {
   14726                 try {
   14727                     fd.close();
   14728                 } catch (IOException e) {
   14729                 }
   14730             }
   14731         }
   14732     }
   14733 
   14734     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
   14735     public void monitor() {
   14736         synchronized (this) { }
   14737     }
   14738 
   14739     public void onCoreSettingsChange(Bundle settings) {
   14740         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   14741             ProcessRecord processRecord = mLruProcesses.get(i);
   14742             try {
   14743                 if (processRecord.thread != null) {
   14744                     processRecord.thread.setCoreSettings(settings);
   14745                 }
   14746             } catch (RemoteException re) {
   14747                 /* ignore */
   14748             }
   14749         }
   14750     }
   14751 
   14752     // Multi-user methods
   14753 
   14754     public boolean switchUser(int userid) {
   14755         // TODO
   14756         return true;
   14757     }
   14758 }
   14759