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.text.format.Time;
    109 import android.util.EventLog;
    110 import android.util.Pair;
    111 import android.util.Slog;
    112 import android.util.Log;
    113 import android.util.PrintWriterPrinter;
    114 import android.util.SparseArray;
    115 import android.util.TimeUtils;
    116 import android.view.Gravity;
    117 import android.view.LayoutInflater;
    118 import android.view.View;
    119 import android.view.WindowManager;
    120 import android.view.WindowManagerPolicy;
    121 
    122 import java.io.BufferedInputStream;
    123 import java.io.BufferedOutputStream;
    124 import java.io.BufferedReader;
    125 import java.io.DataInputStream;
    126 import java.io.DataOutputStream;
    127 import java.io.File;
    128 import java.io.FileDescriptor;
    129 import java.io.FileInputStream;
    130 import java.io.FileNotFoundException;
    131 import java.io.FileOutputStream;
    132 import java.io.IOException;
    133 import java.io.InputStreamReader;
    134 import java.io.PrintWriter;
    135 import java.io.StringWriter;
    136 import java.lang.IllegalStateException;
    137 import java.lang.ref.WeakReference;
    138 import java.util.ArrayList;
    139 import java.util.Collections;
    140 import java.util.Comparator;
    141 import java.util.HashMap;
    142 import java.util.HashSet;
    143 import java.util.Iterator;
    144 import java.util.List;
    145 import java.util.Locale;
    146 import java.util.Map;
    147 import java.util.Set;
    148 import java.util.concurrent.atomic.AtomicBoolean;
    149 import java.util.concurrent.atomic.AtomicLong;
    150 
    151 public final class ActivityManagerService extends ActivityManagerNative
    152         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    153     static final String TAG = "ActivityManager";
    154     static final boolean DEBUG = false;
    155     static final boolean localLOGV = DEBUG;
    156     static final boolean DEBUG_SWITCH = localLOGV || false;
    157     static final boolean DEBUG_TASKS = localLOGV || false;
    158     static final boolean DEBUG_PAUSE = localLOGV || false;
    159     static final boolean DEBUG_OOM_ADJ = localLOGV || false;
    160     static final boolean DEBUG_TRANSITION = localLOGV || false;
    161     static final boolean DEBUG_BROADCAST = localLOGV || false;
    162     static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
    163     static final boolean DEBUG_SERVICE = localLOGV || false;
    164     static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
    165     static final boolean DEBUG_VISBILITY = localLOGV || false;
    166     static final boolean DEBUG_PROCESSES = localLOGV || false;
    167     static final boolean DEBUG_PROVIDER = localLOGV || false;
    168     static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
    169     static final boolean DEBUG_USER_LEAVING = localLOGV || false;
    170     static final boolean DEBUG_RESULTS = localLOGV || false;
    171     static final boolean DEBUG_BACKUP = localLOGV || false;
    172     static final boolean DEBUG_CONFIGURATION = localLOGV || false;
    173     static final boolean DEBUG_POWER = localLOGV || false;
    174     static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
    175     static final boolean VALIDATE_TOKENS = false;
    176     static final boolean SHOW_ACTIVITY_START_TIME = true;
    177 
    178     // Control over CPU and battery monitoring.
    179     static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
    180     static final boolean MONITOR_CPU_USAGE = true;
    181     static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
    182     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
    183     static final boolean MONITOR_THREAD_CPU_USAGE = false;
    184 
    185     // The flags that are set for all calls we make to the package manager.
    186     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
    187 
    188     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
    189 
    190     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
    191 
    192     // Maximum number of recent tasks that we can remember.
    193     static final int MAX_RECENT_TASKS = 20;
    194 
    195     // Amount of time after a call to stopAppSwitches() during which we will
    196     // prevent further untrusted switches from happening.
    197     static final long APP_SWITCH_DELAY_TIME = 5*1000;
    198 
    199     // How long we wait for a launched process to attach to the activity manager
    200     // before we decide it's never going to come up for real.
    201     static final int PROC_START_TIMEOUT = 10*1000;
    202 
    203     // How long we wait for a launched process to attach to the activity manager
    204     // before we decide it's never going to come up for real, when the process was
    205     // started with a wrapper for instrumentation (such as Valgrind) because it
    206     // could take much longer than usual.
    207     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
    208 
    209     // How long to wait after going idle before forcing apps to GC.
    210     static final int GC_TIMEOUT = 5*1000;
    211 
    212     // The minimum amount of time between successive GC requests for a process.
    213     static final int GC_MIN_INTERVAL = 60*1000;
    214 
    215     // The rate at which we check for apps using excessive power -- 15 mins.
    216     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
    217 
    218     // The minimum sample duration we will allow before deciding we have
    219     // enough data on wake locks to start killing things.
    220     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    221 
    222     // The minimum sample duration we will allow before deciding we have
    223     // enough data on CPU usage to start killing things.
    224     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    225 
    226     // How long we allow a receiver to run before giving up on it.
    227     static final int BROADCAST_TIMEOUT = 10*1000;
    228 
    229     // How long we wait for a service to finish executing.
    230     static final int SERVICE_TIMEOUT = 20*1000;
    231 
    232     // How long a service needs to be running until restarting its process
    233     // is no longer considered to be a relaunch of the service.
    234     static final int SERVICE_RESTART_DURATION = 5*1000;
    235 
    236     // How long a service needs to be running until it will start back at
    237     // SERVICE_RESTART_DURATION after being killed.
    238     static final int SERVICE_RESET_RUN_DURATION = 60*1000;
    239 
    240     // Multiplying factor to increase restart duration time by, for each time
    241     // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
    242     static final int SERVICE_RESTART_DURATION_FACTOR = 4;
    243 
    244     // The minimum amount of time between restarting services that we allow.
    245     // That is, when multiple services are restarting, we won't allow each
    246     // to restart less than this amount of time from the last one.
    247     static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
    248 
    249     // Maximum amount of time for there to be no activity on a service before
    250     // we consider it non-essential and allow its process to go on the
    251     // LRU background list.
    252     static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
    253 
    254     // How long we wait until we timeout on key dispatching.
    255     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
    256 
    257     // How long we wait until we timeout on key dispatching during instrumentation.
    258     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
    259 
    260     static final int MY_PID = Process.myPid();
    261 
    262     static final String[] EMPTY_STRING_ARRAY = new String[0];
    263 
    264     public ActivityStack mMainStack;
    265 
    266     /**
    267      * Description of a request to start a new activity, which has been held
    268      * due to app switches being disabled.
    269      */
    270     static class PendingActivityLaunch {
    271         ActivityRecord r;
    272         ActivityRecord sourceRecord;
    273         Uri[] grantedUriPermissions;
    274         int grantedMode;
    275         boolean onlyIfNeeded;
    276     }
    277 
    278     final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
    279             = new ArrayList<PendingActivityLaunch>();
    280 
    281     /**
    282      * List of all active broadcasts that are to be executed immediately
    283      * (without waiting for another broadcast to finish).  Currently this only
    284      * contains broadcasts to registered receivers, to avoid spinning up
    285      * a bunch of processes to execute IntentReceiver components.
    286      */
    287     final ArrayList<BroadcastRecord> mParallelBroadcasts
    288             = new ArrayList<BroadcastRecord>();
    289 
    290     /**
    291      * List of all active broadcasts that are to be executed one at a time.
    292      * The object at the top of the list is the currently activity broadcasts;
    293      * those after it are waiting for the top to finish..
    294      */
    295     final ArrayList<BroadcastRecord> mOrderedBroadcasts
    296             = new ArrayList<BroadcastRecord>();
    297 
    298     /**
    299      * Historical data of past broadcasts, for debugging.
    300      */
    301     static final int MAX_BROADCAST_HISTORY = 25;
    302     final BroadcastRecord[] mBroadcastHistory
    303             = new BroadcastRecord[MAX_BROADCAST_HISTORY];
    304 
    305     /**
    306      * Set when we current have a BROADCAST_INTENT_MSG in flight.
    307      */
    308     boolean mBroadcastsScheduled = false;
    309 
    310     /**
    311      * Activity we have told the window manager to have key focus.
    312      */
    313     ActivityRecord mFocusedActivity = null;
    314     /**
    315      * List of intents that were used to start the most recent tasks.
    316      */
    317     final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
    318 
    319     /**
    320      * Process management.
    321      */
    322     final ProcessList mProcessList = new ProcessList();
    323 
    324     /**
    325      * All of the applications we currently have running organized by name.
    326      * The keys are strings of the application package name (as
    327      * returned by the package manager), and the keys are ApplicationRecord
    328      * objects.
    329      */
    330     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
    331 
    332     /**
    333      * The currently running heavy-weight process, if any.
    334      */
    335     ProcessRecord mHeavyWeightProcess = null;
    336 
    337     /**
    338      * The last time that various processes have crashed.
    339      */
    340     final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
    341 
    342     /**
    343      * Set of applications that we consider to be bad, and will reject
    344      * incoming broadcasts from (which the user has no control over).
    345      * Processes are added to this set when they have crashed twice within
    346      * a minimum amount of time; they are removed from it when they are
    347      * later restarted (hopefully due to some user action).  The value is the
    348      * time it was added to the list.
    349      */
    350     final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
    351 
    352     /**
    353      * All of the processes we currently have running organized by pid.
    354      * The keys are the pid running the application.
    355      *
    356      * <p>NOTE: This object is protected by its own lock, NOT the global
    357      * activity manager lock!
    358      */
    359     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
    360 
    361     /**
    362      * All of the processes that have been forced to be foreground.  The key
    363      * is the pid of the caller who requested it (we hold a death
    364      * link on it).
    365      */
    366     abstract class ForegroundToken implements IBinder.DeathRecipient {
    367         int pid;
    368         IBinder token;
    369     }
    370     final SparseArray<ForegroundToken> mForegroundProcesses
    371             = new SparseArray<ForegroundToken>();
    372 
    373     /**
    374      * List of records for processes that someone had tried to start before the
    375      * system was ready.  We don't start them at that point, but ensure they
    376      * are started by the time booting is complete.
    377      */
    378     final ArrayList<ProcessRecord> mProcessesOnHold
    379             = new ArrayList<ProcessRecord>();
    380 
    381     /**
    382      * List of persistent applications that are in the process
    383      * of being started.
    384      */
    385     final ArrayList<ProcessRecord> mPersistentStartingProcesses
    386             = new ArrayList<ProcessRecord>();
    387 
    388     /**
    389      * Processes that are being forcibly torn down.
    390      */
    391     final ArrayList<ProcessRecord> mRemovedProcesses
    392             = new ArrayList<ProcessRecord>();
    393 
    394     /**
    395      * List of running applications, sorted by recent usage.
    396      * The first entry in the list is the least recently used.
    397      * It contains ApplicationRecord objects.  This list does NOT include
    398      * any persistent application records (since we never want to exit them).
    399      */
    400     final ArrayList<ProcessRecord> mLruProcesses
    401             = new ArrayList<ProcessRecord>();
    402 
    403     /**
    404      * List of processes that should gc as soon as things are idle.
    405      */
    406     final ArrayList<ProcessRecord> mProcessesToGc
    407             = new ArrayList<ProcessRecord>();
    408 
    409     /**
    410      * This is the process holding what we currently consider to be
    411      * the "home" activity.
    412      */
    413     ProcessRecord mHomeProcess;
    414 
    415     /**
    416      * This is the process holding the activity the user last visited that
    417      * is in a different process from the one they are currently in.
    418      */
    419     ProcessRecord mPreviousProcess;
    420 
    421     /**
    422      * The time at which the previous process was last visible.
    423      */
    424     long mPreviousProcessVisibleTime;
    425 
    426     /**
    427      * Packages that the user has asked to have run in screen size
    428      * compatibility mode instead of filling the screen.
    429      */
    430     final CompatModePackages mCompatModePackages;
    431 
    432     /**
    433      * Set of PendingResultRecord objects that are currently active.
    434      */
    435     final HashSet mPendingResultRecords = new HashSet();
    436 
    437     /**
    438      * Set of IntentSenderRecord objects that are currently active.
    439      */
    440     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
    441             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
    442 
    443     /**
    444      * Fingerprints (hashCode()) of stack traces that we've
    445      * already logged DropBox entries for.  Guarded by itself.  If
    446      * something (rogue user app) forces this over
    447      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
    448      */
    449     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
    450     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
    451 
    452     /**
    453      * Strict Mode background batched logging state.
    454      *
    455      * The string buffer is guarded by itself, and its lock is also
    456      * used to determine if another batched write is already
    457      * in-flight.
    458      */
    459     private final StringBuilder mStrictModeBuffer = new StringBuilder();
    460 
    461     /**
    462      * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
    463      */
    464     private boolean mPendingBroadcastTimeoutMessage;
    465 
    466     /**
    467      * Intent broadcast that we have tried to start, but are
    468      * waiting for its application's process to be created.  We only
    469      * need one (instead of a list) because we always process broadcasts
    470      * one at a time, so no others can be started while waiting for this
    471      * one.
    472      */
    473     BroadcastRecord mPendingBroadcast = null;
    474 
    475     /**
    476      * The receiver index that is pending, to restart the broadcast if needed.
    477      */
    478     int mPendingBroadcastRecvIndex;
    479 
    480     /**
    481      * Keeps track of all IIntentReceivers that have been registered for
    482      * broadcasts.  Hash keys are the receiver IBinder, hash value is
    483      * a ReceiverList.
    484      */
    485     final HashMap mRegisteredReceivers = new HashMap();
    486 
    487     /**
    488      * Resolver for broadcast intents to registered receivers.
    489      * Holds BroadcastFilter (subclass of IntentFilter).
    490      */
    491     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
    492             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
    493         @Override
    494         protected boolean allowFilterResult(
    495                 BroadcastFilter filter, List<BroadcastFilter> dest) {
    496             IBinder target = filter.receiverList.receiver.asBinder();
    497             for (int i=dest.size()-1; i>=0; i--) {
    498                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
    499                     return false;
    500                 }
    501             }
    502             return true;
    503         }
    504 
    505         @Override
    506         protected String packageForFilter(BroadcastFilter filter) {
    507             return filter.packageName;
    508         }
    509     };
    510 
    511     /**
    512      * State of all active sticky broadcasts.  Keys are the action of the
    513      * sticky Intent, values are an ArrayList of all broadcasted intents with
    514      * that action (which should usually be one).
    515      */
    516     final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
    517             new HashMap<String, ArrayList<Intent>>();
    518 
    519     /**
    520      * All currently running services.
    521      */
    522     final HashMap<ComponentName, ServiceRecord> mServices =
    523         new HashMap<ComponentName, ServiceRecord>();
    524 
    525     /**
    526      * All currently running services indexed by the Intent used to start them.
    527      */
    528     final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
    529         new HashMap<Intent.FilterComparison, ServiceRecord>();
    530 
    531     /**
    532      * All currently bound service connections.  Keys are the IBinder of
    533      * the client's IServiceConnection.
    534      */
    535     final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
    536             = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
    537 
    538     /**
    539      * List of services that we have been asked to start,
    540      * but haven't yet been able to.  It is used to hold start requests
    541      * while waiting for their corresponding application thread to get
    542      * going.
    543      */
    544     final ArrayList<ServiceRecord> mPendingServices
    545             = new ArrayList<ServiceRecord>();
    546 
    547     /**
    548      * List of services that are scheduled to restart following a crash.
    549      */
    550     final ArrayList<ServiceRecord> mRestartingServices
    551             = new ArrayList<ServiceRecord>();
    552 
    553     /**
    554      * List of services that are in the process of being stopped.
    555      */
    556     final ArrayList<ServiceRecord> mStoppingServices
    557             = new ArrayList<ServiceRecord>();
    558 
    559     /**
    560      * Backup/restore process management
    561      */
    562     String mBackupAppName = null;
    563     BackupRecord mBackupTarget = null;
    564 
    565     /**
    566      * List of PendingThumbnailsRecord objects of clients who are still
    567      * waiting to receive all of the thumbnails for a task.
    568      */
    569     final ArrayList mPendingThumbnails = new ArrayList();
    570 
    571     /**
    572      * List of HistoryRecord objects that have been finished and must
    573      * still report back to a pending thumbnail receiver.
    574      */
    575     final ArrayList mCancelledThumbnails = new ArrayList();
    576 
    577     /**
    578      * All of the currently running global content providers.  Keys are a
    579      * string containing the provider name and values are a
    580      * ContentProviderRecord object containing the data about it.  Note
    581      * that a single provider may be published under multiple names, so
    582      * there may be multiple entries here for a single one in mProvidersByClass.
    583      */
    584     final HashMap<String, ContentProviderRecord> mProvidersByName
    585             = new HashMap<String, ContentProviderRecord>();
    586 
    587     /**
    588      * All of the currently running global content providers.  Keys are a
    589      * string containing the provider's implementation class and values are a
    590      * ContentProviderRecord object containing the data about it.
    591      */
    592     final HashMap<ComponentName, ContentProviderRecord> mProvidersByClass
    593             = new HashMap<ComponentName, ContentProviderRecord>();
    594 
    595     /**
    596      * List of content providers who have clients waiting for them.  The
    597      * application is currently being launched and the provider will be
    598      * removed from this list once it is published.
    599      */
    600     final ArrayList<ContentProviderRecord> mLaunchingProviders
    601             = new ArrayList<ContentProviderRecord>();
    602 
    603     /**
    604      * Global set of specific Uri permissions that have been granted.
    605      */
    606     final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
    607             = new SparseArray<HashMap<Uri, UriPermission>>();
    608 
    609     CoreSettingsObserver mCoreSettingsObserver;
    610 
    611     /**
    612      * Thread-local storage used to carry caller permissions over through
    613      * indirect content-provider access.
    614      * @see #ActivityManagerService.openContentUri()
    615      */
    616     private class Identity {
    617         public int pid;
    618         public int uid;
    619 
    620         Identity(int _pid, int _uid) {
    621             pid = _pid;
    622             uid = _uid;
    623         }
    624     }
    625     private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
    626 
    627     /**
    628      * All information we have collected about the runtime performance of
    629      * any user id that can impact battery performance.
    630      */
    631     final BatteryStatsService mBatteryStatsService;
    632 
    633     /**
    634      * information about component usage
    635      */
    636     final UsageStatsService mUsageStatsService;
    637 
    638     /**
    639      * Current configuration information.  HistoryRecord objects are given
    640      * a reference to this object to indicate which configuration they are
    641      * currently running in, so this object must be kept immutable.
    642      */
    643     Configuration mConfiguration = new Configuration();
    644 
    645     /**
    646      * Current sequencing integer of the configuration, for skipping old
    647      * configurations.
    648      */
    649     int mConfigurationSeq = 0;
    650 
    651     /**
    652      * Hardware-reported OpenGLES version.
    653      */
    654     final int GL_ES_VERSION;
    655 
    656     /**
    657      * List of initialization arguments to pass to all processes when binding applications to them.
    658      * For example, references to the commonly used services.
    659      */
    660     HashMap<String, IBinder> mAppBindArgs;
    661 
    662     /**
    663      * Temporary to avoid allocations.  Protected by main lock.
    664      */
    665     final StringBuilder mStringBuilder = new StringBuilder(256);
    666 
    667     /**
    668      * Used to control how we initialize the service.
    669      */
    670     boolean mStartRunning = false;
    671     ComponentName mTopComponent;
    672     String mTopAction;
    673     String mTopData;
    674     boolean mProcessesReady = false;
    675     boolean mSystemReady = false;
    676     boolean mBooting = false;
    677     boolean mWaitingUpdate = false;
    678     boolean mDidUpdate = false;
    679     boolean mOnBattery = false;
    680     boolean mLaunchWarningShown = false;
    681 
    682     Context mContext;
    683 
    684     int mFactoryTest;
    685 
    686     boolean mCheckedForSetup;
    687 
    688     /**
    689      * The time at which we will allow normal application switches again,
    690      * after a call to {@link #stopAppSwitches()}.
    691      */
    692     long mAppSwitchesAllowedTime;
    693 
    694     /**
    695      * This is set to true after the first switch after mAppSwitchesAllowedTime
    696      * is set; any switches after that will clear the time.
    697      */
    698     boolean mDidAppSwitch;
    699 
    700     /**
    701      * Last time (in realtime) at which we checked for power usage.
    702      */
    703     long mLastPowerCheckRealtime;
    704 
    705     /**
    706      * Last time (in uptime) at which we checked for power usage.
    707      */
    708     long mLastPowerCheckUptime;
    709 
    710     /**
    711      * Set while we are wanting to sleep, to prevent any
    712      * activities from being started/resumed.
    713      */
    714     boolean mSleeping = false;
    715 
    716     /**
    717      * Set if we are shutting down the system, similar to sleeping.
    718      */
    719     boolean mShuttingDown = false;
    720 
    721     /**
    722      * Task identifier that activities are currently being started
    723      * in.  Incremented each time a new task is created.
    724      * todo: Replace this with a TokenSpace class that generates non-repeating
    725      * integers that won't wrap.
    726      */
    727     int mCurTask = 1;
    728 
    729     /**
    730      * Current sequence id for oom_adj computation traversal.
    731      */
    732     int mAdjSeq = 0;
    733 
    734     /**
    735      * Current sequence id for process LRU updating.
    736      */
    737     int mLruSeq = 0;
    738 
    739     /**
    740      * Keep track of the number of service processes we last found, to
    741      * determine on the next iteration which should be B services.
    742      */
    743     int mNumServiceProcs = 0;
    744     int mNewNumServiceProcs = 0;
    745 
    746     /**
    747      * System monitoring: number of processes that died since the last
    748      * N procs were started.
    749      */
    750     int[] mProcDeaths = new int[20];
    751 
    752     /**
    753      * This is set if we had to do a delayed dexopt of an app before launching
    754      * it, to increasing the ANR timeouts in that case.
    755      */
    756     boolean mDidDexOpt;
    757 
    758     String mDebugApp = null;
    759     boolean mWaitForDebugger = false;
    760     boolean mDebugTransient = false;
    761     String mOrigDebugApp = null;
    762     boolean mOrigWaitForDebugger = false;
    763     boolean mAlwaysFinishActivities = false;
    764     IActivityController mController = null;
    765     String mProfileApp = null;
    766     ProcessRecord mProfileProc = null;
    767     String mProfileFile;
    768     ParcelFileDescriptor mProfileFd;
    769     int mProfileType = 0;
    770     boolean mAutoStopProfiler = false;
    771 
    772     final RemoteCallbackList<IActivityWatcher> mWatchers
    773             = new RemoteCallbackList<IActivityWatcher>();
    774 
    775     final RemoteCallbackList<IProcessObserver> mProcessObservers
    776             = new RemoteCallbackList<IProcessObserver>();
    777 
    778     /**
    779      * Callback of last caller to {@link #requestPss}.
    780      */
    781     Runnable mRequestPssCallback;
    782 
    783     /**
    784      * Remaining processes for which we are waiting results from the last
    785      * call to {@link #requestPss}.
    786      */
    787     final ArrayList<ProcessRecord> mRequestPssList
    788             = new ArrayList<ProcessRecord>();
    789 
    790     /**
    791      * Runtime statistics collection thread.  This object's lock is used to
    792      * protect all related state.
    793      */
    794     final Thread mProcessStatsThread;
    795 
    796     /**
    797      * Used to collect process stats when showing not responding dialog.
    798      * Protected by mProcessStatsThread.
    799      */
    800     final ProcessStats mProcessStats = new ProcessStats(
    801             MONITOR_THREAD_CPU_USAGE);
    802     final AtomicLong mLastCpuTime = new AtomicLong(0);
    803     final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
    804 
    805     long mLastWriteTime = 0;
    806 
    807     /**
    808      * Set to true after the system has finished booting.
    809      */
    810     boolean mBooted = false;
    811 
    812     int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
    813     int mProcessLimitOverride = -1;
    814 
    815     WindowManagerService mWindowManager;
    816 
    817     static ActivityManagerService mSelf;
    818     static ActivityThread mSystemThread;
    819 
    820     private final class AppDeathRecipient implements IBinder.DeathRecipient {
    821         final ProcessRecord mApp;
    822         final int mPid;
    823         final IApplicationThread mAppThread;
    824 
    825         AppDeathRecipient(ProcessRecord app, int pid,
    826                 IApplicationThread thread) {
    827             if (localLOGV) Slog.v(
    828                 TAG, "New death recipient " + this
    829                 + " for thread " + thread.asBinder());
    830             mApp = app;
    831             mPid = pid;
    832             mAppThread = thread;
    833         }
    834 
    835         public void binderDied() {
    836             if (localLOGV) Slog.v(
    837                 TAG, "Death received in " + this
    838                 + " for thread " + mAppThread.asBinder());
    839             synchronized(ActivityManagerService.this) {
    840                 appDiedLocked(mApp, mPid, mAppThread);
    841             }
    842         }
    843     }
    844 
    845     static final int SHOW_ERROR_MSG = 1;
    846     static final int SHOW_NOT_RESPONDING_MSG = 2;
    847     static final int SHOW_FACTORY_ERROR_MSG = 3;
    848     static final int UPDATE_CONFIGURATION_MSG = 4;
    849     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
    850     static final int WAIT_FOR_DEBUGGER_MSG = 6;
    851     static final int BROADCAST_INTENT_MSG = 7;
    852     static final int BROADCAST_TIMEOUT_MSG = 8;
    853     static final int SERVICE_TIMEOUT_MSG = 12;
    854     static final int UPDATE_TIME_ZONE = 13;
    855     static final int SHOW_UID_ERROR_MSG = 14;
    856     static final int IM_FEELING_LUCKY_MSG = 15;
    857     static final int PROC_START_TIMEOUT_MSG = 20;
    858     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
    859     static final int KILL_APPLICATION_MSG = 22;
    860     static final int FINALIZE_PENDING_INTENT_MSG = 23;
    861     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
    862     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
    863     static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
    864     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
    865     static final int CLEAR_DNS_CACHE = 28;
    866     static final int UPDATE_HTTP_PROXY = 29;
    867     static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
    868     static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
    869     static final int DISPATCH_PROCESS_DIED = 32;
    870     static final int REPORT_MEM_USAGE = 33;
    871 
    872     AlertDialog mUidAlert;
    873     CompatModeDialog mCompatModeDialog;
    874     long mLastMemUsageReportTime = 0;
    875 
    876     final Handler mHandler = new Handler() {
    877         //public Handler() {
    878         //    if (localLOGV) Slog.v(TAG, "Handler started!");
    879         //}
    880 
    881         public void handleMessage(Message msg) {
    882             switch (msg.what) {
    883             case SHOW_ERROR_MSG: {
    884                 HashMap data = (HashMap) msg.obj;
    885                 synchronized (ActivityManagerService.this) {
    886                     ProcessRecord proc = (ProcessRecord)data.get("app");
    887                     if (proc != null && proc.crashDialog != null) {
    888                         Slog.e(TAG, "App already has crash dialog: " + proc);
    889                         return;
    890                     }
    891                     AppErrorResult res = (AppErrorResult) data.get("result");
    892                     if (!mSleeping && !mShuttingDown) {
    893                         Dialog d = new AppErrorDialog(mContext, res, proc);
    894                         d.show();
    895                         proc.crashDialog = d;
    896                     } else {
    897                         // The device is asleep, so just pretend that the user
    898                         // saw a crash dialog and hit "force quit".
    899                         res.set(0);
    900                     }
    901                 }
    902 
    903                 ensureBootCompleted();
    904             } break;
    905             case SHOW_NOT_RESPONDING_MSG: {
    906                 synchronized (ActivityManagerService.this) {
    907                     HashMap data = (HashMap) msg.obj;
    908                     ProcessRecord proc = (ProcessRecord)data.get("app");
    909                     if (proc != null && proc.anrDialog != null) {
    910                         Slog.e(TAG, "App already has anr dialog: " + proc);
    911                         return;
    912                     }
    913 
    914                     Intent intent = new Intent("android.intent.action.ANR");
    915                     if (!mProcessesReady) {
    916                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
    917                     }
    918                     broadcastIntentLocked(null, null, intent,
    919                             null, null, 0, null, null, null,
    920                             false, false, MY_PID, Process.SYSTEM_UID);
    921 
    922                     Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
    923                             mContext, proc, (ActivityRecord)data.get("activity"));
    924                     d.show();
    925                     proc.anrDialog = d;
    926                 }
    927 
    928                 ensureBootCompleted();
    929             } break;
    930             case SHOW_STRICT_MODE_VIOLATION_MSG: {
    931                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
    932                 synchronized (ActivityManagerService.this) {
    933                     ProcessRecord proc = (ProcessRecord) data.get("app");
    934                     if (proc == null) {
    935                         Slog.e(TAG, "App not found when showing strict mode dialog.");
    936                         break;
    937                     }
    938                     if (proc.crashDialog != null) {
    939                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
    940                         return;
    941                     }
    942                     AppErrorResult res = (AppErrorResult) data.get("result");
    943                     if (!mSleeping && !mShuttingDown) {
    944                         Dialog d = new StrictModeViolationDialog(mContext, res, proc);
    945                         d.show();
    946                         proc.crashDialog = d;
    947                     } else {
    948                         // The device is asleep, so just pretend that the user
    949                         // saw a crash dialog and hit "force quit".
    950                         res.set(0);
    951                     }
    952                 }
    953                 ensureBootCompleted();
    954             } break;
    955             case SHOW_FACTORY_ERROR_MSG: {
    956                 Dialog d = new FactoryErrorDialog(
    957                     mContext, msg.getData().getCharSequence("msg"));
    958                 d.show();
    959                 ensureBootCompleted();
    960             } break;
    961             case UPDATE_CONFIGURATION_MSG: {
    962                 final ContentResolver resolver = mContext.getContentResolver();
    963                 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
    964             } break;
    965             case GC_BACKGROUND_PROCESSES_MSG: {
    966                 synchronized (ActivityManagerService.this) {
    967                     performAppGcsIfAppropriateLocked();
    968                 }
    969             } break;
    970             case WAIT_FOR_DEBUGGER_MSG: {
    971                 synchronized (ActivityManagerService.this) {
    972                     ProcessRecord app = (ProcessRecord)msg.obj;
    973                     if (msg.arg1 != 0) {
    974                         if (!app.waitedForDebugger) {
    975                             Dialog d = new AppWaitingForDebuggerDialog(
    976                                     ActivityManagerService.this,
    977                                     mContext, app);
    978                             app.waitDialog = d;
    979                             app.waitedForDebugger = true;
    980                             d.show();
    981                         }
    982                     } else {
    983                         if (app.waitDialog != null) {
    984                             app.waitDialog.dismiss();
    985                             app.waitDialog = null;
    986                         }
    987                     }
    988                 }
    989             } break;
    990             case BROADCAST_INTENT_MSG: {
    991                 if (DEBUG_BROADCAST) Slog.v(
    992                         TAG, "Received BROADCAST_INTENT_MSG");
    993                 processNextBroadcast(true);
    994             } break;
    995             case BROADCAST_TIMEOUT_MSG: {
    996                 synchronized (ActivityManagerService.this) {
    997                     broadcastTimeoutLocked(true);
    998                 }
    999             } break;
   1000             case SERVICE_TIMEOUT_MSG: {
   1001                 if (mDidDexOpt) {
   1002                     mDidDexOpt = false;
   1003                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   1004                     nmsg.obj = msg.obj;
   1005                     mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
   1006                     return;
   1007                 }
   1008                 serviceTimeout((ProcessRecord)msg.obj);
   1009             } break;
   1010             case UPDATE_TIME_ZONE: {
   1011                 synchronized (ActivityManagerService.this) {
   1012                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1013                         ProcessRecord r = mLruProcesses.get(i);
   1014                         if (r.thread != null) {
   1015                             try {
   1016                                 r.thread.updateTimeZone();
   1017                             } catch (RemoteException ex) {
   1018                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
   1019                             }
   1020                         }
   1021                     }
   1022                 }
   1023             } break;
   1024             case CLEAR_DNS_CACHE: {
   1025                 synchronized (ActivityManagerService.this) {
   1026                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1027                         ProcessRecord r = mLruProcesses.get(i);
   1028                         if (r.thread != null) {
   1029                             try {
   1030                                 r.thread.clearDnsCache();
   1031                             } catch (RemoteException ex) {
   1032                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
   1033                             }
   1034                         }
   1035                     }
   1036                 }
   1037             } break;
   1038             case UPDATE_HTTP_PROXY: {
   1039                 ProxyProperties proxy = (ProxyProperties)msg.obj;
   1040                 String host = "";
   1041                 String port = "";
   1042                 String exclList = "";
   1043                 if (proxy != null) {
   1044                     host = proxy.getHost();
   1045                     port = Integer.toString(proxy.getPort());
   1046                     exclList = proxy.getExclusionList();
   1047                 }
   1048                 synchronized (ActivityManagerService.this) {
   1049                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1050                         ProcessRecord r = mLruProcesses.get(i);
   1051                         if (r.thread != null) {
   1052                             try {
   1053                                 r.thread.setHttpProxy(host, port, exclList);
   1054                             } catch (RemoteException ex) {
   1055                                 Slog.w(TAG, "Failed to update http proxy for: " +
   1056                                         r.info.processName);
   1057                             }
   1058                         }
   1059                     }
   1060                 }
   1061             } break;
   1062             case SHOW_UID_ERROR_MSG: {
   1063                 // XXX This is a temporary dialog, no need to localize.
   1064                 AlertDialog d = new BaseErrorDialog(mContext);
   1065                 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
   1066                 d.setCancelable(false);
   1067                 d.setTitle("System UIDs Inconsistent");
   1068                 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
   1069                 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
   1070                         mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
   1071                 mUidAlert = d;
   1072                 d.show();
   1073             } break;
   1074             case IM_FEELING_LUCKY_MSG: {
   1075                 if (mUidAlert != null) {
   1076                     mUidAlert.dismiss();
   1077                     mUidAlert = null;
   1078                 }
   1079             } break;
   1080             case PROC_START_TIMEOUT_MSG: {
   1081                 if (mDidDexOpt) {
   1082                     mDidDexOpt = false;
   1083                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   1084                     nmsg.obj = msg.obj;
   1085                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
   1086                     return;
   1087                 }
   1088                 ProcessRecord app = (ProcessRecord)msg.obj;
   1089                 synchronized (ActivityManagerService.this) {
   1090                     processStartTimedOutLocked(app);
   1091                 }
   1092             } break;
   1093             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
   1094                 synchronized (ActivityManagerService.this) {
   1095                     doPendingActivityLaunchesLocked(true);
   1096                 }
   1097             } break;
   1098             case KILL_APPLICATION_MSG: {
   1099                 synchronized (ActivityManagerService.this) {
   1100                     int uid = msg.arg1;
   1101                     boolean restart = (msg.arg2 == 1);
   1102                     String pkg = (String) msg.obj;
   1103                     forceStopPackageLocked(pkg, uid, restart, false, true, false);
   1104                 }
   1105             } break;
   1106             case FINALIZE_PENDING_INTENT_MSG: {
   1107                 ((PendingIntentRecord)msg.obj).completeFinalize();
   1108             } break;
   1109             case POST_HEAVY_NOTIFICATION_MSG: {
   1110                 INotificationManager inm = NotificationManager.getService();
   1111                 if (inm == null) {
   1112                     return;
   1113                 }
   1114 
   1115                 ActivityRecord root = (ActivityRecord)msg.obj;
   1116                 ProcessRecord process = root.app;
   1117                 if (process == null) {
   1118                     return;
   1119                 }
   1120 
   1121                 try {
   1122                     Context context = mContext.createPackageContext(process.info.packageName, 0);
   1123                     String text = mContext.getString(R.string.heavy_weight_notification,
   1124                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
   1125                     Notification notification = new Notification();
   1126                     notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
   1127                     notification.when = 0;
   1128                     notification.flags = Notification.FLAG_ONGOING_EVENT;
   1129                     notification.tickerText = text;
   1130                     notification.defaults = 0; // please be quiet
   1131                     notification.sound = null;
   1132                     notification.vibrate = null;
   1133                     notification.setLatestEventInfo(context, text,
   1134                             mContext.getText(R.string.heavy_weight_notification_detail),
   1135                             PendingIntent.getActivity(mContext, 0, root.intent,
   1136                                     PendingIntent.FLAG_CANCEL_CURRENT));
   1137 
   1138                     try {
   1139                         int[] outId = new int[1];
   1140                         inm.enqueueNotification("android", R.string.heavy_weight_notification,
   1141                                 notification, outId);
   1142                     } catch (RuntimeException e) {
   1143                         Slog.w(ActivityManagerService.TAG,
   1144                                 "Error showing notification for heavy-weight app", e);
   1145                     } catch (RemoteException e) {
   1146                     }
   1147                 } catch (NameNotFoundException e) {
   1148                     Slog.w(TAG, "Unable to create context for heavy notification", e);
   1149                 }
   1150             } break;
   1151             case CANCEL_HEAVY_NOTIFICATION_MSG: {
   1152                 INotificationManager inm = NotificationManager.getService();
   1153                 if (inm == null) {
   1154                     return;
   1155                 }
   1156                 try {
   1157                     inm.cancelNotification("android",
   1158                             R.string.heavy_weight_notification);
   1159                 } catch (RuntimeException e) {
   1160                     Slog.w(ActivityManagerService.TAG,
   1161                             "Error canceling notification for service", e);
   1162                 } catch (RemoteException e) {
   1163                 }
   1164             } break;
   1165             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
   1166                 synchronized (ActivityManagerService.this) {
   1167                     checkExcessivePowerUsageLocked(true);
   1168                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1169                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1170                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   1171                 }
   1172             } break;
   1173             case SHOW_COMPAT_MODE_DIALOG_MSG: {
   1174                 synchronized (ActivityManagerService.this) {
   1175                     ActivityRecord ar = (ActivityRecord)msg.obj;
   1176                     if (mCompatModeDialog != null) {
   1177                         if (mCompatModeDialog.mAppInfo.packageName.equals(
   1178                                 ar.info.applicationInfo.packageName)) {
   1179                             return;
   1180                         }
   1181                         mCompatModeDialog.dismiss();
   1182                         mCompatModeDialog = null;
   1183                     }
   1184                     if (ar != null && false) {
   1185                         if (mCompatModePackages.getPackageAskCompatModeLocked(
   1186                                 ar.packageName)) {
   1187                             int mode = mCompatModePackages.computeCompatModeLocked(
   1188                                     ar.info.applicationInfo);
   1189                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
   1190                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
   1191                                 mCompatModeDialog = new CompatModeDialog(
   1192                                         ActivityManagerService.this, mContext,
   1193                                         ar.info.applicationInfo);
   1194                                 mCompatModeDialog.show();
   1195                             }
   1196                         }
   1197                     }
   1198                 }
   1199                 break;
   1200             }
   1201             case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
   1202                 final int pid = msg.arg1;
   1203                 final int uid = msg.arg2;
   1204                 final boolean foregroundActivities = (Boolean) msg.obj;
   1205                 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
   1206                 break;
   1207             }
   1208             case DISPATCH_PROCESS_DIED: {
   1209                 final int pid = msg.arg1;
   1210                 final int uid = msg.arg2;
   1211                 dispatchProcessDied(pid, uid);
   1212                 break;
   1213             }
   1214             case REPORT_MEM_USAGE: {
   1215                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   1216                 if (!isDebuggable) {
   1217                     return;
   1218                 }
   1219                 synchronized (ActivityManagerService.this) {
   1220                     long now = SystemClock.uptimeMillis();
   1221                     if (now < (mLastMemUsageReportTime+5*60*1000)) {
   1222                         // Don't report more than every 5 minutes to somewhat
   1223                         // avoid spamming.
   1224                         return;
   1225                     }
   1226                     mLastMemUsageReportTime = now;
   1227                 }
   1228                 Thread thread = new Thread() {
   1229                     @Override public void run() {
   1230                         StringBuilder dropBuilder = new StringBuilder(1024);
   1231                         StringBuilder logBuilder = new StringBuilder(1024);
   1232                         StringWriter oomSw = new StringWriter();
   1233                         PrintWriter oomPw = new PrintWriter(oomSw);
   1234                         StringWriter catSw = new StringWriter();
   1235                         PrintWriter catPw = new PrintWriter(catSw);
   1236                         String[] emptyArgs = new String[] { };
   1237                         StringBuilder tag = new StringBuilder(128);
   1238                         StringBuilder stack = new StringBuilder(128);
   1239                         tag.append("Low on memory -- ");
   1240                         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
   1241                                 tag, stack);
   1242                         dropBuilder.append(stack);
   1243                         dropBuilder.append('\n');
   1244                         dropBuilder.append('\n');
   1245                         String oomString = oomSw.toString();
   1246                         dropBuilder.append(oomString);
   1247                         dropBuilder.append('\n');
   1248                         logBuilder.append(oomString);
   1249                         try {
   1250                             java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
   1251                                     "procrank", });
   1252                             final InputStreamReader converter = new InputStreamReader(
   1253                                     proc.getInputStream());
   1254                             BufferedReader in = new BufferedReader(converter);
   1255                             String line;
   1256                             while (true) {
   1257                                 line = in.readLine();
   1258                                 if (line == null) {
   1259                                     break;
   1260                                 }
   1261                                 if (line.length() > 0) {
   1262                                     logBuilder.append(line);
   1263                                     logBuilder.append('\n');
   1264                                 }
   1265                                 dropBuilder.append(line);
   1266                                 dropBuilder.append('\n');
   1267                             }
   1268                             converter.close();
   1269                         } catch (IOException e) {
   1270                         }
   1271                         synchronized (ActivityManagerService.this) {
   1272                             catPw.println();
   1273                             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
   1274                             catPw.println();
   1275                             dumpServicesLocked(null, catPw, emptyArgs, 0, false, false, null);
   1276                             catPw.println();
   1277                             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
   1278                         }
   1279                         dropBuilder.append(catSw.toString());
   1280                         addErrorToDropBox("lowmem", null, "system_server", null,
   1281                                 null, tag.toString(), dropBuilder.toString(), null, null);
   1282                         Slog.i(TAG, logBuilder.toString());
   1283                         synchronized (ActivityManagerService.this) {
   1284                             long now = SystemClock.uptimeMillis();
   1285                             if (mLastMemUsageReportTime < now) {
   1286                                 mLastMemUsageReportTime = now;
   1287                             }
   1288                         }
   1289                     }
   1290                 };
   1291                 thread.start();
   1292                 break;
   1293             }
   1294             }
   1295         }
   1296     };
   1297 
   1298     public static void setSystemProcess() {
   1299         try {
   1300             ActivityManagerService m = mSelf;
   1301 
   1302             ServiceManager.addService("activity", m);
   1303             ServiceManager.addService("meminfo", new MemBinder(m));
   1304             ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
   1305             if (MONITOR_CPU_USAGE) {
   1306                 ServiceManager.addService("cpuinfo", new CpuBinder(m));
   1307             }
   1308             ServiceManager.addService("permission", new PermissionController(m));
   1309 
   1310             ApplicationInfo info =
   1311                 mSelf.mContext.getPackageManager().getApplicationInfo(
   1312                         "android", STOCK_PM_FLAGS);
   1313             mSystemThread.installSystemApplicationInfo(info);
   1314 
   1315             synchronized (mSelf) {
   1316                 ProcessRecord app = mSelf.newProcessRecordLocked(
   1317                         mSystemThread.getApplicationThread(), info,
   1318                         info.processName);
   1319                 app.persistent = true;
   1320                 app.pid = MY_PID;
   1321                 app.maxAdj = ProcessList.SYSTEM_ADJ;
   1322                 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
   1323                 synchronized (mSelf.mPidsSelfLocked) {
   1324                     mSelf.mPidsSelfLocked.put(app.pid, app);
   1325                 }
   1326                 mSelf.updateLruProcessLocked(app, true, true);
   1327             }
   1328         } catch (PackageManager.NameNotFoundException e) {
   1329             throw new RuntimeException(
   1330                     "Unable to find android system package", e);
   1331         }
   1332     }
   1333 
   1334     public void setWindowManager(WindowManagerService wm) {
   1335         mWindowManager = wm;
   1336     }
   1337 
   1338     public static final Context main(int factoryTest) {
   1339         AThread thr = new AThread();
   1340         thr.start();
   1341 
   1342         synchronized (thr) {
   1343             while (thr.mService == null) {
   1344                 try {
   1345                     thr.wait();
   1346                 } catch (InterruptedException e) {
   1347                 }
   1348             }
   1349         }
   1350 
   1351         ActivityManagerService m = thr.mService;
   1352         mSelf = m;
   1353         ActivityThread at = ActivityThread.systemMain();
   1354         mSystemThread = at;
   1355         Context context = at.getSystemContext();
   1356         context.setTheme(android.R.style.Theme_Holo);
   1357         m.mContext = context;
   1358         m.mFactoryTest = factoryTest;
   1359         m.mMainStack = new ActivityStack(m, context, true);
   1360 
   1361         m.mBatteryStatsService.publish(context);
   1362         m.mUsageStatsService.publish(context);
   1363 
   1364         synchronized (thr) {
   1365             thr.mReady = true;
   1366             thr.notifyAll();
   1367         }
   1368 
   1369         m.startRunning(null, null, null, null);
   1370 
   1371         return context;
   1372     }
   1373 
   1374     public static ActivityManagerService self() {
   1375         return mSelf;
   1376     }
   1377 
   1378     static class AThread extends Thread {
   1379         ActivityManagerService mService;
   1380         boolean mReady = false;
   1381 
   1382         public AThread() {
   1383             super("ActivityManager");
   1384         }
   1385 
   1386         public void run() {
   1387             Looper.prepare();
   1388 
   1389             android.os.Process.setThreadPriority(
   1390                     android.os.Process.THREAD_PRIORITY_FOREGROUND);
   1391             android.os.Process.setCanSelfBackground(false);
   1392 
   1393             ActivityManagerService m = new ActivityManagerService();
   1394 
   1395             synchronized (this) {
   1396                 mService = m;
   1397                 notifyAll();
   1398             }
   1399 
   1400             synchronized (this) {
   1401                 while (!mReady) {
   1402                     try {
   1403                         wait();
   1404                     } catch (InterruptedException e) {
   1405                     }
   1406                 }
   1407             }
   1408 
   1409             // For debug builds, log event loop stalls to dropbox for analysis.
   1410             if (StrictMode.conditionallyEnableDebugLogging()) {
   1411                 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
   1412             }
   1413 
   1414             Looper.loop();
   1415         }
   1416     }
   1417 
   1418     static class MemBinder extends Binder {
   1419         ActivityManagerService mActivityManagerService;
   1420         MemBinder(ActivityManagerService activityManagerService) {
   1421             mActivityManagerService = activityManagerService;
   1422         }
   1423 
   1424         @Override
   1425         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1426             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1427                     != PackageManager.PERMISSION_GRANTED) {
   1428                 pw.println("Permission Denial: can't dump meminfo from from pid="
   1429                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1430                         + " without permission " + android.Manifest.permission.DUMP);
   1431                 return;
   1432             }
   1433 
   1434             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
   1435                     false, null, null, null);
   1436         }
   1437     }
   1438 
   1439     static class GraphicsBinder extends Binder {
   1440         ActivityManagerService mActivityManagerService;
   1441         GraphicsBinder(ActivityManagerService activityManagerService) {
   1442             mActivityManagerService = activityManagerService;
   1443         }
   1444 
   1445         @Override
   1446         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1447             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1448                     != PackageManager.PERMISSION_GRANTED) {
   1449                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
   1450                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1451                         + " without permission " + android.Manifest.permission.DUMP);
   1452                 return;
   1453             }
   1454 
   1455             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
   1456         }
   1457     }
   1458 
   1459     static class CpuBinder extends Binder {
   1460         ActivityManagerService mActivityManagerService;
   1461         CpuBinder(ActivityManagerService activityManagerService) {
   1462             mActivityManagerService = activityManagerService;
   1463         }
   1464 
   1465         @Override
   1466         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1467             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1468                     != PackageManager.PERMISSION_GRANTED) {
   1469                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
   1470                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1471                         + " without permission " + android.Manifest.permission.DUMP);
   1472                 return;
   1473             }
   1474 
   1475             synchronized (mActivityManagerService.mProcessStatsThread) {
   1476                 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
   1477                 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
   1478                         SystemClock.uptimeMillis()));
   1479             }
   1480         }
   1481     }
   1482 
   1483     private ActivityManagerService() {
   1484         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
   1485 
   1486         File dataDir = Environment.getDataDirectory();
   1487         File systemDir = new File(dataDir, "system");
   1488         systemDir.mkdirs();
   1489         mBatteryStatsService = new BatteryStatsService(new File(
   1490                 systemDir, "batterystats.bin").toString());
   1491         mBatteryStatsService.getActiveStatistics().readLocked();
   1492         mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
   1493         mOnBattery = DEBUG_POWER ? true
   1494                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
   1495         mBatteryStatsService.getActiveStatistics().setCallback(this);
   1496 
   1497         mUsageStatsService = new UsageStatsService(new File(
   1498                 systemDir, "usagestats").toString());
   1499 
   1500         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
   1501             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
   1502 
   1503         mConfiguration.setToDefaults();
   1504         mConfiguration.locale = Locale.getDefault();
   1505         mConfigurationSeq = mConfiguration.seq = 1;
   1506         mProcessStats.init();
   1507 
   1508         mCompatModePackages = new CompatModePackages(this, systemDir);
   1509 
   1510         // Add ourself to the Watchdog monitors.
   1511         Watchdog.getInstance().addMonitor(this);
   1512 
   1513         mProcessStatsThread = new Thread("ProcessStats") {
   1514             public void run() {
   1515                 while (true) {
   1516                     try {
   1517                         try {
   1518                             synchronized(this) {
   1519                                 final long now = SystemClock.uptimeMillis();
   1520                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
   1521                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
   1522                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
   1523                                 //        + ", write delay=" + nextWriteDelay);
   1524                                 if (nextWriteDelay < nextCpuDelay) {
   1525                                     nextCpuDelay = nextWriteDelay;
   1526                                 }
   1527                                 if (nextCpuDelay > 0) {
   1528                                     mProcessStatsMutexFree.set(true);
   1529                                     this.wait(nextCpuDelay);
   1530                                 }
   1531                             }
   1532                         } catch (InterruptedException e) {
   1533                         }
   1534                         updateCpuStatsNow();
   1535                     } catch (Exception e) {
   1536                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
   1537                     }
   1538                 }
   1539             }
   1540         };
   1541         mProcessStatsThread.start();
   1542     }
   1543 
   1544     @Override
   1545     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   1546             throws RemoteException {
   1547         try {
   1548             return super.onTransact(code, data, reply, flags);
   1549         } catch (RuntimeException e) {
   1550             // The activity manager only throws security exceptions, so let's
   1551             // log all others.
   1552             if (!(e instanceof SecurityException)) {
   1553                 Slog.e(TAG, "Activity Manager Crash", e);
   1554             }
   1555             throw e;
   1556         }
   1557     }
   1558 
   1559     void updateCpuStats() {
   1560         final long now = SystemClock.uptimeMillis();
   1561         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
   1562             return;
   1563         }
   1564         if (mProcessStatsMutexFree.compareAndSet(true, false)) {
   1565             synchronized (mProcessStatsThread) {
   1566                 mProcessStatsThread.notify();
   1567             }
   1568         }
   1569     }
   1570 
   1571     void updateCpuStatsNow() {
   1572         synchronized (mProcessStatsThread) {
   1573             mProcessStatsMutexFree.set(false);
   1574             final long now = SystemClock.uptimeMillis();
   1575             boolean haveNewCpuStats = false;
   1576 
   1577             if (MONITOR_CPU_USAGE &&
   1578                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
   1579                 mLastCpuTime.set(now);
   1580                 haveNewCpuStats = true;
   1581                 mProcessStats.update();
   1582                 //Slog.i(TAG, mProcessStats.printCurrentState());
   1583                 //Slog.i(TAG, "Total CPU usage: "
   1584                 //        + mProcessStats.getTotalCpuPercent() + "%");
   1585 
   1586                 // Slog the cpu usage if the property is set.
   1587                 if ("true".equals(SystemProperties.get("events.cpu"))) {
   1588                     int user = mProcessStats.getLastUserTime();
   1589                     int system = mProcessStats.getLastSystemTime();
   1590                     int iowait = mProcessStats.getLastIoWaitTime();
   1591                     int irq = mProcessStats.getLastIrqTime();
   1592                     int softIrq = mProcessStats.getLastSoftIrqTime();
   1593                     int idle = mProcessStats.getLastIdleTime();
   1594 
   1595                     int total = user + system + iowait + irq + softIrq + idle;
   1596                     if (total == 0) total = 1;
   1597 
   1598                     EventLog.writeEvent(EventLogTags.CPU,
   1599                             ((user+system+iowait+irq+softIrq) * 100) / total,
   1600                             (user * 100) / total,
   1601                             (system * 100) / total,
   1602                             (iowait * 100) / total,
   1603                             (irq * 100) / total,
   1604                             (softIrq * 100) / total);
   1605                 }
   1606             }
   1607 
   1608             long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
   1609             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
   1610             synchronized(bstats) {
   1611                 synchronized(mPidsSelfLocked) {
   1612                     if (haveNewCpuStats) {
   1613                         if (mOnBattery) {
   1614                             int perc = bstats.startAddingCpuLocked();
   1615                             int totalUTime = 0;
   1616                             int totalSTime = 0;
   1617                             final int N = mProcessStats.countStats();
   1618                             for (int i=0; i<N; i++) {
   1619                                 ProcessStats.Stats st = mProcessStats.getStats(i);
   1620                                 if (!st.working) {
   1621                                     continue;
   1622                                 }
   1623                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
   1624                                 int otherUTime = (st.rel_utime*perc)/100;
   1625                                 int otherSTime = (st.rel_stime*perc)/100;
   1626                                 totalUTime += otherUTime;
   1627                                 totalSTime += otherSTime;
   1628                                 if (pr != null) {
   1629                                     BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
   1630                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
   1631                                             st.rel_stime-otherSTime);
   1632                                     ps.addSpeedStepTimes(cpuSpeedTimes);
   1633                                     pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
   1634                                 } else {
   1635                                     BatteryStatsImpl.Uid.Proc ps =
   1636                                             bstats.getProcessStatsLocked(st.name, st.pid);
   1637                                     if (ps != null) {
   1638                                         ps.addCpuTimeLocked(st.rel_utime-otherUTime,
   1639                                                 st.rel_stime-otherSTime);
   1640                                         ps.addSpeedStepTimes(cpuSpeedTimes);
   1641                                     }
   1642                                 }
   1643                             }
   1644                             bstats.finishAddingCpuLocked(perc, totalUTime,
   1645                                     totalSTime, cpuSpeedTimes);
   1646                         }
   1647                     }
   1648                 }
   1649 
   1650                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
   1651                     mLastWriteTime = now;
   1652                     mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
   1653                 }
   1654             }
   1655         }
   1656     }
   1657 
   1658     @Override
   1659     public void batteryNeedsCpuUpdate() {
   1660         updateCpuStatsNow();
   1661     }
   1662 
   1663     @Override
   1664     public void batteryPowerChanged(boolean onBattery) {
   1665         // When plugging in, update the CPU stats first before changing
   1666         // the plug state.
   1667         updateCpuStatsNow();
   1668         synchronized (this) {
   1669             synchronized(mPidsSelfLocked) {
   1670                 mOnBattery = DEBUG_POWER ? true : onBattery;
   1671             }
   1672         }
   1673     }
   1674 
   1675     /**
   1676      * Initialize the application bind args. These are passed to each
   1677      * process when the bindApplication() IPC is sent to the process. They're
   1678      * lazily setup to make sure the services are running when they're asked for.
   1679      */
   1680     private HashMap<String, IBinder> getCommonServicesLocked() {
   1681         if (mAppBindArgs == null) {
   1682             mAppBindArgs = new HashMap<String, IBinder>();
   1683 
   1684             // Setup the application init args
   1685             mAppBindArgs.put("package", ServiceManager.getService("package"));
   1686             mAppBindArgs.put("window", ServiceManager.getService("window"));
   1687             mAppBindArgs.put(Context.ALARM_SERVICE,
   1688                     ServiceManager.getService(Context.ALARM_SERVICE));
   1689         }
   1690         return mAppBindArgs;
   1691     }
   1692 
   1693     final void setFocusedActivityLocked(ActivityRecord r) {
   1694         if (mFocusedActivity != r) {
   1695             mFocusedActivity = r;
   1696             if (r != null) {
   1697                 mWindowManager.setFocusedApp(r.appToken, true);
   1698             }
   1699         }
   1700     }
   1701 
   1702     private final void updateLruProcessInternalLocked(ProcessRecord app,
   1703             boolean oomAdj, boolean updateActivityTime, int bestPos) {
   1704         // put it on the LRU to keep track of when it should be exited.
   1705         int lrui = mLruProcesses.indexOf(app);
   1706         if (lrui >= 0) mLruProcesses.remove(lrui);
   1707 
   1708         int i = mLruProcesses.size()-1;
   1709         int skipTop = 0;
   1710 
   1711         app.lruSeq = mLruSeq;
   1712 
   1713         // compute the new weight for this process.
   1714         if (updateActivityTime) {
   1715             app.lastActivityTime = SystemClock.uptimeMillis();
   1716         }
   1717         if (app.activities.size() > 0) {
   1718             // If this process has activities, we more strongly want to keep
   1719             // it around.
   1720             app.lruWeight = app.lastActivityTime;
   1721         } else if (app.pubProviders.size() > 0) {
   1722             // If this process contains content providers, we want to keep
   1723             // it a little more strongly.
   1724             app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
   1725             // Also don't let it kick out the first few "real" hidden processes.
   1726             skipTop = ProcessList.MIN_HIDDEN_APPS;
   1727         } else {
   1728             // If this process doesn't have activities, we less strongly
   1729             // want to keep it around, and generally want to avoid getting
   1730             // in front of any very recently used activities.
   1731             app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
   1732             // Also don't let it kick out the first few "real" hidden processes.
   1733             skipTop = ProcessList.MIN_HIDDEN_APPS;
   1734         }
   1735 
   1736         while (i >= 0) {
   1737             ProcessRecord p = mLruProcesses.get(i);
   1738             // If this app shouldn't be in front of the first N background
   1739             // apps, then skip over that many that are currently hidden.
   1740             if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   1741                 skipTop--;
   1742             }
   1743             if (p.lruWeight <= app.lruWeight || i < bestPos) {
   1744                 mLruProcesses.add(i+1, app);
   1745                 break;
   1746             }
   1747             i--;
   1748         }
   1749         if (i < 0) {
   1750             mLruProcesses.add(0, app);
   1751         }
   1752 
   1753         // If the app is currently using a content provider or service,
   1754         // bump those processes as well.
   1755         if (app.connections.size() > 0) {
   1756             for (ConnectionRecord cr : app.connections) {
   1757                 if (cr.binding != null && cr.binding.service != null
   1758                         && cr.binding.service.app != null
   1759                         && cr.binding.service.app.lruSeq != mLruSeq) {
   1760                     updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
   1761                             updateActivityTime, i+1);
   1762                 }
   1763             }
   1764         }
   1765         if (app.conProviders.size() > 0) {
   1766             for (ContentProviderRecord cpr : app.conProviders.keySet()) {
   1767                 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
   1768                     updateLruProcessInternalLocked(cpr.proc, oomAdj,
   1769                             updateActivityTime, i+1);
   1770                 }
   1771             }
   1772         }
   1773 
   1774         //Slog.i(TAG, "Putting proc to front: " + app.processName);
   1775         if (oomAdj) {
   1776             updateOomAdjLocked();
   1777         }
   1778     }
   1779 
   1780     final void updateLruProcessLocked(ProcessRecord app,
   1781             boolean oomAdj, boolean updateActivityTime) {
   1782         mLruSeq++;
   1783         updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
   1784     }
   1785 
   1786     final ProcessRecord getProcessRecordLocked(
   1787             String processName, int uid) {
   1788         if (uid == Process.SYSTEM_UID) {
   1789             // The system gets to run in any process.  If there are multiple
   1790             // processes with the same uid, just pick the first (this
   1791             // should never happen).
   1792             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
   1793                     processName);
   1794             return procs != null ? procs.valueAt(0) : null;
   1795         }
   1796         ProcessRecord proc = mProcessNames.get(processName, uid);
   1797         return proc;
   1798     }
   1799 
   1800     void ensurePackageDexOpt(String packageName) {
   1801         IPackageManager pm = AppGlobals.getPackageManager();
   1802         try {
   1803             if (pm.performDexOpt(packageName)) {
   1804                 mDidDexOpt = true;
   1805             }
   1806         } catch (RemoteException e) {
   1807         }
   1808     }
   1809 
   1810     boolean isNextTransitionForward() {
   1811         int transit = mWindowManager.getPendingAppTransition();
   1812         return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
   1813                 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
   1814                 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
   1815     }
   1816 
   1817     final ProcessRecord startProcessLocked(String processName,
   1818             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
   1819             String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
   1820         ProcessRecord app = getProcessRecordLocked(processName, info.uid);
   1821         // We don't have to do anything more if:
   1822         // (1) There is an existing application record; and
   1823         // (2) The caller doesn't think it is dead, OR there is no thread
   1824         //     object attached to it so we know it couldn't have crashed; and
   1825         // (3) There is a pid assigned to it, so it is either starting or
   1826         //     already running.
   1827         if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
   1828                 + " app=" + app + " knownToBeDead=" + knownToBeDead
   1829                 + " thread=" + (app != null ? app.thread : null)
   1830                 + " pid=" + (app != null ? app.pid : -1));
   1831         if (app != null && app.pid > 0) {
   1832             if (!knownToBeDead || app.thread == null) {
   1833                 // We already have the app running, or are waiting for it to
   1834                 // come up (we have a pid but not yet its thread), so keep it.
   1835                 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
   1836                 // If this is a new package in the process, add the package to the list
   1837                 app.addPackage(info.packageName);
   1838                 return app;
   1839             } else {
   1840                 // An application record is attached to a previous process,
   1841                 // clean it up now.
   1842                 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
   1843                 handleAppDiedLocked(app, true, true);
   1844             }
   1845         }
   1846 
   1847         String hostingNameStr = hostingName != null
   1848                 ? hostingName.flattenToShortString() : null;
   1849 
   1850         if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
   1851             // If we are in the background, then check to see if this process
   1852             // is bad.  If so, we will just silently fail.
   1853             if (mBadProcesses.get(info.processName, info.uid) != null) {
   1854                 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
   1855                         + "/" + info.processName);
   1856                 return null;
   1857             }
   1858         } else {
   1859             // When the user is explicitly starting a process, then clear its
   1860             // crash count so that we won't make it bad until they see at
   1861             // least one crash dialog again, and make the process good again
   1862             // if it had been bad.
   1863             if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
   1864                     + "/" + info.processName);
   1865             mProcessCrashTimes.remove(info.processName, info.uid);
   1866             if (mBadProcesses.get(info.processName, info.uid) != null) {
   1867                 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
   1868                         info.processName);
   1869                 mBadProcesses.remove(info.processName, info.uid);
   1870                 if (app != null) {
   1871                     app.bad = false;
   1872                 }
   1873             }
   1874         }
   1875 
   1876         if (app == null) {
   1877             app = newProcessRecordLocked(null, info, processName);
   1878             mProcessNames.put(processName, info.uid, app);
   1879         } else {
   1880             // If this is a new package in the process, add the package to the list
   1881             app.addPackage(info.packageName);
   1882         }
   1883 
   1884         // If the system is not ready yet, then hold off on starting this
   1885         // process until it is.
   1886         if (!mProcessesReady
   1887                 && !isAllowedWhileBooting(info)
   1888                 && !allowWhileBooting) {
   1889             if (!mProcessesOnHold.contains(app)) {
   1890                 mProcessesOnHold.add(app);
   1891             }
   1892             if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
   1893             return app;
   1894         }
   1895 
   1896         startProcessLocked(app, hostingType, hostingNameStr);
   1897         return (app.pid != 0) ? app : null;
   1898     }
   1899 
   1900     boolean isAllowedWhileBooting(ApplicationInfo ai) {
   1901         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
   1902     }
   1903 
   1904     private final void startProcessLocked(ProcessRecord app,
   1905             String hostingType, String hostingNameStr) {
   1906         if (app.pid > 0 && app.pid != MY_PID) {
   1907             synchronized (mPidsSelfLocked) {
   1908                 mPidsSelfLocked.remove(app.pid);
   1909                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   1910             }
   1911             app.pid = 0;
   1912         }
   1913 
   1914         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   1915                 "startProcessLocked removing on hold: " + app);
   1916         mProcessesOnHold.remove(app);
   1917 
   1918         updateCpuStats();
   1919 
   1920         System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
   1921         mProcDeaths[0] = 0;
   1922 
   1923         try {
   1924             int uid = app.info.uid;
   1925             int[] gids = null;
   1926             try {
   1927                 gids = mContext.getPackageManager().getPackageGids(
   1928                         app.info.packageName);
   1929             } catch (PackageManager.NameNotFoundException e) {
   1930                 Slog.w(TAG, "Unable to retrieve gids", e);
   1931             }
   1932             if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
   1933                 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
   1934                         && mTopComponent != null
   1935                         && app.processName.equals(mTopComponent.getPackageName())) {
   1936                     uid = 0;
   1937                 }
   1938                 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
   1939                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
   1940                     uid = 0;
   1941                 }
   1942             }
   1943             int debugFlags = 0;
   1944             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   1945                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
   1946                 // Also turn on CheckJNI for debuggable apps. It's quite
   1947                 // awkward to turn on otherwise.
   1948                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   1949             }
   1950             // Run the app in safe mode if its manifest requests so or the
   1951             // system is booted in safe mode.
   1952             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
   1953                 Zygote.systemInSafeMode == true) {
   1954                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
   1955             }
   1956             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
   1957                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   1958             }
   1959             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
   1960                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
   1961             }
   1962             if ("1".equals(SystemProperties.get("debug.assert"))) {
   1963                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
   1964             }
   1965 
   1966             // Start the process.  It will either succeed and return a result containing
   1967             // the PID of the new process, or else throw a RuntimeException.
   1968             Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
   1969                     app.processName, uid, uid, gids, debugFlags,
   1970                     app.info.targetSdkVersion, null);
   1971 
   1972             BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
   1973             synchronized (bs) {
   1974                 if (bs.isOnBattery()) {
   1975                     app.batteryStats.incStartsLocked();
   1976                 }
   1977             }
   1978 
   1979             EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
   1980                     app.processName, hostingType,
   1981                     hostingNameStr != null ? hostingNameStr : "");
   1982 
   1983             if (app.persistent) {
   1984                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
   1985             }
   1986 
   1987             StringBuilder buf = mStringBuilder;
   1988             buf.setLength(0);
   1989             buf.append("Start proc ");
   1990             buf.append(app.processName);
   1991             buf.append(" for ");
   1992             buf.append(hostingType);
   1993             if (hostingNameStr != null) {
   1994                 buf.append(" ");
   1995                 buf.append(hostingNameStr);
   1996             }
   1997             buf.append(": pid=");
   1998             buf.append(startResult.pid);
   1999             buf.append(" uid=");
   2000             buf.append(uid);
   2001             buf.append(" gids={");
   2002             if (gids != null) {
   2003                 for (int gi=0; gi<gids.length; gi++) {
   2004                     if (gi != 0) buf.append(", ");
   2005                     buf.append(gids[gi]);
   2006 
   2007                 }
   2008             }
   2009             buf.append("}");
   2010             Slog.i(TAG, buf.toString());
   2011             app.pid = startResult.pid;
   2012             app.usingWrapper = startResult.usingWrapper;
   2013             app.removed = false;
   2014             synchronized (mPidsSelfLocked) {
   2015                 this.mPidsSelfLocked.put(startResult.pid, app);
   2016                 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   2017                 msg.obj = app;
   2018                 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
   2019                         ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
   2020             }
   2021         } catch (RuntimeException e) {
   2022             // XXX do better error recovery.
   2023             app.pid = 0;
   2024             Slog.e(TAG, "Failure starting process " + app.processName, e);
   2025         }
   2026     }
   2027 
   2028     void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
   2029         if (resumed) {
   2030             mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
   2031         } else {
   2032             mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
   2033         }
   2034     }
   2035 
   2036     boolean startHomeActivityLocked() {
   2037         if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
   2038                 && mTopAction == null) {
   2039             // We are running in factory test mode, but unable to find
   2040             // the factory test app, so just sit around displaying the
   2041             // error message and don't try to start anything.
   2042             return false;
   2043         }
   2044         Intent intent = new Intent(
   2045             mTopAction,
   2046             mTopData != null ? Uri.parse(mTopData) : null);
   2047         intent.setComponent(mTopComponent);
   2048         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   2049             intent.addCategory(Intent.CATEGORY_HOME);
   2050         }
   2051         ActivityInfo aInfo =
   2052             intent.resolveActivityInfo(mContext.getPackageManager(),
   2053                     STOCK_PM_FLAGS);
   2054         if (aInfo != null) {
   2055             intent.setComponent(new ComponentName(
   2056                     aInfo.applicationInfo.packageName, aInfo.name));
   2057             // Don't do this if the home app is currently being
   2058             // instrumented.
   2059             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
   2060                     aInfo.applicationInfo.uid);
   2061             if (app == null || app.instrumentationClass == null) {
   2062                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
   2063                 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
   2064                         null, null, 0, 0, 0, false, false, null);
   2065             }
   2066         }
   2067 
   2068 
   2069         return true;
   2070     }
   2071 
   2072     /**
   2073      * Starts the "new version setup screen" if appropriate.
   2074      */
   2075     void startSetupActivityLocked() {
   2076         // Only do this once per boot.
   2077         if (mCheckedForSetup) {
   2078             return;
   2079         }
   2080 
   2081         // We will show this screen if the current one is a different
   2082         // version than the last one shown, and we are not running in
   2083         // low-level factory test mode.
   2084         final ContentResolver resolver = mContext.getContentResolver();
   2085         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
   2086                 Settings.Secure.getInt(resolver,
   2087                         Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
   2088             mCheckedForSetup = true;
   2089 
   2090             // See if we should be showing the platform update setup UI.
   2091             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
   2092             List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
   2093                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
   2094 
   2095             // We don't allow third party apps to replace this.
   2096             ResolveInfo ri = null;
   2097             for (int i=0; ris != null && i<ris.size(); i++) {
   2098                 if ((ris.get(i).activityInfo.applicationInfo.flags
   2099                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
   2100                     ri = ris.get(i);
   2101                     break;
   2102                 }
   2103             }
   2104 
   2105             if (ri != null) {
   2106                 String vers = ri.activityInfo.metaData != null
   2107                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
   2108                         : null;
   2109                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
   2110                     vers = ri.activityInfo.applicationInfo.metaData.getString(
   2111                             Intent.METADATA_SETUP_VERSION);
   2112                 }
   2113                 String lastVers = Settings.Secure.getString(
   2114                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
   2115                 if (vers != null && !vers.equals(lastVers)) {
   2116                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   2117                     intent.setComponent(new ComponentName(
   2118                             ri.activityInfo.packageName, ri.activityInfo.name));
   2119                     mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
   2120                             null, null, 0, 0, 0, false, false, null);
   2121                 }
   2122             }
   2123         }
   2124     }
   2125 
   2126     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
   2127         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
   2128     }
   2129 
   2130     public int getFrontActivityScreenCompatMode() {
   2131         synchronized (this) {
   2132             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
   2133         }
   2134     }
   2135 
   2136     public void setFrontActivityScreenCompatMode(int mode) {
   2137         synchronized (this) {
   2138             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
   2139         }
   2140     }
   2141 
   2142     public int getPackageScreenCompatMode(String packageName) {
   2143         synchronized (this) {
   2144             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
   2145         }
   2146     }
   2147 
   2148     public void setPackageScreenCompatMode(String packageName, int mode) {
   2149         synchronized (this) {
   2150             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
   2151         }
   2152     }
   2153 
   2154     public boolean getPackageAskScreenCompat(String packageName) {
   2155         synchronized (this) {
   2156             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
   2157         }
   2158     }
   2159 
   2160     public void setPackageAskScreenCompat(String packageName, boolean ask) {
   2161         synchronized (this) {
   2162             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
   2163         }
   2164     }
   2165 
   2166     void reportResumedActivityLocked(ActivityRecord r) {
   2167         //Slog.i(TAG, "**** REPORT RESUME: " + r);
   2168 
   2169         final int identHash = System.identityHashCode(r);
   2170         updateUsageStats(r, true);
   2171 
   2172         int i = mWatchers.beginBroadcast();
   2173         while (i > 0) {
   2174             i--;
   2175             IActivityWatcher w = mWatchers.getBroadcastItem(i);
   2176             if (w != null) {
   2177                 try {
   2178                     w.activityResuming(identHash);
   2179                 } catch (RemoteException e) {
   2180                 }
   2181             }
   2182         }
   2183         mWatchers.finishBroadcast();
   2184     }
   2185 
   2186     private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
   2187         int i = mProcessObservers.beginBroadcast();
   2188         while (i > 0) {
   2189             i--;
   2190             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   2191             if (observer != null) {
   2192                 try {
   2193                     observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
   2194                 } catch (RemoteException e) {
   2195                 }
   2196             }
   2197         }
   2198         mProcessObservers.finishBroadcast();
   2199     }
   2200 
   2201     private void dispatchProcessDied(int pid, int uid) {
   2202         int i = mProcessObservers.beginBroadcast();
   2203         while (i > 0) {
   2204             i--;
   2205             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   2206             if (observer != null) {
   2207                 try {
   2208                     observer.onProcessDied(pid, uid);
   2209                 } catch (RemoteException e) {
   2210                 }
   2211             }
   2212         }
   2213         mProcessObservers.finishBroadcast();
   2214     }
   2215 
   2216     final void doPendingActivityLaunchesLocked(boolean doResume) {
   2217         final int N = mPendingActivityLaunches.size();
   2218         if (N <= 0) {
   2219             return;
   2220         }
   2221         for (int i=0; i<N; i++) {
   2222             PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
   2223             mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
   2224                     pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
   2225                     doResume && i == (N-1));
   2226         }
   2227         mPendingActivityLaunches.clear();
   2228     }
   2229 
   2230     public final int startActivity(IApplicationThread caller,
   2231             Intent intent, String resolvedType, Uri[] grantedUriPermissions,
   2232             int grantedMode, IBinder resultTo,
   2233             String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
   2234             String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
   2235         return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
   2236                 grantedUriPermissions, grantedMode, resultTo, resultWho,
   2237                 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
   2238                 null, null);
   2239     }
   2240 
   2241     public final WaitResult startActivityAndWait(IApplicationThread caller,
   2242             Intent intent, String resolvedType, Uri[] grantedUriPermissions,
   2243             int grantedMode, IBinder resultTo,
   2244             String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
   2245             String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
   2246         WaitResult res = new WaitResult();
   2247         mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
   2248                 grantedUriPermissions, grantedMode, resultTo, resultWho,
   2249                 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
   2250                 res, null);
   2251         return res;
   2252     }
   2253 
   2254     public final int startActivityWithConfig(IApplicationThread caller,
   2255             Intent intent, String resolvedType, Uri[] grantedUriPermissions,
   2256             int grantedMode, IBinder resultTo,
   2257             String resultWho, int requestCode, boolean onlyIfNeeded,
   2258             boolean debug, Configuration config) {
   2259         return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
   2260                 grantedUriPermissions, grantedMode, resultTo, resultWho,
   2261                 requestCode, onlyIfNeeded, debug, null, null, false, null, config);
   2262     }
   2263 
   2264     public int startActivityIntentSender(IApplicationThread caller,
   2265             IntentSender intent, Intent fillInIntent, String resolvedType,
   2266             IBinder resultTo, String resultWho, int requestCode,
   2267             int flagsMask, int flagsValues) {
   2268         // Refuse possible leaked file descriptors
   2269         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
   2270             throw new IllegalArgumentException("File descriptors passed in Intent");
   2271         }
   2272 
   2273         IIntentSender sender = intent.getTarget();
   2274         if (!(sender instanceof PendingIntentRecord)) {
   2275             throw new IllegalArgumentException("Bad PendingIntent object");
   2276         }
   2277 
   2278         PendingIntentRecord pir = (PendingIntentRecord)sender;
   2279 
   2280         synchronized (this) {
   2281             // If this is coming from the currently resumed activity, it is
   2282             // effectively saying that app switches are allowed at this point.
   2283             if (mMainStack.mResumedActivity != null
   2284                     && mMainStack.mResumedActivity.info.applicationInfo.uid ==
   2285                             Binder.getCallingUid()) {
   2286                 mAppSwitchesAllowedTime = 0;
   2287             }
   2288         }
   2289 
   2290         return pir.sendInner(0, fillInIntent, resolvedType, null,
   2291                 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
   2292     }
   2293 
   2294     public boolean startNextMatchingActivity(IBinder callingActivity,
   2295             Intent intent) {
   2296         // Refuse possible leaked file descriptors
   2297         if (intent != null && intent.hasFileDescriptors() == true) {
   2298             throw new IllegalArgumentException("File descriptors passed in Intent");
   2299         }
   2300 
   2301         synchronized (this) {
   2302             ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
   2303             if (r == null) {
   2304                 return false;
   2305             }
   2306             if (r.app == null || r.app.thread == null) {
   2307                 // The caller is not running...  d'oh!
   2308                 return false;
   2309             }
   2310             intent = new Intent(intent);
   2311             // The caller is not allowed to change the data.
   2312             intent.setDataAndType(r.intent.getData(), r.intent.getType());
   2313             // And we are resetting to find the next component...
   2314             intent.setComponent(null);
   2315 
   2316             ActivityInfo aInfo = null;
   2317             try {
   2318                 List<ResolveInfo> resolves =
   2319                     AppGlobals.getPackageManager().queryIntentActivities(
   2320                             intent, r.resolvedType,
   2321                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
   2322 
   2323                 // Look for the original activity in the list...
   2324                 final int N = resolves != null ? resolves.size() : 0;
   2325                 for (int i=0; i<N; i++) {
   2326                     ResolveInfo rInfo = resolves.get(i);
   2327                     if (rInfo.activityInfo.packageName.equals(r.packageName)
   2328                             && rInfo.activityInfo.name.equals(r.info.name)) {
   2329                         // We found the current one...  the next matching is
   2330                         // after it.
   2331                         i++;
   2332                         if (i<N) {
   2333                             aInfo = resolves.get(i).activityInfo;
   2334                         }
   2335                         break;
   2336                     }
   2337                 }
   2338             } catch (RemoteException e) {
   2339             }
   2340 
   2341             if (aInfo == null) {
   2342                 // Nobody who is next!
   2343                 return false;
   2344             }
   2345 
   2346             intent.setComponent(new ComponentName(
   2347                     aInfo.applicationInfo.packageName, aInfo.name));
   2348             intent.setFlags(intent.getFlags()&~(
   2349                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
   2350                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
   2351                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
   2352                     Intent.FLAG_ACTIVITY_NEW_TASK));
   2353 
   2354             // Okay now we need to start the new activity, replacing the
   2355             // currently running activity.  This is a little tricky because
   2356             // we want to start the new one as if the current one is finished,
   2357             // but not finish the current one first so that there is no flicker.
   2358             // And thus...
   2359             final boolean wasFinishing = r.finishing;
   2360             r.finishing = true;
   2361 
   2362             // Propagate reply information over to the new activity.
   2363             final ActivityRecord resultTo = r.resultTo;
   2364             final String resultWho = r.resultWho;
   2365             final int requestCode = r.requestCode;
   2366             r.resultTo = null;
   2367             if (resultTo != null) {
   2368                 resultTo.removeResultsLocked(r, resultWho, requestCode);
   2369             }
   2370 
   2371             final long origId = Binder.clearCallingIdentity();
   2372             // XXX we are not dealing with propagating grantedUriPermissions...
   2373             // those are not yet exposed to user code, so there is no need.
   2374             int res = mMainStack.startActivityLocked(r.app.thread, intent,
   2375                     r.resolvedType, null, 0, aInfo,
   2376                     resultTo != null ? resultTo.appToken : null, resultWho,
   2377                     requestCode, -1, r.launchedFromUid, false, false, null);
   2378             Binder.restoreCallingIdentity(origId);
   2379 
   2380             r.finishing = wasFinishing;
   2381             if (res != START_SUCCESS) {
   2382                 return false;
   2383             }
   2384             return true;
   2385         }
   2386     }
   2387 
   2388     public final int startActivityInPackage(int uid,
   2389             Intent intent, String resolvedType, IBinder resultTo,
   2390             String resultWho, int requestCode, boolean onlyIfNeeded) {
   2391 
   2392         // This is so super not safe, that only the system (or okay root)
   2393         // can do it.
   2394         final int callingUid = Binder.getCallingUid();
   2395         if (callingUid != 0 && callingUid != Process.myUid()) {
   2396             throw new SecurityException(
   2397                     "startActivityInPackage only available to the system");
   2398         }
   2399 
   2400         return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
   2401                 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
   2402                 null, null, false, null, null);
   2403     }
   2404 
   2405     public final int startActivities(IApplicationThread caller,
   2406             Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
   2407         return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
   2408     }
   2409 
   2410     public final int startActivitiesInPackage(int uid,
   2411             Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
   2412 
   2413         // This is so super not safe, that only the system (or okay root)
   2414         // can do it.
   2415         final int callingUid = Binder.getCallingUid();
   2416         if (callingUid != 0 && callingUid != Process.myUid()) {
   2417             throw new SecurityException(
   2418                     "startActivityInPackage only available to the system");
   2419         }
   2420 
   2421         return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
   2422     }
   2423 
   2424     final void addRecentTaskLocked(TaskRecord task) {
   2425         int N = mRecentTasks.size();
   2426         // Quick case: check if the top-most recent task is the same.
   2427         if (N > 0 && mRecentTasks.get(0) == task) {
   2428             return;
   2429         }
   2430         // Remove any existing entries that are the same kind of task.
   2431         for (int i=0; i<N; i++) {
   2432             TaskRecord tr = mRecentTasks.get(i);
   2433             if ((task.affinity != null && task.affinity.equals(tr.affinity))
   2434                     || (task.intent != null && task.intent.filterEquals(tr.intent))) {
   2435                 mRecentTasks.remove(i);
   2436                 i--;
   2437                 N--;
   2438                 if (task.intent == null) {
   2439                     // If the new recent task we are adding is not fully
   2440                     // specified, then replace it with the existing recent task.
   2441                     task = tr;
   2442                 }
   2443             }
   2444         }
   2445         if (N >= MAX_RECENT_TASKS) {
   2446             mRecentTasks.remove(N-1);
   2447         }
   2448         mRecentTasks.add(0, task);
   2449     }
   2450 
   2451     public void setRequestedOrientation(IBinder token,
   2452             int requestedOrientation) {
   2453         synchronized (this) {
   2454             ActivityRecord r = mMainStack.isInStackLocked(token);
   2455             if (r == null) {
   2456                 return;
   2457             }
   2458             final long origId = Binder.clearCallingIdentity();
   2459             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
   2460             Configuration config = mWindowManager.updateOrientationFromAppTokens(
   2461                     mConfiguration,
   2462                     r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
   2463             if (config != null) {
   2464                 r.frozenBeforeDestroy = true;
   2465                 if (!updateConfigurationLocked(config, r, false, false)) {
   2466                     mMainStack.resumeTopActivityLocked(null);
   2467                 }
   2468             }
   2469             Binder.restoreCallingIdentity(origId);
   2470         }
   2471     }
   2472 
   2473     public int getRequestedOrientation(IBinder token) {
   2474         synchronized (this) {
   2475             ActivityRecord r = mMainStack.isInStackLocked(token);
   2476             if (r == null) {
   2477                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
   2478             }
   2479             return mWindowManager.getAppOrientation(r.appToken);
   2480         }
   2481     }
   2482 
   2483     /**
   2484      * This is the internal entry point for handling Activity.finish().
   2485      *
   2486      * @param token The Binder token referencing the Activity we want to finish.
   2487      * @param resultCode Result code, if any, from this Activity.
   2488      * @param resultData Result data (Intent), if any, from this Activity.
   2489      *
   2490      * @return Returns true if the activity successfully finished, or false if it is still running.
   2491      */
   2492     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
   2493         // Refuse possible leaked file descriptors
   2494         if (resultData != null && resultData.hasFileDescriptors() == true) {
   2495             throw new IllegalArgumentException("File descriptors passed in Intent");
   2496         }
   2497 
   2498         synchronized(this) {
   2499             if (mController != null) {
   2500                 // Find the first activity that is not finishing.
   2501                 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
   2502                 if (next != null) {
   2503                     // ask watcher if this is allowed
   2504                     boolean resumeOK = true;
   2505                     try {
   2506                         resumeOK = mController.activityResuming(next.packageName);
   2507                     } catch (RemoteException e) {
   2508                         mController = null;
   2509                     }
   2510 
   2511                     if (!resumeOK) {
   2512                         return false;
   2513                     }
   2514                 }
   2515             }
   2516             final long origId = Binder.clearCallingIdentity();
   2517             boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
   2518                     resultData, "app-request");
   2519             Binder.restoreCallingIdentity(origId);
   2520             return res;
   2521         }
   2522     }
   2523 
   2524     public final void finishHeavyWeightApp() {
   2525         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   2526                 != PackageManager.PERMISSION_GRANTED) {
   2527             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
   2528                     + Binder.getCallingPid()
   2529                     + ", uid=" + Binder.getCallingUid()
   2530                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   2531             Slog.w(TAG, msg);
   2532             throw new SecurityException(msg);
   2533         }
   2534 
   2535         synchronized(this) {
   2536             if (mHeavyWeightProcess == null) {
   2537                 return;
   2538             }
   2539 
   2540             ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
   2541                     mHeavyWeightProcess.activities);
   2542             for (int i=0; i<activities.size(); i++) {
   2543                 ActivityRecord r = activities.get(i);
   2544                 if (!r.finishing) {
   2545                     int index = mMainStack.indexOfTokenLocked(r.appToken);
   2546                     if (index >= 0) {
   2547                         mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
   2548                                 null, "finish-heavy");
   2549                     }
   2550                 }
   2551             }
   2552 
   2553             mHeavyWeightProcess = null;
   2554             mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
   2555         }
   2556     }
   2557 
   2558     public void crashApplication(int uid, int initialPid, String packageName,
   2559             String message) {
   2560         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   2561                 != PackageManager.PERMISSION_GRANTED) {
   2562             String msg = "Permission Denial: crashApplication() from pid="
   2563                     + Binder.getCallingPid()
   2564                     + ", uid=" + Binder.getCallingUid()
   2565                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   2566             Slog.w(TAG, msg);
   2567             throw new SecurityException(msg);
   2568         }
   2569 
   2570         synchronized(this) {
   2571             ProcessRecord proc = null;
   2572 
   2573             // Figure out which process to kill.  We don't trust that initialPid
   2574             // still has any relation to current pids, so must scan through the
   2575             // list.
   2576             synchronized (mPidsSelfLocked) {
   2577                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   2578                     ProcessRecord p = mPidsSelfLocked.valueAt(i);
   2579                     if (p.info.uid != uid) {
   2580                         continue;
   2581                     }
   2582                     if (p.pid == initialPid) {
   2583                         proc = p;
   2584                         break;
   2585                     }
   2586                     for (String str : p.pkgList) {
   2587                         if (str.equals(packageName)) {
   2588                             proc = p;
   2589                         }
   2590                     }
   2591                 }
   2592             }
   2593 
   2594             if (proc == null) {
   2595                 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
   2596                         + " initialPid=" + initialPid
   2597                         + " packageName=" + packageName);
   2598                 return;
   2599             }
   2600 
   2601             if (proc.thread != null) {
   2602                 if (proc.pid == Process.myPid()) {
   2603                     Log.w(TAG, "crashApplication: trying to crash self!");
   2604                     return;
   2605                 }
   2606                 long ident = Binder.clearCallingIdentity();
   2607                 try {
   2608                     proc.thread.scheduleCrash(message);
   2609                 } catch (RemoteException e) {
   2610                 }
   2611                 Binder.restoreCallingIdentity(ident);
   2612             }
   2613         }
   2614     }
   2615 
   2616     public final void finishSubActivity(IBinder token, String resultWho,
   2617             int requestCode) {
   2618         synchronized(this) {
   2619             ActivityRecord self = mMainStack.isInStackLocked(token);
   2620             if (self == null) {
   2621                 return;
   2622             }
   2623 
   2624             final long origId = Binder.clearCallingIdentity();
   2625 
   2626             int i;
   2627             for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
   2628                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   2629                 if (r.resultTo == self && r.requestCode == requestCode) {
   2630                     if ((r.resultWho == null && resultWho == null) ||
   2631                         (r.resultWho != null && r.resultWho.equals(resultWho))) {
   2632                         mMainStack.finishActivityLocked(r, i,
   2633                                 Activity.RESULT_CANCELED, null, "request-sub");
   2634                     }
   2635                 }
   2636             }
   2637 
   2638             Binder.restoreCallingIdentity(origId);
   2639         }
   2640     }
   2641 
   2642     public boolean willActivityBeVisible(IBinder token) {
   2643         synchronized(this) {
   2644             int i;
   2645             for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
   2646                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   2647                 if (r.appToken == token) {
   2648                     return true;
   2649                 }
   2650                 if (r.fullscreen && !r.finishing) {
   2651                     return false;
   2652                 }
   2653             }
   2654             return true;
   2655         }
   2656     }
   2657 
   2658     public void overridePendingTransition(IBinder token, String packageName,
   2659             int enterAnim, int exitAnim) {
   2660         synchronized(this) {
   2661             ActivityRecord self = mMainStack.isInStackLocked(token);
   2662             if (self == null) {
   2663                 return;
   2664             }
   2665 
   2666             final long origId = Binder.clearCallingIdentity();
   2667 
   2668             if (self.state == ActivityState.RESUMED
   2669                     || self.state == ActivityState.PAUSING) {
   2670                 mWindowManager.overridePendingAppTransition(packageName,
   2671                         enterAnim, exitAnim);
   2672             }
   2673 
   2674             Binder.restoreCallingIdentity(origId);
   2675         }
   2676     }
   2677 
   2678     /**
   2679      * Main function for removing an existing process from the activity manager
   2680      * as a result of that process going away.  Clears out all connections
   2681      * to the process.
   2682      */
   2683     private final void handleAppDiedLocked(ProcessRecord app,
   2684             boolean restarting, boolean allowRestart) {
   2685         cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
   2686         if (!restarting) {
   2687             mLruProcesses.remove(app);
   2688         }
   2689 
   2690         if (mProfileProc == app) {
   2691             clearProfilerLocked();
   2692         }
   2693 
   2694         // Just in case...
   2695         if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
   2696             if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
   2697             mMainStack.mPausingActivity = null;
   2698         }
   2699         if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
   2700             mMainStack.mLastPausedActivity = null;
   2701         }
   2702 
   2703         // Remove this application's activities from active lists.
   2704         mMainStack.removeHistoryRecordsForAppLocked(app);
   2705 
   2706         boolean atTop = true;
   2707         boolean hasVisibleActivities = false;
   2708 
   2709         // Clean out the history list.
   2710         int i = mMainStack.mHistory.size();
   2711         if (localLOGV) Slog.v(
   2712             TAG, "Removing app " + app + " from history with " + i + " entries");
   2713         while (i > 0) {
   2714             i--;
   2715             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   2716             if (localLOGV) Slog.v(
   2717                 TAG, "Record #" + i + " " + r + ": app=" + r.app);
   2718             if (r.app == app) {
   2719                 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
   2720                     if (ActivityStack.DEBUG_ADD_REMOVE) {
   2721                         RuntimeException here = new RuntimeException("here");
   2722                         here.fillInStackTrace();
   2723                         Slog.i(TAG, "Removing activity " + r + " from stack at " + i
   2724                                 + ": haveState=" + r.haveState
   2725                                 + " stateNotNeeded=" + r.stateNotNeeded
   2726                                 + " finishing=" + r.finishing
   2727                                 + " state=" + r.state, here);
   2728                     }
   2729                     if (!r.finishing) {
   2730                         Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
   2731                         EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
   2732                                 System.identityHashCode(r),
   2733                                 r.task.taskId, r.shortComponentName,
   2734                                 "proc died without state saved");
   2735                     }
   2736                     mMainStack.removeActivityFromHistoryLocked(r);
   2737 
   2738                 } else {
   2739                     // We have the current state for this activity, so
   2740                     // it can be restarted later when needed.
   2741                     if (localLOGV) Slog.v(
   2742                         TAG, "Keeping entry, setting app to null");
   2743                     if (r.visible) {
   2744                         hasVisibleActivities = true;
   2745                     }
   2746                     r.app = null;
   2747                     r.nowVisible = false;
   2748                     if (!r.haveState) {
   2749                         if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
   2750                                 "App died, clearing saved state of " + r);
   2751                         r.icicle = null;
   2752                     }
   2753                 }
   2754 
   2755                 r.stack.cleanUpActivityLocked(r, true, true);
   2756             }
   2757             atTop = false;
   2758         }
   2759 
   2760         app.activities.clear();
   2761 
   2762         if (app.instrumentationClass != null) {
   2763             Slog.w(TAG, "Crash of app " + app.processName
   2764                   + " running instrumentation " + app.instrumentationClass);
   2765             Bundle info = new Bundle();
   2766             info.putString("shortMsg", "Process crashed.");
   2767             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
   2768         }
   2769 
   2770         if (!restarting) {
   2771             if (!mMainStack.resumeTopActivityLocked(null)) {
   2772                 // If there was nothing to resume, and we are not already
   2773                 // restarting this process, but there is a visible activity that
   2774                 // is hosted by the process...  then make sure all visible
   2775                 // activities are running, taking care of restarting this
   2776                 // process.
   2777                 if (hasVisibleActivities) {
   2778                     mMainStack.ensureActivitiesVisibleLocked(null, 0);
   2779                 }
   2780             }
   2781         }
   2782     }
   2783 
   2784     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
   2785         IBinder threadBinder = thread.asBinder();
   2786 
   2787         // Find the application record.
   2788         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   2789             ProcessRecord rec = mLruProcesses.get(i);
   2790             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
   2791                 return i;
   2792             }
   2793         }
   2794         return -1;
   2795     }
   2796 
   2797     final ProcessRecord getRecordForAppLocked(
   2798             IApplicationThread thread) {
   2799         if (thread == null) {
   2800             return null;
   2801         }
   2802 
   2803         int appIndex = getLRURecordIndexForAppLocked(thread);
   2804         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
   2805     }
   2806 
   2807     final void appDiedLocked(ProcessRecord app, int pid,
   2808             IApplicationThread thread) {
   2809 
   2810         mProcDeaths[0]++;
   2811 
   2812         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   2813         synchronized (stats) {
   2814             stats.noteProcessDiedLocked(app.info.uid, pid);
   2815         }
   2816 
   2817         // Clean up already done if the process has been re-started.
   2818         if (app.pid == pid && app.thread != null &&
   2819                 app.thread.asBinder() == thread.asBinder()) {
   2820             if (!app.killedBackground) {
   2821                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   2822                         + ") has died.");
   2823             }
   2824             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
   2825             if (localLOGV) Slog.v(
   2826                 TAG, "Dying app: " + app + ", pid: " + pid
   2827                 + ", thread: " + thread.asBinder());
   2828             boolean doLowMem = app.instrumentationClass == null;
   2829             handleAppDiedLocked(app, false, true);
   2830 
   2831             if (doLowMem) {
   2832                 // If there are no longer any background processes running,
   2833                 // and the app that died was not running instrumentation,
   2834                 // then tell everyone we are now low on memory.
   2835                 boolean haveBg = false;
   2836                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   2837                     ProcessRecord rec = mLruProcesses.get(i);
   2838                     if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   2839                         haveBg = true;
   2840                         break;
   2841                     }
   2842                 }
   2843 
   2844                 if (!haveBg) {
   2845                     EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
   2846                     long now = SystemClock.uptimeMillis();
   2847                     for (int i=mLruProcesses.size()-1; i>=0; i--) {
   2848                         ProcessRecord rec = mLruProcesses.get(i);
   2849                         if (rec != app && rec.thread != null &&
   2850                                 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
   2851                             // The low memory report is overriding any current
   2852                             // state for a GC request.  Make sure to do
   2853                             // heavy/important/visible/foreground processes first.
   2854                             if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   2855                                 rec.lastRequestedGc = 0;
   2856                             } else {
   2857                                 rec.lastRequestedGc = rec.lastLowMemory;
   2858                             }
   2859                             rec.reportLowMemory = true;
   2860                             rec.lastLowMemory = now;
   2861                             mProcessesToGc.remove(rec);
   2862                             addProcessToGcListLocked(rec);
   2863                         }
   2864                     }
   2865                     mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
   2866                     scheduleAppGcsLocked();
   2867                 }
   2868             }
   2869         } else if (app.pid != pid) {
   2870             // A new process has already been started.
   2871             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   2872                     + ") has died and restarted (pid " + app.pid + ").");
   2873             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
   2874         } else if (DEBUG_PROCESSES) {
   2875             Slog.d(TAG, "Received spurious death notification for thread "
   2876                     + thread.asBinder());
   2877         }
   2878     }
   2879 
   2880     /**
   2881      * If a stack trace dump file is configured, dump process stack traces.
   2882      * @param clearTraces causes the dump file to be erased prior to the new
   2883      *    traces being written, if true; when false, the new traces will be
   2884      *    appended to any existing file content.
   2885      * @param firstPids of dalvik VM processes to dump stack traces for first
   2886      * @param lastPids of dalvik VM processes to dump stack traces for last
   2887      * @return file containing stack traces, or null if no dump file is configured
   2888      */
   2889     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
   2890             ProcessStats processStats, SparseArray<Boolean> lastPids) {
   2891         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   2892         if (tracesPath == null || tracesPath.length() == 0) {
   2893             return null;
   2894         }
   2895 
   2896         File tracesFile = new File(tracesPath);
   2897         try {
   2898             File tracesDir = tracesFile.getParentFile();
   2899             if (!tracesDir.exists()) tracesFile.mkdirs();
   2900             FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
   2901 
   2902             if (clearTraces && tracesFile.exists()) tracesFile.delete();
   2903             tracesFile.createNewFile();
   2904             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   2905         } catch (IOException e) {
   2906             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
   2907             return null;
   2908         }
   2909 
   2910         dumpStackTraces(tracesPath, firstPids, processStats, lastPids);
   2911         return tracesFile;
   2912     }
   2913 
   2914     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
   2915             ProcessStats processStats, SparseArray<Boolean> lastPids) {
   2916         // Use a FileObserver to detect when traces finish writing.
   2917         // The order of traces is considered important to maintain for legibility.
   2918         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
   2919             public synchronized void onEvent(int event, String path) { notify(); }
   2920         };
   2921 
   2922         try {
   2923             observer.startWatching();
   2924 
   2925             // First collect all of the stacks of the most important pids.
   2926             if (firstPids != null) {
   2927                 try {
   2928                     int num = firstPids.size();
   2929                     for (int i = 0; i < num; i++) {
   2930                         synchronized (observer) {
   2931                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
   2932                             observer.wait(200);  // Wait for write-close, give up after 200msec
   2933                         }
   2934                     }
   2935                 } catch (InterruptedException e) {
   2936                     Log.wtf(TAG, e);
   2937                 }
   2938             }
   2939 
   2940             // Next measure CPU usage.
   2941             if (processStats != null) {
   2942                 processStats.init();
   2943                 System.gc();
   2944                 processStats.update();
   2945                 try {
   2946                     synchronized (processStats) {
   2947                         processStats.wait(500); // measure over 1/2 second.
   2948                     }
   2949                 } catch (InterruptedException e) {
   2950                 }
   2951                 processStats.update();
   2952 
   2953                 // We'll take the stack crawls of just the top apps using CPU.
   2954                 final int N = processStats.countWorkingStats();
   2955                 int numProcs = 0;
   2956                 for (int i=0; i<N && numProcs<5; i++) {
   2957                     ProcessStats.Stats stats = processStats.getWorkingStats(i);
   2958                     if (lastPids.indexOfKey(stats.pid) >= 0) {
   2959                         numProcs++;
   2960                         try {
   2961                             synchronized (observer) {
   2962                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
   2963                                 observer.wait(200);  // Wait for write-close, give up after 200msec
   2964                             }
   2965                         } catch (InterruptedException e) {
   2966                             Log.wtf(TAG, e);
   2967                         }
   2968 
   2969                     }
   2970                 }
   2971             }
   2972 
   2973         } finally {
   2974             observer.stopWatching();
   2975         }
   2976     }
   2977 
   2978     private final class AppNotResponding implements Runnable {
   2979         private final ProcessRecord mApp;
   2980         private final String mAnnotation;
   2981 
   2982         public AppNotResponding(ProcessRecord app, String annotation) {
   2983             mApp = app;
   2984             mAnnotation = annotation;
   2985         }
   2986 
   2987         @Override
   2988         public void run() {
   2989             appNotResponding(mApp, null, null, mAnnotation);
   2990         }
   2991     }
   2992 
   2993     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
   2994         if (IS_USER_BUILD) {
   2995             return;
   2996         }
   2997         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   2998         if (tracesPath == null || tracesPath.length() == 0) {
   2999             return;
   3000         }
   3001 
   3002         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
   3003         StrictMode.allowThreadDiskWrites();
   3004         try {
   3005             final File tracesFile = new File(tracesPath);
   3006             final File tracesDir = tracesFile.getParentFile();
   3007             final File tracesTmp = new File(tracesDir, "__tmp__");
   3008             try {
   3009                 if (!tracesDir.exists()) tracesFile.mkdirs();
   3010                 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
   3011 
   3012                 if (tracesFile.exists()) {
   3013                     tracesTmp.delete();
   3014                     tracesFile.renameTo(tracesTmp);
   3015                 }
   3016                 StringBuilder sb = new StringBuilder();
   3017                 Time tobj = new Time();
   3018                 tobj.set(System.currentTimeMillis());
   3019                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
   3020                 sb.append(": ");
   3021                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
   3022                 sb.append(" since ");
   3023                 sb.append(msg);
   3024                 FileOutputStream fos = new FileOutputStream(tracesFile);
   3025                 fos.write(sb.toString().getBytes());
   3026                 if (app == null) {
   3027                     fos.write("\n*** No application process!".getBytes());
   3028                 }
   3029                 fos.close();
   3030                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   3031             } catch (IOException e) {
   3032                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
   3033                 return;
   3034             }
   3035 
   3036             if (app != null) {
   3037                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
   3038                 firstPids.add(app.pid);
   3039                 dumpStackTraces(tracesPath, firstPids, null, null);
   3040             }
   3041 
   3042             File lastTracesFile = null;
   3043             File curTracesFile = null;
   3044             for (int i=9; i>=0; i--) {
   3045                 String name = String.format("slow%02d.txt", i);
   3046                 curTracesFile = new File(tracesDir, name);
   3047                 if (curTracesFile.exists()) {
   3048                     if (lastTracesFile != null) {
   3049                         curTracesFile.renameTo(lastTracesFile);
   3050                     } else {
   3051                         curTracesFile.delete();
   3052                     }
   3053                 }
   3054                 lastTracesFile = curTracesFile;
   3055             }
   3056             tracesFile.renameTo(curTracesFile);
   3057             if (tracesTmp.exists()) {
   3058                 tracesTmp.renameTo(tracesFile);
   3059             }
   3060         } finally {
   3061             StrictMode.setThreadPolicy(oldPolicy);
   3062         }
   3063     }
   3064 
   3065     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
   3066             ActivityRecord parent, final String annotation) {
   3067         ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
   3068         SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
   3069 
   3070         if (mController != null) {
   3071             try {
   3072                 // 0 == continue, -1 = kill process immediately
   3073                 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
   3074                 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
   3075             } catch (RemoteException e) {
   3076                 mController = null;
   3077             }
   3078         }
   3079 
   3080         long anrTime = SystemClock.uptimeMillis();
   3081         if (MONITOR_CPU_USAGE) {
   3082             updateCpuStatsNow();
   3083         }
   3084 
   3085         synchronized (this) {
   3086             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
   3087             if (mShuttingDown) {
   3088                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
   3089                 return;
   3090             } else if (app.notResponding) {
   3091                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
   3092                 return;
   3093             } else if (app.crashing) {
   3094                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
   3095                 return;
   3096             }
   3097 
   3098             // In case we come through here for the same app before completing
   3099             // this one, mark as anring now so we will bail out.
   3100             app.notResponding = true;
   3101 
   3102             // Log the ANR to the event log.
   3103             EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
   3104                     annotation);
   3105 
   3106             // Dump thread traces as quickly as we can, starting with "interesting" processes.
   3107             firstPids.add(app.pid);
   3108 
   3109             int parentPid = app.pid;
   3110             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
   3111             if (parentPid != app.pid) firstPids.add(parentPid);
   3112 
   3113             if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
   3114 
   3115             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   3116                 ProcessRecord r = mLruProcesses.get(i);
   3117                 if (r != null && r.thread != null) {
   3118                     int pid = r.pid;
   3119                     if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
   3120                         if (r.persistent) {
   3121                             firstPids.add(pid);
   3122                         } else {
   3123                             lastPids.put(pid, Boolean.TRUE);
   3124                         }
   3125                     }
   3126                 }
   3127             }
   3128         }
   3129 
   3130         // Log the ANR to the main log.
   3131         StringBuilder info = mStringBuilder;
   3132         info.setLength(0);
   3133         info.append("ANR in ").append(app.processName);
   3134         if (activity != null && activity.shortComponentName != null) {
   3135             info.append(" (").append(activity.shortComponentName).append(")");
   3136         }
   3137         info.append("\n");
   3138         if (annotation != null) {
   3139             info.append("Reason: ").append(annotation).append("\n");
   3140         }
   3141         if (parent != null && parent != activity) {
   3142             info.append("Parent: ").append(parent.shortComponentName).append("\n");
   3143         }
   3144 
   3145         final ProcessStats processStats = new ProcessStats(true);
   3146 
   3147         File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
   3148 
   3149         String cpuInfo = null;
   3150         if (MONITOR_CPU_USAGE) {
   3151             updateCpuStatsNow();
   3152             synchronized (mProcessStatsThread) {
   3153                 cpuInfo = mProcessStats.printCurrentState(anrTime);
   3154             }
   3155             info.append(processStats.printCurrentLoad());
   3156             info.append(cpuInfo);
   3157         }
   3158 
   3159         info.append(processStats.printCurrentState(anrTime));
   3160 
   3161         Slog.e(TAG, info.toString());
   3162         if (tracesFile == null) {
   3163             // There is no trace file, so dump (only) the alleged culprit's threads to the log
   3164             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
   3165         }
   3166 
   3167         addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
   3168                 cpuInfo, tracesFile, null);
   3169 
   3170         if (mController != null) {
   3171             try {
   3172                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
   3173                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
   3174                 if (res != 0) {
   3175                     if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
   3176                     return;
   3177                 }
   3178             } catch (RemoteException e) {
   3179                 mController = null;
   3180             }
   3181         }
   3182 
   3183         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
   3184         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
   3185                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
   3186 
   3187         synchronized (this) {
   3188             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
   3189                 Slog.w(TAG, "Killing " + app + ": background ANR");
   3190                 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   3191                         app.processName, app.setAdj, "background ANR");
   3192                 Process.killProcessQuiet(app.pid);
   3193                 return;
   3194             }
   3195 
   3196             // Set the app's notResponding state, and look up the errorReportReceiver
   3197             makeAppNotRespondingLocked(app,
   3198                     activity != null ? activity.shortComponentName : null,
   3199                     annotation != null ? "ANR " + annotation : "ANR",
   3200                     info.toString());
   3201 
   3202             // Bring up the infamous App Not Responding dialog
   3203             Message msg = Message.obtain();
   3204             HashMap map = new HashMap();
   3205             msg.what = SHOW_NOT_RESPONDING_MSG;
   3206             msg.obj = map;
   3207             map.put("app", app);
   3208             if (activity != null) {
   3209                 map.put("activity", activity);
   3210             }
   3211 
   3212             mHandler.sendMessage(msg);
   3213         }
   3214     }
   3215 
   3216     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
   3217         if (!mLaunchWarningShown) {
   3218             mLaunchWarningShown = true;
   3219             mHandler.post(new Runnable() {
   3220                 @Override
   3221                 public void run() {
   3222                     synchronized (ActivityManagerService.this) {
   3223                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
   3224                         d.show();
   3225                         mHandler.postDelayed(new Runnable() {
   3226                             @Override
   3227                             public void run() {
   3228                                 synchronized (ActivityManagerService.this) {
   3229                                     d.dismiss();
   3230                                     mLaunchWarningShown = false;
   3231                                 }
   3232                             }
   3233                         }, 4000);
   3234                     }
   3235                 }
   3236             });
   3237         }
   3238     }
   3239 
   3240     public boolean clearApplicationUserData(final String packageName,
   3241             final IPackageDataObserver observer) {
   3242         int uid = Binder.getCallingUid();
   3243         int pid = Binder.getCallingPid();
   3244         long callingId = Binder.clearCallingIdentity();
   3245         try {
   3246             IPackageManager pm = AppGlobals.getPackageManager();
   3247             int pkgUid = -1;
   3248             synchronized(this) {
   3249                 try {
   3250                     pkgUid = pm.getPackageUid(packageName);
   3251                 } catch (RemoteException e) {
   3252                 }
   3253                 if (pkgUid == -1) {
   3254                     Slog.w(TAG, "Invalid packageName:" + packageName);
   3255                     return false;
   3256                 }
   3257                 if (uid == pkgUid || checkComponentPermission(
   3258                         android.Manifest.permission.CLEAR_APP_USER_DATA,
   3259                         pid, uid, -1, true)
   3260                         == PackageManager.PERMISSION_GRANTED) {
   3261                     forceStopPackageLocked(packageName, pkgUid);
   3262                 } else {
   3263                     throw new SecurityException(pid+" does not have permission:"+
   3264                             android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
   3265                                     "for process:"+packageName);
   3266                 }
   3267             }
   3268 
   3269             try {
   3270                 //clear application user data
   3271                 pm.clearApplicationUserData(packageName, observer);
   3272                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
   3273                         Uri.fromParts("package", packageName, null));
   3274                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
   3275                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
   3276                         null, null, 0, null, null, null, false, false);
   3277             } catch (RemoteException e) {
   3278             }
   3279         } finally {
   3280             Binder.restoreCallingIdentity(callingId);
   3281         }
   3282         return true;
   3283     }
   3284 
   3285     public void killBackgroundProcesses(final String packageName) {
   3286         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   3287                 != PackageManager.PERMISSION_GRANTED &&
   3288                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
   3289                         != PackageManager.PERMISSION_GRANTED) {
   3290             String msg = "Permission Denial: killBackgroundProcesses() from pid="
   3291                     + Binder.getCallingPid()
   3292                     + ", uid=" + Binder.getCallingUid()
   3293                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   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                 killPackageProcessesLocked(packageName, pkgUid,
   3312                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
   3313             }
   3314         } finally {
   3315             Binder.restoreCallingIdentity(callingId);
   3316         }
   3317     }
   3318 
   3319     public void killAllBackgroundProcesses() {
   3320         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   3321                 != PackageManager.PERMISSION_GRANTED) {
   3322             String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
   3323                     + Binder.getCallingPid()
   3324                     + ", uid=" + Binder.getCallingUid()
   3325                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   3326             Slog.w(TAG, msg);
   3327             throw new SecurityException(msg);
   3328         }
   3329 
   3330         long callingId = Binder.clearCallingIdentity();
   3331         try {
   3332             synchronized(this) {
   3333                 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   3334                 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   3335                     final int NA = apps.size();
   3336                     for (int ia=0; ia<NA; ia++) {
   3337                         ProcessRecord app = apps.valueAt(ia);
   3338                         if (app.persistent) {
   3339                             // we don't kill persistent processes
   3340                             continue;
   3341                         }
   3342                         if (app.removed) {
   3343                             procs.add(app);
   3344                         } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   3345                             app.removed = true;
   3346                             procs.add(app);
   3347                         }
   3348                     }
   3349                 }
   3350 
   3351                 int N = procs.size();
   3352                 for (int i=0; i<N; i++) {
   3353                     removeProcessLocked(procs.get(i), false, true, "kill all background");
   3354                 }
   3355             }
   3356         } finally {
   3357             Binder.restoreCallingIdentity(callingId);
   3358         }
   3359     }
   3360 
   3361     public void forceStopPackage(final String packageName) {
   3362         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   3363                 != PackageManager.PERMISSION_GRANTED) {
   3364             String msg = "Permission Denial: forceStopPackage() from pid="
   3365                     + Binder.getCallingPid()
   3366                     + ", uid=" + Binder.getCallingUid()
   3367                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   3368             Slog.w(TAG, msg);
   3369             throw new SecurityException(msg);
   3370         }
   3371 
   3372         long callingId = Binder.clearCallingIdentity();
   3373         try {
   3374             IPackageManager pm = AppGlobals.getPackageManager();
   3375             int pkgUid = -1;
   3376             synchronized(this) {
   3377                 try {
   3378                     pkgUid = pm.getPackageUid(packageName);
   3379                 } catch (RemoteException e) {
   3380                 }
   3381                 if (pkgUid == -1) {
   3382                     Slog.w(TAG, "Invalid packageName: " + packageName);
   3383                     return;
   3384                 }
   3385                 forceStopPackageLocked(packageName, pkgUid);
   3386                 try {
   3387                     pm.setPackageStoppedState(packageName, true);
   3388                 } catch (RemoteException e) {
   3389                 } catch (IllegalArgumentException e) {
   3390                     Slog.w(TAG, "Failed trying to unstop package "
   3391                             + packageName + ": " + e);
   3392                 }
   3393             }
   3394         } finally {
   3395             Binder.restoreCallingIdentity(callingId);
   3396         }
   3397     }
   3398 
   3399     /*
   3400      * The pkg name and uid have to be specified.
   3401      * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
   3402      */
   3403     public void killApplicationWithUid(String pkg, int uid) {
   3404         if (pkg == null) {
   3405             return;
   3406         }
   3407         // Make sure the uid is valid.
   3408         if (uid < 0) {
   3409             Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
   3410             return;
   3411         }
   3412         int callerUid = Binder.getCallingUid();
   3413         // Only the system server can kill an application
   3414         if (callerUid == Process.SYSTEM_UID) {
   3415             // Post an aysnc message to kill the application
   3416             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
   3417             msg.arg1 = uid;
   3418             msg.arg2 = 0;
   3419             msg.obj = pkg;
   3420             mHandler.sendMessage(msg);
   3421         } else {
   3422             throw new SecurityException(callerUid + " cannot kill pkg: " +
   3423                     pkg);
   3424         }
   3425     }
   3426 
   3427     public void closeSystemDialogs(String reason) {
   3428         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
   3429         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   3430         if (reason != null) {
   3431             intent.putExtra("reason", reason);
   3432         }
   3433 
   3434         final int uid = Binder.getCallingUid();
   3435         final long origId = Binder.clearCallingIdentity();
   3436         synchronized (this) {
   3437             int i = mWatchers.beginBroadcast();
   3438             while (i > 0) {
   3439                 i--;
   3440                 IActivityWatcher w = mWatchers.getBroadcastItem(i);
   3441                 if (w != null) {
   3442                     try {
   3443                         w.closingSystemDialogs(reason);
   3444                     } catch (RemoteException e) {
   3445                     }
   3446                 }
   3447             }
   3448             mWatchers.finishBroadcast();
   3449 
   3450             mWindowManager.closeSystemDialogs(reason);
   3451 
   3452             for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
   3453                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   3454                 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
   3455                     r.stack.finishActivityLocked(r, i,
   3456                             Activity.RESULT_CANCELED, null, "close-sys");
   3457                 }
   3458             }
   3459 
   3460             broadcastIntentLocked(null, null, intent, null,
   3461                     null, 0, null, null, null, false, false, -1, uid);
   3462         }
   3463         Binder.restoreCallingIdentity(origId);
   3464     }
   3465 
   3466     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
   3467             throws RemoteException {
   3468         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
   3469         for (int i=pids.length-1; i>=0; i--) {
   3470             infos[i] = new Debug.MemoryInfo();
   3471             Debug.getMemoryInfo(pids[i], infos[i]);
   3472         }
   3473         return infos;
   3474     }
   3475 
   3476     public long[] getProcessPss(int[] pids) throws RemoteException {
   3477         long[] pss = new long[pids.length];
   3478         for (int i=pids.length-1; i>=0; i--) {
   3479             pss[i] = Debug.getPss(pids[i]);
   3480         }
   3481         return pss;
   3482     }
   3483 
   3484     public void killApplicationProcess(String processName, int uid) {
   3485         if (processName == null) {
   3486             return;
   3487         }
   3488 
   3489         int callerUid = Binder.getCallingUid();
   3490         // Only the system server can kill an application
   3491         if (callerUid == Process.SYSTEM_UID) {
   3492             synchronized (this) {
   3493                 ProcessRecord app = getProcessRecordLocked(processName, uid);
   3494                 if (app != null && app.thread != null) {
   3495                     try {
   3496                         app.thread.scheduleSuicide();
   3497                     } catch (RemoteException e) {
   3498                         // If the other end already died, then our work here is done.
   3499                     }
   3500                 } else {
   3501                     Slog.w(TAG, "Process/uid not found attempting kill of "
   3502                             + processName + " / " + uid);
   3503                 }
   3504             }
   3505         } else {
   3506             throw new SecurityException(callerUid + " cannot kill app process: " +
   3507                     processName);
   3508         }
   3509     }
   3510 
   3511     private void forceStopPackageLocked(final String packageName, int uid) {
   3512         forceStopPackageLocked(packageName, uid, false, false, true, false);
   3513         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
   3514                 Uri.fromParts("package", packageName, null));
   3515         if (!mProcessesReady) {
   3516             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   3517         }
   3518         intent.putExtra(Intent.EXTRA_UID, uid);
   3519         broadcastIntentLocked(null, null, intent,
   3520                 null, null, 0, null, null, null,
   3521                 false, false, MY_PID, Process.SYSTEM_UID);
   3522     }
   3523 
   3524     private final boolean killPackageProcessesLocked(String packageName, int uid,
   3525             int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
   3526             boolean evenPersistent, String reason) {
   3527         ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   3528 
   3529         // Remove all processes this package may have touched: all with the
   3530         // same UID (except for the system or root user), and all whose name
   3531         // matches the package name.
   3532         final String procNamePrefix = packageName + ":";
   3533         for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   3534             final int NA = apps.size();
   3535             for (int ia=0; ia<NA; ia++) {
   3536                 ProcessRecord app = apps.valueAt(ia);
   3537                 if (app.persistent && !evenPersistent) {
   3538                     // we don't kill persistent processes
   3539                     continue;
   3540                 }
   3541                 if (app.removed) {
   3542                     if (doit) {
   3543                         procs.add(app);
   3544                     }
   3545                 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
   3546                         || app.processName.equals(packageName)
   3547                         || app.processName.startsWith(procNamePrefix)) {
   3548                     if (app.setAdj >= minOomAdj) {
   3549                         if (!doit) {
   3550                             return true;
   3551                         }
   3552                         app.removed = true;
   3553                         procs.add(app);
   3554                     }
   3555                 }
   3556             }
   3557         }
   3558 
   3559         int N = procs.size();
   3560         for (int i=0; i<N; i++) {
   3561             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
   3562         }
   3563         return N > 0;
   3564     }
   3565 
   3566     private final boolean forceStopPackageLocked(String name, int uid,
   3567             boolean callerWillRestart, boolean purgeCache, boolean doit,
   3568             boolean evenPersistent) {
   3569         int i;
   3570         int N;
   3571 
   3572         if (uid < 0) {
   3573             try {
   3574                 uid = AppGlobals.getPackageManager().getPackageUid(name);
   3575             } catch (RemoteException e) {
   3576             }
   3577         }
   3578 
   3579         if (doit) {
   3580             Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
   3581 
   3582             Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
   3583             while (badApps.hasNext()) {
   3584                 SparseArray<Long> ba = badApps.next();
   3585                 if (ba.get(uid) != null) {
   3586                     badApps.remove();
   3587                 }
   3588             }
   3589         }
   3590 
   3591         boolean didSomething = killPackageProcessesLocked(name, uid, -100,
   3592                 callerWillRestart, false, doit, evenPersistent, "force stop");
   3593 
   3594         TaskRecord lastTask = null;
   3595         for (i=0; i<mMainStack.mHistory.size(); i++) {
   3596             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   3597             final boolean samePackage = r.packageName.equals(name);
   3598             if ((samePackage || r.task == lastTask)
   3599                     && (r.app == null || evenPersistent || !r.app.persistent)) {
   3600                 if (!doit) {
   3601                     if (r.finishing) {
   3602                         // If this activity is just finishing, then it is not
   3603                         // interesting as far as something to stop.
   3604                         continue;
   3605                     }
   3606                     return true;
   3607                 }
   3608                 didSomething = true;
   3609                 Slog.i(TAG, "  Force finishing activity " + r);
   3610                 if (samePackage) {
   3611                     if (r.app != null) {
   3612                         r.app.removed = true;
   3613                     }
   3614                     r.app = null;
   3615                 }
   3616                 lastTask = r.task;
   3617                 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
   3618                         null, "force-stop")) {
   3619                     i--;
   3620                 }
   3621             }
   3622         }
   3623 
   3624         ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
   3625         for (ServiceRecord service : mServices.values()) {
   3626             if (service.packageName.equals(name)
   3627                     && (service.app == null || evenPersistent || !service.app.persistent)) {
   3628                 if (!doit) {
   3629                     return true;
   3630                 }
   3631                 didSomething = true;
   3632                 Slog.i(TAG, "  Force stopping service " + service);
   3633                 if (service.app != null) {
   3634                     service.app.removed = true;
   3635                 }
   3636                 service.app = null;
   3637                 services.add(service);
   3638             }
   3639         }
   3640 
   3641         N = services.size();
   3642         for (i=0; i<N; i++) {
   3643             bringDownServiceLocked(services.get(i), true);
   3644         }
   3645 
   3646         ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
   3647         for (ContentProviderRecord provider : mProvidersByClass.values()) {
   3648             if (provider.info.packageName.equals(name)
   3649                     && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
   3650                 if (!doit) {
   3651                     return true;
   3652                 }
   3653                 didSomething = true;
   3654                 providers.add(provider);
   3655             }
   3656         }
   3657 
   3658         N = providers.size();
   3659         for (i=0; i<N; i++) {
   3660             removeDyingProviderLocked(null, providers.get(i));
   3661         }
   3662 
   3663         if (doit) {
   3664             if (purgeCache) {
   3665                 AttributeCache ac = AttributeCache.instance();
   3666                 if (ac != null) {
   3667                     ac.removePackage(name);
   3668                 }
   3669             }
   3670             if (mBooted) {
   3671                 mMainStack.resumeTopActivityLocked(null);
   3672                 mMainStack.scheduleIdleLocked();
   3673             }
   3674         }
   3675 
   3676         return didSomething;
   3677     }
   3678 
   3679     private final boolean removeProcessLocked(ProcessRecord app,
   3680             boolean callerWillRestart, boolean allowRestart, String reason) {
   3681         final String name = app.processName;
   3682         final int uid = app.info.uid;
   3683         if (DEBUG_PROCESSES) Slog.d(
   3684             TAG, "Force removing proc " + app.toShortString() + " (" + name
   3685             + "/" + uid + ")");
   3686 
   3687         mProcessNames.remove(name, uid);
   3688         if (mHeavyWeightProcess == app) {
   3689             mHeavyWeightProcess = null;
   3690             mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
   3691         }
   3692         boolean needRestart = false;
   3693         if (app.pid > 0 && app.pid != MY_PID) {
   3694             int pid = app.pid;
   3695             synchronized (mPidsSelfLocked) {
   3696                 mPidsSelfLocked.remove(pid);
   3697                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   3698             }
   3699             Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
   3700             handleAppDiedLocked(app, true, allowRestart);
   3701             mLruProcesses.remove(app);
   3702             Process.killProcessQuiet(pid);
   3703 
   3704             if (app.persistent) {
   3705                 if (!callerWillRestart) {
   3706                     addAppLocked(app.info);
   3707                 } else {
   3708                     needRestart = true;
   3709                 }
   3710             }
   3711         } else {
   3712             mRemovedProcesses.add(app);
   3713         }
   3714 
   3715         return needRestart;
   3716     }
   3717 
   3718     private final void processStartTimedOutLocked(ProcessRecord app) {
   3719         final int pid = app.pid;
   3720         boolean gone = false;
   3721         synchronized (mPidsSelfLocked) {
   3722             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
   3723             if (knownApp != null && knownApp.thread == null) {
   3724                 mPidsSelfLocked.remove(pid);
   3725                 gone = true;
   3726             }
   3727         }
   3728 
   3729         if (gone) {
   3730             Slog.w(TAG, "Process " + app + " failed to attach");
   3731             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
   3732                     app.processName);
   3733             mProcessNames.remove(app.processName, app.info.uid);
   3734             if (mHeavyWeightProcess == app) {
   3735                 mHeavyWeightProcess = null;
   3736                 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
   3737             }
   3738             // Take care of any launching providers waiting for this process.
   3739             checkAppInLaunchingProvidersLocked(app, true);
   3740             // Take care of any services that are waiting for the process.
   3741             for (int i=0; i<mPendingServices.size(); i++) {
   3742                 ServiceRecord sr = mPendingServices.get(i);
   3743                 if (app.info.uid == sr.appInfo.uid
   3744                         && app.processName.equals(sr.processName)) {
   3745                     Slog.w(TAG, "Forcing bringing down service: " + sr);
   3746                     mPendingServices.remove(i);
   3747                     i--;
   3748                     bringDownServiceLocked(sr, true);
   3749                 }
   3750             }
   3751             EventLog.writeEvent(EventLogTags.AM_KILL, pid,
   3752                     app.processName, app.setAdj, "start timeout");
   3753             Process.killProcessQuiet(pid);
   3754             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
   3755                 Slog.w(TAG, "Unattached app died before backup, skipping");
   3756                 try {
   3757                     IBackupManager bm = IBackupManager.Stub.asInterface(
   3758                             ServiceManager.getService(Context.BACKUP_SERVICE));
   3759                     bm.agentDisconnected(app.info.packageName);
   3760                 } catch (RemoteException e) {
   3761                     // Can't happen; the backup manager is local
   3762                 }
   3763             }
   3764             if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
   3765                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   3766                 mPendingBroadcast.state = BroadcastRecord.IDLE;
   3767                 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
   3768                 mPendingBroadcast = null;
   3769                 scheduleBroadcastsLocked();
   3770             }
   3771         } else {
   3772             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
   3773         }
   3774     }
   3775 
   3776     private final boolean attachApplicationLocked(IApplicationThread thread,
   3777             int pid) {
   3778 
   3779         // Find the application record that is being attached...  either via
   3780         // the pid if we are running in multiple processes, or just pull the
   3781         // next app record if we are emulating process with anonymous threads.
   3782         ProcessRecord app;
   3783         if (pid != MY_PID && pid >= 0) {
   3784             synchronized (mPidsSelfLocked) {
   3785                 app = mPidsSelfLocked.get(pid);
   3786             }
   3787         } else {
   3788             app = null;
   3789         }
   3790 
   3791         if (app == null) {
   3792             Slog.w(TAG, "No pending application record for pid " + pid
   3793                     + " (IApplicationThread " + thread + "); dropping process");
   3794             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
   3795             if (pid > 0 && pid != MY_PID) {
   3796                 Process.killProcessQuiet(pid);
   3797             } else {
   3798                 try {
   3799                     thread.scheduleExit();
   3800                 } catch (Exception e) {
   3801                     // Ignore exceptions.
   3802                 }
   3803             }
   3804             return false;
   3805         }
   3806 
   3807         // If this application record is still attached to a previous
   3808         // process, clean it up now.
   3809         if (app.thread != null) {
   3810             handleAppDiedLocked(app, true, true);
   3811         }
   3812 
   3813         // Tell the process all about itself.
   3814 
   3815         if (localLOGV) Slog.v(
   3816                 TAG, "Binding process pid " + pid + " to record " + app);
   3817 
   3818         String processName = app.processName;
   3819         try {
   3820             AppDeathRecipient adr = new AppDeathRecipient(
   3821                     app, pid, thread);
   3822             thread.asBinder().linkToDeath(adr, 0);
   3823             app.deathRecipient = adr;
   3824         } catch (RemoteException e) {
   3825             app.resetPackageList();
   3826             startProcessLocked(app, "link fail", processName);
   3827             return false;
   3828         }
   3829 
   3830         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
   3831 
   3832         app.thread = thread;
   3833         app.curAdj = app.setAdj = -100;
   3834         app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
   3835         app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   3836         app.forcingToForeground = null;
   3837         app.foregroundServices = false;
   3838         app.hasShownUi = false;
   3839         app.debugging = false;
   3840 
   3841         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   3842 
   3843         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
   3844         List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
   3845 
   3846         if (!normalMode) {
   3847             Slog.i(TAG, "Launching preboot mode app: " + app);
   3848         }
   3849 
   3850         if (localLOGV) Slog.v(
   3851             TAG, "New app record " + app
   3852             + " thread=" + thread.asBinder() + " pid=" + pid);
   3853         try {
   3854             int testMode = IApplicationThread.DEBUG_OFF;
   3855             if (mDebugApp != null && mDebugApp.equals(processName)) {
   3856                 testMode = mWaitForDebugger
   3857                     ? IApplicationThread.DEBUG_WAIT
   3858                     : IApplicationThread.DEBUG_ON;
   3859                 app.debugging = true;
   3860                 if (mDebugTransient) {
   3861                     mDebugApp = mOrigDebugApp;
   3862                     mWaitForDebugger = mOrigWaitForDebugger;
   3863                 }
   3864             }
   3865             String profileFile = app.instrumentationProfileFile;
   3866             ParcelFileDescriptor profileFd = null;
   3867             boolean profileAutoStop = false;
   3868             if (mProfileApp != null && mProfileApp.equals(processName)) {
   3869                 mProfileProc = app;
   3870                 profileFile = mProfileFile;
   3871                 profileFd = mProfileFd;
   3872                 profileAutoStop = mAutoStopProfiler;
   3873             }
   3874 
   3875             // If the app is being launched for restore or full backup, set it up specially
   3876             boolean isRestrictedBackupMode = false;
   3877             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
   3878                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
   3879                         || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
   3880                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
   3881             }
   3882 
   3883             ensurePackageDexOpt(app.instrumentationInfo != null
   3884                     ? app.instrumentationInfo.packageName
   3885                     : app.info.packageName);
   3886             if (app.instrumentationClass != null) {
   3887                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
   3888             }
   3889             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
   3890                     + processName + " with config " + mConfiguration);
   3891             ApplicationInfo appInfo = app.instrumentationInfo != null
   3892                     ? app.instrumentationInfo : app.info;
   3893             app.compat = compatibilityInfoForPackageLocked(appInfo);
   3894             if (profileFd != null) {
   3895                 profileFd = profileFd.dup();
   3896             }
   3897             thread.bindApplication(processName, appInfo, providers,
   3898                     app.instrumentationClass, profileFile, profileFd, profileAutoStop,
   3899                     app.instrumentationArguments, app.instrumentationWatcher, testMode,
   3900                     isRestrictedBackupMode || !normalMode, app.persistent,
   3901                     new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
   3902                     mCoreSettingsObserver.getCoreSettingsLocked());
   3903             updateLruProcessLocked(app, false, true);
   3904             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
   3905         } catch (Exception e) {
   3906             // todo: Yikes!  What should we do?  For now we will try to
   3907             // start another process, but that could easily get us in
   3908             // an infinite loop of restarting processes...
   3909             Slog.w(TAG, "Exception thrown during bind!", e);
   3910 
   3911             app.resetPackageList();
   3912             app.unlinkDeathRecipient();
   3913             startProcessLocked(app, "bind fail", processName);
   3914             return false;
   3915         }
   3916 
   3917         // Remove this record from the list of starting applications.
   3918         mPersistentStartingProcesses.remove(app);
   3919         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   3920                 "Attach application locked removing on hold: " + app);
   3921         mProcessesOnHold.remove(app);
   3922 
   3923         boolean badApp = false;
   3924         boolean didSomething = false;
   3925 
   3926         // See if the top visible activity is waiting to run in this process...
   3927         ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
   3928         if (hr != null && normalMode) {
   3929             if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
   3930                     && processName.equals(hr.processName)) {
   3931                 try {
   3932                     if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
   3933                         didSomething = true;
   3934                     }
   3935                 } catch (Exception e) {
   3936                     Slog.w(TAG, "Exception in new application when starting activity "
   3937                           + hr.intent.getComponent().flattenToShortString(), e);
   3938                     badApp = true;
   3939                 }
   3940             } else {
   3941                 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
   3942             }
   3943         }
   3944 
   3945         // Find any services that should be running in this process...
   3946         if (!badApp && mPendingServices.size() > 0) {
   3947             ServiceRecord sr = null;
   3948             try {
   3949                 for (int i=0; i<mPendingServices.size(); i++) {
   3950                     sr = mPendingServices.get(i);
   3951                     if (app.info.uid != sr.appInfo.uid
   3952                             || !processName.equals(sr.processName)) {
   3953                         continue;
   3954                     }
   3955 
   3956                     mPendingServices.remove(i);
   3957                     i--;
   3958                     realStartServiceLocked(sr, app);
   3959                     didSomething = true;
   3960                 }
   3961             } catch (Exception e) {
   3962                 Slog.w(TAG, "Exception in new application when starting service "
   3963                       + sr.shortName, e);
   3964                 badApp = true;
   3965             }
   3966         }
   3967 
   3968         // Check if the next broadcast receiver is in this process...
   3969         BroadcastRecord br = mPendingBroadcast;
   3970         if (!badApp && br != null && br.curApp == app) {
   3971             try {
   3972                 mPendingBroadcast = null;
   3973                 processCurBroadcastLocked(br, app);
   3974                 didSomething = true;
   3975             } catch (Exception e) {
   3976                 Slog.w(TAG, "Exception in new application when starting receiver "
   3977                       + br.curComponent.flattenToShortString(), e);
   3978                 badApp = true;
   3979                 logBroadcastReceiverDiscardLocked(br);
   3980                 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
   3981                         br.resultExtras, br.resultAbort, true);
   3982                 scheduleBroadcastsLocked();
   3983                 // We need to reset the state if we fails to start the receiver.
   3984                 br.state = BroadcastRecord.IDLE;
   3985             }
   3986         }
   3987 
   3988         // Check whether the next backup agent is in this process...
   3989         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
   3990             if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
   3991             ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
   3992             try {
   3993                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
   3994                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
   3995                         mBackupTarget.backupMode);
   3996             } catch (Exception e) {
   3997                 Slog.w(TAG, "Exception scheduling backup agent creation: ");
   3998                 e.printStackTrace();
   3999             }
   4000         }
   4001 
   4002         if (badApp) {
   4003             // todo: Also need to kill application to deal with all
   4004             // kinds of exceptions.
   4005             handleAppDiedLocked(app, false, true);
   4006             return false;
   4007         }
   4008 
   4009         if (!didSomething) {
   4010             updateOomAdjLocked();
   4011         }
   4012 
   4013         return true;
   4014     }
   4015 
   4016     public final void attachApplication(IApplicationThread thread) {
   4017         synchronized (this) {
   4018             int callingPid = Binder.getCallingPid();
   4019             final long origId = Binder.clearCallingIdentity();
   4020             attachApplicationLocked(thread, callingPid);
   4021             Binder.restoreCallingIdentity(origId);
   4022         }
   4023     }
   4024 
   4025     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
   4026         final long origId = Binder.clearCallingIdentity();
   4027         ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
   4028         if (stopProfiling) {
   4029             synchronized (this) {
   4030                 if (mProfileProc == r.app) {
   4031                     if (mProfileFd != null) {
   4032                         try {
   4033                             mProfileFd.close();
   4034                         } catch (IOException e) {
   4035                         }
   4036                         clearProfilerLocked();
   4037                     }
   4038                 }
   4039             }
   4040         }
   4041         Binder.restoreCallingIdentity(origId);
   4042     }
   4043 
   4044     void enableScreenAfterBoot() {
   4045         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
   4046                 SystemClock.uptimeMillis());
   4047         mWindowManager.enableScreenAfterBoot();
   4048     }
   4049 
   4050     public void showBootMessage(final CharSequence msg, final boolean always) {
   4051         mWindowManager.showBootMessage(msg, always);
   4052     }
   4053 
   4054     public void dismissKeyguardOnNextActivity() {
   4055         synchronized (this) {
   4056             mMainStack.dismissKeyguardOnNextActivityLocked();
   4057         }
   4058     }
   4059 
   4060     final void finishBooting() {
   4061         IntentFilter pkgFilter = new IntentFilter();
   4062         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
   4063         pkgFilter.addDataScheme("package");
   4064         mContext.registerReceiver(new BroadcastReceiver() {
   4065             @Override
   4066             public void onReceive(Context context, Intent intent) {
   4067                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
   4068                 if (pkgs != null) {
   4069                     for (String pkg : pkgs) {
   4070                         synchronized (ActivityManagerService.this) {
   4071                           if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
   4072                               setResultCode(Activity.RESULT_OK);
   4073                               return;
   4074                           }
   4075                        }
   4076                     }
   4077                 }
   4078             }
   4079         }, pkgFilter);
   4080 
   4081         synchronized (this) {
   4082             // Ensure that any processes we had put on hold are now started
   4083             // up.
   4084             final int NP = mProcessesOnHold.size();
   4085             if (NP > 0) {
   4086                 ArrayList<ProcessRecord> procs =
   4087                     new ArrayList<ProcessRecord>(mProcessesOnHold);
   4088                 for (int ip=0; ip<NP; ip++) {
   4089                     if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
   4090                             + procs.get(ip));
   4091                     startProcessLocked(procs.get(ip), "on-hold", null);
   4092                 }
   4093             }
   4094 
   4095             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   4096                 // Start looking for apps that are abusing wake locks.
   4097                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   4098                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   4099                 // Tell anyone interested that we are done booting!
   4100                 SystemProperties.set("sys.boot_completed", "1");
   4101                 broadcastIntentLocked(null, null,
   4102                         new Intent(Intent.ACTION_BOOT_COMPLETED, null),
   4103                         null, null, 0, null, null,
   4104                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
   4105                         false, false, MY_PID, Process.SYSTEM_UID);
   4106             }
   4107         }
   4108     }
   4109 
   4110     final void ensureBootCompleted() {
   4111         boolean booting;
   4112         boolean enableScreen;
   4113         synchronized (this) {
   4114             booting = mBooting;
   4115             mBooting = false;
   4116             enableScreen = !mBooted;
   4117             mBooted = true;
   4118         }
   4119 
   4120         if (booting) {
   4121             finishBooting();
   4122         }
   4123 
   4124         if (enableScreen) {
   4125             enableScreenAfterBoot();
   4126         }
   4127     }
   4128 
   4129     public final void activityPaused(IBinder token) {
   4130         final long origId = Binder.clearCallingIdentity();
   4131         mMainStack.activityPaused(token, false);
   4132         Binder.restoreCallingIdentity(origId);
   4133     }
   4134 
   4135     public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
   4136             CharSequence description) {
   4137         if (localLOGV) Slog.v(
   4138             TAG, "Activity stopped: token=" + token);
   4139 
   4140         // Refuse possible leaked file descriptors
   4141         if (icicle != null && icicle.hasFileDescriptors()) {
   4142             throw new IllegalArgumentException("File descriptors passed in Bundle");
   4143         }
   4144 
   4145         ActivityRecord r = null;
   4146 
   4147         final long origId = Binder.clearCallingIdentity();
   4148 
   4149         synchronized (this) {
   4150             r = mMainStack.isInStackLocked(token);
   4151             if (r != null) {
   4152                 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
   4153             }
   4154         }
   4155 
   4156         if (r != null) {
   4157             sendPendingThumbnail(r, null, null, null, false);
   4158         }
   4159 
   4160         trimApplications();
   4161 
   4162         Binder.restoreCallingIdentity(origId);
   4163     }
   4164 
   4165     public final void activityDestroyed(IBinder token) {
   4166         if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
   4167         mMainStack.activityDestroyed(token);
   4168     }
   4169 
   4170     public String getCallingPackage(IBinder token) {
   4171         synchronized (this) {
   4172             ActivityRecord r = getCallingRecordLocked(token);
   4173             return r != null && r.app != null ? r.info.packageName : null;
   4174         }
   4175     }
   4176 
   4177     public ComponentName getCallingActivity(IBinder token) {
   4178         synchronized (this) {
   4179             ActivityRecord r = getCallingRecordLocked(token);
   4180             return r != null ? r.intent.getComponent() : null;
   4181         }
   4182     }
   4183 
   4184     private ActivityRecord getCallingRecordLocked(IBinder token) {
   4185         ActivityRecord r = mMainStack.isInStackLocked(token);
   4186         if (r == null) {
   4187             return null;
   4188         }
   4189         return r.resultTo;
   4190     }
   4191 
   4192     public ComponentName getActivityClassForToken(IBinder token) {
   4193         synchronized(this) {
   4194             ActivityRecord r = mMainStack.isInStackLocked(token);
   4195             if (r == null) {
   4196                 return null;
   4197             }
   4198             return r.intent.getComponent();
   4199         }
   4200     }
   4201 
   4202     public String getPackageForToken(IBinder token) {
   4203         synchronized(this) {
   4204             ActivityRecord r = mMainStack.isInStackLocked(token);
   4205             if (r == null) {
   4206                 return null;
   4207             }
   4208             return r.packageName;
   4209         }
   4210     }
   4211 
   4212     public IIntentSender getIntentSender(int type,
   4213             String packageName, IBinder token, String resultWho,
   4214             int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
   4215         // Refuse possible leaked file descriptors
   4216         if (intents != null) {
   4217             if (intents.length < 1) {
   4218                 throw new IllegalArgumentException("Intents array length must be >= 1");
   4219             }
   4220             for (int i=0; i<intents.length; i++) {
   4221                 Intent intent = intents[i];
   4222                 if (intent != null) {
   4223                     if (intent.hasFileDescriptors()) {
   4224                         throw new IllegalArgumentException("File descriptors passed in Intent");
   4225                     }
   4226                     if (type == INTENT_SENDER_BROADCAST &&
   4227                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   4228                         throw new IllegalArgumentException(
   4229                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   4230                     }
   4231                     intents[i] = new Intent(intent);
   4232                 }
   4233             }
   4234             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
   4235                 throw new IllegalArgumentException(
   4236                         "Intent array length does not match resolvedTypes length");
   4237             }
   4238         }
   4239 
   4240         synchronized(this) {
   4241             int callingUid = Binder.getCallingUid();
   4242             try {
   4243                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   4244                     int uid = AppGlobals.getPackageManager()
   4245                             .getPackageUid(packageName);
   4246                     if (uid != Binder.getCallingUid()) {
   4247                         String msg = "Permission Denial: getIntentSender() from pid="
   4248                             + Binder.getCallingPid()
   4249                             + ", uid=" + Binder.getCallingUid()
   4250                             + ", (need uid=" + uid + ")"
   4251                             + " is not allowed to send as package " + packageName;
   4252                         Slog.w(TAG, msg);
   4253                         throw new SecurityException(msg);
   4254                     }
   4255                 }
   4256 
   4257                 return getIntentSenderLocked(type, packageName, callingUid,
   4258                         token, resultWho, requestCode, intents, resolvedTypes, flags);
   4259 
   4260             } catch (RemoteException e) {
   4261                 throw new SecurityException(e);
   4262             }
   4263         }
   4264     }
   4265 
   4266     IIntentSender getIntentSenderLocked(int type,
   4267             String packageName, int callingUid, IBinder token, String resultWho,
   4268             int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
   4269         ActivityRecord activity = null;
   4270         if (type == INTENT_SENDER_ACTIVITY_RESULT) {
   4271             activity = mMainStack.isInStackLocked(token);
   4272             if (activity == null) {
   4273                 return null;
   4274             }
   4275             if (activity.finishing) {
   4276                 return null;
   4277             }
   4278         }
   4279 
   4280         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
   4281         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
   4282         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
   4283         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
   4284                 |PendingIntent.FLAG_UPDATE_CURRENT);
   4285 
   4286         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
   4287                 type, packageName, activity, resultWho,
   4288                 requestCode, intents, resolvedTypes, flags);
   4289         WeakReference<PendingIntentRecord> ref;
   4290         ref = mIntentSenderRecords.get(key);
   4291         PendingIntentRecord rec = ref != null ? ref.get() : null;
   4292         if (rec != null) {
   4293             if (!cancelCurrent) {
   4294                 if (updateCurrent) {
   4295                     if (rec.key.requestIntent != null) {
   4296                         rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
   4297                     }
   4298                     if (intents != null) {
   4299                         intents[intents.length-1] = rec.key.requestIntent;
   4300                         rec.key.allIntents = intents;
   4301                         rec.key.allResolvedTypes = resolvedTypes;
   4302                     } else {
   4303                         rec.key.allIntents = null;
   4304                         rec.key.allResolvedTypes = null;
   4305                     }
   4306                 }
   4307                 return rec;
   4308             }
   4309             rec.canceled = true;
   4310             mIntentSenderRecords.remove(key);
   4311         }
   4312         if (noCreate) {
   4313             return rec;
   4314         }
   4315         rec = new PendingIntentRecord(this, key, callingUid);
   4316         mIntentSenderRecords.put(key, rec.ref);
   4317         if (type == INTENT_SENDER_ACTIVITY_RESULT) {
   4318             if (activity.pendingResults == null) {
   4319                 activity.pendingResults
   4320                         = new HashSet<WeakReference<PendingIntentRecord>>();
   4321             }
   4322             activity.pendingResults.add(rec.ref);
   4323         }
   4324         return rec;
   4325     }
   4326 
   4327     public void cancelIntentSender(IIntentSender sender) {
   4328         if (!(sender instanceof PendingIntentRecord)) {
   4329             return;
   4330         }
   4331         synchronized(this) {
   4332             PendingIntentRecord rec = (PendingIntentRecord)sender;
   4333             try {
   4334                 int uid = AppGlobals.getPackageManager()
   4335                         .getPackageUid(rec.key.packageName);
   4336                 if (uid != Binder.getCallingUid()) {
   4337                     String msg = "Permission Denial: cancelIntentSender() from pid="
   4338                         + Binder.getCallingPid()
   4339                         + ", uid=" + Binder.getCallingUid()
   4340                         + " is not allowed to cancel packges "
   4341                         + rec.key.packageName;
   4342                     Slog.w(TAG, msg);
   4343                     throw new SecurityException(msg);
   4344                 }
   4345             } catch (RemoteException e) {
   4346                 throw new SecurityException(e);
   4347             }
   4348             cancelIntentSenderLocked(rec, true);
   4349         }
   4350     }
   4351 
   4352     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
   4353         rec.canceled = true;
   4354         mIntentSenderRecords.remove(rec.key);
   4355         if (cleanActivity && rec.key.activity != null) {
   4356             rec.key.activity.pendingResults.remove(rec.ref);
   4357         }
   4358     }
   4359 
   4360     public String getPackageForIntentSender(IIntentSender pendingResult) {
   4361         if (!(pendingResult instanceof PendingIntentRecord)) {
   4362             return null;
   4363         }
   4364         try {
   4365             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   4366             return res.key.packageName;
   4367         } catch (ClassCastException e) {
   4368         }
   4369         return null;
   4370     }
   4371 
   4372     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
   4373         if (!(pendingResult instanceof PendingIntentRecord)) {
   4374             return false;
   4375         }
   4376         try {
   4377             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   4378             if (res.key.allIntents == null) {
   4379                 return false;
   4380             }
   4381             for (int i=0; i<res.key.allIntents.length; i++) {
   4382                 Intent intent = res.key.allIntents[i];
   4383                 if (intent.getPackage() != null && intent.getComponent() != null) {
   4384                     return false;
   4385                 }
   4386             }
   4387             return true;
   4388         } catch (ClassCastException e) {
   4389         }
   4390         return false;
   4391     }
   4392 
   4393     public void setProcessLimit(int max) {
   4394         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   4395                 "setProcessLimit()");
   4396         synchronized (this) {
   4397             mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
   4398             mProcessLimitOverride = max;
   4399         }
   4400         trimApplications();
   4401     }
   4402 
   4403     public int getProcessLimit() {
   4404         synchronized (this) {
   4405             return mProcessLimitOverride;
   4406         }
   4407     }
   4408 
   4409     void foregroundTokenDied(ForegroundToken token) {
   4410         synchronized (ActivityManagerService.this) {
   4411             synchronized (mPidsSelfLocked) {
   4412                 ForegroundToken cur
   4413                     = mForegroundProcesses.get(token.pid);
   4414                 if (cur != token) {
   4415                     return;
   4416                 }
   4417                 mForegroundProcesses.remove(token.pid);
   4418                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
   4419                 if (pr == null) {
   4420                     return;
   4421                 }
   4422                 pr.forcingToForeground = null;
   4423                 pr.foregroundServices = false;
   4424             }
   4425             updateOomAdjLocked();
   4426         }
   4427     }
   4428 
   4429     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
   4430         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   4431                 "setProcessForeground()");
   4432         synchronized(this) {
   4433             boolean changed = false;
   4434 
   4435             synchronized (mPidsSelfLocked) {
   4436                 ProcessRecord pr = mPidsSelfLocked.get(pid);
   4437                 if (pr == null) {
   4438                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
   4439                     return;
   4440                 }
   4441                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
   4442                 if (oldToken != null) {
   4443                     oldToken.token.unlinkToDeath(oldToken, 0);
   4444                     mForegroundProcesses.remove(pid);
   4445                     pr.forcingToForeground = null;
   4446                     changed = true;
   4447                 }
   4448                 if (isForeground && token != null) {
   4449                     ForegroundToken newToken = new ForegroundToken() {
   4450                         public void binderDied() {
   4451                             foregroundTokenDied(this);
   4452                         }
   4453                     };
   4454                     newToken.pid = pid;
   4455                     newToken.token = token;
   4456                     try {
   4457                         token.linkToDeath(newToken, 0);
   4458                         mForegroundProcesses.put(pid, newToken);
   4459                         pr.forcingToForeground = token;
   4460                         changed = true;
   4461                     } catch (RemoteException e) {
   4462                         // If the process died while doing this, we will later
   4463                         // do the cleanup with the process death link.
   4464                     }
   4465                 }
   4466             }
   4467 
   4468             if (changed) {
   4469                 updateOomAdjLocked();
   4470             }
   4471         }
   4472     }
   4473 
   4474     // =========================================================
   4475     // PERMISSIONS
   4476     // =========================================================
   4477 
   4478     static class PermissionController extends IPermissionController.Stub {
   4479         ActivityManagerService mActivityManagerService;
   4480         PermissionController(ActivityManagerService activityManagerService) {
   4481             mActivityManagerService = activityManagerService;
   4482         }
   4483 
   4484         public boolean checkPermission(String permission, int pid, int uid) {
   4485             return mActivityManagerService.checkPermission(permission, pid,
   4486                     uid) == PackageManager.PERMISSION_GRANTED;
   4487         }
   4488     }
   4489 
   4490     /**
   4491      * This can be called with or without the global lock held.
   4492      */
   4493     int checkComponentPermission(String permission, int pid, int uid,
   4494             int owningUid, boolean exported) {
   4495         // We might be performing an operation on behalf of an indirect binder
   4496         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
   4497         // client identity accordingly before proceeding.
   4498         Identity tlsIdentity = sCallerIdentity.get();
   4499         if (tlsIdentity != null) {
   4500             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
   4501                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
   4502             uid = tlsIdentity.uid;
   4503             pid = tlsIdentity.pid;
   4504         }
   4505 
   4506         // Root, system server and our own process get to do everything.
   4507         if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
   4508             return PackageManager.PERMISSION_GRANTED;
   4509         }
   4510         // If there is a uid that owns whatever is being accessed, it has
   4511         // blanket access to it regardless of the permissions it requires.
   4512         if (owningUid >= 0 && uid == owningUid) {
   4513             return PackageManager.PERMISSION_GRANTED;
   4514         }
   4515         // If the target is not exported, then nobody else can get to it.
   4516         if (!exported) {
   4517             Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
   4518             return PackageManager.PERMISSION_DENIED;
   4519         }
   4520         if (permission == null) {
   4521             return PackageManager.PERMISSION_GRANTED;
   4522         }
   4523         try {
   4524             return AppGlobals.getPackageManager()
   4525                     .checkUidPermission(permission, uid);
   4526         } catch (RemoteException e) {
   4527             // Should never happen, but if it does... deny!
   4528             Slog.e(TAG, "PackageManager is dead?!?", e);
   4529         }
   4530         return PackageManager.PERMISSION_DENIED;
   4531     }
   4532 
   4533     /**
   4534      * As the only public entry point for permissions checking, this method
   4535      * can enforce the semantic that requesting a check on a null global
   4536      * permission is automatically denied.  (Internally a null permission
   4537      * string is used when calling {@link #checkComponentPermission} in cases
   4538      * when only uid-based security is needed.)
   4539      *
   4540      * This can be called with or without the global lock held.
   4541      */
   4542     public int checkPermission(String permission, int pid, int uid) {
   4543         if (permission == null) {
   4544             return PackageManager.PERMISSION_DENIED;
   4545         }
   4546         return checkComponentPermission(permission, pid, uid, -1, true);
   4547     }
   4548 
   4549     /**
   4550      * Binder IPC calls go through the public entry point.
   4551      * This can be called with or without the global lock held.
   4552      */
   4553     int checkCallingPermission(String permission) {
   4554         return checkPermission(permission,
   4555                 Binder.getCallingPid(),
   4556                 Binder.getCallingUid());
   4557     }
   4558 
   4559     /**
   4560      * This can be called with or without the global lock held.
   4561      */
   4562     void enforceCallingPermission(String permission, String func) {
   4563         if (checkCallingPermission(permission)
   4564                 == PackageManager.PERMISSION_GRANTED) {
   4565             return;
   4566         }
   4567 
   4568         String msg = "Permission Denial: " + func + " from pid="
   4569                 + Binder.getCallingPid()
   4570                 + ", uid=" + Binder.getCallingUid()
   4571                 + " requires " + permission;
   4572         Slog.w(TAG, msg);
   4573         throw new SecurityException(msg);
   4574     }
   4575 
   4576     private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
   4577             ProviderInfo pi, Uri uri, int uid, int modeFlags) {
   4578         boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
   4579         boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
   4580         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4581                 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
   4582         try {
   4583             // Is the component private from the target uid?
   4584             final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
   4585 
   4586             // Acceptable if the there is no read permission needed from the
   4587             // target or the target is holding the read permission.
   4588             if (!readPerm) {
   4589                 if ((!prv && pi.readPermission == null) ||
   4590                         (pm.checkUidPermission(pi.readPermission, uid)
   4591                                 == PackageManager.PERMISSION_GRANTED)) {
   4592                     readPerm = true;
   4593                 }
   4594             }
   4595 
   4596             // Acceptable if the there is no write permission needed from the
   4597             // target or the target is holding the read permission.
   4598             if (!writePerm) {
   4599                 if (!prv && (pi.writePermission == null) ||
   4600                         (pm.checkUidPermission(pi.writePermission, uid)
   4601                                 == PackageManager.PERMISSION_GRANTED)) {
   4602                     writePerm = true;
   4603                 }
   4604             }
   4605 
   4606             // Acceptable if there is a path permission matching the URI that
   4607             // the target holds the permission on.
   4608             PathPermission[] pps = pi.pathPermissions;
   4609             if (pps != null && (!readPerm || !writePerm)) {
   4610                 final String path = uri.getPath();
   4611                 int i = pps.length;
   4612                 while (i > 0 && (!readPerm || !writePerm)) {
   4613                     i--;
   4614                     PathPermission pp = pps[i];
   4615                     if (!readPerm) {
   4616                         final String pprperm = pp.getReadPermission();
   4617                         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
   4618                                 + pprperm + " for " + pp.getPath()
   4619                                 + ": match=" + pp.match(path)
   4620                                 + " check=" + pm.checkUidPermission(pprperm, uid));
   4621                         if (pprperm != null && pp.match(path) &&
   4622                                 (pm.checkUidPermission(pprperm, uid)
   4623                                         == PackageManager.PERMISSION_GRANTED)) {
   4624                             readPerm = true;
   4625                         }
   4626                     }
   4627                     if (!writePerm) {
   4628                         final String ppwperm = pp.getWritePermission();
   4629                         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
   4630                                 + ppwperm + " for " + pp.getPath()
   4631                                 + ": match=" + pp.match(path)
   4632                                 + " check=" + pm.checkUidPermission(ppwperm, uid));
   4633                         if (ppwperm != null && pp.match(path) &&
   4634                                 (pm.checkUidPermission(ppwperm, uid)
   4635                                         == PackageManager.PERMISSION_GRANTED)) {
   4636                             writePerm = true;
   4637                         }
   4638                     }
   4639                 }
   4640             }
   4641         } catch (RemoteException e) {
   4642             return false;
   4643         }
   4644 
   4645         return readPerm && writePerm;
   4646     }
   4647 
   4648     private final boolean checkUriPermissionLocked(Uri uri, int uid,
   4649             int modeFlags) {
   4650         // Root gets to do everything.
   4651         if (uid == 0) {
   4652             return true;
   4653         }
   4654         HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   4655         if (perms == null) return false;
   4656         UriPermission perm = perms.get(uri);
   4657         if (perm == null) return false;
   4658         return (modeFlags&perm.modeFlags) == modeFlags;
   4659     }
   4660 
   4661     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
   4662         // Another redirected-binder-call permissions check as in
   4663         // {@link checkComponentPermission}.
   4664         Identity tlsIdentity = sCallerIdentity.get();
   4665         if (tlsIdentity != null) {
   4666             uid = tlsIdentity.uid;
   4667             pid = tlsIdentity.pid;
   4668         }
   4669 
   4670         // Our own process gets to do everything.
   4671         if (pid == MY_PID) {
   4672             return PackageManager.PERMISSION_GRANTED;
   4673         }
   4674         synchronized(this) {
   4675             return checkUriPermissionLocked(uri, uid, modeFlags)
   4676                     ? PackageManager.PERMISSION_GRANTED
   4677                     : PackageManager.PERMISSION_DENIED;
   4678         }
   4679     }
   4680 
   4681     /**
   4682      * Check if the targetPkg can be granted permission to access uri by
   4683      * the callingUid using the given modeFlags.  Throws a security exception
   4684      * if callingUid is not allowed to do this.  Returns the uid of the target
   4685      * if the URI permission grant should be performed; returns -1 if it is not
   4686      * needed (for example targetPkg already has permission to access the URI).
   4687      */
   4688     int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
   4689             Uri uri, int modeFlags) {
   4690         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   4691                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   4692         if (modeFlags == 0) {
   4693             return -1;
   4694         }
   4695 
   4696         if (targetPkg != null) {
   4697             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4698                     "Checking grant " + targetPkg + " permission to " + uri);
   4699         }
   4700 
   4701         final IPackageManager pm = AppGlobals.getPackageManager();
   4702 
   4703         // If this is not a content: uri, we can't do anything with it.
   4704         if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
   4705             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4706                     "Can't grant URI permission for non-content URI: " + uri);
   4707             return -1;
   4708         }
   4709 
   4710         String name = uri.getAuthority();
   4711         ProviderInfo pi = null;
   4712         ContentProviderRecord cpr = mProvidersByName.get(name);
   4713         if (cpr != null) {
   4714             pi = cpr.info;
   4715         } else {
   4716             try {
   4717                 pi = pm.resolveContentProvider(name,
   4718                         PackageManager.GET_URI_PERMISSION_PATTERNS);
   4719             } catch (RemoteException ex) {
   4720             }
   4721         }
   4722         if (pi == null) {
   4723             Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
   4724             return -1;
   4725         }
   4726 
   4727         int targetUid;
   4728         if (targetPkg != null) {
   4729             try {
   4730                 targetUid = pm.getPackageUid(targetPkg);
   4731                 if (targetUid < 0) {
   4732                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4733                             "Can't grant URI permission no uid for: " + targetPkg);
   4734                     return -1;
   4735                 }
   4736             } catch (RemoteException ex) {
   4737                 return -1;
   4738             }
   4739         } else {
   4740             targetUid = -1;
   4741         }
   4742 
   4743         if (targetUid >= 0) {
   4744             // First...  does the target actually need this permission?
   4745             if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
   4746                 // No need to grant the target this permission.
   4747                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4748                         "Target " + targetPkg + " already has full permission to " + uri);
   4749                 return -1;
   4750             }
   4751         } else {
   4752             // First...  there is no target package, so can anyone access it?
   4753             boolean allowed = pi.exported;
   4754             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   4755                 if (pi.readPermission != null) {
   4756                     allowed = false;
   4757                 }
   4758             }
   4759             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   4760                 if (pi.writePermission != null) {
   4761                     allowed = false;
   4762                 }
   4763             }
   4764             if (allowed) {
   4765                 return -1;
   4766             }
   4767         }
   4768 
   4769         // Second...  is the provider allowing granting of URI permissions?
   4770         if (!pi.grantUriPermissions) {
   4771             throw new SecurityException("Provider " + pi.packageName
   4772                     + "/" + pi.name
   4773                     + " does not allow granting of Uri permissions (uri "
   4774                     + uri + ")");
   4775         }
   4776         if (pi.uriPermissionPatterns != null) {
   4777             final int N = pi.uriPermissionPatterns.length;
   4778             boolean allowed = false;
   4779             for (int i=0; i<N; i++) {
   4780                 if (pi.uriPermissionPatterns[i] != null
   4781                         && pi.uriPermissionPatterns[i].match(uri.getPath())) {
   4782                     allowed = true;
   4783                     break;
   4784                 }
   4785             }
   4786             if (!allowed) {
   4787                 throw new SecurityException("Provider " + pi.packageName
   4788                         + "/" + pi.name
   4789                         + " does not allow granting of permission to path of Uri "
   4790                         + uri);
   4791             }
   4792         }
   4793 
   4794         // Third...  does the caller itself have permission to access
   4795         // this uri?
   4796         if (callingUid != Process.myUid()) {
   4797             if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
   4798                 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
   4799                     throw new SecurityException("Uid " + callingUid
   4800                             + " does not have permission to uri " + uri);
   4801                 }
   4802             }
   4803         }
   4804 
   4805         return targetUid;
   4806     }
   4807 
   4808     public int checkGrantUriPermission(int callingUid, String targetPkg,
   4809             Uri uri, int modeFlags) {
   4810         synchronized(this) {
   4811             return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
   4812         }
   4813     }
   4814 
   4815     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
   4816             Uri uri, int modeFlags, UriPermissionOwner owner) {
   4817         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   4818                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   4819         if (modeFlags == 0) {
   4820             return;
   4821         }
   4822 
   4823         // So here we are: the caller has the assumed permission
   4824         // to the uri, and the target doesn't.  Let's now give this to
   4825         // the target.
   4826 
   4827         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4828                 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
   4829 
   4830         HashMap<Uri, UriPermission> targetUris
   4831                 = mGrantedUriPermissions.get(targetUid);
   4832         if (targetUris == null) {
   4833             targetUris = new HashMap<Uri, UriPermission>();
   4834             mGrantedUriPermissions.put(targetUid, targetUris);
   4835         }
   4836 
   4837         UriPermission perm = targetUris.get(uri);
   4838         if (perm == null) {
   4839             perm = new UriPermission(targetUid, uri);
   4840             targetUris.put(uri, perm);
   4841         }
   4842 
   4843         perm.modeFlags |= modeFlags;
   4844         if (owner == null) {
   4845             perm.globalModeFlags |= modeFlags;
   4846         } else {
   4847             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   4848                  perm.readOwners.add(owner);
   4849                  owner.addReadPermission(perm);
   4850             }
   4851             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   4852                  perm.writeOwners.add(owner);
   4853                  owner.addWritePermission(perm);
   4854             }
   4855         }
   4856     }
   4857 
   4858     void grantUriPermissionLocked(int callingUid,
   4859             String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
   4860         if (targetPkg == null) {
   4861             throw new NullPointerException("targetPkg");
   4862         }
   4863 
   4864         int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
   4865         if (targetUid < 0) {
   4866             return;
   4867         }
   4868 
   4869         grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
   4870     }
   4871 
   4872     /**
   4873      * Like checkGrantUriPermissionLocked, but takes an Intent.
   4874      */
   4875     int checkGrantUriPermissionFromIntentLocked(int callingUid,
   4876             String targetPkg, Intent intent) {
   4877         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4878                 "Checking URI perm to " + (intent != null ? intent.getData() : null)
   4879                 + " from " + intent + "; flags=0x"
   4880                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
   4881 
   4882         if (targetPkg == null) {
   4883             throw new NullPointerException("targetPkg");
   4884         }
   4885 
   4886         if (intent == null) {
   4887             return -1;
   4888         }
   4889         Uri data = intent.getData();
   4890         if (data == null) {
   4891             return -1;
   4892         }
   4893         return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
   4894                 intent.getFlags());
   4895     }
   4896 
   4897     /**
   4898      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
   4899      */
   4900     void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
   4901             String targetPkg, Intent intent, UriPermissionOwner owner) {
   4902         grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
   4903                 intent.getFlags(), owner);
   4904     }
   4905 
   4906     void grantUriPermissionFromIntentLocked(int callingUid,
   4907             String targetPkg, Intent intent, UriPermissionOwner owner) {
   4908         int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
   4909         if (targetUid < 0) {
   4910             return;
   4911         }
   4912 
   4913         grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
   4914     }
   4915 
   4916     public void grantUriPermission(IApplicationThread caller, String targetPkg,
   4917             Uri uri, int modeFlags) {
   4918         synchronized(this) {
   4919             final ProcessRecord r = getRecordForAppLocked(caller);
   4920             if (r == null) {
   4921                 throw new SecurityException("Unable to find app for caller "
   4922                         + caller
   4923                         + " when granting permission to uri " + uri);
   4924             }
   4925             if (targetPkg == null) {
   4926                 throw new IllegalArgumentException("null target");
   4927             }
   4928             if (uri == null) {
   4929                 throw new IllegalArgumentException("null uri");
   4930             }
   4931 
   4932             grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
   4933                     null);
   4934         }
   4935     }
   4936 
   4937     void removeUriPermissionIfNeededLocked(UriPermission perm) {
   4938         if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
   4939                 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
   4940             HashMap<Uri, UriPermission> perms
   4941                     = mGrantedUriPermissions.get(perm.uid);
   4942             if (perms != null) {
   4943                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4944                         "Removing " + perm.uid + " permission to " + perm.uri);
   4945                 perms.remove(perm.uri);
   4946                 if (perms.size() == 0) {
   4947                     mGrantedUriPermissions.remove(perm.uid);
   4948                 }
   4949             }
   4950         }
   4951     }
   4952 
   4953     private void revokeUriPermissionLocked(int callingUid, Uri uri,
   4954             int modeFlags) {
   4955         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   4956                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   4957         if (modeFlags == 0) {
   4958             return;
   4959         }
   4960 
   4961         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4962                 "Revoking all granted permissions to " + uri);
   4963 
   4964         final IPackageManager pm = AppGlobals.getPackageManager();
   4965 
   4966         final String authority = uri.getAuthority();
   4967         ProviderInfo pi = null;
   4968         ContentProviderRecord cpr = mProvidersByName.get(authority);
   4969         if (cpr != null) {
   4970             pi = cpr.info;
   4971         } else {
   4972             try {
   4973                 pi = pm.resolveContentProvider(authority,
   4974                         PackageManager.GET_URI_PERMISSION_PATTERNS);
   4975             } catch (RemoteException ex) {
   4976             }
   4977         }
   4978         if (pi == null) {
   4979             Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
   4980             return;
   4981         }
   4982 
   4983         // Does the caller have this permission on the URI?
   4984         if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
   4985             // Right now, if you are not the original owner of the permission,
   4986             // you are not allowed to revoke it.
   4987             //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
   4988                 throw new SecurityException("Uid " + callingUid
   4989                         + " does not have permission to uri " + uri);
   4990             //}
   4991         }
   4992 
   4993         // Go through all of the permissions and remove any that match.
   4994         final List<String> SEGMENTS = uri.getPathSegments();
   4995         if (SEGMENTS != null) {
   4996             final int NS = SEGMENTS.size();
   4997             int N = mGrantedUriPermissions.size();
   4998             for (int i=0; i<N; i++) {
   4999                 HashMap<Uri, UriPermission> perms
   5000                         = mGrantedUriPermissions.valueAt(i);
   5001                 Iterator<UriPermission> it = perms.values().iterator();
   5002             toploop:
   5003                 while (it.hasNext()) {
   5004                     UriPermission perm = it.next();
   5005                     Uri targetUri = perm.uri;
   5006                     if (!authority.equals(targetUri.getAuthority())) {
   5007                         continue;
   5008                     }
   5009                     List<String> targetSegments = targetUri.getPathSegments();
   5010                     if (targetSegments == null) {
   5011                         continue;
   5012                     }
   5013                     if (targetSegments.size() < NS) {
   5014                         continue;
   5015                     }
   5016                     for (int j=0; j<NS; j++) {
   5017                         if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
   5018                             continue toploop;
   5019                         }
   5020                     }
   5021                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5022                             "Revoking " + perm.uid + " permission to " + perm.uri);
   5023                     perm.clearModes(modeFlags);
   5024                     if (perm.modeFlags == 0) {
   5025                         it.remove();
   5026                     }
   5027                 }
   5028                 if (perms.size() == 0) {
   5029                     mGrantedUriPermissions.remove(
   5030                             mGrantedUriPermissions.keyAt(i));
   5031                     N--;
   5032                     i--;
   5033                 }
   5034             }
   5035         }
   5036     }
   5037 
   5038     public void revokeUriPermission(IApplicationThread caller, Uri uri,
   5039             int modeFlags) {
   5040         synchronized(this) {
   5041             final ProcessRecord r = getRecordForAppLocked(caller);
   5042             if (r == null) {
   5043                 throw new SecurityException("Unable to find app for caller "
   5044                         + caller
   5045                         + " when revoking permission to uri " + uri);
   5046             }
   5047             if (uri == null) {
   5048                 Slog.w(TAG, "revokeUriPermission: null uri");
   5049                 return;
   5050             }
   5051 
   5052             modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   5053                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   5054             if (modeFlags == 0) {
   5055                 return;
   5056             }
   5057 
   5058             final IPackageManager pm = AppGlobals.getPackageManager();
   5059 
   5060             final String authority = uri.getAuthority();
   5061             ProviderInfo pi = null;
   5062             ContentProviderRecord cpr = mProvidersByName.get(authority);
   5063             if (cpr != null) {
   5064                 pi = cpr.info;
   5065             } else {
   5066                 try {
   5067                     pi = pm.resolveContentProvider(authority,
   5068                             PackageManager.GET_URI_PERMISSION_PATTERNS);
   5069                 } catch (RemoteException ex) {
   5070                 }
   5071             }
   5072             if (pi == null) {
   5073                 Slog.w(TAG, "No content provider found for permission revoke: "
   5074                         + uri.toSafeString());
   5075                 return;
   5076             }
   5077 
   5078             revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
   5079         }
   5080     }
   5081 
   5082     @Override
   5083     public IBinder newUriPermissionOwner(String name) {
   5084         synchronized(this) {
   5085             UriPermissionOwner owner = new UriPermissionOwner(this, name);
   5086             return owner.getExternalTokenLocked();
   5087         }
   5088     }
   5089 
   5090     @Override
   5091     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
   5092             Uri uri, int modeFlags) {
   5093         synchronized(this) {
   5094             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   5095             if (owner == null) {
   5096                 throw new IllegalArgumentException("Unknown owner: " + token);
   5097             }
   5098             if (fromUid != Binder.getCallingUid()) {
   5099                 if (Binder.getCallingUid() != Process.myUid()) {
   5100                     // Only system code can grant URI permissions on behalf
   5101                     // of other users.
   5102                     throw new SecurityException("nice try");
   5103                 }
   5104             }
   5105             if (targetPkg == null) {
   5106                 throw new IllegalArgumentException("null target");
   5107             }
   5108             if (uri == null) {
   5109                 throw new IllegalArgumentException("null uri");
   5110             }
   5111 
   5112             grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
   5113         }
   5114     }
   5115 
   5116     @Override
   5117     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
   5118         synchronized(this) {
   5119             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   5120             if (owner == null) {
   5121                 throw new IllegalArgumentException("Unknown owner: " + token);
   5122             }
   5123 
   5124             if (uri == null) {
   5125                 owner.removeUriPermissionsLocked(mode);
   5126             } else {
   5127                 owner.removeUriPermissionLocked(uri, mode);
   5128             }
   5129         }
   5130     }
   5131 
   5132     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
   5133         synchronized (this) {
   5134             ProcessRecord app =
   5135                 who != null ? getRecordForAppLocked(who) : null;
   5136             if (app == null) return;
   5137 
   5138             Message msg = Message.obtain();
   5139             msg.what = WAIT_FOR_DEBUGGER_MSG;
   5140             msg.obj = app;
   5141             msg.arg1 = waiting ? 1 : 0;
   5142             mHandler.sendMessage(msg);
   5143         }
   5144     }
   5145 
   5146     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
   5147         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
   5148         final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
   5149         outInfo.availMem = Process.getFreeMemory();
   5150         outInfo.threshold = homeAppMem;
   5151         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
   5152         outInfo.hiddenAppThreshold = hiddenAppMem;
   5153         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
   5154                 ProcessList.SERVICE_ADJ);
   5155         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
   5156                 ProcessList.VISIBLE_APP_ADJ);
   5157         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
   5158                 ProcessList.FOREGROUND_APP_ADJ);
   5159     }
   5160 
   5161     // =========================================================
   5162     // TASK MANAGEMENT
   5163     // =========================================================
   5164 
   5165     public List getTasks(int maxNum, int flags,
   5166                          IThumbnailReceiver receiver) {
   5167         ArrayList list = new ArrayList();
   5168 
   5169         PendingThumbnailsRecord pending = null;
   5170         IApplicationThread topThumbnail = null;
   5171         ActivityRecord topRecord = null;
   5172 
   5173         synchronized(this) {
   5174             if (localLOGV) Slog.v(
   5175                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
   5176                 + ", receiver=" + receiver);
   5177 
   5178             if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
   5179                     != PackageManager.PERMISSION_GRANTED) {
   5180                 if (receiver != null) {
   5181                     // If the caller wants to wait for pending thumbnails,
   5182                     // it ain't gonna get them.
   5183                     try {
   5184                         receiver.finished();
   5185                     } catch (RemoteException ex) {
   5186                     }
   5187                 }
   5188                 String msg = "Permission Denial: getTasks() from pid="
   5189                         + Binder.getCallingPid()
   5190                         + ", uid=" + Binder.getCallingUid()
   5191                         + " requires " + android.Manifest.permission.GET_TASKS;
   5192                 Slog.w(TAG, msg);
   5193                 throw new SecurityException(msg);
   5194             }
   5195 
   5196             int pos = mMainStack.mHistory.size()-1;
   5197             ActivityRecord next =
   5198                 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
   5199             ActivityRecord top = null;
   5200             TaskRecord curTask = null;
   5201             int numActivities = 0;
   5202             int numRunning = 0;
   5203             while (pos >= 0 && maxNum > 0) {
   5204                 final ActivityRecord r = next;
   5205                 pos--;
   5206                 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
   5207 
   5208                 // Initialize state for next task if needed.
   5209                 if (top == null ||
   5210                         (top.state == ActivityState.INITIALIZING
   5211                             && top.task == r.task)) {
   5212                     top = r;
   5213                     curTask = r.task;
   5214                     numActivities = numRunning = 0;
   5215                 }
   5216 
   5217                 // Add 'r' into the current task.
   5218                 numActivities++;
   5219                 if (r.app != null && r.app.thread != null) {
   5220                     numRunning++;
   5221                 }
   5222 
   5223                 if (localLOGV) Slog.v(
   5224                     TAG, r.intent.getComponent().flattenToShortString()
   5225                     + ": task=" + r.task);
   5226 
   5227                 // If the next one is a different task, generate a new
   5228                 // TaskInfo entry for what we have.
   5229                 if (next == null || next.task != curTask) {
   5230                     ActivityManager.RunningTaskInfo ci
   5231                             = new ActivityManager.RunningTaskInfo();
   5232                     ci.id = curTask.taskId;
   5233                     ci.baseActivity = r.intent.getComponent();
   5234                     ci.topActivity = top.intent.getComponent();
   5235                     if (top.thumbHolder != null) {
   5236                         ci.description = top.thumbHolder.lastDescription;
   5237                     }
   5238                     ci.numActivities = numActivities;
   5239                     ci.numRunning = numRunning;
   5240                     //System.out.println(
   5241                     //    "#" + maxNum + ": " + " descr=" + ci.description);
   5242                     if (ci.thumbnail == null && receiver != null) {
   5243                         if (localLOGV) Slog.v(
   5244                             TAG, "State=" + top.state + "Idle=" + top.idle
   5245                             + " app=" + top.app
   5246                             + " thr=" + (top.app != null ? top.app.thread : null));
   5247                         if (top.state == ActivityState.RESUMED
   5248                                 || top.state == ActivityState.PAUSING) {
   5249                             if (top.idle && top.app != null
   5250                                 && top.app.thread != null) {
   5251                                 topRecord = top;
   5252                                 topThumbnail = top.app.thread;
   5253                             } else {
   5254                                 top.thumbnailNeeded = true;
   5255                             }
   5256                         }
   5257                         if (pending == null) {
   5258                             pending = new PendingThumbnailsRecord(receiver);
   5259                         }
   5260                         pending.pendingRecords.add(top);
   5261                     }
   5262                     list.add(ci);
   5263                     maxNum--;
   5264                     top = null;
   5265                 }
   5266             }
   5267 
   5268             if (pending != null) {
   5269                 mPendingThumbnails.add(pending);
   5270             }
   5271         }
   5272 
   5273         if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
   5274 
   5275         if (topThumbnail != null) {
   5276             if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
   5277             try {
   5278                 topThumbnail.requestThumbnail(topRecord.appToken);
   5279             } catch (Exception e) {
   5280                 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
   5281                 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
   5282             }
   5283         }
   5284 
   5285         if (pending == null && receiver != null) {
   5286             // In this case all thumbnails were available and the client
   5287             // is being asked to be told when the remaining ones come in...
   5288             // which is unusually, since the top-most currently running
   5289             // activity should never have a canned thumbnail!  Oh well.
   5290             try {
   5291                 receiver.finished();
   5292             } catch (RemoteException ex) {
   5293             }
   5294         }
   5295 
   5296         return list;
   5297     }
   5298 
   5299     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
   5300             int flags) {
   5301         synchronized (this) {
   5302             enforceCallingPermission(android.Manifest.permission.GET_TASKS,
   5303                     "getRecentTasks()");
   5304 
   5305             IPackageManager pm = AppGlobals.getPackageManager();
   5306 
   5307             final int N = mRecentTasks.size();
   5308             ArrayList<ActivityManager.RecentTaskInfo> res
   5309                     = new ArrayList<ActivityManager.RecentTaskInfo>(
   5310                             maxNum < N ? maxNum : N);
   5311             for (int i=0; i<N && maxNum > 0; i++) {
   5312                 TaskRecord tr = mRecentTasks.get(i);
   5313                 // Return the entry if desired by the caller.  We always return
   5314                 // the first entry, because callers always expect this to be the
   5315                 // forground app.  We may filter others if the caller has
   5316                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
   5317                 // we should exclude the entry.
   5318                 if (i == 0
   5319                         || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
   5320                         || (tr.intent == null)
   5321                         || ((tr.intent.getFlags()
   5322                                 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
   5323                     ActivityManager.RecentTaskInfo rti
   5324                             = new ActivityManager.RecentTaskInfo();
   5325                     rti.id = tr.numActivities > 0 ? tr.taskId : -1;
   5326                     rti.persistentId = tr.taskId;
   5327                     rti.baseIntent = new Intent(
   5328                             tr.intent != null ? tr.intent : tr.affinityIntent);
   5329                     rti.origActivity = tr.origActivity;
   5330                     rti.description = tr.lastDescription;
   5331 
   5332                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
   5333                         // Check whether this activity is currently available.
   5334                         try {
   5335                             if (rti.origActivity != null) {
   5336                                 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
   5337                                     continue;
   5338                                 }
   5339                             } else if (rti.baseIntent != null) {
   5340                                 if (pm.queryIntentActivities(rti.baseIntent,
   5341                                         null, 0) == null) {
   5342                                     continue;
   5343                                 }
   5344                             }
   5345                         } catch (RemoteException e) {
   5346                             // Will never happen.
   5347                         }
   5348                     }
   5349 
   5350                     res.add(rti);
   5351                     maxNum--;
   5352                 }
   5353             }
   5354             return res;
   5355         }
   5356     }
   5357 
   5358     private TaskRecord taskForIdLocked(int id) {
   5359         final int N = mRecentTasks.size();
   5360         for (int i=0; i<N; i++) {
   5361             TaskRecord tr = mRecentTasks.get(i);
   5362             if (tr.taskId == id) {
   5363                 return tr;
   5364             }
   5365         }
   5366         return null;
   5367     }
   5368 
   5369     public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
   5370         synchronized (this) {
   5371             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
   5372                     "getTaskThumbnails()");
   5373             TaskRecord tr = taskForIdLocked(id);
   5374             if (tr != null) {
   5375                 return mMainStack.getTaskThumbnailsLocked(tr);
   5376             }
   5377         }
   5378         return null;
   5379     }
   5380 
   5381     public boolean removeSubTask(int taskId, int subTaskIndex) {
   5382         synchronized (this) {
   5383             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
   5384                     "removeSubTask()");
   5385             long ident = Binder.clearCallingIdentity();
   5386             try {
   5387                 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
   5388             } finally {
   5389                 Binder.restoreCallingIdentity(ident);
   5390             }
   5391         }
   5392     }
   5393 
   5394     private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
   5395         TaskRecord tr = root.task;
   5396         Intent baseIntent = new Intent(
   5397                 tr.intent != null ? tr.intent : tr.affinityIntent);
   5398         ComponentName component = baseIntent.getComponent();
   5399         if (component == null) {
   5400             Slog.w(TAG, "Now component for base intent of task: " + tr);
   5401             return;
   5402         }
   5403 
   5404         // Find any running services associated with this app.
   5405         ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
   5406         for (ServiceRecord sr : mServices.values()) {
   5407             if (sr.packageName.equals(component.getPackageName())) {
   5408                 services.add(sr);
   5409             }
   5410         }
   5411 
   5412         // Take care of any running services associated with the app.
   5413         for (int i=0; i<services.size(); i++) {
   5414             ServiceRecord sr = services.get(i);
   5415             if (sr.startRequested) {
   5416                 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
   5417                     Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
   5418                     stopServiceLocked(sr);
   5419                 } else {
   5420                     sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
   5421                             sr.makeNextStartId(), baseIntent, -1));
   5422                     if (sr.app != null && sr.app.thread != null) {
   5423                         sendServiceArgsLocked(sr, false);
   5424                     }
   5425                 }
   5426             }
   5427         }
   5428 
   5429         if (killProcesses) {
   5430             // Find any running processes associated with this app.
   5431             ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   5432             SparseArray<ProcessRecord> appProcs
   5433                     = mProcessNames.getMap().get(component.getPackageName());
   5434             if (appProcs != null) {
   5435                 for (int i=0; i<appProcs.size(); i++) {
   5436                     procs.add(appProcs.valueAt(i));
   5437                 }
   5438             }
   5439 
   5440             // Kill the running processes.
   5441             for (int i=0; i<procs.size(); i++) {
   5442                 ProcessRecord pr = procs.get(i);
   5443                 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
   5444                     Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
   5445                     EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
   5446                             pr.processName, pr.setAdj, "remove task");
   5447                     Process.killProcessQuiet(pr.pid);
   5448                 } else {
   5449                     pr.waitingToKill = "remove task";
   5450                 }
   5451             }
   5452         }
   5453     }
   5454 
   5455     public boolean removeTask(int taskId, int flags) {
   5456         synchronized (this) {
   5457             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
   5458                     "removeTask()");
   5459             long ident = Binder.clearCallingIdentity();
   5460             try {
   5461                 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
   5462                 if (r != null) {
   5463                     mRecentTasks.remove(r.task);
   5464                     cleanUpRemovedTaskLocked(r,
   5465                             (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
   5466                     return true;
   5467                 } else {
   5468                     TaskRecord tr = null;
   5469                     int i=0;
   5470                     while (i < mRecentTasks.size()) {
   5471                         TaskRecord t = mRecentTasks.get(i);
   5472                         if (t.taskId == taskId) {
   5473                             tr = t;
   5474                             break;
   5475                         }
   5476                         i++;
   5477                     }
   5478                     if (tr != null) {
   5479                         if (tr.numActivities <= 0) {
   5480                             // Caller is just removing a recent task that is
   5481                             // not actively running.  That is easy!
   5482                             mRecentTasks.remove(i);
   5483                         } else {
   5484                             Slog.w(TAG, "removeTask: task " + taskId
   5485                                     + " does not have activities to remove, "
   5486                                     + " but numActivities=" + tr.numActivities
   5487                                     + ": " + tr);
   5488                         }
   5489                     }
   5490                 }
   5491             } finally {
   5492                 Binder.restoreCallingIdentity(ident);
   5493             }
   5494         }
   5495         return false;
   5496     }
   5497 
   5498     private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
   5499         int j;
   5500         TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
   5501         TaskRecord jt = startTask;
   5502 
   5503         // First look backwards
   5504         for (j=startIndex-1; j>=0; j--) {
   5505             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
   5506             if (r.task != jt) {
   5507                 jt = r.task;
   5508                 if (affinity.equals(jt.affinity)) {
   5509                     return j;
   5510                 }
   5511             }
   5512         }
   5513 
   5514         // Now look forwards
   5515         final int N = mMainStack.mHistory.size();
   5516         jt = startTask;
   5517         for (j=startIndex+1; j<N; j++) {
   5518             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
   5519             if (r.task != jt) {
   5520                 if (affinity.equals(jt.affinity)) {
   5521                     return j;
   5522                 }
   5523                 jt = r.task;
   5524             }
   5525         }
   5526 
   5527         // Might it be at the top?
   5528         if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
   5529             return N-1;
   5530         }
   5531 
   5532         return -1;
   5533     }
   5534 
   5535     /**
   5536      * TODO: Add mController hook
   5537      */
   5538     public void moveTaskToFront(int task, int flags) {
   5539         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   5540                 "moveTaskToFront()");
   5541 
   5542         synchronized(this) {
   5543             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   5544                     Binder.getCallingUid(), "Task to front")) {
   5545                 return;
   5546             }
   5547             final long origId = Binder.clearCallingIdentity();
   5548             try {
   5549                 TaskRecord tr = taskForIdLocked(task);
   5550                 if (tr != null) {
   5551                     if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
   5552                         mMainStack.mUserLeaving = true;
   5553                     }
   5554                     if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
   5555                         // Caller wants the home activity moved with it.  To accomplish this,
   5556                         // we'll just move the home task to the top first.
   5557                         mMainStack.moveHomeToFrontLocked();
   5558                     }
   5559                     mMainStack.moveTaskToFrontLocked(tr, null);
   5560                     return;
   5561                 }
   5562                 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
   5563                     ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
   5564                     if (hr.task.taskId == task) {
   5565                         if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
   5566                             mMainStack.mUserLeaving = true;
   5567                         }
   5568                         if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
   5569                             // Caller wants the home activity moved with it.  To accomplish this,
   5570                             // we'll just move the home task to the top first.
   5571                             mMainStack.moveHomeToFrontLocked();
   5572                         }
   5573                         mMainStack.moveTaskToFrontLocked(hr.task, null);
   5574                         return;
   5575                     }
   5576                 }
   5577             } finally {
   5578                 Binder.restoreCallingIdentity(origId);
   5579             }
   5580         }
   5581     }
   5582 
   5583     public void moveTaskToBack(int task) {
   5584         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   5585                 "moveTaskToBack()");
   5586 
   5587         synchronized(this) {
   5588             if (mMainStack.mResumedActivity != null
   5589                     && mMainStack.mResumedActivity.task.taskId == task) {
   5590                 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   5591                         Binder.getCallingUid(), "Task to back")) {
   5592                     return;
   5593                 }
   5594             }
   5595             final long origId = Binder.clearCallingIdentity();
   5596             mMainStack.moveTaskToBackLocked(task, null);
   5597             Binder.restoreCallingIdentity(origId);
   5598         }
   5599     }
   5600 
   5601     /**
   5602      * Moves an activity, and all of the other activities within the same task, to the bottom
   5603      * of the history stack.  The activity's order within the task is unchanged.
   5604      *
   5605      * @param token A reference to the activity we wish to move
   5606      * @param nonRoot If false then this only works if the activity is the root
   5607      *                of a task; if true it will work for any activity in a task.
   5608      * @return Returns true if the move completed, false if not.
   5609      */
   5610     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
   5611         synchronized(this) {
   5612             final long origId = Binder.clearCallingIdentity();
   5613             int taskId = getTaskForActivityLocked(token, !nonRoot);
   5614             if (taskId >= 0) {
   5615                 return mMainStack.moveTaskToBackLocked(taskId, null);
   5616             }
   5617             Binder.restoreCallingIdentity(origId);
   5618         }
   5619         return false;
   5620     }
   5621 
   5622     public void moveTaskBackwards(int task) {
   5623         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   5624                 "moveTaskBackwards()");
   5625 
   5626         synchronized(this) {
   5627             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   5628                     Binder.getCallingUid(), "Task backwards")) {
   5629                 return;
   5630             }
   5631             final long origId = Binder.clearCallingIdentity();
   5632             moveTaskBackwardsLocked(task);
   5633             Binder.restoreCallingIdentity(origId);
   5634         }
   5635     }
   5636 
   5637     private final void moveTaskBackwardsLocked(int task) {
   5638         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
   5639     }
   5640 
   5641     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
   5642         synchronized(this) {
   5643             return getTaskForActivityLocked(token, onlyRoot);
   5644         }
   5645     }
   5646 
   5647     int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
   5648         final int N = mMainStack.mHistory.size();
   5649         TaskRecord lastTask = null;
   5650         for (int i=0; i<N; i++) {
   5651             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   5652             if (r.appToken == token) {
   5653                 if (!onlyRoot || lastTask != r.task) {
   5654                     return r.task.taskId;
   5655                 }
   5656                 return -1;
   5657             }
   5658             lastTask = r.task;
   5659         }
   5660 
   5661         return -1;
   5662     }
   5663 
   5664     public void finishOtherInstances(IBinder token, ComponentName className) {
   5665         synchronized(this) {
   5666             final long origId = Binder.clearCallingIdentity();
   5667 
   5668             int N = mMainStack.mHistory.size();
   5669             TaskRecord lastTask = null;
   5670             for (int i=0; i<N; i++) {
   5671                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   5672                 if (r.realActivity.equals(className)
   5673                         && r.appToken != token && lastTask != r.task) {
   5674                     if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
   5675                             null, "others")) {
   5676                         i--;
   5677                         N--;
   5678                     }
   5679                 }
   5680                 lastTask = r.task;
   5681             }
   5682 
   5683             Binder.restoreCallingIdentity(origId);
   5684         }
   5685     }
   5686 
   5687     // =========================================================
   5688     // THUMBNAILS
   5689     // =========================================================
   5690 
   5691     public void reportThumbnail(IBinder token,
   5692             Bitmap thumbnail, CharSequence description) {
   5693         //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
   5694         final long origId = Binder.clearCallingIdentity();
   5695         sendPendingThumbnail(null, token, thumbnail, description, true);
   5696         Binder.restoreCallingIdentity(origId);
   5697     }
   5698 
   5699     final void sendPendingThumbnail(ActivityRecord r, IBinder token,
   5700             Bitmap thumbnail, CharSequence description, boolean always) {
   5701         TaskRecord task = null;
   5702         ArrayList receivers = null;
   5703 
   5704         //System.out.println("Send pending thumbnail: " + r);
   5705 
   5706         synchronized(this) {
   5707             if (r == null) {
   5708                 r = mMainStack.isInStackLocked(token);
   5709                 if (r == null) {
   5710                     return;
   5711                 }
   5712             }
   5713             if (thumbnail == null && r.thumbHolder != null) {
   5714                 thumbnail = r.thumbHolder.lastThumbnail;
   5715                 description = r.thumbHolder.lastDescription;
   5716             }
   5717             if (thumbnail == null && !always) {
   5718                 // If there is no thumbnail, and this entry is not actually
   5719                 // going away, then abort for now and pick up the next
   5720                 // thumbnail we get.
   5721                 return;
   5722             }
   5723             task = r.task;
   5724 
   5725             int N = mPendingThumbnails.size();
   5726             int i=0;
   5727             while (i<N) {
   5728                 PendingThumbnailsRecord pr =
   5729                     (PendingThumbnailsRecord)mPendingThumbnails.get(i);
   5730                 //System.out.println("Looking in " + pr.pendingRecords);
   5731                 if (pr.pendingRecords.remove(r)) {
   5732                     if (receivers == null) {
   5733                         receivers = new ArrayList();
   5734                     }
   5735                     receivers.add(pr);
   5736                     if (pr.pendingRecords.size() == 0) {
   5737                         pr.finished = true;
   5738                         mPendingThumbnails.remove(i);
   5739                         N--;
   5740                         continue;
   5741                     }
   5742                 }
   5743                 i++;
   5744             }
   5745         }
   5746 
   5747         if (receivers != null) {
   5748             final int N = receivers.size();
   5749             for (int i=0; i<N; i++) {
   5750                 try {
   5751                     PendingThumbnailsRecord pr =
   5752                         (PendingThumbnailsRecord)receivers.get(i);
   5753                     pr.receiver.newThumbnail(
   5754                         task != null ? task.taskId : -1, thumbnail, description);
   5755                     if (pr.finished) {
   5756                         pr.receiver.finished();
   5757                     }
   5758                 } catch (Exception e) {
   5759                     Slog.w(TAG, "Exception thrown when sending thumbnail", e);
   5760                 }
   5761             }
   5762         }
   5763     }
   5764 
   5765     // =========================================================
   5766     // CONTENT PROVIDERS
   5767     // =========================================================
   5768 
   5769     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
   5770         List<ProviderInfo> providers = null;
   5771         try {
   5772             providers = AppGlobals.getPackageManager().
   5773                 queryContentProviders(app.processName, app.info.uid,
   5774                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
   5775         } catch (RemoteException ex) {
   5776         }
   5777         if (providers != null) {
   5778             final int N = providers.size();
   5779             for (int i=0; i<N; i++) {
   5780                 ProviderInfo cpi =
   5781                     (ProviderInfo)providers.get(i);
   5782                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   5783                 ContentProviderRecord cpr = mProvidersByClass.get(comp);
   5784                 if (cpr == null) {
   5785                     cpr = new ContentProviderRecord(cpi, app.info, comp);
   5786                     mProvidersByClass.put(comp, cpr);
   5787                 }
   5788                 app.pubProviders.put(cpi.name, cpr);
   5789                 app.addPackage(cpi.applicationInfo.packageName);
   5790                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
   5791             }
   5792         }
   5793         return providers;
   5794     }
   5795 
   5796     private final String checkContentProviderPermissionLocked(
   5797             ProviderInfo cpi, ProcessRecord r) {
   5798         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
   5799         final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
   5800         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
   5801                 cpi.applicationInfo.uid, cpi.exported)
   5802                 == PackageManager.PERMISSION_GRANTED) {
   5803             return null;
   5804         }
   5805         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
   5806                 cpi.applicationInfo.uid, cpi.exported)
   5807                 == PackageManager.PERMISSION_GRANTED) {
   5808             return null;
   5809         }
   5810 
   5811         PathPermission[] pps = cpi.pathPermissions;
   5812         if (pps != null) {
   5813             int i = pps.length;
   5814             while (i > 0) {
   5815                 i--;
   5816                 PathPermission pp = pps[i];
   5817                 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
   5818                         cpi.applicationInfo.uid, cpi.exported)
   5819                         == PackageManager.PERMISSION_GRANTED) {
   5820                     return null;
   5821                 }
   5822                 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
   5823                         cpi.applicationInfo.uid, cpi.exported)
   5824                         == PackageManager.PERMISSION_GRANTED) {
   5825                     return null;
   5826                 }
   5827             }
   5828         }
   5829 
   5830         HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   5831         if (perms != null) {
   5832             for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
   5833                 if (uri.getKey().getAuthority().equals(cpi.authority)) {
   5834                     return null;
   5835                 }
   5836             }
   5837         }
   5838 
   5839         String msg;
   5840         if (!cpi.exported) {
   5841             msg = "Permission Denial: opening provider " + cpi.name
   5842                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   5843                     + ", uid=" + callingUid + ") that is not exported from uid "
   5844                     + cpi.applicationInfo.uid;
   5845         } else {
   5846             msg = "Permission Denial: opening provider " + cpi.name
   5847                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   5848                     + ", uid=" + callingUid + ") requires "
   5849                     + cpi.readPermission + " or " + cpi.writePermission;
   5850         }
   5851         Slog.w(TAG, msg);
   5852         return msg;
   5853     }
   5854 
   5855     boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
   5856         if (r != null) {
   5857             Integer cnt = r.conProviders.get(cpr);
   5858             if (DEBUG_PROVIDER) Slog.v(TAG,
   5859                     "Adding provider requested by "
   5860                     + r.processName + " from process "
   5861                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   5862                     + " cnt=" + (cnt == null ? 1 : cnt));
   5863             if (cnt == null) {
   5864                 cpr.clients.add(r);
   5865                 r.conProviders.put(cpr, new Integer(1));
   5866                 return true;
   5867             } else {
   5868                 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
   5869             }
   5870         } else {
   5871             cpr.externals++;
   5872         }
   5873         return false;
   5874     }
   5875 
   5876     boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
   5877         if (r != null) {
   5878             Integer cnt = r.conProviders.get(cpr);
   5879             if (DEBUG_PROVIDER) Slog.v(TAG,
   5880                     "Removing provider requested by "
   5881                     + r.processName + " from process "
   5882                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   5883                     + " cnt=" + cnt);
   5884             if (cnt == null || cnt.intValue() <= 1) {
   5885                 cpr.clients.remove(r);
   5886                 r.conProviders.remove(cpr);
   5887                 return true;
   5888             } else {
   5889                 r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
   5890             }
   5891         } else {
   5892             cpr.externals++;
   5893         }
   5894         return false;
   5895     }
   5896 
   5897     private final ContentProviderHolder getContentProviderImpl(
   5898         IApplicationThread caller, String name) {
   5899         ContentProviderRecord cpr;
   5900         ProviderInfo cpi = null;
   5901 
   5902         synchronized(this) {
   5903             ProcessRecord r = null;
   5904             if (caller != null) {
   5905                 r = getRecordForAppLocked(caller);
   5906                 if (r == null) {
   5907                     throw new SecurityException(
   5908                             "Unable to find app for caller " + caller
   5909                           + " (pid=" + Binder.getCallingPid()
   5910                           + ") when getting content provider " + name);
   5911                 }
   5912             }
   5913 
   5914             // First check if this content provider has been published...
   5915             cpr = mProvidersByName.get(name);
   5916             boolean providerRunning = cpr != null;
   5917             if (providerRunning) {
   5918                 cpi = cpr.info;
   5919                 String msg;
   5920                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
   5921                     throw new SecurityException(msg);
   5922                 }
   5923 
   5924                 if (r != null && cpr.canRunHere(r)) {
   5925                     // This provider has been published or is in the process
   5926                     // of being published...  but it is also allowed to run
   5927                     // in the caller's process, so don't make a connection
   5928                     // and just let the caller instantiate its own instance.
   5929                     if (cpr.provider != null) {
   5930                         // don't give caller the provider object, it needs
   5931                         // to make its own.
   5932                         cpr = new ContentProviderRecord(cpr);
   5933                     }
   5934                     return cpr;
   5935                 }
   5936 
   5937                 final long origId = Binder.clearCallingIdentity();
   5938 
   5939                 // In this case the provider instance already exists, so we can
   5940                 // return it right away.
   5941                 final boolean countChanged = incProviderCount(r, cpr);
   5942                 if (countChanged) {
   5943                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   5944                         // If this is a perceptible app accessing the provider,
   5945                         // make sure to count it as being accessed and thus
   5946                         // back up on the LRU list.  This is good because
   5947                         // content providers are often expensive to start.
   5948                         updateLruProcessLocked(cpr.proc, false, true);
   5949                     }
   5950                 }
   5951 
   5952                 if (cpr.proc != null) {
   5953                     if (false) {
   5954                         if (cpr.name.flattenToShortString().equals(
   5955                                 "com.android.providers.calendar/.CalendarProvider2")) {
   5956                             Slog.v(TAG, "****************** KILLING "
   5957                                 + cpr.name.flattenToShortString());
   5958                             Process.killProcess(cpr.proc.pid);
   5959                         }
   5960                     }
   5961                     boolean success = updateOomAdjLocked(cpr.proc);
   5962                     if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
   5963                     // NOTE: there is still a race here where a signal could be
   5964                     // pending on the process even though we managed to update its
   5965                     // adj level.  Not sure what to do about this, but at least
   5966                     // the race is now smaller.
   5967                     if (!success) {
   5968                         // Uh oh...  it looks like the provider's process
   5969                         // has been killed on us.  We need to wait for a new
   5970                         // process to be started, and make sure its death
   5971                         // doesn't kill our process.
   5972                         Slog.i(TAG,
   5973                                 "Existing provider " + cpr.name.flattenToShortString()
   5974                                 + " is crashing; detaching " + r);
   5975                         boolean lastRef = decProviderCount(r, cpr);
   5976                         appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
   5977                         if (!lastRef) {
   5978                             // This wasn't the last ref our process had on
   5979                             // the provider...  we have now been killed, bail.
   5980                             return null;
   5981                         }
   5982                         providerRunning = false;
   5983                     }
   5984                 }
   5985 
   5986                 Binder.restoreCallingIdentity(origId);
   5987             }
   5988 
   5989             if (!providerRunning) {
   5990                 try {
   5991                     cpi = AppGlobals.getPackageManager().
   5992                         resolveContentProvider(name,
   5993                                 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
   5994                 } catch (RemoteException ex) {
   5995                 }
   5996                 if (cpi == null) {
   5997                     return null;
   5998                 }
   5999 
   6000                 String msg;
   6001                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
   6002                     throw new SecurityException(msg);
   6003                 }
   6004 
   6005                 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
   6006                         && !cpi.processName.equals("system")) {
   6007                     // If this content provider does not run in the system
   6008                     // process, and the system is not yet ready to run other
   6009                     // processes, then fail fast instead of hanging.
   6010                     throw new IllegalArgumentException(
   6011                             "Attempt to launch content provider before system ready");
   6012                 }
   6013 
   6014                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   6015                 cpr = mProvidersByClass.get(comp);
   6016                 final boolean firstClass = cpr == null;
   6017                 if (firstClass) {
   6018                     try {
   6019                         ApplicationInfo ai =
   6020                             AppGlobals.getPackageManager().
   6021                                 getApplicationInfo(
   6022                                         cpi.applicationInfo.packageName,
   6023                                         STOCK_PM_FLAGS);
   6024                         if (ai == null) {
   6025                             Slog.w(TAG, "No package info for content provider "
   6026                                     + cpi.name);
   6027                             return null;
   6028                         }
   6029                         cpr = new ContentProviderRecord(cpi, ai, comp);
   6030                     } catch (RemoteException ex) {
   6031                         // pm is in same process, this will never happen.
   6032                     }
   6033                 }
   6034 
   6035                 if (r != null && cpr.canRunHere(r)) {
   6036                     // If this is a multiprocess provider, then just return its
   6037                     // info and allow the caller to instantiate it.  Only do
   6038                     // this if the provider is the same user as the caller's
   6039                     // process, or can run as root (so can be in any process).
   6040                     return cpr;
   6041                 }
   6042 
   6043                 if (DEBUG_PROVIDER) {
   6044                     RuntimeException e = new RuntimeException("here");
   6045                     Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
   6046                           + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
   6047                 }
   6048 
   6049                 // This is single process, and our app is now connecting to it.
   6050                 // See if we are already in the process of launching this
   6051                 // provider.
   6052                 final int N = mLaunchingProviders.size();
   6053                 int i;
   6054                 for (i=0; i<N; i++) {
   6055                     if (mLaunchingProviders.get(i) == cpr) {
   6056                         break;
   6057                     }
   6058                 }
   6059 
   6060                 // If the provider is not already being launched, then get it
   6061                 // started.
   6062                 if (i >= N) {
   6063                     final long origId = Binder.clearCallingIdentity();
   6064 
   6065                     try {
   6066                         // Content provider is now in use, its package can't be stopped.
   6067                         try {
   6068                             AppGlobals.getPackageManager().setPackageStoppedState(
   6069                                     cpr.appInfo.packageName, false);
   6070                         } catch (RemoteException e) {
   6071                         } catch (IllegalArgumentException e) {
   6072                             Slog.w(TAG, "Failed trying to unstop package "
   6073                                     + cpr.appInfo.packageName + ": " + e);
   6074                         }
   6075 
   6076                         ProcessRecord proc = startProcessLocked(cpi.processName,
   6077                                 cpr.appInfo, false, 0, "content provider",
   6078                                 new ComponentName(cpi.applicationInfo.packageName,
   6079                                         cpi.name), false);
   6080                         if (proc == null) {
   6081                             Slog.w(TAG, "Unable to launch app "
   6082                                     + cpi.applicationInfo.packageName + "/"
   6083                                     + cpi.applicationInfo.uid + " for provider "
   6084                                     + name + ": process is bad");
   6085                             return null;
   6086                         }
   6087                         cpr.launchingApp = proc;
   6088                         mLaunchingProviders.add(cpr);
   6089                     } finally {
   6090                         Binder.restoreCallingIdentity(origId);
   6091                     }
   6092                 }
   6093 
   6094                 // Make sure the provider is published (the same provider class
   6095                 // may be published under multiple names).
   6096                 if (firstClass) {
   6097                     mProvidersByClass.put(comp, cpr);
   6098                 }
   6099                 mProvidersByName.put(name, cpr);
   6100                 incProviderCount(r, cpr);
   6101             }
   6102         }
   6103 
   6104         // Wait for the provider to be published...
   6105         synchronized (cpr) {
   6106             while (cpr.provider == null) {
   6107                 if (cpr.launchingApp == null) {
   6108                     Slog.w(TAG, "Unable to launch app "
   6109                             + cpi.applicationInfo.packageName + "/"
   6110                             + cpi.applicationInfo.uid + " for provider "
   6111                             + name + ": launching app became null");
   6112                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
   6113                             cpi.applicationInfo.packageName,
   6114                             cpi.applicationInfo.uid, name);
   6115                     return null;
   6116                 }
   6117                 try {
   6118                     cpr.wait();
   6119                 } catch (InterruptedException ex) {
   6120                 }
   6121             }
   6122         }
   6123         return cpr;
   6124     }
   6125 
   6126     public final ContentProviderHolder getContentProvider(
   6127             IApplicationThread caller, String name) {
   6128         if (caller == null) {
   6129             String msg = "null IApplicationThread when getting content provider "
   6130                     + name;
   6131             Slog.w(TAG, msg);
   6132             throw new SecurityException(msg);
   6133         }
   6134 
   6135         return getContentProviderImpl(caller, name);
   6136     }
   6137 
   6138     private ContentProviderHolder getContentProviderExternal(String name) {
   6139         return getContentProviderImpl(null, name);
   6140     }
   6141 
   6142     /**
   6143      * Drop a content provider from a ProcessRecord's bookkeeping
   6144      * @param cpr
   6145      */
   6146     public void removeContentProvider(IApplicationThread caller, String name) {
   6147         synchronized (this) {
   6148             ContentProviderRecord cpr = mProvidersByName.get(name);
   6149             if(cpr == null) {
   6150                 // remove from mProvidersByClass
   6151                 if (DEBUG_PROVIDER) Slog.v(TAG, name +
   6152                         " provider not found in providers list");
   6153                 return;
   6154             }
   6155             final ProcessRecord r = getRecordForAppLocked(caller);
   6156             if (r == null) {
   6157                 throw new SecurityException(
   6158                         "Unable to find app for caller " + caller +
   6159                         " when removing content provider " + name);
   6160             }
   6161             //update content provider record entry info
   6162             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
   6163             ContentProviderRecord localCpr = mProvidersByClass.get(comp);
   6164             if (localCpr.proc == r) {
   6165                 //should not happen. taken care of as a local provider
   6166                 Slog.w(TAG, "removeContentProvider called on local provider: "
   6167                         + cpr.info.name + " in process " + r.processName);
   6168                 return;
   6169             } else {
   6170                 if (decProviderCount(r, localCpr)) {
   6171                     updateOomAdjLocked();
   6172                 }
   6173             }
   6174         }
   6175     }
   6176 
   6177     private void removeContentProviderExternal(String name) {
   6178         synchronized (this) {
   6179             ContentProviderRecord cpr = mProvidersByName.get(name);
   6180             if(cpr == null) {
   6181                 //remove from mProvidersByClass
   6182                 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
   6183                 return;
   6184             }
   6185 
   6186             //update content provider record entry info
   6187             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
   6188             ContentProviderRecord localCpr = mProvidersByClass.get(comp);
   6189             localCpr.externals--;
   6190             if (localCpr.externals < 0) {
   6191                 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
   6192             }
   6193             updateOomAdjLocked();
   6194         }
   6195     }
   6196 
   6197     public final void publishContentProviders(IApplicationThread caller,
   6198             List<ContentProviderHolder> providers) {
   6199         if (providers == null) {
   6200             return;
   6201         }
   6202 
   6203         synchronized(this) {
   6204             final ProcessRecord r = getRecordForAppLocked(caller);
   6205             if (r == null) {
   6206                 throw new SecurityException(
   6207                         "Unable to find app for caller " + caller
   6208                       + " (pid=" + Binder.getCallingPid()
   6209                       + ") when publishing content providers");
   6210             }
   6211 
   6212             final long origId = Binder.clearCallingIdentity();
   6213 
   6214             final int N = providers.size();
   6215             for (int i=0; i<N; i++) {
   6216                 ContentProviderHolder src = providers.get(i);
   6217                 if (src == null || src.info == null || src.provider == null) {
   6218                     continue;
   6219                 }
   6220                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
   6221                 if (dst != null) {
   6222                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
   6223                     mProvidersByClass.put(comp, dst);
   6224                     String names[] = dst.info.authority.split(";");
   6225                     for (int j = 0; j < names.length; j++) {
   6226                         mProvidersByName.put(names[j], dst);
   6227                     }
   6228 
   6229                     int NL = mLaunchingProviders.size();
   6230                     int j;
   6231                     for (j=0; j<NL; j++) {
   6232                         if (mLaunchingProviders.get(j) == dst) {
   6233                             mLaunchingProviders.remove(j);
   6234                             j--;
   6235                             NL--;
   6236                         }
   6237                     }
   6238                     synchronized (dst) {
   6239                         dst.provider = src.provider;
   6240                         dst.proc = r;
   6241                         dst.notifyAll();
   6242                     }
   6243                     updateOomAdjLocked(r);
   6244                 }
   6245             }
   6246 
   6247             Binder.restoreCallingIdentity(origId);
   6248         }
   6249     }
   6250 
   6251     public static final void installSystemProviders() {
   6252         List<ProviderInfo> providers;
   6253         synchronized (mSelf) {
   6254             ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
   6255             providers = mSelf.generateApplicationProvidersLocked(app);
   6256             if (providers != null) {
   6257                 for (int i=providers.size()-1; i>=0; i--) {
   6258                     ProviderInfo pi = (ProviderInfo)providers.get(i);
   6259                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   6260                         Slog.w(TAG, "Not installing system proc provider " + pi.name
   6261                                 + ": not system .apk");
   6262                         providers.remove(i);
   6263                     }
   6264                 }
   6265             }
   6266         }
   6267         if (providers != null) {
   6268             mSystemThread.installSystemProviders(providers);
   6269         }
   6270 
   6271         mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
   6272 
   6273         mSelf.mUsageStatsService.monitorPackages();
   6274     }
   6275 
   6276     /**
   6277      * Allows app to retrieve the MIME type of a URI without having permission
   6278      * to access its content provider.
   6279      *
   6280      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
   6281      *
   6282      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
   6283      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
   6284      */
   6285     public String getProviderMimeType(Uri uri) {
   6286         final String name = uri.getAuthority();
   6287         final long ident = Binder.clearCallingIdentity();
   6288         ContentProviderHolder holder = null;
   6289 
   6290         try {
   6291             holder = getContentProviderExternal(name);
   6292             if (holder != null) {
   6293                 return holder.provider.getType(uri);
   6294             }
   6295         } catch (RemoteException e) {
   6296             Log.w(TAG, "Content provider dead retrieving " + uri, e);
   6297             return null;
   6298         } finally {
   6299             if (holder != null) {
   6300                 removeContentProviderExternal(name);
   6301             }
   6302             Binder.restoreCallingIdentity(ident);
   6303         }
   6304 
   6305         return null;
   6306     }
   6307 
   6308     // =========================================================
   6309     // GLOBAL MANAGEMENT
   6310     // =========================================================
   6311 
   6312     final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
   6313             ApplicationInfo info, String customProcess) {
   6314         String proc = customProcess != null ? customProcess : info.processName;
   6315         BatteryStatsImpl.Uid.Proc ps = null;
   6316         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   6317         synchronized (stats) {
   6318             ps = stats.getProcessStatsLocked(info.uid, proc);
   6319         }
   6320         return new ProcessRecord(ps, thread, info, proc);
   6321     }
   6322 
   6323     final ProcessRecord addAppLocked(ApplicationInfo info) {
   6324         ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
   6325 
   6326         if (app == null) {
   6327             app = newProcessRecordLocked(null, info, null);
   6328             mProcessNames.put(info.processName, info.uid, app);
   6329             updateLruProcessLocked(app, true, true);
   6330         }
   6331 
   6332         // This package really, really can not be stopped.
   6333         try {
   6334             AppGlobals.getPackageManager().setPackageStoppedState(
   6335                     info.packageName, false);
   6336         } catch (RemoteException e) {
   6337         } catch (IllegalArgumentException e) {
   6338             Slog.w(TAG, "Failed trying to unstop package "
   6339                     + info.packageName + ": " + e);
   6340         }
   6341 
   6342         if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
   6343                 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
   6344             app.persistent = true;
   6345             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
   6346         }
   6347         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
   6348             mPersistentStartingProcesses.add(app);
   6349             startProcessLocked(app, "added application", app.processName);
   6350         }
   6351 
   6352         return app;
   6353     }
   6354 
   6355     public void unhandledBack() {
   6356         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
   6357                 "unhandledBack()");
   6358 
   6359         synchronized(this) {
   6360             int count = mMainStack.mHistory.size();
   6361             if (DEBUG_SWITCH) Slog.d(
   6362                 TAG, "Performing unhandledBack(): stack size = " + count);
   6363             if (count > 1) {
   6364                 final long origId = Binder.clearCallingIdentity();
   6365                 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
   6366                         count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
   6367                 Binder.restoreCallingIdentity(origId);
   6368             }
   6369         }
   6370     }
   6371 
   6372     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
   6373         String name = uri.getAuthority();
   6374         ContentProviderHolder cph = getContentProviderExternal(name);
   6375         ParcelFileDescriptor pfd = null;
   6376         if (cph != null) {
   6377             // We record the binder invoker's uid in thread-local storage before
   6378             // going to the content provider to open the file.  Later, in the code
   6379             // that handles all permissions checks, we look for this uid and use
   6380             // that rather than the Activity Manager's own uid.  The effect is that
   6381             // we do the check against the caller's permissions even though it looks
   6382             // to the content provider like the Activity Manager itself is making
   6383             // the request.
   6384             sCallerIdentity.set(new Identity(
   6385                     Binder.getCallingPid(), Binder.getCallingUid()));
   6386             try {
   6387                 pfd = cph.provider.openFile(uri, "r");
   6388             } catch (FileNotFoundException e) {
   6389                 // do nothing; pfd will be returned null
   6390             } finally {
   6391                 // Ensure that whatever happens, we clean up the identity state
   6392                 sCallerIdentity.remove();
   6393             }
   6394 
   6395             // We've got the fd now, so we're done with the provider.
   6396             removeContentProviderExternal(name);
   6397         } else {
   6398             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
   6399         }
   6400         return pfd;
   6401     }
   6402 
   6403     // Actually is sleeping or shutting down or whatever else in the future
   6404     // is an inactive state.
   6405     public boolean isSleeping() {
   6406         return mSleeping || mShuttingDown;
   6407     }
   6408 
   6409     public void goingToSleep() {
   6410         synchronized(this) {
   6411             mSleeping = true;
   6412             mWindowManager.setEventDispatching(false);
   6413 
   6414             mMainStack.stopIfSleepingLocked();
   6415 
   6416             // Initialize the wake times of all processes.
   6417             checkExcessivePowerUsageLocked(false);
   6418             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   6419             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   6420             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   6421         }
   6422     }
   6423 
   6424     public boolean shutdown(int timeout) {
   6425         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
   6426                 != PackageManager.PERMISSION_GRANTED) {
   6427             throw new SecurityException("Requires permission "
   6428                     + android.Manifest.permission.SHUTDOWN);
   6429         }
   6430 
   6431         boolean timedout = false;
   6432 
   6433         synchronized(this) {
   6434             mShuttingDown = true;
   6435             mWindowManager.setEventDispatching(false);
   6436 
   6437             if (mMainStack.mResumedActivity != null) {
   6438                 mMainStack.stopIfSleepingLocked();
   6439                 final long endTime = System.currentTimeMillis() + timeout;
   6440                 while (mMainStack.mResumedActivity != null
   6441                         || mMainStack.mPausingActivity != null) {
   6442                     long delay = endTime - System.currentTimeMillis();
   6443                     if (delay <= 0) {
   6444                         Slog.w(TAG, "Activity manager shutdown timed out");
   6445                         timedout = true;
   6446                         break;
   6447                     }
   6448                     try {
   6449                         this.wait();
   6450                     } catch (InterruptedException e) {
   6451                     }
   6452                 }
   6453             }
   6454         }
   6455 
   6456         mUsageStatsService.shutdown();
   6457         mBatteryStatsService.shutdown();
   6458 
   6459         return timedout;
   6460     }
   6461 
   6462     public final void activitySlept(IBinder token) {
   6463         if (localLOGV) Slog.v(
   6464             TAG, "Activity slept: token=" + token);
   6465 
   6466         ActivityRecord r = null;
   6467 
   6468         final long origId = Binder.clearCallingIdentity();
   6469 
   6470         synchronized (this) {
   6471             r = mMainStack.isInStackLocked(token);
   6472             if (r != null) {
   6473                 mMainStack.activitySleptLocked(r);
   6474             }
   6475         }
   6476 
   6477         Binder.restoreCallingIdentity(origId);
   6478     }
   6479 
   6480     public void wakingUp() {
   6481         synchronized(this) {
   6482             mWindowManager.setEventDispatching(true);
   6483             mSleeping = false;
   6484             mMainStack.awakeFromSleepingLocked();
   6485             mMainStack.resumeTopActivityLocked(null);
   6486         }
   6487     }
   6488 
   6489     public void stopAppSwitches() {
   6490         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   6491                 != PackageManager.PERMISSION_GRANTED) {
   6492             throw new SecurityException("Requires permission "
   6493                     + android.Manifest.permission.STOP_APP_SWITCHES);
   6494         }
   6495 
   6496         synchronized(this) {
   6497             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
   6498                     + APP_SWITCH_DELAY_TIME;
   6499             mDidAppSwitch = false;
   6500             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   6501             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   6502             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
   6503         }
   6504     }
   6505 
   6506     public void resumeAppSwitches() {
   6507         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   6508                 != PackageManager.PERMISSION_GRANTED) {
   6509             throw new SecurityException("Requires permission "
   6510                     + android.Manifest.permission.STOP_APP_SWITCHES);
   6511         }
   6512 
   6513         synchronized(this) {
   6514             // Note that we don't execute any pending app switches... we will
   6515             // let those wait until either the timeout, or the next start
   6516             // activity request.
   6517             mAppSwitchesAllowedTime = 0;
   6518         }
   6519     }
   6520 
   6521     boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
   6522             String name) {
   6523         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
   6524             return true;
   6525         }
   6526 
   6527         final int perm = checkComponentPermission(
   6528                 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
   6529                 callingUid, -1, true);
   6530         if (perm == PackageManager.PERMISSION_GRANTED) {
   6531             return true;
   6532         }
   6533 
   6534         Slog.w(TAG, name + " request from " + callingUid + " stopped");
   6535         return false;
   6536     }
   6537 
   6538     public void setDebugApp(String packageName, boolean waitForDebugger,
   6539             boolean persistent) {
   6540         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
   6541                 "setDebugApp()");
   6542 
   6543         // Note that this is not really thread safe if there are multiple
   6544         // callers into it at the same time, but that's not a situation we
   6545         // care about.
   6546         if (persistent) {
   6547             final ContentResolver resolver = mContext.getContentResolver();
   6548             Settings.System.putString(
   6549                 resolver, Settings.System.DEBUG_APP,
   6550                 packageName);
   6551             Settings.System.putInt(
   6552                 resolver, Settings.System.WAIT_FOR_DEBUGGER,
   6553                 waitForDebugger ? 1 : 0);
   6554         }
   6555 
   6556         synchronized (this) {
   6557             if (!persistent) {
   6558                 mOrigDebugApp = mDebugApp;
   6559                 mOrigWaitForDebugger = mWaitForDebugger;
   6560             }
   6561             mDebugApp = packageName;
   6562             mWaitForDebugger = waitForDebugger;
   6563             mDebugTransient = !persistent;
   6564             if (packageName != null) {
   6565                 final long origId = Binder.clearCallingIdentity();
   6566                 forceStopPackageLocked(packageName, -1, false, false, true, true);
   6567                 Binder.restoreCallingIdentity(origId);
   6568             }
   6569         }
   6570     }
   6571 
   6572     void setProfileApp(ApplicationInfo app, String processName, String profileFile,
   6573             ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
   6574         synchronized (this) {
   6575             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   6576             if (!isDebuggable) {
   6577                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   6578                     throw new SecurityException("Process not debuggable: " + app.packageName);
   6579                 }
   6580             }
   6581             mProfileApp = processName;
   6582             mProfileFile = profileFile;
   6583             if (mProfileFd != null) {
   6584                 try {
   6585                     mProfileFd.close();
   6586                 } catch (IOException e) {
   6587                 }
   6588                 mProfileFd = null;
   6589             }
   6590             mProfileFd = profileFd;
   6591             mProfileType = 0;
   6592             mAutoStopProfiler = autoStopProfiler;
   6593         }
   6594     }
   6595 
   6596     public void setAlwaysFinish(boolean enabled) {
   6597         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
   6598                 "setAlwaysFinish()");
   6599 
   6600         Settings.System.putInt(
   6601                 mContext.getContentResolver(),
   6602                 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
   6603 
   6604         synchronized (this) {
   6605             mAlwaysFinishActivities = enabled;
   6606         }
   6607     }
   6608 
   6609     public void setActivityController(IActivityController controller) {
   6610         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   6611                 "setActivityController()");
   6612         synchronized (this) {
   6613             mController = controller;
   6614         }
   6615     }
   6616 
   6617     public boolean isUserAMonkey() {
   6618         // For now the fact that there is a controller implies
   6619         // we have a monkey.
   6620         synchronized (this) {
   6621             return mController != null;
   6622         }
   6623     }
   6624 
   6625     public void registerActivityWatcher(IActivityWatcher watcher) {
   6626         synchronized (this) {
   6627             mWatchers.register(watcher);
   6628         }
   6629     }
   6630 
   6631     public void unregisterActivityWatcher(IActivityWatcher watcher) {
   6632         synchronized (this) {
   6633             mWatchers.unregister(watcher);
   6634         }
   6635     }
   6636 
   6637     public void registerProcessObserver(IProcessObserver observer) {
   6638         mProcessObservers.register(observer);
   6639     }
   6640 
   6641     public void unregisterProcessObserver(IProcessObserver observer) {
   6642         mProcessObservers.unregister(observer);
   6643     }
   6644 
   6645     public void setImmersive(IBinder token, boolean immersive) {
   6646         synchronized(this) {
   6647             ActivityRecord r = mMainStack.isInStackLocked(token);
   6648             if (r == null) {
   6649                 throw new IllegalArgumentException();
   6650             }
   6651             r.immersive = immersive;
   6652         }
   6653     }
   6654 
   6655     public boolean isImmersive(IBinder token) {
   6656         synchronized (this) {
   6657             ActivityRecord r = mMainStack.isInStackLocked(token);
   6658             if (r == null) {
   6659                 throw new IllegalArgumentException();
   6660             }
   6661             return r.immersive;
   6662         }
   6663     }
   6664 
   6665     public boolean isTopActivityImmersive() {
   6666         synchronized (this) {
   6667             ActivityRecord r = mMainStack.topRunningActivityLocked(null);
   6668             return (r != null) ? r.immersive : false;
   6669         }
   6670     }
   6671 
   6672     public final void enterSafeMode() {
   6673         synchronized(this) {
   6674             // It only makes sense to do this before the system is ready
   6675             // and started launching other packages.
   6676             if (!mSystemReady) {
   6677                 try {
   6678                     AppGlobals.getPackageManager().enterSafeMode();
   6679                 } catch (RemoteException e) {
   6680                 }
   6681             }
   6682         }
   6683     }
   6684 
   6685     public final void showSafeModeOverlay() {
   6686         View v = LayoutInflater.from(mContext).inflate(
   6687                 com.android.internal.R.layout.safe_mode, null);
   6688         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
   6689         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
   6690         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
   6691         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
   6692         lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
   6693         lp.format = v.getBackground().getOpacity();
   6694         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
   6695                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
   6696         ((WindowManager)mContext.getSystemService(
   6697                 Context.WINDOW_SERVICE)).addView(v, lp);
   6698     }
   6699 
   6700     public void noteWakeupAlarm(IIntentSender sender) {
   6701         if (!(sender instanceof PendingIntentRecord)) {
   6702             return;
   6703         }
   6704         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   6705         synchronized (stats) {
   6706             if (mBatteryStatsService.isOnBattery()) {
   6707                 mBatteryStatsService.enforceCallingPermission();
   6708                 PendingIntentRecord rec = (PendingIntentRecord)sender;
   6709                 int MY_UID = Binder.getCallingUid();
   6710                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
   6711                 BatteryStatsImpl.Uid.Pkg pkg =
   6712                     stats.getPackageStatsLocked(uid, rec.key.packageName);
   6713                 pkg.incWakeupsLocked();
   6714             }
   6715         }
   6716     }
   6717 
   6718     public boolean killPids(int[] pids, String pReason, boolean secure) {
   6719         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   6720             throw new SecurityException("killPids only available to the system");
   6721         }
   6722         String reason = (pReason == null) ? "Unknown" : pReason;
   6723         // XXX Note: don't acquire main activity lock here, because the window
   6724         // manager calls in with its locks held.
   6725 
   6726         boolean killed = false;
   6727         synchronized (mPidsSelfLocked) {
   6728             int[] types = new int[pids.length];
   6729             int worstType = 0;
   6730             for (int i=0; i<pids.length; i++) {
   6731                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   6732                 if (proc != null) {
   6733                     int type = proc.setAdj;
   6734                     types[i] = type;
   6735                     if (type > worstType) {
   6736                         worstType = type;
   6737                     }
   6738                 }
   6739             }
   6740 
   6741             // If the worst oom_adj is somewhere in the hidden proc LRU range,
   6742             // then constrain it so we will kill all hidden procs.
   6743             if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
   6744                     && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
   6745                 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
   6746             }
   6747 
   6748             // If this is not a secure call, don't let it kill processes that
   6749             // are important.
   6750             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
   6751                 worstType = ProcessList.SERVICE_ADJ;
   6752             }
   6753 
   6754             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
   6755             for (int i=0; i<pids.length; i++) {
   6756                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   6757                 if (proc == null) {
   6758                     continue;
   6759                 }
   6760                 int adj = proc.setAdj;
   6761                 if (adj >= worstType && !proc.killedBackground) {
   6762                     Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
   6763                     EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
   6764                             proc.processName, adj, reason);
   6765                     killed = true;
   6766                     proc.killedBackground = true;
   6767                     Process.killProcessQuiet(pids[i]);
   6768                 }
   6769             }
   6770         }
   6771         return killed;
   6772     }
   6773 
   6774     public final void startRunning(String pkg, String cls, String action,
   6775             String data) {
   6776         synchronized(this) {
   6777             if (mStartRunning) {
   6778                 return;
   6779             }
   6780             mStartRunning = true;
   6781             mTopComponent = pkg != null && cls != null
   6782                     ? new ComponentName(pkg, cls) : null;
   6783             mTopAction = action != null ? action : Intent.ACTION_MAIN;
   6784             mTopData = data;
   6785             if (!mSystemReady) {
   6786                 return;
   6787             }
   6788         }
   6789 
   6790         systemReady(null);
   6791     }
   6792 
   6793     private void retrieveSettings() {
   6794         final ContentResolver resolver = mContext.getContentResolver();
   6795         String debugApp = Settings.System.getString(
   6796             resolver, Settings.System.DEBUG_APP);
   6797         boolean waitForDebugger = Settings.System.getInt(
   6798             resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
   6799         boolean alwaysFinishActivities = Settings.System.getInt(
   6800             resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
   6801 
   6802         Configuration configuration = new Configuration();
   6803         Settings.System.getConfiguration(resolver, configuration);
   6804 
   6805         synchronized (this) {
   6806             mDebugApp = mOrigDebugApp = debugApp;
   6807             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
   6808             mAlwaysFinishActivities = alwaysFinishActivities;
   6809             // This happens before any activities are started, so we can
   6810             // change mConfiguration in-place.
   6811             updateConfigurationLocked(configuration, null, false, true);
   6812             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
   6813         }
   6814     }
   6815 
   6816     public boolean testIsSystemReady() {
   6817         // no need to synchronize(this) just to read & return the value
   6818         return mSystemReady;
   6819     }
   6820 
   6821     private static File getCalledPreBootReceiversFile() {
   6822         File dataDir = Environment.getDataDirectory();
   6823         File systemDir = new File(dataDir, "system");
   6824         File fname = new File(systemDir, "called_pre_boots.dat");
   6825         return fname;
   6826     }
   6827 
   6828     static final int LAST_DONE_VERSION = 10000;
   6829 
   6830     private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
   6831         ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
   6832         File file = getCalledPreBootReceiversFile();
   6833         FileInputStream fis = null;
   6834         try {
   6835             fis = new FileInputStream(file);
   6836             DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
   6837             int fvers = dis.readInt();
   6838             if (fvers == LAST_DONE_VERSION) {
   6839                 String vers = dis.readUTF();
   6840                 String codename = dis.readUTF();
   6841                 String build = dis.readUTF();
   6842                 if (android.os.Build.VERSION.RELEASE.equals(vers)
   6843                         && android.os.Build.VERSION.CODENAME.equals(codename)
   6844                         && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
   6845                     int num = dis.readInt();
   6846                     while (num > 0) {
   6847                         num--;
   6848                         String pkg = dis.readUTF();
   6849                         String cls = dis.readUTF();
   6850                         lastDoneReceivers.add(new ComponentName(pkg, cls));
   6851                     }
   6852                 }
   6853             }
   6854         } catch (FileNotFoundException e) {
   6855         } catch (IOException e) {
   6856             Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
   6857         } finally {
   6858             if (fis != null) {
   6859                 try {
   6860                     fis.close();
   6861                 } catch (IOException e) {
   6862                 }
   6863             }
   6864         }
   6865         return lastDoneReceivers;
   6866     }
   6867 
   6868     private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
   6869         File file = getCalledPreBootReceiversFile();
   6870         FileOutputStream fos = null;
   6871         DataOutputStream dos = null;
   6872         try {
   6873             Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
   6874             fos = new FileOutputStream(file);
   6875             dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
   6876             dos.writeInt(LAST_DONE_VERSION);
   6877             dos.writeUTF(android.os.Build.VERSION.RELEASE);
   6878             dos.writeUTF(android.os.Build.VERSION.CODENAME);
   6879             dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
   6880             dos.writeInt(list.size());
   6881             for (int i=0; i<list.size(); i++) {
   6882                 dos.writeUTF(list.get(i).getPackageName());
   6883                 dos.writeUTF(list.get(i).getClassName());
   6884             }
   6885         } catch (IOException e) {
   6886             Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
   6887             file.delete();
   6888         } finally {
   6889             FileUtils.sync(fos);
   6890             if (dos != null) {
   6891                 try {
   6892                     dos.close();
   6893                 } catch (IOException e) {
   6894                     // TODO Auto-generated catch block
   6895                     e.printStackTrace();
   6896                 }
   6897             }
   6898         }
   6899     }
   6900 
   6901     public void systemReady(final Runnable goingCallback) {
   6902         synchronized(this) {
   6903             if (mSystemReady) {
   6904                 if (goingCallback != null) goingCallback.run();
   6905                 return;
   6906             }
   6907 
   6908             // Check to see if there are any update receivers to run.
   6909             if (!mDidUpdate) {
   6910                 if (mWaitingUpdate) {
   6911                     return;
   6912                 }
   6913                 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
   6914                 List<ResolveInfo> ris = null;
   6915                 try {
   6916                     ris = AppGlobals.getPackageManager().queryIntentReceivers(
   6917                                 intent, null, 0);
   6918                 } catch (RemoteException e) {
   6919                 }
   6920                 if (ris != null) {
   6921                     for (int i=ris.size()-1; i>=0; i--) {
   6922                         if ((ris.get(i).activityInfo.applicationInfo.flags
   6923                                 &ApplicationInfo.FLAG_SYSTEM) == 0) {
   6924                             ris.remove(i);
   6925                         }
   6926                     }
   6927                     intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
   6928 
   6929                     ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
   6930 
   6931                     final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
   6932                     for (int i=0; i<ris.size(); i++) {
   6933                         ActivityInfo ai = ris.get(i).activityInfo;
   6934                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
   6935                         if (lastDoneReceivers.contains(comp)) {
   6936                             ris.remove(i);
   6937                             i--;
   6938                         }
   6939                     }
   6940 
   6941                     for (int i=0; i<ris.size(); i++) {
   6942                         ActivityInfo ai = ris.get(i).activityInfo;
   6943                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
   6944                         doneReceivers.add(comp);
   6945                         intent.setComponent(comp);
   6946                         IIntentReceiver finisher = null;
   6947                         if (i == ris.size()-1) {
   6948                             finisher = new IIntentReceiver.Stub() {
   6949                                 public void performReceive(Intent intent, int resultCode,
   6950                                         String data, Bundle extras, boolean ordered,
   6951                                         boolean sticky) {
   6952                                     // The raw IIntentReceiver interface is called
   6953                                     // with the AM lock held, so redispatch to
   6954                                     // execute our code without the lock.
   6955                                     mHandler.post(new Runnable() {
   6956                                         public void run() {
   6957                                             synchronized (ActivityManagerService.this) {
   6958                                                 mDidUpdate = true;
   6959                                             }
   6960                                             writeLastDonePreBootReceivers(doneReceivers);
   6961                                             showBootMessage(mContext.getText(
   6962                                                     R.string.android_upgrading_complete),
   6963                                                     false);
   6964                                             systemReady(goingCallback);
   6965                                         }
   6966                                     });
   6967                                 }
   6968                             };
   6969                         }
   6970                         Slog.i(TAG, "Sending system update to: " + intent.getComponent());
   6971                         broadcastIntentLocked(null, null, intent, null, finisher,
   6972                                 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
   6973                         if (finisher != null) {
   6974                             mWaitingUpdate = true;
   6975                         }
   6976                     }
   6977                 }
   6978                 if (mWaitingUpdate) {
   6979                     return;
   6980                 }
   6981                 mDidUpdate = true;
   6982             }
   6983 
   6984             mSystemReady = true;
   6985             if (!mStartRunning) {
   6986                 return;
   6987             }
   6988         }
   6989 
   6990         ArrayList<ProcessRecord> procsToKill = null;
   6991         synchronized(mPidsSelfLocked) {
   6992             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
   6993                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   6994                 if (!isAllowedWhileBooting(proc.info)){
   6995                     if (procsToKill == null) {
   6996                         procsToKill = new ArrayList<ProcessRecord>();
   6997                     }
   6998                     procsToKill.add(proc);
   6999                 }
   7000             }
   7001         }
   7002 
   7003         synchronized(this) {
   7004             if (procsToKill != null) {
   7005                 for (int i=procsToKill.size()-1; i>=0; i--) {
   7006                     ProcessRecord proc = procsToKill.get(i);
   7007                     Slog.i(TAG, "Removing system update proc: " + proc);
   7008                     removeProcessLocked(proc, true, false, "system update done");
   7009                 }
   7010             }
   7011 
   7012             // Now that we have cleaned up any update processes, we
   7013             // are ready to start launching real processes and know that
   7014             // we won't trample on them any more.
   7015             mProcessesReady = true;
   7016         }
   7017 
   7018         Slog.i(TAG, "System now ready");
   7019         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
   7020             SystemClock.uptimeMillis());
   7021 
   7022         synchronized(this) {
   7023             // Make sure we have no pre-ready processes sitting around.
   7024 
   7025             if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
   7026                 ResolveInfo ri = mContext.getPackageManager()
   7027                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
   7028                                 STOCK_PM_FLAGS);
   7029                 CharSequence errorMsg = null;
   7030                 if (ri != null) {
   7031                     ActivityInfo ai = ri.activityInfo;
   7032                     ApplicationInfo app = ai.applicationInfo;
   7033                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   7034                         mTopAction = Intent.ACTION_FACTORY_TEST;
   7035                         mTopData = null;
   7036                         mTopComponent = new ComponentName(app.packageName,
   7037                                 ai.name);
   7038                     } else {
   7039                         errorMsg = mContext.getResources().getText(
   7040                                 com.android.internal.R.string.factorytest_not_system);
   7041                     }
   7042                 } else {
   7043                     errorMsg = mContext.getResources().getText(
   7044                             com.android.internal.R.string.factorytest_no_action);
   7045                 }
   7046                 if (errorMsg != null) {
   7047                     mTopAction = null;
   7048                     mTopData = null;
   7049                     mTopComponent = null;
   7050                     Message msg = Message.obtain();
   7051                     msg.what = SHOW_FACTORY_ERROR_MSG;
   7052                     msg.getData().putCharSequence("msg", errorMsg);
   7053                     mHandler.sendMessage(msg);
   7054                 }
   7055             }
   7056         }
   7057 
   7058         retrieveSettings();
   7059 
   7060         if (goingCallback != null) goingCallback.run();
   7061 
   7062         synchronized (this) {
   7063             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   7064                 try {
   7065                     List apps = AppGlobals.getPackageManager().
   7066                         getPersistentApplications(STOCK_PM_FLAGS);
   7067                     if (apps != null) {
   7068                         int N = apps.size();
   7069                         int i;
   7070                         for (i=0; i<N; i++) {
   7071                             ApplicationInfo info
   7072                                 = (ApplicationInfo)apps.get(i);
   7073                             if (info != null &&
   7074                                     !info.packageName.equals("android")) {
   7075                                 addAppLocked(info);
   7076                             }
   7077                         }
   7078                     }
   7079                 } catch (RemoteException ex) {
   7080                     // pm is in same process, this will never happen.
   7081                 }
   7082             }
   7083 
   7084             // Start up initial activity.
   7085             mBooting = true;
   7086 
   7087             try {
   7088                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
   7089                     Message msg = Message.obtain();
   7090                     msg.what = SHOW_UID_ERROR_MSG;
   7091                     mHandler.sendMessage(msg);
   7092                 }
   7093             } catch (RemoteException e) {
   7094             }
   7095 
   7096             mMainStack.resumeTopActivityLocked(null);
   7097         }
   7098     }
   7099 
   7100     private boolean makeAppCrashingLocked(ProcessRecord app,
   7101             String shortMsg, String longMsg, String stackTrace) {
   7102         app.crashing = true;
   7103         app.crashingReport = generateProcessError(app,
   7104                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
   7105         startAppProblemLocked(app);
   7106         app.stopFreezingAllLocked();
   7107         return handleAppCrashLocked(app);
   7108     }
   7109 
   7110     private void makeAppNotRespondingLocked(ProcessRecord app,
   7111             String activity, String shortMsg, String longMsg) {
   7112         app.notResponding = true;
   7113         app.notRespondingReport = generateProcessError(app,
   7114                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
   7115                 activity, shortMsg, longMsg, null);
   7116         startAppProblemLocked(app);
   7117         app.stopFreezingAllLocked();
   7118     }
   7119 
   7120     /**
   7121      * Generate a process error record, suitable for attachment to a ProcessRecord.
   7122      *
   7123      * @param app The ProcessRecord in which the error occurred.
   7124      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
   7125      *                      ActivityManager.AppErrorStateInfo
   7126      * @param activity The activity associated with the crash, if known.
   7127      * @param shortMsg Short message describing the crash.
   7128      * @param longMsg Long message describing the crash.
   7129      * @param stackTrace Full crash stack trace, may be null.
   7130      *
   7131      * @return Returns a fully-formed AppErrorStateInfo record.
   7132      */
   7133     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
   7134             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
   7135         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
   7136 
   7137         report.condition = condition;
   7138         report.processName = app.processName;
   7139         report.pid = app.pid;
   7140         report.uid = app.info.uid;
   7141         report.tag = activity;
   7142         report.shortMsg = shortMsg;
   7143         report.longMsg = longMsg;
   7144         report.stackTrace = stackTrace;
   7145 
   7146         return report;
   7147     }
   7148 
   7149     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
   7150         synchronized (this) {
   7151             app.crashing = false;
   7152             app.crashingReport = null;
   7153             app.notResponding = false;
   7154             app.notRespondingReport = null;
   7155             if (app.anrDialog == fromDialog) {
   7156                 app.anrDialog = null;
   7157             }
   7158             if (app.waitDialog == fromDialog) {
   7159                 app.waitDialog = null;
   7160             }
   7161             if (app.pid > 0 && app.pid != MY_PID) {
   7162                 handleAppCrashLocked(app);
   7163                 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
   7164                 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   7165                         app.processName, app.setAdj, "user's request after error");
   7166                 Process.killProcessQuiet(app.pid);
   7167             }
   7168         }
   7169     }
   7170 
   7171     private boolean handleAppCrashLocked(ProcessRecord app) {
   7172         long now = SystemClock.uptimeMillis();
   7173 
   7174         Long crashTime = mProcessCrashTimes.get(app.info.processName,
   7175                 app.info.uid);
   7176         if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
   7177             // This process loses!
   7178             Slog.w(TAG, "Process " + app.info.processName
   7179                     + " has crashed too many times: killing!");
   7180             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
   7181                     app.info.processName, app.info.uid);
   7182             for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
   7183                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   7184                 if (r.app == app) {
   7185                     Slog.w(TAG, "  Force finishing activity "
   7186                         + r.intent.getComponent().flattenToShortString());
   7187                     r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
   7188                 }
   7189             }
   7190             if (!app.persistent) {
   7191                 // We don't want to start this process again until the user
   7192                 // explicitly does so...  but for persistent process, we really
   7193                 // need to keep it running.  If a persistent process is actually
   7194                 // repeatedly crashing, then badness for everyone.
   7195                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
   7196                         app.info.processName);
   7197                 mBadProcesses.put(app.info.processName, app.info.uid, now);
   7198                 app.bad = true;
   7199                 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
   7200                 app.removed = true;
   7201                 // Don't let services in this process be restarted and potentially
   7202                 // annoy the user repeatedly.  Unless it is persistent, since those
   7203                 // processes run critical code.
   7204                 removeProcessLocked(app, false, false, "crash");
   7205                 mMainStack.resumeTopActivityLocked(null);
   7206                 return false;
   7207             }
   7208             mMainStack.resumeTopActivityLocked(null);
   7209         } else {
   7210             ActivityRecord r = mMainStack.topRunningActivityLocked(null);
   7211             if (r.app == app) {
   7212                 // If the top running activity is from this crashing
   7213                 // process, then terminate it to avoid getting in a loop.
   7214                 Slog.w(TAG, "  Force finishing activity "
   7215                         + r.intent.getComponent().flattenToShortString());
   7216                 int index = mMainStack.indexOfActivityLocked(r);
   7217                 r.stack.finishActivityLocked(r, index,
   7218                         Activity.RESULT_CANCELED, null, "crashed");
   7219                 // Also terminate any activities below it that aren't yet
   7220                 // stopped, to avoid a situation where one will get
   7221                 // re-start our crashing activity once it gets resumed again.
   7222                 index--;
   7223                 if (index >= 0) {
   7224                     r = (ActivityRecord)mMainStack.mHistory.get(index);
   7225                     if (r.state == ActivityState.RESUMED
   7226                             || r.state == ActivityState.PAUSING
   7227                             || r.state == ActivityState.PAUSED) {
   7228                         if (!r.isHomeActivity || mHomeProcess != r.app) {
   7229                             Slog.w(TAG, "  Force finishing activity "
   7230                                     + r.intent.getComponent().flattenToShortString());
   7231                             r.stack.finishActivityLocked(r, index,
   7232                                     Activity.RESULT_CANCELED, null, "crashed");
   7233                         }
   7234                     }
   7235                 }
   7236             }
   7237         }
   7238 
   7239         // Bump up the crash count of any services currently running in the proc.
   7240         if (app.services.size() != 0) {
   7241             // Any services running in the application need to be placed
   7242             // back in the pending list.
   7243             Iterator<ServiceRecord> it = app.services.iterator();
   7244             while (it.hasNext()) {
   7245                 ServiceRecord sr = it.next();
   7246                 sr.crashCount++;
   7247             }
   7248         }
   7249 
   7250         // If the crashing process is what we consider to be the "home process" and it has been
   7251         // replaced by a third-party app, clear the package preferred activities from packages
   7252         // with a home activity running in the process to prevent a repeatedly crashing app
   7253         // from blocking the user to manually clear the list.
   7254         if (app == mHomeProcess && mHomeProcess.activities.size() > 0
   7255                     && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
   7256             Iterator it = mHomeProcess.activities.iterator();
   7257             while (it.hasNext()) {
   7258                 ActivityRecord r = (ActivityRecord)it.next();
   7259                 if (r.isHomeActivity) {
   7260                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
   7261                     try {
   7262                         ActivityThread.getPackageManager()
   7263                                 .clearPackagePreferredActivities(r.packageName);
   7264                     } catch (RemoteException c) {
   7265                         // pm is in same process, this will never happen.
   7266                     }
   7267                 }
   7268             }
   7269         }
   7270 
   7271         mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
   7272         return true;
   7273     }
   7274 
   7275     void startAppProblemLocked(ProcessRecord app) {
   7276         app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
   7277                 mContext, app.info.packageName, app.info.flags);
   7278         skipCurrentReceiverLocked(app);
   7279     }
   7280 
   7281     void skipCurrentReceiverLocked(ProcessRecord app) {
   7282         boolean reschedule = false;
   7283         BroadcastRecord r = app.curReceiver;
   7284         if (r != null) {
   7285             // The current broadcast is waiting for this app's receiver
   7286             // to be finished.  Looks like that's not going to happen, so
   7287             // let the broadcast continue.
   7288             logBroadcastReceiverDiscardLocked(r);
   7289             finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
   7290                     r.resultExtras, r.resultAbort, true);
   7291             reschedule = true;
   7292         }
   7293         r = mPendingBroadcast;
   7294         if (r != null && r.curApp == app) {
   7295             if (DEBUG_BROADCAST) Slog.v(TAG,
   7296                     "skip & discard pending app " + r);
   7297             logBroadcastReceiverDiscardLocked(r);
   7298             finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
   7299                     r.resultExtras, r.resultAbort, true);
   7300             reschedule = true;
   7301         }
   7302         if (reschedule) {
   7303             scheduleBroadcastsLocked();
   7304         }
   7305     }
   7306 
   7307     /**
   7308      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
   7309      * The application process will exit immediately after this call returns.
   7310      * @param app object of the crashing app, null for the system server
   7311      * @param crashInfo describing the exception
   7312      */
   7313     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
   7314         ProcessRecord r = findAppProcess(app, "Crash");
   7315         final String processName = app == null ? "system_server"
   7316                 : (r == null ? "unknown" : r.processName);
   7317 
   7318         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
   7319                 processName,
   7320                 r == null ? -1 : r.info.flags,
   7321                 crashInfo.exceptionClassName,
   7322                 crashInfo.exceptionMessage,
   7323                 crashInfo.throwFileName,
   7324                 crashInfo.throwLineNumber);
   7325 
   7326         addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
   7327 
   7328         crashApplication(r, crashInfo);
   7329     }
   7330 
   7331     public void handleApplicationStrictModeViolation(
   7332             IBinder app,
   7333             int violationMask,
   7334             StrictMode.ViolationInfo info) {
   7335         ProcessRecord r = findAppProcess(app, "StrictMode");
   7336         if (r == null) {
   7337             return;
   7338         }
   7339 
   7340         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
   7341             Integer stackFingerprint = info.hashCode();
   7342             boolean logIt = true;
   7343             synchronized (mAlreadyLoggedViolatedStacks) {
   7344                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
   7345                     logIt = false;
   7346                     // TODO: sub-sample into EventLog for these, with
   7347                     // the info.durationMillis?  Then we'd get
   7348                     // the relative pain numbers, without logging all
   7349                     // the stack traces repeatedly.  We'd want to do
   7350                     // likewise in the client code, which also does
   7351                     // dup suppression, before the Binder call.
   7352                 } else {
   7353                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
   7354                         mAlreadyLoggedViolatedStacks.clear();
   7355                     }
   7356                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
   7357                 }
   7358             }
   7359             if (logIt) {
   7360                 logStrictModeViolationToDropBox(r, info);
   7361             }
   7362         }
   7363 
   7364         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
   7365             AppErrorResult result = new AppErrorResult();
   7366             synchronized (this) {
   7367                 final long origId = Binder.clearCallingIdentity();
   7368 
   7369                 Message msg = Message.obtain();
   7370                 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
   7371                 HashMap<String, Object> data = new HashMap<String, Object>();
   7372                 data.put("result", result);
   7373                 data.put("app", r);
   7374                 data.put("violationMask", violationMask);
   7375                 data.put("info", info);
   7376                 msg.obj = data;
   7377                 mHandler.sendMessage(msg);
   7378 
   7379                 Binder.restoreCallingIdentity(origId);
   7380             }
   7381             int res = result.get();
   7382             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
   7383         }
   7384     }
   7385 
   7386     // Depending on the policy in effect, there could be a bunch of
   7387     // these in quick succession so we try to batch these together to
   7388     // minimize disk writes, number of dropbox entries, and maximize
   7389     // compression, by having more fewer, larger records.
   7390     private void logStrictModeViolationToDropBox(
   7391             ProcessRecord process,
   7392             StrictMode.ViolationInfo info) {
   7393         if (info == null) {
   7394             return;
   7395         }
   7396         final boolean isSystemApp = process == null ||
   7397                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
   7398                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
   7399         final String processName = process == null ? "unknown" : process.processName;
   7400         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
   7401         final DropBoxManager dbox = (DropBoxManager)
   7402                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   7403 
   7404         // Exit early if the dropbox isn't configured to accept this report type.
   7405         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   7406 
   7407         boolean bufferWasEmpty;
   7408         boolean needsFlush;
   7409         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
   7410         synchronized (sb) {
   7411             bufferWasEmpty = sb.length() == 0;
   7412             appendDropBoxProcessHeaders(process, processName, sb);
   7413             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   7414             sb.append("System-App: ").append(isSystemApp).append("\n");
   7415             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
   7416             if (info.violationNumThisLoop != 0) {
   7417                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
   7418             }
   7419             if (info.numAnimationsRunning != 0) {
   7420                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
   7421             }
   7422             if (info.broadcastIntentAction != null) {
   7423                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
   7424             }
   7425             if (info.durationMillis != -1) {
   7426                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
   7427             }
   7428             if (info.numInstances != -1) {
   7429                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
   7430             }
   7431             if (info.tags != null) {
   7432                 for (String tag : info.tags) {
   7433                     sb.append("Span-Tag: ").append(tag).append("\n");
   7434                 }
   7435             }
   7436             sb.append("\n");
   7437             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
   7438                 sb.append(info.crashInfo.stackTrace);
   7439             }
   7440             sb.append("\n");
   7441 
   7442             // Only buffer up to ~64k.  Various logging bits truncate
   7443             // things at 128k.
   7444             needsFlush = (sb.length() > 64 * 1024);
   7445         }
   7446 
   7447         // Flush immediately if the buffer's grown too large, or this
   7448         // is a non-system app.  Non-system apps are isolated with a
   7449         // different tag & policy and not batched.
   7450         //
   7451         // Batching is useful during internal testing with
   7452         // StrictMode settings turned up high.  Without batching,
   7453         // thousands of separate files could be created on boot.
   7454         if (!isSystemApp || needsFlush) {
   7455             new Thread("Error dump: " + dropboxTag) {
   7456                 @Override
   7457                 public void run() {
   7458                     String report;
   7459                     synchronized (sb) {
   7460                         report = sb.toString();
   7461                         sb.delete(0, sb.length());
   7462                         sb.trimToSize();
   7463                     }
   7464                     if (report.length() != 0) {
   7465                         dbox.addText(dropboxTag, report);
   7466                     }
   7467                 }
   7468             }.start();
   7469             return;
   7470         }
   7471 
   7472         // System app batching:
   7473         if (!bufferWasEmpty) {
   7474             // An existing dropbox-writing thread is outstanding, so
   7475             // we don't need to start it up.  The existing thread will
   7476             // catch the buffer appends we just did.
   7477             return;
   7478         }
   7479 
   7480         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
   7481         // (After this point, we shouldn't access AMS internal data structures.)
   7482         new Thread("Error dump: " + dropboxTag) {
   7483             @Override
   7484             public void run() {
   7485                 // 5 second sleep to let stacks arrive and be batched together
   7486                 try {
   7487                     Thread.sleep(5000);  // 5 seconds
   7488                 } catch (InterruptedException e) {}
   7489 
   7490                 String errorReport;
   7491                 synchronized (mStrictModeBuffer) {
   7492                     errorReport = mStrictModeBuffer.toString();
   7493                     if (errorReport.length() == 0) {
   7494                         return;
   7495                     }
   7496                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
   7497                     mStrictModeBuffer.trimToSize();
   7498                 }
   7499                 dbox.addText(dropboxTag, errorReport);
   7500             }
   7501         }.start();
   7502     }
   7503 
   7504     /**
   7505      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
   7506      * @param app object of the crashing app, null for the system server
   7507      * @param tag reported by the caller
   7508      * @param crashInfo describing the context of the error
   7509      * @return true if the process should exit immediately (WTF is fatal)
   7510      */
   7511     public boolean handleApplicationWtf(IBinder app, String tag,
   7512             ApplicationErrorReport.CrashInfo crashInfo) {
   7513         ProcessRecord r = findAppProcess(app, "WTF");
   7514         final String processName = app == null ? "system_server"
   7515                 : (r == null ? "unknown" : r.processName);
   7516 
   7517         EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
   7518                 processName,
   7519                 r == null ? -1 : r.info.flags,
   7520                 tag, crashInfo.exceptionMessage);
   7521 
   7522         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
   7523 
   7524         if (r != null && r.pid != Process.myPid() &&
   7525                 Settings.Secure.getInt(mContext.getContentResolver(),
   7526                         Settings.Secure.WTF_IS_FATAL, 0) != 0) {
   7527             crashApplication(r, crashInfo);
   7528             return true;
   7529         } else {
   7530             return false;
   7531         }
   7532     }
   7533 
   7534     /**
   7535      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
   7536      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
   7537      */
   7538     private ProcessRecord findAppProcess(IBinder app, String reason) {
   7539         if (app == null) {
   7540             return null;
   7541         }
   7542 
   7543         synchronized (this) {
   7544             for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   7545                 final int NA = apps.size();
   7546                 for (int ia=0; ia<NA; ia++) {
   7547                     ProcessRecord p = apps.valueAt(ia);
   7548                     if (p.thread != null && p.thread.asBinder() == app) {
   7549                         return p;
   7550                     }
   7551                 }
   7552             }
   7553 
   7554             Slog.w(TAG, "Can't find mystery application for " + reason
   7555                     + " from pid=" + Binder.getCallingPid()
   7556                     + " uid=" + Binder.getCallingUid() + ": " + app);
   7557             return null;
   7558         }
   7559     }
   7560 
   7561     /**
   7562      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
   7563      * to append various headers to the dropbox log text.
   7564      */
   7565     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
   7566             StringBuilder sb) {
   7567         // Watchdog thread ends up invoking this function (with
   7568         // a null ProcessRecord) to add the stack file to dropbox.
   7569         // Do not acquire a lock on this (am) in such cases, as it
   7570         // could cause a potential deadlock, if and when watchdog
   7571         // is invoked due to unavailability of lock on am and it
   7572         // would prevent watchdog from killing system_server.
   7573         if (process == null) {
   7574             sb.append("Process: ").append(processName).append("\n");
   7575             return;
   7576         }
   7577         // Note: ProcessRecord 'process' is guarded by the service
   7578         // instance.  (notably process.pkgList, which could otherwise change
   7579         // concurrently during execution of this method)
   7580         synchronized (this) {
   7581             sb.append("Process: ").append(processName).append("\n");
   7582             int flags = process.info.flags;
   7583             IPackageManager pm = AppGlobals.getPackageManager();
   7584             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
   7585             for (String pkg : process.pkgList) {
   7586                 sb.append("Package: ").append(pkg);
   7587                 try {
   7588                     PackageInfo pi = pm.getPackageInfo(pkg, 0);
   7589                     if (pi != null) {
   7590                         sb.append(" v").append(pi.versionCode);
   7591                         if (pi.versionName != null) {
   7592                             sb.append(" (").append(pi.versionName).append(")");
   7593                         }
   7594                     }
   7595                 } catch (RemoteException e) {
   7596                     Slog.e(TAG, "Error getting package info: " + pkg, e);
   7597                 }
   7598                 sb.append("\n");
   7599             }
   7600         }
   7601     }
   7602 
   7603     private static String processClass(ProcessRecord process) {
   7604         if (process == null || process.pid == MY_PID) {
   7605             return "system_server";
   7606         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   7607             return "system_app";
   7608         } else {
   7609             return "data_app";
   7610         }
   7611     }
   7612 
   7613     /**
   7614      * Write a description of an error (crash, WTF, ANR) to the drop box.
   7615      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
   7616      * @param process which caused the error, null means the system server
   7617      * @param activity which triggered the error, null if unknown
   7618      * @param parent activity related to the error, null if unknown
   7619      * @param subject line related to the error, null if absent
   7620      * @param report in long form describing the error, null if absent
   7621      * @param logFile to include in the report, null if none
   7622      * @param crashInfo giving an application stack trace, null if absent
   7623      */
   7624     public void addErrorToDropBox(String eventType,
   7625             ProcessRecord process, String processName, ActivityRecord activity,
   7626             ActivityRecord parent, String subject,
   7627             final String report, final File logFile,
   7628             final ApplicationErrorReport.CrashInfo crashInfo) {
   7629         // NOTE -- this must never acquire the ActivityManagerService lock,
   7630         // otherwise the watchdog may be prevented from resetting the system.
   7631 
   7632         final String dropboxTag = processClass(process) + "_" + eventType;
   7633         final DropBoxManager dbox = (DropBoxManager)
   7634                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   7635 
   7636         // Exit early if the dropbox isn't configured to accept this report type.
   7637         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   7638 
   7639         final StringBuilder sb = new StringBuilder(1024);
   7640         appendDropBoxProcessHeaders(process, processName, sb);
   7641         if (activity != null) {
   7642             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
   7643         }
   7644         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
   7645             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
   7646         }
   7647         if (parent != null && parent != activity) {
   7648             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
   7649         }
   7650         if (subject != null) {
   7651             sb.append("Subject: ").append(subject).append("\n");
   7652         }
   7653         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   7654         if (Debug.isDebuggerConnected()) {
   7655             sb.append("Debugger: Connected\n");
   7656         }
   7657         sb.append("\n");
   7658 
   7659         // Do the rest in a worker thread to avoid blocking the caller on I/O
   7660         // (After this point, we shouldn't access AMS internal data structures.)
   7661         Thread worker = new Thread("Error dump: " + dropboxTag) {
   7662             @Override
   7663             public void run() {
   7664                 if (report != null) {
   7665                     sb.append(report);
   7666                 }
   7667                 if (logFile != null) {
   7668                     try {
   7669                         sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
   7670                     } catch (IOException e) {
   7671                         Slog.e(TAG, "Error reading " + logFile, e);
   7672                     }
   7673                 }
   7674                 if (crashInfo != null && crashInfo.stackTrace != null) {
   7675                     sb.append(crashInfo.stackTrace);
   7676                 }
   7677 
   7678                 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
   7679                 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
   7680                 if (lines > 0) {
   7681                     sb.append("\n");
   7682 
   7683                     // Merge several logcat streams, and take the last N lines
   7684                     InputStreamReader input = null;
   7685                     try {
   7686                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
   7687                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
   7688                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
   7689 
   7690                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
   7691                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
   7692                         input = new InputStreamReader(logcat.getInputStream());
   7693 
   7694                         int num;
   7695                         char[] buf = new char[8192];
   7696                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
   7697                     } catch (IOException e) {
   7698                         Slog.e(TAG, "Error running logcat", e);
   7699                     } finally {
   7700                         if (input != null) try { input.close(); } catch (IOException e) {}
   7701                     }
   7702                 }
   7703 
   7704                 dbox.addText(dropboxTag, sb.toString());
   7705             }
   7706         };
   7707 
   7708         if (process == null || process.pid == MY_PID) {
   7709             worker.run();  // We may be about to die -- need to run this synchronously
   7710         } else {
   7711             worker.start();
   7712         }
   7713     }
   7714 
   7715     /**
   7716      * Bring up the "unexpected error" dialog box for a crashing app.
   7717      * Deal with edge cases (intercepts from instrumented applications,
   7718      * ActivityController, error intent receivers, that sort of thing).
   7719      * @param r the application crashing
   7720      * @param crashInfo describing the failure
   7721      */
   7722     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
   7723         long timeMillis = System.currentTimeMillis();
   7724         String shortMsg = crashInfo.exceptionClassName;
   7725         String longMsg = crashInfo.exceptionMessage;
   7726         String stackTrace = crashInfo.stackTrace;
   7727         if (shortMsg != null && longMsg != null) {
   7728             longMsg = shortMsg + ": " + longMsg;
   7729         } else if (shortMsg != null) {
   7730             longMsg = shortMsg;
   7731         }
   7732 
   7733         AppErrorResult result = new AppErrorResult();
   7734         synchronized (this) {
   7735             if (mController != null) {
   7736                 try {
   7737                     String name = r != null ? r.processName : null;
   7738                     int pid = r != null ? r.pid : Binder.getCallingPid();
   7739                     if (!mController.appCrashed(name, pid,
   7740                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
   7741                         Slog.w(TAG, "Force-killing crashed app " + name
   7742                                 + " at watcher's request");
   7743                         Process.killProcess(pid);
   7744                         return;
   7745                     }
   7746                 } catch (RemoteException e) {
   7747                     mController = null;
   7748                 }
   7749             }
   7750 
   7751             final long origId = Binder.clearCallingIdentity();
   7752 
   7753             // If this process is running instrumentation, finish it.
   7754             if (r != null && r.instrumentationClass != null) {
   7755                 Slog.w(TAG, "Error in app " + r.processName
   7756                       + " running instrumentation " + r.instrumentationClass + ":");
   7757                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
   7758                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
   7759                 Bundle info = new Bundle();
   7760                 info.putString("shortMsg", shortMsg);
   7761                 info.putString("longMsg", longMsg);
   7762                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
   7763                 Binder.restoreCallingIdentity(origId);
   7764                 return;
   7765             }
   7766 
   7767             // If we can't identify the process or it's already exceeded its crash quota,
   7768             // quit right away without showing a crash dialog.
   7769             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
   7770                 Binder.restoreCallingIdentity(origId);
   7771                 return;
   7772             }
   7773 
   7774             Message msg = Message.obtain();
   7775             msg.what = SHOW_ERROR_MSG;
   7776             HashMap data = new HashMap();
   7777             data.put("result", result);
   7778             data.put("app", r);
   7779             msg.obj = data;
   7780             mHandler.sendMessage(msg);
   7781 
   7782             Binder.restoreCallingIdentity(origId);
   7783         }
   7784 
   7785         int res = result.get();
   7786 
   7787         Intent appErrorIntent = null;
   7788         synchronized (this) {
   7789             if (r != null) {
   7790                 mProcessCrashTimes.put(r.info.processName, r.info.uid,
   7791                         SystemClock.uptimeMillis());
   7792             }
   7793             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
   7794                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
   7795             }
   7796         }
   7797 
   7798         if (appErrorIntent != null) {
   7799             try {
   7800                 mContext.startActivity(appErrorIntent);
   7801             } catch (ActivityNotFoundException e) {
   7802                 Slog.w(TAG, "bug report receiver dissappeared", e);
   7803             }
   7804         }
   7805     }
   7806 
   7807     Intent createAppErrorIntentLocked(ProcessRecord r,
   7808             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   7809         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
   7810         if (report == null) {
   7811             return null;
   7812         }
   7813         Intent result = new Intent(Intent.ACTION_APP_ERROR);
   7814         result.setComponent(r.errorReportReceiver);
   7815         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
   7816         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   7817         return result;
   7818     }
   7819 
   7820     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
   7821             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   7822         if (r.errorReportReceiver == null) {
   7823             return null;
   7824         }
   7825 
   7826         if (!r.crashing && !r.notResponding) {
   7827             return null;
   7828         }
   7829 
   7830         ApplicationErrorReport report = new ApplicationErrorReport();
   7831         report.packageName = r.info.packageName;
   7832         report.installerPackageName = r.errorReportReceiver.getPackageName();
   7833         report.processName = r.processName;
   7834         report.time = timeMillis;
   7835         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   7836 
   7837         if (r.crashing) {
   7838             report.type = ApplicationErrorReport.TYPE_CRASH;
   7839             report.crashInfo = crashInfo;
   7840         } else if (r.notResponding) {
   7841             report.type = ApplicationErrorReport.TYPE_ANR;
   7842             report.anrInfo = new ApplicationErrorReport.AnrInfo();
   7843 
   7844             report.anrInfo.activity = r.notRespondingReport.tag;
   7845             report.anrInfo.cause = r.notRespondingReport.shortMsg;
   7846             report.anrInfo.info = r.notRespondingReport.longMsg;
   7847         }
   7848 
   7849         return report;
   7850     }
   7851 
   7852     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
   7853         // assume our apps are happy - lazy create the list
   7854         List<ActivityManager.ProcessErrorStateInfo> errList = null;
   7855 
   7856         synchronized (this) {
   7857 
   7858             // iterate across all processes
   7859             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   7860                 ProcessRecord app = mLruProcesses.get(i);
   7861                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
   7862                     // This one's in trouble, so we'll generate a report for it
   7863                     // crashes are higher priority (in case there's a crash *and* an anr)
   7864                     ActivityManager.ProcessErrorStateInfo report = null;
   7865                     if (app.crashing) {
   7866                         report = app.crashingReport;
   7867                     } else if (app.notResponding) {
   7868                         report = app.notRespondingReport;
   7869                     }
   7870 
   7871                     if (report != null) {
   7872                         if (errList == null) {
   7873                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
   7874                         }
   7875                         errList.add(report);
   7876                     } else {
   7877                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
   7878                                 " crashing = " + app.crashing +
   7879                                 " notResponding = " + app.notResponding);
   7880                     }
   7881                 }
   7882             }
   7883         }
   7884 
   7885         return errList;
   7886     }
   7887 
   7888     static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
   7889         if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   7890             if (currApp != null) {
   7891                 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
   7892             }
   7893             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   7894         } else if (adj >= ProcessList.SERVICE_B_ADJ) {
   7895             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   7896         } else if (adj >= ProcessList.HOME_APP_ADJ) {
   7897             if (currApp != null) {
   7898                 currApp.lru = 0;
   7899             }
   7900             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   7901         } else if (adj >= ProcessList.SERVICE_ADJ) {
   7902             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   7903         } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   7904             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
   7905         } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   7906             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
   7907         } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
   7908             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
   7909         } else {
   7910             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
   7911         }
   7912     }
   7913 
   7914     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
   7915         // Lazy instantiation of list
   7916         List<ActivityManager.RunningAppProcessInfo> runList = null;
   7917         synchronized (this) {
   7918             // Iterate across all processes
   7919             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   7920                 ProcessRecord app = mLruProcesses.get(i);
   7921                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
   7922                     // Generate process state info for running application
   7923                     ActivityManager.RunningAppProcessInfo currApp =
   7924                         new ActivityManager.RunningAppProcessInfo(app.processName,
   7925                                 app.pid, app.getPackageList());
   7926                     currApp.uid = app.info.uid;
   7927                     if (mHeavyWeightProcess == app) {
   7928                         currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
   7929                     }
   7930                     if (app.persistent) {
   7931                         currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
   7932                     }
   7933                     int adj = app.curAdj;
   7934                     currApp.importance = oomAdjToImportance(adj, currApp);
   7935                     currApp.importanceReasonCode = app.adjTypeCode;
   7936                     if (app.adjSource instanceof ProcessRecord) {
   7937                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
   7938                         currApp.importanceReasonImportance = oomAdjToImportance(
   7939                                 app.adjSourceOom, null);
   7940                     } else if (app.adjSource instanceof ActivityRecord) {
   7941                         ActivityRecord r = (ActivityRecord)app.adjSource;
   7942                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
   7943                     }
   7944                     if (app.adjTarget instanceof ComponentName) {
   7945                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
   7946                     }
   7947                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
   7948                     //        + " lru=" + currApp.lru);
   7949                     if (runList == null) {
   7950                         runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
   7951                     }
   7952                     runList.add(currApp);
   7953                 }
   7954             }
   7955         }
   7956         return runList;
   7957     }
   7958 
   7959     public List<ApplicationInfo> getRunningExternalApplications() {
   7960         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
   7961         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
   7962         if (runningApps != null && runningApps.size() > 0) {
   7963             Set<String> extList = new HashSet<String>();
   7964             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
   7965                 if (app.pkgList != null) {
   7966                     for (String pkg : app.pkgList) {
   7967                         extList.add(pkg);
   7968                     }
   7969                 }
   7970             }
   7971             IPackageManager pm = AppGlobals.getPackageManager();
   7972             for (String pkg : extList) {
   7973                 try {
   7974                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
   7975                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
   7976                         retList.add(info);
   7977                     }
   7978                 } catch (RemoteException e) {
   7979                 }
   7980             }
   7981         }
   7982         return retList;
   7983     }
   7984 
   7985     @Override
   7986     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   7987         if (checkCallingPermission(android.Manifest.permission.DUMP)
   7988                 != PackageManager.PERMISSION_GRANTED) {
   7989             pw.println("Permission Denial: can't dump ActivityManager from from pid="
   7990                     + Binder.getCallingPid()
   7991                     + ", uid=" + Binder.getCallingUid()
   7992                     + " without permission "
   7993                     + android.Manifest.permission.DUMP);
   7994             return;
   7995         }
   7996 
   7997         boolean dumpAll = false;
   7998         boolean dumpClient = false;
   7999         String dumpPackage = null;
   8000 
   8001         int opti = 0;
   8002         while (opti < args.length) {
   8003             String opt = args[opti];
   8004             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   8005                 break;
   8006             }
   8007             opti++;
   8008             if ("-a".equals(opt)) {
   8009                 dumpAll = true;
   8010             } else if ("-c".equals(opt)) {
   8011                 dumpClient = true;
   8012             } else if ("-h".equals(opt)) {
   8013                 pw.println("Activity manager dump options:");
   8014                 pw.println("  [-a] [-c] [-h] [cmd] ...");
   8015                 pw.println("  cmd may be one of:");
   8016                 pw.println("    a[ctivities]: activity stack state");
   8017                 pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
   8018                 pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
   8019                 pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
   8020                 pw.println("    o[om]: out of memory management");
   8021                 pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
   8022                 pw.println("    s[ervices] [COMP_SPEC ...]: service state");
   8023                 pw.println("    service [COMP_SPEC]: service client-side state");
   8024                 pw.println("    package [PACKAGE_NAME]: all state related to given package");
   8025                 pw.println("    all: dump all activities");
   8026                 pw.println("    top: dump the top activity");
   8027                 pw.println("  cmd may also be a COMP_SPEC to dump activities.");
   8028                 pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
   8029                 pw.println("    a partial substring in a component name, a");
   8030                 pw.println("    hex object identifier.");
   8031                 pw.println("  -a: include all available server state.");
   8032                 pw.println("  -c: include client state.");
   8033                 return;
   8034             } else {
   8035                 pw.println("Unknown argument: " + opt + "; use -h for help");
   8036             }
   8037         }
   8038 
   8039         // Is the caller requesting to dump a particular piece of data?
   8040         if (opti < args.length) {
   8041             String cmd = args[opti];
   8042             opti++;
   8043             if ("activities".equals(cmd) || "a".equals(cmd)) {
   8044                 synchronized (this) {
   8045                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
   8046                 }
   8047                 return;
   8048             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
   8049                 String[] newArgs;
   8050                 String name;
   8051                 if (opti >= args.length) {
   8052                     name = null;
   8053                     newArgs = EMPTY_STRING_ARRAY;
   8054                 } else {
   8055                     name = args[opti];
   8056                     opti++;
   8057                     newArgs = new String[args.length - opti];
   8058                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   8059                             args.length - opti);
   8060                 }
   8061                 synchronized (this) {
   8062                     dumpBroadcastsLocked(fd, pw, args, opti, true, name);
   8063                 }
   8064                 return;
   8065             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
   8066                 String[] newArgs;
   8067                 String name;
   8068                 if (opti >= args.length) {
   8069                     name = null;
   8070                     newArgs = EMPTY_STRING_ARRAY;
   8071                 } else {
   8072                     name = args[opti];
   8073                     opti++;
   8074                     newArgs = new String[args.length - opti];
   8075                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   8076                             args.length - opti);
   8077                 }
   8078                 synchronized (this) {
   8079                     dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
   8080                 }
   8081                 return;
   8082             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
   8083                 String[] newArgs;
   8084                 String name;
   8085                 if (opti >= args.length) {
   8086                     name = null;
   8087                     newArgs = EMPTY_STRING_ARRAY;
   8088                 } else {
   8089                     name = args[opti];
   8090                     opti++;
   8091                     newArgs = new String[args.length - opti];
   8092                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   8093                             args.length - opti);
   8094                 }
   8095                 synchronized (this) {
   8096                     dumpProcessesLocked(fd, pw, args, opti, true, name);
   8097                 }
   8098                 return;
   8099             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
   8100                 synchronized (this) {
   8101                     dumpOomLocked(fd, pw, args, opti, true);
   8102                 }
   8103                 return;
   8104             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
   8105                 synchronized (this) {
   8106                     dumpProvidersLocked(fd, pw, args, opti, true, null);
   8107                 }
   8108                 return;
   8109             } else if ("service".equals(cmd)) {
   8110                 String[] newArgs;
   8111                 String name;
   8112                 if (opti >= args.length) {
   8113                     name = null;
   8114                     newArgs = EMPTY_STRING_ARRAY;
   8115                 } else {
   8116                     name = args[opti];
   8117                     opti++;
   8118                     newArgs = new String[args.length - opti];
   8119                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   8120                             args.length - opti);
   8121                 }
   8122                 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
   8123                     pw.println("No services match: " + name);
   8124                     pw.println("Use -h for help.");
   8125                 }
   8126                 return;
   8127             } else if ("package".equals(cmd)) {
   8128                 String[] newArgs;
   8129                 if (opti >= args.length) {
   8130                     pw.println("package: no package name specified");
   8131                     pw.println("Use -h for help.");
   8132                     return;
   8133                 } else {
   8134                     dumpPackage = args[opti];
   8135                     opti++;
   8136                     newArgs = new String[args.length - opti];
   8137                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   8138                             args.length - opti);
   8139                     args = newArgs;
   8140                     opti = 0;
   8141                 }
   8142             } else if ("services".equals(cmd) || "s".equals(cmd)) {
   8143                 synchronized (this) {
   8144                     dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
   8145                 }
   8146                 return;
   8147             } else {
   8148                 // Dumping a single activity?
   8149                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
   8150                     pw.println("Bad activity command, or no activities match: " + cmd);
   8151                     pw.println("Use -h for help.");
   8152                 }
   8153                 return;
   8154             }
   8155         }
   8156 
   8157         // No piece of data specified, dump everything.
   8158         synchronized (this) {
   8159             boolean needSep;
   8160             needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   8161             if (needSep) {
   8162                 pw.println(" ");
   8163             }
   8164             if (dumpAll) {
   8165                 pw.println("-------------------------------------------------------------------------------");
   8166             }
   8167             needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   8168             if (needSep) {
   8169                 pw.println(" ");
   8170             }
   8171             if (dumpAll) {
   8172                 pw.println("-------------------------------------------------------------------------------");
   8173             }
   8174             needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   8175             if (needSep) {
   8176                 pw.println(" ");
   8177             }
   8178             if (dumpAll) {
   8179                 pw.println("-------------------------------------------------------------------------------");
   8180             }
   8181             needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   8182             if (needSep) {
   8183                 pw.println(" ");
   8184             }
   8185             if (dumpAll) {
   8186                 pw.println("-------------------------------------------------------------------------------");
   8187             }
   8188             needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   8189             if (needSep) {
   8190                 pw.println(" ");
   8191             }
   8192             if (dumpAll) {
   8193                 pw.println("-------------------------------------------------------------------------------");
   8194             }
   8195             dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   8196         }
   8197     }
   8198 
   8199     boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   8200             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   8201         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
   8202         pw.println("  Main stack:");
   8203         dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
   8204                 dumpPackage);
   8205         pw.println(" ");
   8206         pw.println("  Running activities (most recent first):");
   8207         dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
   8208                 dumpPackage);
   8209         if (mMainStack.mWaitingVisibleActivities.size() > 0) {
   8210             pw.println(" ");
   8211             pw.println("  Activities waiting for another to become visible:");
   8212             dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
   8213                     !dumpAll, false, dumpPackage);
   8214         }
   8215         if (mMainStack.mStoppingActivities.size() > 0) {
   8216             pw.println(" ");
   8217             pw.println("  Activities waiting to stop:");
   8218             dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
   8219                     !dumpAll, false, dumpPackage);
   8220         }
   8221         if (mMainStack.mGoingToSleepActivities.size() > 0) {
   8222             pw.println(" ");
   8223             pw.println("  Activities waiting to sleep:");
   8224             dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
   8225                     !dumpAll, false, dumpPackage);
   8226         }
   8227         if (mMainStack.mFinishingActivities.size() > 0) {
   8228             pw.println(" ");
   8229             pw.println("  Activities waiting to finish:");
   8230             dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
   8231                     !dumpAll, false, dumpPackage);
   8232         }
   8233 
   8234         pw.println(" ");
   8235         if (mMainStack.mPausingActivity != null) {
   8236             pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
   8237         }
   8238         pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
   8239         pw.println("  mFocusedActivity: " + mFocusedActivity);
   8240         if (dumpAll) {
   8241             pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
   8242             pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
   8243             pw.println("  mDismissKeyguardOnNextActivity: "
   8244                     + mMainStack.mDismissKeyguardOnNextActivity);
   8245         }
   8246 
   8247         if (mRecentTasks.size() > 0) {
   8248             pw.println();
   8249             pw.println("  Recent tasks:");
   8250 
   8251             final int N = mRecentTasks.size();
   8252             for (int i=0; i<N; i++) {
   8253                 TaskRecord tr = mRecentTasks.get(i);
   8254                 if (dumpPackage != null) {
   8255                     if (tr.realActivity == null ||
   8256                             !dumpPackage.equals(tr.realActivity)) {
   8257                         continue;
   8258                     }
   8259                 }
   8260                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
   8261                         pw.println(tr);
   8262                 if (dumpAll) {
   8263                     mRecentTasks.get(i).dump(pw, "    ");
   8264                 }
   8265             }
   8266         }
   8267 
   8268         if (dumpAll) {
   8269             pw.println(" ");
   8270             pw.println("  mCurTask: " + mCurTask);
   8271         }
   8272 
   8273         return true;
   8274     }
   8275 
   8276     boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   8277             int opti, boolean dumpAll, String dumpPackage) {
   8278         boolean needSep = false;
   8279         int numPers = 0;
   8280 
   8281         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
   8282 
   8283         if (dumpAll) {
   8284             for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
   8285                 final int NA = procs.size();
   8286                 for (int ia=0; ia<NA; ia++) {
   8287                     ProcessRecord r = procs.valueAt(ia);
   8288                     if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   8289                         continue;
   8290                     }
   8291                     if (!needSep) {
   8292                         pw.println("  All known processes:");
   8293                         needSep = true;
   8294                     }
   8295                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
   8296                         pw.print(" UID "); pw.print(procs.keyAt(ia));
   8297                         pw.print(" "); pw.println(r);
   8298                     r.dump(pw, "    ");
   8299                     if (r.persistent) {
   8300                         numPers++;
   8301                     }
   8302                 }
   8303             }
   8304         }
   8305 
   8306         if (mLruProcesses.size() > 0) {
   8307             if (needSep) pw.println(" ");
   8308             needSep = true;
   8309             pw.println("  Process LRU list (sorted by oom_adj):");
   8310             dumpProcessOomList(pw, this, mLruProcesses, "    ",
   8311                     "Proc", "PERS", false, dumpPackage);
   8312             needSep = true;
   8313         }
   8314 
   8315         if (dumpAll) {
   8316             synchronized (mPidsSelfLocked) {
   8317                 boolean printed = false;
   8318                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   8319                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
   8320                     if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   8321                         continue;
   8322                     }
   8323                     if (!printed) {
   8324                         if (needSep) pw.println(" ");
   8325                         needSep = true;
   8326                         pw.println("  PID mappings:");
   8327                         printed = true;
   8328                     }
   8329                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
   8330                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
   8331                 }
   8332             }
   8333         }
   8334 
   8335         if (mForegroundProcesses.size() > 0) {
   8336             synchronized (mPidsSelfLocked) {
   8337                 boolean printed = false;
   8338                 for (int i=0; i<mForegroundProcesses.size(); i++) {
   8339                     ProcessRecord r = mPidsSelfLocked.get(
   8340                             mForegroundProcesses.valueAt(i).pid);
   8341                     if (dumpPackage != null && (r == null
   8342                             || !dumpPackage.equals(r.info.packageName))) {
   8343                         continue;
   8344                     }
   8345                     if (!printed) {
   8346                         if (needSep) pw.println(" ");
   8347                         needSep = true;
   8348                         pw.println("  Foreground Processes:");
   8349                         printed = true;
   8350                     }
   8351                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
   8352                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
   8353                 }
   8354             }
   8355         }
   8356 
   8357         if (mPersistentStartingProcesses.size() > 0) {
   8358             if (needSep) pw.println(" ");
   8359             needSep = true;
   8360             pw.println("  Persisent processes that are starting:");
   8361             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
   8362                     "Starting Norm", "Restarting PERS", dumpPackage);
   8363         }
   8364 
   8365         if (mRemovedProcesses.size() > 0) {
   8366             if (needSep) pw.println(" ");
   8367             needSep = true;
   8368             pw.println("  Processes that are being removed:");
   8369             dumpProcessList(pw, this, mRemovedProcesses, "    ",
   8370                     "Removed Norm", "Removed PERS", dumpPackage);
   8371         }
   8372 
   8373         if (mProcessesOnHold.size() > 0) {
   8374             if (needSep) pw.println(" ");
   8375             needSep = true;
   8376             pw.println("  Processes that are on old until the system is ready:");
   8377             dumpProcessList(pw, this, mProcessesOnHold, "    ",
   8378                     "OnHold Norm", "OnHold PERS", dumpPackage);
   8379         }
   8380 
   8381         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
   8382 
   8383         if (mProcessCrashTimes.getMap().size() > 0) {
   8384             boolean printed = false;
   8385             long now = SystemClock.uptimeMillis();
   8386             for (Map.Entry<String, SparseArray<Long>> procs
   8387                     : mProcessCrashTimes.getMap().entrySet()) {
   8388                 String pname = procs.getKey();
   8389                 SparseArray<Long> uids = procs.getValue();
   8390                 final int N = uids.size();
   8391                 for (int i=0; i<N; i++) {
   8392                     int puid = uids.keyAt(i);
   8393                     ProcessRecord r = mProcessNames.get(pname, puid);
   8394                     if (dumpPackage != null && (r == null
   8395                             || !dumpPackage.equals(r.info.packageName))) {
   8396                         continue;
   8397                     }
   8398                     if (!printed) {
   8399                         if (needSep) pw.println(" ");
   8400                         needSep = true;
   8401                         pw.println("  Time since processes crashed:");
   8402                         printed = true;
   8403                     }
   8404                     pw.print("    Process "); pw.print(pname);
   8405                             pw.print(" uid "); pw.print(puid);
   8406                             pw.print(": last crashed ");
   8407                             pw.print((now-uids.valueAt(i)));
   8408                             pw.println(" ms ago");
   8409                 }
   8410             }
   8411         }
   8412 
   8413         if (mBadProcesses.getMap().size() > 0) {
   8414             boolean printed = false;
   8415             for (Map.Entry<String, SparseArray<Long>> procs
   8416                     : mBadProcesses.getMap().entrySet()) {
   8417                 String pname = procs.getKey();
   8418                 SparseArray<Long> uids = procs.getValue();
   8419                 final int N = uids.size();
   8420                 for (int i=0; i<N; i++) {
   8421                     int puid = uids.keyAt(i);
   8422                     ProcessRecord r = mProcessNames.get(pname, puid);
   8423                     if (dumpPackage != null && (r == null
   8424                             || !dumpPackage.equals(r.info.packageName))) {
   8425                         continue;
   8426                     }
   8427                     if (!printed) {
   8428                         if (needSep) pw.println(" ");
   8429                         needSep = true;
   8430                         pw.println("  Bad processes:");
   8431                     }
   8432                     pw.print("    Bad process "); pw.print(pname);
   8433                             pw.print(" uid "); pw.print(puid);
   8434                             pw.print(": crashed at time ");
   8435                             pw.println(uids.valueAt(i));
   8436                 }
   8437             }
   8438         }
   8439 
   8440         pw.println();
   8441         pw.println("  mHomeProcess: " + mHomeProcess);
   8442         pw.println("  mPreviousProcess: " + mPreviousProcess);
   8443         if (dumpAll) {
   8444             StringBuilder sb = new StringBuilder(128);
   8445             sb.append("  mPreviousProcessVisibleTime: ");
   8446             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
   8447             pw.println(sb);
   8448         }
   8449         if (mHeavyWeightProcess != null) {
   8450             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   8451         }
   8452         pw.println("  mConfiguration: " + mConfiguration);
   8453         if (dumpAll) {
   8454             pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
   8455             if (mCompatModePackages.getPackages().size() > 0) {
   8456                 boolean printed = false;
   8457                 for (Map.Entry<String, Integer> entry
   8458                         : mCompatModePackages.getPackages().entrySet()) {
   8459                     String pkg = entry.getKey();
   8460                     int mode = entry.getValue();
   8461                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
   8462                         continue;
   8463                     }
   8464                     if (!printed) {
   8465                         pw.println("  mScreenCompatPackages:");
   8466                         printed = true;
   8467                     }
   8468                     pw.print("    "); pw.print(pkg); pw.print(": ");
   8469                             pw.print(mode); pw.println();
   8470                 }
   8471             }
   8472         }
   8473         pw.println("  mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
   8474         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
   8475                 || mOrigWaitForDebugger) {
   8476             pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
   8477                     + " mDebugTransient=" + mDebugTransient
   8478                     + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
   8479         }
   8480         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
   8481                 || mProfileFd != null) {
   8482             pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
   8483             pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
   8484             pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
   8485                     + mAutoStopProfiler);
   8486         }
   8487         if (mAlwaysFinishActivities || mController != null) {
   8488             pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
   8489                     + " mController=" + mController);
   8490         }
   8491         if (dumpAll) {
   8492             pw.println("  Total persistent processes: " + numPers);
   8493             pw.println("  mStartRunning=" + mStartRunning
   8494                     + " mProcessesReady=" + mProcessesReady
   8495                     + " mSystemReady=" + mSystemReady);
   8496             pw.println("  mBooting=" + mBooting
   8497                     + " mBooted=" + mBooted
   8498                     + " mFactoryTest=" + mFactoryTest);
   8499             pw.print("  mLastPowerCheckRealtime=");
   8500                     TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
   8501                     pw.println("");
   8502             pw.print("  mLastPowerCheckUptime=");
   8503                     TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
   8504                     pw.println("");
   8505             pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
   8506             pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
   8507             pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
   8508             pw.println("  mNumServiceProcs=" + mNumServiceProcs
   8509                     + " mNewNumServiceProcs=" + mNewNumServiceProcs);
   8510         }
   8511 
   8512         return true;
   8513     }
   8514 
   8515     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
   8516             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
   8517         if (mProcessesToGc.size() > 0) {
   8518             boolean printed = false;
   8519             long now = SystemClock.uptimeMillis();
   8520             for (int i=0; i<mProcessesToGc.size(); i++) {
   8521                 ProcessRecord proc = mProcessesToGc.get(i);
   8522                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
   8523                     continue;
   8524                 }
   8525                 if (!printed) {
   8526                     if (needSep) pw.println(" ");
   8527                     needSep = true;
   8528                     pw.println("  Processes that are waiting to GC:");
   8529                     printed = true;
   8530                 }
   8531                 pw.print("    Process "); pw.println(proc);
   8532                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
   8533                         pw.print(", last gced=");
   8534                         pw.print(now-proc.lastRequestedGc);
   8535                         pw.print(" ms ago, last lowMem=");
   8536                         pw.print(now-proc.lastLowMemory);
   8537                         pw.println(" ms ago");
   8538 
   8539             }
   8540         }
   8541         return needSep;
   8542     }
   8543 
   8544     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   8545             int opti, boolean dumpAll) {
   8546         boolean needSep = false;
   8547 
   8548         if (mLruProcesses.size() > 0) {
   8549             if (needSep) pw.println(" ");
   8550             needSep = true;
   8551             pw.println("  OOM levels:");
   8552             pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
   8553             pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
   8554             pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
   8555             pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
   8556             pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
   8557             pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
   8558             pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
   8559             pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
   8560             pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
   8561             pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
   8562             pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
   8563             pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
   8564             pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
   8565 
   8566             if (needSep) pw.println(" ");
   8567             needSep = true;
   8568             pw.println("  Process OOM control:");
   8569             dumpProcessOomList(pw, this, mLruProcesses, "    ",
   8570                     "Proc", "PERS", true, null);
   8571             needSep = true;
   8572         }
   8573 
   8574         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
   8575 
   8576         pw.println();
   8577         pw.println("  mHomeProcess: " + mHomeProcess);
   8578         pw.println("  mPreviousProcess: " + mPreviousProcess);
   8579         if (mHeavyWeightProcess != null) {
   8580             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   8581         }
   8582 
   8583         return true;
   8584     }
   8585 
   8586     /**
   8587      * There are three ways to call this:
   8588      *  - no service specified: dump all the services
   8589      *  - a flattened component name that matched an existing service was specified as the
   8590      *    first arg: dump that one service
   8591      *  - the first arg isn't the flattened component name of an existing service:
   8592      *    dump all services whose component contains the first arg as a substring
   8593      */
   8594     protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   8595             int opti, boolean dumpAll) {
   8596         ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
   8597 
   8598         if ("all".equals(name)) {
   8599             synchronized (this) {
   8600                 for (ServiceRecord r1 : mServices.values()) {
   8601                     services.add(r1);
   8602                 }
   8603             }
   8604         } else {
   8605             ComponentName componentName = name != null
   8606                     ? ComponentName.unflattenFromString(name) : null;
   8607             int objectId = 0;
   8608             if (componentName == null) {
   8609                 // Not a '/' separated full component name; maybe an object ID?
   8610                 try {
   8611                     objectId = Integer.parseInt(name, 16);
   8612                     name = null;
   8613                     componentName = null;
   8614                 } catch (RuntimeException e) {
   8615                 }
   8616             }
   8617 
   8618             synchronized (this) {
   8619                 for (ServiceRecord r1 : mServices.values()) {
   8620                     if (componentName != null) {
   8621                         if (r1.name.equals(componentName)) {
   8622                             services.add(r1);
   8623                         }
   8624                     } else if (name != null) {
   8625                         if (r1.name.flattenToString().contains(name)) {
   8626                             services.add(r1);
   8627                         }
   8628                     } else if (System.identityHashCode(r1) == objectId) {
   8629                         services.add(r1);
   8630                     }
   8631                 }
   8632             }
   8633         }
   8634 
   8635         if (services.size() <= 0) {
   8636             return false;
   8637         }
   8638 
   8639         boolean needSep = false;
   8640         for (int i=0; i<services.size(); i++) {
   8641             if (needSep) {
   8642                 pw.println();
   8643             }
   8644             needSep = true;
   8645             dumpService("", fd, pw, services.get(i), args, dumpAll);
   8646         }
   8647         return true;
   8648     }
   8649 
   8650     /**
   8651      * Invokes IApplicationThread.dumpService() on the thread of the specified service if
   8652      * there is a thread associated with the service.
   8653      */
   8654     private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
   8655             final ServiceRecord r, String[] args, boolean dumpAll) {
   8656         String innerPrefix = prefix + "  ";
   8657         synchronized (this) {
   8658             pw.print(prefix); pw.print("SERVICE ");
   8659                     pw.print(r.shortName); pw.print(" ");
   8660                     pw.print(Integer.toHexString(System.identityHashCode(r)));
   8661                     pw.print(" pid=");
   8662                     if (r.app != null) pw.println(r.app.pid);
   8663                     else pw.println("(not running)");
   8664             if (dumpAll) {
   8665                 r.dump(pw, innerPrefix);
   8666             }
   8667         }
   8668         if (r.app != null && r.app.thread != null) {
   8669             pw.print(prefix); pw.println("  Client:");
   8670             pw.flush();
   8671             try {
   8672                 TransferPipe tp = new TransferPipe();
   8673                 try {
   8674                     r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
   8675                     tp.setBufferPrefix(prefix + "    ");
   8676                     tp.go(fd);
   8677                 } finally {
   8678                     tp.kill();
   8679                 }
   8680             } catch (IOException e) {
   8681                 pw.println(prefix + "    Failure while dumping the service: " + e);
   8682             } catch (RemoteException e) {
   8683                 pw.println(prefix + "    Got a RemoteException while dumping the service");
   8684             }
   8685         }
   8686     }
   8687 
   8688     static class ItemMatcher {
   8689         ArrayList<ComponentName> components;
   8690         ArrayList<String> strings;
   8691         ArrayList<Integer> objects;
   8692         boolean all;
   8693 
   8694         ItemMatcher() {
   8695             all = true;
   8696         }
   8697 
   8698         void build(String name) {
   8699             ComponentName componentName = ComponentName.unflattenFromString(name);
   8700             if (componentName != null) {
   8701                 if (components == null) {
   8702                     components = new ArrayList<ComponentName>();
   8703                 }
   8704                 components.add(componentName);
   8705                 all = false;
   8706             } else {
   8707                 int objectId = 0;
   8708                 // Not a '/' separated full component name; maybe an object ID?
   8709                 try {
   8710                     objectId = Integer.parseInt(name, 16);
   8711                     if (objects == null) {
   8712                         objects = new ArrayList<Integer>();
   8713                     }
   8714                     objects.add(objectId);
   8715                     all = false;
   8716                 } catch (RuntimeException e) {
   8717                     // Not an integer; just do string match.
   8718                     if (strings == null) {
   8719                         strings = new ArrayList<String>();
   8720                     }
   8721                     strings.add(name);
   8722                     all = false;
   8723                 }
   8724             }
   8725         }
   8726 
   8727         int build(String[] args, int opti) {
   8728             for (; opti<args.length; opti++) {
   8729                 String name = args[opti];
   8730                 if ("--".equals(name)) {
   8731                     return opti+1;
   8732                 }
   8733                 build(name);
   8734             }
   8735             return opti;
   8736         }
   8737 
   8738         boolean match(Object object, ComponentName comp) {
   8739             if (all) {
   8740                 return true;
   8741             }
   8742             if (components != null) {
   8743                 for (int i=0; i<components.size(); i++) {
   8744                     if (components.get(i).equals(comp)) {
   8745                         return true;
   8746                     }
   8747                 }
   8748             }
   8749             if (objects != null) {
   8750                 for (int i=0; i<objects.size(); i++) {
   8751                     if (System.identityHashCode(object) == objects.get(i)) {
   8752                         return true;
   8753                     }
   8754                 }
   8755             }
   8756             if (strings != null) {
   8757                 String flat = comp.flattenToString();
   8758                 for (int i=0; i<strings.size(); i++) {
   8759                     if (flat.contains(strings.get(i))) {
   8760                         return true;
   8761                     }
   8762                 }
   8763             }
   8764             return false;
   8765         }
   8766     }
   8767 
   8768     /**
   8769      * There are three things that cmd can be:
   8770      *  - a flattened component name that matches an existing activity
   8771      *  - the cmd arg isn't the flattened component name of an existing activity:
   8772      *    dump all activity whose component contains the cmd as a substring
   8773      *  - A hex number of the ActivityRecord object instance.
   8774      */
   8775     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   8776             int opti, boolean dumpAll) {
   8777         ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
   8778 
   8779         if ("all".equals(name)) {
   8780             synchronized (this) {
   8781                 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
   8782                     activities.add(r1);
   8783                 }
   8784             }
   8785         } else if ("top".equals(name)) {
   8786             synchronized (this) {
   8787                 final int N = mMainStack.mHistory.size();
   8788                 if (N > 0) {
   8789                     activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
   8790                 }
   8791             }
   8792         } else {
   8793             ItemMatcher matcher = new ItemMatcher();
   8794             matcher.build(name);
   8795 
   8796             synchronized (this) {
   8797                 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
   8798                     if (matcher.match(r1, r1.intent.getComponent())) {
   8799                         activities.add(r1);
   8800                     }
   8801                 }
   8802             }
   8803         }
   8804 
   8805         if (activities.size() <= 0) {
   8806             return false;
   8807         }
   8808 
   8809         String[] newArgs = new String[args.length - opti];
   8810         if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   8811 
   8812         TaskRecord lastTask = null;
   8813         boolean needSep = false;
   8814         for (int i=activities.size()-1; i>=0; i--) {
   8815             ActivityRecord r = (ActivityRecord)activities.get(i);
   8816             if (needSep) {
   8817                 pw.println();
   8818             }
   8819             needSep = true;
   8820             synchronized (this) {
   8821                 if (lastTask != r.task) {
   8822                     lastTask = r.task;
   8823                     pw.print("TASK "); pw.print(lastTask.affinity);
   8824                             pw.print(" id="); pw.println(lastTask.taskId);
   8825                     if (dumpAll) {
   8826                         lastTask.dump(pw, "  ");
   8827                     }
   8828                 }
   8829             }
   8830             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
   8831         }
   8832         return true;
   8833     }
   8834 
   8835     /**
   8836      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
   8837      * there is a thread associated with the activity.
   8838      */
   8839     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
   8840             final ActivityRecord r, String[] args, boolean dumpAll) {
   8841         String innerPrefix = prefix + "  ";
   8842         synchronized (this) {
   8843             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
   8844                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
   8845                     pw.print(" pid=");
   8846                     if (r.app != null) pw.println(r.app.pid);
   8847                     else pw.println("(not running)");
   8848             if (dumpAll) {
   8849                 r.dump(pw, innerPrefix);
   8850             }
   8851         }
   8852         if (r.app != null && r.app.thread != null) {
   8853             // flush anything that is already in the PrintWriter since the thread is going
   8854             // to write to the file descriptor directly
   8855             pw.flush();
   8856             try {
   8857                 TransferPipe tp = new TransferPipe();
   8858                 try {
   8859                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
   8860                             r.appToken, innerPrefix, args);
   8861                     tp.go(fd);
   8862                 } finally {
   8863                     tp.kill();
   8864                 }
   8865             } catch (IOException e) {
   8866                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   8867             } catch (RemoteException e) {
   8868                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   8869             }
   8870         }
   8871     }
   8872 
   8873     boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   8874             int opti, boolean dumpAll, String dumpPackage) {
   8875         boolean needSep = false;
   8876 
   8877         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
   8878         if (dumpAll) {
   8879             if (mRegisteredReceivers.size() > 0) {
   8880                 boolean printed = false;
   8881                 Iterator it = mRegisteredReceivers.values().iterator();
   8882                 while (it.hasNext()) {
   8883                     ReceiverList r = (ReceiverList)it.next();
   8884                     if (dumpPackage != null && (r.app == null ||
   8885                             !dumpPackage.equals(r.app.info.packageName))) {
   8886                         continue;
   8887                     }
   8888                     if (!printed) {
   8889                         pw.println("  Registered Receivers:");
   8890                         needSep = true;
   8891                         printed = true;
   8892                     }
   8893                     pw.print("  * "); pw.println(r);
   8894                     r.dump(pw, "    ");
   8895                 }
   8896             }
   8897 
   8898             if (mReceiverResolver.dump(pw, needSep ?
   8899                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
   8900                     "    ", dumpPackage, false)) {
   8901                 needSep = true;
   8902             }
   8903         }
   8904 
   8905         if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
   8906                 || mPendingBroadcast != null) {
   8907             boolean printed = false;
   8908             for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
   8909                 BroadcastRecord br = mParallelBroadcasts.get(i);
   8910                 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
   8911                     continue;
   8912                 }
   8913                 if (!printed) {
   8914                     if (needSep) {
   8915                         pw.println();
   8916                     }
   8917                     needSep = true;
   8918                     pw.println("  Active broadcasts:");
   8919                 }
   8920                 pw.println("  Broadcast #" + i + ":");
   8921                 br.dump(pw, "    ");
   8922             }
   8923             printed = false;
   8924             for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
   8925                 BroadcastRecord br = mOrderedBroadcasts.get(i);
   8926                 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
   8927                     continue;
   8928                 }
   8929                 if (!printed) {
   8930                     if (needSep) {
   8931                         pw.println();
   8932                     }
   8933                     needSep = true;
   8934                     pw.println("  Active ordered broadcasts:");
   8935                 }
   8936                 pw.println("  Ordered Broadcast #" + i + ":");
   8937                 mOrderedBroadcasts.get(i).dump(pw, "    ");
   8938             }
   8939             if (dumpPackage == null || (mPendingBroadcast != null
   8940                     && dumpPackage.equals(mPendingBroadcast.callerPackage))) {
   8941                 if (needSep) {
   8942                     pw.println();
   8943                 }
   8944                 pw.println("  Pending broadcast:");
   8945                 if (mPendingBroadcast != null) {
   8946                     mPendingBroadcast.dump(pw, "    ");
   8947                 } else {
   8948                     pw.println("    (null)");
   8949                 }
   8950                 needSep = true;
   8951             }
   8952         }
   8953 
   8954         boolean printed = false;
   8955         for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
   8956             BroadcastRecord r = mBroadcastHistory[i];
   8957             if (r == null) {
   8958                 break;
   8959             }
   8960             if (dumpPackage != null && !dumpPackage.equals(r.callerPackage)) {
   8961                 continue;
   8962             }
   8963             if (!printed) {
   8964                 if (needSep) {
   8965                     pw.println();
   8966                 }
   8967                 needSep = true;
   8968                 pw.println("  Historical broadcasts:");
   8969                 printed = true;
   8970             }
   8971             if (dumpAll) {
   8972                 pw.print("  Historical Broadcast #"); pw.print(i); pw.println(":");
   8973                 r.dump(pw, "    ");
   8974             } else {
   8975                 if (i >= 50) {
   8976                     pw.println("  ...");
   8977                     break;
   8978                 }
   8979                 pw.print("  #"); pw.print(i); pw.print(": "); pw.println(r);
   8980             }
   8981         }
   8982         needSep = true;
   8983 
   8984         if (mStickyBroadcasts != null && dumpPackage == null) {
   8985             if (needSep) {
   8986                 pw.println();
   8987             }
   8988             needSep = true;
   8989             pw.println("  Sticky broadcasts:");
   8990             StringBuilder sb = new StringBuilder(128);
   8991             for (Map.Entry<String, ArrayList<Intent>> ent
   8992                     : mStickyBroadcasts.entrySet()) {
   8993                 pw.print("  * Sticky action "); pw.print(ent.getKey());
   8994                 if (dumpAll) {
   8995                     pw.println(":");
   8996                     ArrayList<Intent> intents = ent.getValue();
   8997                     final int N = intents.size();
   8998                     for (int i=0; i<N; i++) {
   8999                         sb.setLength(0);
   9000                         sb.append("    Intent: ");
   9001                         intents.get(i).toShortString(sb, false, true, false);
   9002                         pw.println(sb.toString());
   9003                         Bundle bundle = intents.get(i).getExtras();
   9004                         if (bundle != null) {
   9005                             pw.print("      ");
   9006                             pw.println(bundle.toString());
   9007                         }
   9008                     }
   9009                 } else {
   9010                     pw.println("");
   9011                 }
   9012             }
   9013             needSep = true;
   9014         }
   9015 
   9016         if (dumpAll) {
   9017             pw.println();
   9018             pw.println("  mBroadcastsScheduled=" + mBroadcastsScheduled);
   9019             pw.println("  mHandler:");
   9020             mHandler.dump(new PrintWriterPrinter(pw), "    ");
   9021             needSep = true;
   9022         }
   9023 
   9024         return needSep;
   9025     }
   9026 
   9027     boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   9028             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   9029         boolean needSep = false;
   9030 
   9031         ItemMatcher matcher = new ItemMatcher();
   9032         matcher.build(args, opti);
   9033 
   9034         pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
   9035         if (mServices.size() > 0) {
   9036             boolean printed = false;
   9037             long nowReal = SystemClock.elapsedRealtime();
   9038             Iterator<ServiceRecord> it = mServices.values().iterator();
   9039             needSep = false;
   9040             while (it.hasNext()) {
   9041                 ServiceRecord r = it.next();
   9042                 if (!matcher.match(r, r.name)) {
   9043                     continue;
   9044                 }
   9045                 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
   9046                     continue;
   9047                 }
   9048                 if (!printed) {
   9049                     pw.println("  Active services:");
   9050                     printed = true;
   9051                 }
   9052                 if (needSep) {
   9053                     pw.println();
   9054                 }
   9055                 pw.print("  * "); pw.println(r);
   9056                 if (dumpAll) {
   9057                     r.dump(pw, "    ");
   9058                     needSep = true;
   9059                 } else {
   9060                     pw.print("    app="); pw.println(r.app);
   9061                     pw.print("    created=");
   9062                         TimeUtils.formatDuration(r.createTime, nowReal, pw);
   9063                         pw.print(" started="); pw.print(r.startRequested);
   9064                         pw.print(" connections="); pw.println(r.connections.size());
   9065                     if (r.connections.size() > 0) {
   9066                         pw.println("    Connections:");
   9067                         for (ArrayList<ConnectionRecord> clist : r.connections.values()) {
   9068                             for (int i=0; i<clist.size(); i++) {
   9069                                 ConnectionRecord conn = clist.get(i);
   9070                                 pw.print("      ");
   9071                                 pw.print(conn.binding.intent.intent.getIntent().toShortString(
   9072                                         false, false, false));
   9073                                 pw.print(" -> ");
   9074                                 ProcessRecord proc = conn.binding.client;
   9075                                 pw.println(proc != null ? proc.toShortString() : "null");
   9076                             }
   9077                         }
   9078                     }
   9079                 }
   9080                 if (dumpClient && r.app != null && r.app.thread != null) {
   9081                     pw.println("    Client:");
   9082                     pw.flush();
   9083                     try {
   9084                         TransferPipe tp = new TransferPipe();
   9085                         try {
   9086                             r.app.thread.dumpService(
   9087                                     tp.getWriteFd().getFileDescriptor(), r, args);
   9088                             tp.setBufferPrefix("      ");
   9089                             // Short timeout, since blocking here can
   9090                             // deadlock with the application.
   9091                             tp.go(fd, 2000);
   9092                         } finally {
   9093                             tp.kill();
   9094                         }
   9095                     } catch (IOException e) {
   9096                         pw.println("      Failure while dumping the service: " + e);
   9097                     } catch (RemoteException e) {
   9098                         pw.println("      Got a RemoteException while dumping the service");
   9099                     }
   9100                     needSep = true;
   9101                 }
   9102             }
   9103             needSep = printed;
   9104         }
   9105 
   9106         if (mPendingServices.size() > 0) {
   9107             boolean printed = false;
   9108             for (int i=0; i<mPendingServices.size(); i++) {
   9109                 ServiceRecord r = mPendingServices.get(i);
   9110                 if (!matcher.match(r, r.name)) {
   9111                     continue;
   9112                 }
   9113                 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
   9114                     continue;
   9115                 }
   9116                 if (!printed) {
   9117                     if (needSep) pw.println(" ");
   9118                     needSep = true;
   9119                     pw.println("  Pending services:");
   9120                     printed = true;
   9121                 }
   9122                 pw.print("  * Pending "); pw.println(r);
   9123                 r.dump(pw, "    ");
   9124             }
   9125             needSep = true;
   9126         }
   9127 
   9128         if (mRestartingServices.size() > 0) {
   9129             boolean printed = false;
   9130             for (int i=0; i<mRestartingServices.size(); i++) {
   9131                 ServiceRecord r = mRestartingServices.get(i);
   9132                 if (!matcher.match(r, r.name)) {
   9133                     continue;
   9134                 }
   9135                 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
   9136                     continue;
   9137                 }
   9138                 if (!printed) {
   9139                     if (needSep) pw.println(" ");
   9140                     needSep = true;
   9141                     pw.println("  Restarting services:");
   9142                     printed = true;
   9143                 }
   9144                 pw.print("  * Restarting "); pw.println(r);
   9145                 r.dump(pw, "    ");
   9146             }
   9147             needSep = true;
   9148         }
   9149 
   9150         if (mStoppingServices.size() > 0) {
   9151             boolean printed = false;
   9152             for (int i=0; i<mStoppingServices.size(); i++) {
   9153                 ServiceRecord r = mStoppingServices.get(i);
   9154                 if (!matcher.match(r, r.name)) {
   9155                     continue;
   9156                 }
   9157                 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
   9158                     continue;
   9159                 }
   9160                 if (!printed) {
   9161                     if (needSep) pw.println(" ");
   9162                     needSep = true;
   9163                     pw.println("  Stopping services:");
   9164                     printed = true;
   9165                 }
   9166                 pw.print("  * Stopping "); pw.println(r);
   9167                 r.dump(pw, "    ");
   9168             }
   9169             needSep = true;
   9170         }
   9171 
   9172         if (dumpAll) {
   9173             if (mServiceConnections.size() > 0) {
   9174                 boolean printed = false;
   9175                 Iterator<ArrayList<ConnectionRecord>> it
   9176                         = mServiceConnections.values().iterator();
   9177                 while (it.hasNext()) {
   9178                     ArrayList<ConnectionRecord> r = it.next();
   9179                     for (int i=0; i<r.size(); i++) {
   9180                         ConnectionRecord cr = r.get(i);
   9181                         if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
   9182                             continue;
   9183                         }
   9184                         if (dumpPackage != null && (cr.binding.client == null
   9185                                 || !dumpPackage.equals(cr.binding.client.info.packageName))) {
   9186                             continue;
   9187                         }
   9188                         if (!printed) {
   9189                             if (needSep) pw.println(" ");
   9190                             needSep = true;
   9191                             pw.println("  Connection bindings to services:");
   9192                             printed = true;
   9193                         }
   9194                         pw.print("  * "); pw.println(cr);
   9195                         cr.dump(pw, "    ");
   9196                     }
   9197                 }
   9198                 needSep = true;
   9199             }
   9200         }
   9201 
   9202         return needSep;
   9203     }
   9204 
   9205     boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   9206             int opti, boolean dumpAll, String dumpPackage) {
   9207         boolean needSep = false;
   9208 
   9209         ItemMatcher matcher = new ItemMatcher();
   9210         matcher.build(args, opti);
   9211 
   9212         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
   9213         if (mProvidersByClass.size() > 0) {
   9214             boolean printed = false;
   9215             Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it
   9216                     = mProvidersByClass.entrySet().iterator();
   9217             while (it.hasNext()) {
   9218                 Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
   9219                 ContentProviderRecord r = e.getValue();
   9220                 ComponentName comp = e.getKey();
   9221                 String cls = comp.getClassName();
   9222                 int end = cls.lastIndexOf('.');
   9223                 if (end > 0 && end < (cls.length()-2)) {
   9224                     cls = cls.substring(end+1);
   9225                 }
   9226                 if (!matcher.match(r, comp)) {
   9227                     continue;
   9228                 }
   9229                 if (dumpPackage != null && !dumpPackage.equals(comp.getPackageName())) {
   9230                     continue;
   9231                 }
   9232                 if (!printed) {
   9233                     if (needSep) pw.println(" ");
   9234                     needSep = true;
   9235                     pw.println("  Published content providers (by class):");
   9236                     printed = true;
   9237                 }
   9238                 pw.print("  * "); pw.print(cls); pw.print(" (");
   9239                         pw.print(comp.flattenToShortString()); pw.println(")");
   9240                 if (dumpAll) {
   9241                     r.dump(pw, "      ");
   9242                 } else {
   9243                     if (r.proc != null) {
   9244                         pw.print("      "); pw.println(r.proc);
   9245                     } else {
   9246                         pw.println();
   9247                     }
   9248                     if (r.clients.size() > 0) {
   9249                         pw.println("      Clients:");
   9250                         for (ProcessRecord cproc : r.clients) {
   9251                             pw.print("        - "); pw.println(cproc);
   9252                         }
   9253                     }
   9254                 }
   9255             }
   9256         }
   9257 
   9258         if (dumpAll) {
   9259             if (mProvidersByName.size() > 0) {
   9260                 boolean printed = false;
   9261                 Iterator<Map.Entry<String, ContentProviderRecord>> it
   9262                         = mProvidersByName.entrySet().iterator();
   9263                 while (it.hasNext()) {
   9264                     Map.Entry<String, ContentProviderRecord> e = it.next();
   9265                     ContentProviderRecord r = e.getValue();
   9266                     if (!matcher.match(r, r.name)) {
   9267                         continue;
   9268                     }
   9269                     if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
   9270                         continue;
   9271                     }
   9272                     if (!printed) {
   9273                         if (needSep) pw.println(" ");
   9274                         needSep = true;
   9275                         pw.println("  Authority to provider mappings:");
   9276                         printed = true;
   9277                     }
   9278                     pw.print("  "); pw.print(e.getKey()); pw.println(":");
   9279                     pw.print("    "); pw.println(r);
   9280                 }
   9281             }
   9282         }
   9283 
   9284         if (mLaunchingProviders.size() > 0) {
   9285             boolean printed = false;
   9286             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
   9287                 ContentProviderRecord r = mLaunchingProviders.get(i);
   9288                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
   9289                     continue;
   9290                 }
   9291                 if (!printed) {
   9292                     if (needSep) pw.println(" ");
   9293                     needSep = true;
   9294                     pw.println("  Launching content providers:");
   9295                     printed = true;
   9296                 }
   9297                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
   9298                         pw.println(r);
   9299             }
   9300         }
   9301 
   9302         if (mGrantedUriPermissions.size() > 0) {
   9303             if (needSep) pw.println();
   9304             needSep = true;
   9305             pw.println("Granted Uri Permissions:");
   9306             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
   9307                 int uid = mGrantedUriPermissions.keyAt(i);
   9308                 HashMap<Uri, UriPermission> perms
   9309                         = mGrantedUriPermissions.valueAt(i);
   9310                 pw.print("  * UID "); pw.print(uid);
   9311                         pw.println(" holds:");
   9312                 for (UriPermission perm : perms.values()) {
   9313                     pw.print("    "); pw.println(perm);
   9314                     if (dumpAll) {
   9315                         perm.dump(pw, "      ");
   9316                     }
   9317                 }
   9318             }
   9319             needSep = true;
   9320         }
   9321 
   9322         return needSep;
   9323     }
   9324 
   9325     boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   9326             int opti, boolean dumpAll, String dumpPackage) {
   9327         boolean needSep = false;
   9328 
   9329         if (mIntentSenderRecords.size() > 0) {
   9330             boolean printed = false;
   9331             Iterator<WeakReference<PendingIntentRecord>> it
   9332                     = mIntentSenderRecords.values().iterator();
   9333             while (it.hasNext()) {
   9334                 WeakReference<PendingIntentRecord> ref = it.next();
   9335                 PendingIntentRecord rec = ref != null ? ref.get(): null;
   9336                 if (dumpPackage != null && (rec == null
   9337                         || !dumpPackage.equals(rec.key.packageName))) {
   9338                     continue;
   9339                 }
   9340                 if (!printed) {
   9341                     pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
   9342                     printed = true;
   9343                 }
   9344                 needSep = true;
   9345                 if (rec != null) {
   9346                     pw.print("  * "); pw.println(rec);
   9347                     if (dumpAll) {
   9348                         rec.dump(pw, "    ");
   9349                     }
   9350                 } else {
   9351                     pw.print("  * "); pw.println(ref);
   9352                 }
   9353             }
   9354         }
   9355 
   9356         return needSep;
   9357     }
   9358 
   9359     private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
   9360             String prefix, String label, boolean complete, boolean brief, boolean client,
   9361             String dumpPackage) {
   9362         TaskRecord lastTask = null;
   9363         boolean needNL = false;
   9364         final String innerPrefix = prefix + "      ";
   9365         final String[] args = new String[0];
   9366         for (int i=list.size()-1; i>=0; i--) {
   9367             final ActivityRecord r = (ActivityRecord)list.get(i);
   9368             if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
   9369                 continue;
   9370             }
   9371             final boolean full = !brief && (complete || !r.isInHistory());
   9372             if (needNL) {
   9373                 pw.println(" ");
   9374                 needNL = false;
   9375             }
   9376             if (lastTask != r.task) {
   9377                 lastTask = r.task;
   9378                 pw.print(prefix);
   9379                 pw.print(full ? "* " : "  ");
   9380                 pw.println(lastTask);
   9381                 if (full) {
   9382                     lastTask.dump(pw, prefix + "  ");
   9383                 } else if (complete) {
   9384                     // Complete + brief == give a summary.  Isn't that obvious?!?
   9385                     if (lastTask.intent != null) {
   9386                         pw.print(prefix); pw.print("  ");
   9387                                 pw.println(lastTask.intent.toInsecureString());
   9388                     }
   9389                 }
   9390             }
   9391             pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
   9392             pw.print(" #"); pw.print(i); pw.print(": ");
   9393             pw.println(r);
   9394             if (full) {
   9395                 r.dump(pw, innerPrefix);
   9396             } else if (complete) {
   9397                 // Complete + brief == give a summary.  Isn't that obvious?!?
   9398                 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
   9399                 if (r.app != null) {
   9400                     pw.print(innerPrefix); pw.println(r.app);
   9401                 }
   9402             }
   9403             if (client && r.app != null && r.app.thread != null) {
   9404                 // flush anything that is already in the PrintWriter since the thread is going
   9405                 // to write to the file descriptor directly
   9406                 pw.flush();
   9407                 try {
   9408                     TransferPipe tp = new TransferPipe();
   9409                     try {
   9410                         r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
   9411                                 r.appToken, innerPrefix, args);
   9412                         // Short timeout, since blocking here can
   9413                         // deadlock with the application.
   9414                         tp.go(fd, 2000);
   9415                     } finally {
   9416                         tp.kill();
   9417                     }
   9418                 } catch (IOException e) {
   9419                     pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   9420                 } catch (RemoteException e) {
   9421                     pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   9422                 }
   9423                 needNL = true;
   9424             }
   9425         }
   9426     }
   9427 
   9428     private static String buildOomTag(String prefix, String space, int val, int base) {
   9429         if (val == base) {
   9430             if (space == null) return prefix;
   9431             return prefix + "  ";
   9432         }
   9433         return prefix + "+" + Integer.toString(val-base);
   9434     }
   9435 
   9436     private static final int dumpProcessList(PrintWriter pw,
   9437             ActivityManagerService service, List list,
   9438             String prefix, String normalLabel, String persistentLabel,
   9439             String dumpPackage) {
   9440         int numPers = 0;
   9441         final int N = list.size()-1;
   9442         for (int i=N; i>=0; i--) {
   9443             ProcessRecord r = (ProcessRecord)list.get(i);
   9444             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   9445                 continue;
   9446             }
   9447             pw.println(String.format("%s%s #%2d: %s",
   9448                     prefix, (r.persistent ? persistentLabel : normalLabel),
   9449                     i, r.toString()));
   9450             if (r.persistent) {
   9451                 numPers++;
   9452             }
   9453         }
   9454         return numPers;
   9455     }
   9456 
   9457     private static final boolean dumpProcessOomList(PrintWriter pw,
   9458             ActivityManagerService service, List<ProcessRecord> origList,
   9459             String prefix, String normalLabel, String persistentLabel,
   9460             boolean inclDetails, String dumpPackage) {
   9461 
   9462         ArrayList<Pair<ProcessRecord, Integer>> list
   9463                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
   9464         for (int i=0; i<origList.size(); i++) {
   9465             ProcessRecord r = origList.get(i);
   9466             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   9467                 continue;
   9468             }
   9469             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
   9470         }
   9471 
   9472         if (list.size() <= 0) {
   9473             return false;
   9474         }
   9475 
   9476         Comparator<Pair<ProcessRecord, Integer>> comparator
   9477                 = new Comparator<Pair<ProcessRecord, Integer>>() {
   9478             @Override
   9479             public int compare(Pair<ProcessRecord, Integer> object1,
   9480                     Pair<ProcessRecord, Integer> object2) {
   9481                 if (object1.first.setAdj != object2.first.setAdj) {
   9482                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
   9483                 }
   9484                 if (object1.second.intValue() != object2.second.intValue()) {
   9485                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
   9486                 }
   9487                 return 0;
   9488             }
   9489         };
   9490 
   9491         Collections.sort(list, comparator);
   9492 
   9493         final long curRealtime = SystemClock.elapsedRealtime();
   9494         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
   9495         final long curUptime = SystemClock.uptimeMillis();
   9496         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
   9497 
   9498         for (int i=list.size()-1; i>=0; i--) {
   9499             ProcessRecord r = list.get(i).first;
   9500             String oomAdj;
   9501             if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   9502                 oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
   9503             } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
   9504                 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
   9505             } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
   9506                 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
   9507             } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
   9508                 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
   9509             } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
   9510                 oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
   9511             } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
   9512                 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
   9513             } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   9514                 oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
   9515             } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   9516                 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
   9517             } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
   9518                 oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
   9519             } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
   9520                 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
   9521             } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
   9522                 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
   9523             } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
   9524                 oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
   9525             } else {
   9526                 oomAdj = Integer.toString(r.setAdj);
   9527             }
   9528             String schedGroup;
   9529             switch (r.setSchedGroup) {
   9530                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
   9531                     schedGroup = "B";
   9532                     break;
   9533                 case Process.THREAD_GROUP_DEFAULT:
   9534                     schedGroup = "F";
   9535                     break;
   9536                 default:
   9537                     schedGroup = Integer.toString(r.setSchedGroup);
   9538                     break;
   9539             }
   9540             String foreground;
   9541             if (r.foregroundActivities) {
   9542                 foreground = "A";
   9543             } else if (r.foregroundServices) {
   9544                 foreground = "S";
   9545             } else {
   9546                 foreground = " ";
   9547             }
   9548             pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
   9549                     prefix, (r.persistent ? persistentLabel : normalLabel),
   9550                     (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
   9551                     foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
   9552             if (r.adjSource != null || r.adjTarget != null) {
   9553                 pw.print(prefix);
   9554                 pw.print("    ");
   9555                 if (r.adjTarget instanceof ComponentName) {
   9556                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
   9557                 } else if (r.adjTarget != null) {
   9558                     pw.print(r.adjTarget.toString());
   9559                 } else {
   9560                     pw.print("{null}");
   9561                 }
   9562                 pw.print("<=");
   9563                 if (r.adjSource instanceof ProcessRecord) {
   9564                     pw.print("Proc{");
   9565                     pw.print(((ProcessRecord)r.adjSource).toShortString());
   9566                     pw.println("}");
   9567                 } else if (r.adjSource != null) {
   9568                     pw.println(r.adjSource.toString());
   9569                 } else {
   9570                     pw.println("{null}");
   9571                 }
   9572             }
   9573             if (inclDetails) {
   9574                 pw.print(prefix);
   9575                 pw.print("    ");
   9576                 pw.print("oom: max="); pw.print(r.maxAdj);
   9577                 pw.print(" hidden="); pw.print(r.hiddenAdj);
   9578                 pw.print(" curRaw="); pw.print(r.curRawAdj);
   9579                 pw.print(" setRaw="); pw.print(r.setRawAdj);
   9580                 pw.print(" cur="); pw.print(r.curAdj);
   9581                 pw.print(" set="); pw.println(r.setAdj);
   9582                 pw.print(prefix);
   9583                 pw.print("    ");
   9584                 pw.print("keeping="); pw.print(r.keeping);
   9585                 pw.print(" hidden="); pw.print(r.hidden);
   9586                 pw.print(" empty="); pw.print(r.empty);
   9587                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
   9588 
   9589                 if (!r.keeping) {
   9590                     if (r.lastWakeTime != 0) {
   9591                         long wtime;
   9592                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
   9593                         synchronized (stats) {
   9594                             wtime = stats.getProcessWakeTime(r.info.uid,
   9595                                     r.pid, curRealtime);
   9596                         }
   9597                         long timeUsed = wtime - r.lastWakeTime;
   9598                         pw.print(prefix);
   9599                         pw.print("    ");
   9600                         pw.print("keep awake over ");
   9601                         TimeUtils.formatDuration(realtimeSince, pw);
   9602                         pw.print(" used ");
   9603                         TimeUtils.formatDuration(timeUsed, pw);
   9604                         pw.print(" (");
   9605                         pw.print((timeUsed*100)/realtimeSince);
   9606                         pw.println("%)");
   9607                     }
   9608                     if (r.lastCpuTime != 0) {
   9609                         long timeUsed = r.curCpuTime - r.lastCpuTime;
   9610                         pw.print(prefix);
   9611                         pw.print("    ");
   9612                         pw.print("run cpu over ");
   9613                         TimeUtils.formatDuration(uptimeSince, pw);
   9614                         pw.print(" used ");
   9615                         TimeUtils.formatDuration(timeUsed, pw);
   9616                         pw.print(" (");
   9617                         pw.print((timeUsed*100)/uptimeSince);
   9618                         pw.println("%)");
   9619                     }
   9620                 }
   9621             }
   9622         }
   9623         return true;
   9624     }
   9625 
   9626     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
   9627         ArrayList<ProcessRecord> procs;
   9628         synchronized (this) {
   9629             if (args != null && args.length > start
   9630                     && args[start].charAt(0) != '-') {
   9631                 procs = new ArrayList<ProcessRecord>();
   9632                 int pid = -1;
   9633                 try {
   9634                     pid = Integer.parseInt(args[start]);
   9635                 } catch (NumberFormatException e) {
   9636 
   9637                 }
   9638                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   9639                     ProcessRecord proc = mLruProcesses.get(i);
   9640                     if (proc.pid == pid) {
   9641                         procs.add(proc);
   9642                     } else if (proc.processName.equals(args[start])) {
   9643                         procs.add(proc);
   9644                     }
   9645                 }
   9646                 if (procs.size() <= 0) {
   9647                     pw.println("No process found for: " + args[start]);
   9648                     return null;
   9649                 }
   9650             } else {
   9651                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
   9652             }
   9653         }
   9654         return procs;
   9655     }
   9656 
   9657     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
   9658             PrintWriter pw, String[] args) {
   9659         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
   9660         if (procs == null) {
   9661             return;
   9662         }
   9663 
   9664         long uptime = SystemClock.uptimeMillis();
   9665         long realtime = SystemClock.elapsedRealtime();
   9666         pw.println("Applications Graphics Acceleration Info:");
   9667         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   9668 
   9669         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   9670             ProcessRecord r = procs.get(i);
   9671             if (r.thread != null) {
   9672                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
   9673                 pw.flush();
   9674                 try {
   9675                     TransferPipe tp = new TransferPipe();
   9676                     try {
   9677                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
   9678                         tp.go(fd);
   9679                     } finally {
   9680                         tp.kill();
   9681                     }
   9682                 } catch (IOException e) {
   9683                     pw.println("Failure while dumping the app: " + r);
   9684                     pw.flush();
   9685                 } catch (RemoteException e) {
   9686                     pw.println("Got a RemoteException while dumping the app " + r);
   9687                     pw.flush();
   9688                 }
   9689             }
   9690         }
   9691     }
   9692 
   9693     final static class MemItem {
   9694         final String label;
   9695         final String shortLabel;
   9696         final long pss;
   9697         final int id;
   9698         ArrayList<MemItem> subitems;
   9699 
   9700         public MemItem(String _label, String _shortLabel, long _pss, int _id) {
   9701             label = _label;
   9702             shortLabel = _shortLabel;
   9703             pss = _pss;
   9704             id = _id;
   9705         }
   9706     }
   9707 
   9708     static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
   9709             boolean sort) {
   9710         if (sort) {
   9711             Collections.sort(items, new Comparator<MemItem>() {
   9712                 @Override
   9713                 public int compare(MemItem lhs, MemItem rhs) {
   9714                     if (lhs.pss < rhs.pss) {
   9715                         return 1;
   9716                     } else if (lhs.pss > rhs.pss) {
   9717                         return -1;
   9718                     }
   9719                     return 0;
   9720                 }
   9721             });
   9722         }
   9723 
   9724         for (int i=0; i<items.size(); i++) {
   9725             MemItem mi = items.get(i);
   9726             pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
   9727             if (mi.subitems != null) {
   9728                 dumpMemItems(pw, prefix + "           ", mi.subitems, true);
   9729             }
   9730         }
   9731     }
   9732 
   9733     // These are in KB.
   9734     static final long[] DUMP_MEM_BUCKETS = new long[] {
   9735         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
   9736         120*1024, 160*1024, 200*1024,
   9737         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
   9738         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
   9739     };
   9740 
   9741     static final void appendMemBucket(StringBuilder out, long memKB, String label,
   9742             boolean stackLike) {
   9743         int start = label.lastIndexOf('.');
   9744         if (start >= 0) start++;
   9745         else start = 0;
   9746         int end = label.length();
   9747         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
   9748             if (DUMP_MEM_BUCKETS[i] >= memKB) {
   9749                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
   9750                 out.append(bucket);
   9751                 out.append(stackLike ? "MB." : "MB ");
   9752                 out.append(label, start, end);
   9753                 return;
   9754             }
   9755         }
   9756         out.append(memKB/1024);
   9757         out.append(stackLike ? "MB." : "MB ");
   9758         out.append(label, start, end);
   9759     }
   9760 
   9761     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
   9762             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
   9763             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
   9764             ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
   9765             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
   9766     };
   9767     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
   9768             "System", "Persistent", "Foreground",
   9769             "Visible", "Perceptible", "Heavy Weight",
   9770             "Backup", "A Services", "Home", "Previous",
   9771             "B Services", "Background"
   9772     };
   9773 
   9774     final void dumpApplicationMemoryUsage(FileDescriptor fd,
   9775             PrintWriter pw, String prefix, String[] args, boolean brief,
   9776             PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
   9777         boolean dumpAll = false;
   9778         boolean oomOnly = false;
   9779 
   9780         int opti = 0;
   9781         while (opti < args.length) {
   9782             String opt = args[opti];
   9783             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   9784                 break;
   9785             }
   9786             opti++;
   9787             if ("-a".equals(opt)) {
   9788                 dumpAll = true;
   9789             } else if ("--oom".equals(opt)) {
   9790                 oomOnly = true;
   9791             } else if ("-h".equals(opt)) {
   9792                 pw.println("meminfo dump options: [-a] [--oom] [process]");
   9793                 pw.println("  -a: include all available information for each process.");
   9794                 pw.println("  --oom: only show processes organized by oom adj.");
   9795                 pw.println("If [process] is specified it can be the name or ");
   9796                 pw.println("pid of a specific process to dump.");
   9797                 return;
   9798             } else {
   9799                 pw.println("Unknown argument: " + opt + "; use -h for help");
   9800             }
   9801         }
   9802 
   9803         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
   9804         if (procs == null) {
   9805             return;
   9806         }
   9807 
   9808         final boolean isCheckinRequest = scanArgs(args, "--checkin");
   9809         long uptime = SystemClock.uptimeMillis();
   9810         long realtime = SystemClock.elapsedRealtime();
   9811 
   9812         if (procs.size() == 1 || isCheckinRequest) {
   9813             dumpAll = true;
   9814         }
   9815 
   9816         if (isCheckinRequest) {
   9817             // short checkin version
   9818             pw.println(uptime + "," + realtime);
   9819             pw.flush();
   9820         } else {
   9821             pw.println("Applications Memory Usage (kB):");
   9822             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   9823         }
   9824 
   9825         String[] innerArgs = new String[args.length-opti];
   9826         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
   9827 
   9828         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
   9829         long nativePss=0, dalvikPss=0, otherPss=0;
   9830         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
   9831 
   9832         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
   9833         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
   9834                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
   9835 
   9836         long totalPss = 0;
   9837 
   9838         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   9839             ProcessRecord r = procs.get(i);
   9840             if (r.thread != null) {
   9841                 if (!isCheckinRequest && dumpAll) {
   9842                     pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
   9843                     pw.flush();
   9844                 }
   9845                 Debug.MemoryInfo mi = null;
   9846                 if (dumpAll) {
   9847                     try {
   9848                         mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
   9849                     } catch (RemoteException e) {
   9850                         if (!isCheckinRequest) {
   9851                             pw.println("Got RemoteException!");
   9852                             pw.flush();
   9853                         }
   9854                     }
   9855                 } else {
   9856                     mi = new Debug.MemoryInfo();
   9857                     Debug.getMemoryInfo(r.pid, mi);
   9858                 }
   9859 
   9860                 if (!isCheckinRequest && mi != null) {
   9861                     long myTotalPss = mi.getTotalPss();
   9862                     totalPss += myTotalPss;
   9863                     MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
   9864                             r.processName, myTotalPss, 0);
   9865                     procMems.add(pssItem);
   9866 
   9867                     nativePss += mi.nativePss;
   9868                     dalvikPss += mi.dalvikPss;
   9869                     otherPss += mi.otherPss;
   9870                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   9871                         long mem = mi.getOtherPss(j);
   9872                         miscPss[j] += mem;
   9873                         otherPss -= mem;
   9874                     }
   9875 
   9876                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
   9877                         if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
   9878                                 || oomIndex == (oomPss.length-1)) {
   9879                             oomPss[oomIndex] += myTotalPss;
   9880                             if (oomProcs[oomIndex] == null) {
   9881                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
   9882                             }
   9883                             oomProcs[oomIndex].add(pssItem);
   9884                             break;
   9885                         }
   9886                     }
   9887                 }
   9888             }
   9889         }
   9890 
   9891         if (!isCheckinRequest && procs.size() > 1) {
   9892             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
   9893 
   9894             catMems.add(new MemItem("Native", "Native", nativePss, -1));
   9895             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
   9896             catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
   9897             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   9898                 String label = Debug.MemoryInfo.getOtherLabel(j);
   9899                 catMems.add(new MemItem(label, label, miscPss[j], j));
   9900             }
   9901 
   9902             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
   9903             for (int j=0; j<oomPss.length; j++) {
   9904                 if (oomPss[j] != 0) {
   9905                     String label = DUMP_MEM_OOM_LABEL[j];
   9906                     MemItem item = new MemItem(label, label, oomPss[j],
   9907                             DUMP_MEM_OOM_ADJ[j]);
   9908                     item.subitems = oomProcs[j];
   9909                     oomMems.add(item);
   9910                 }
   9911             }
   9912 
   9913             if (outTag != null || outStack != null) {
   9914                 if (outTag != null) {
   9915                     appendMemBucket(outTag, totalPss, "total", false);
   9916                 }
   9917                 if (outStack != null) {
   9918                     appendMemBucket(outStack, totalPss, "total", true);
   9919                 }
   9920                 boolean firstLine = true;
   9921                 for (int i=0; i<oomMems.size(); i++) {
   9922                     MemItem miCat = oomMems.get(i);
   9923                     if (miCat.subitems == null || miCat.subitems.size() < 1) {
   9924                         continue;
   9925                     }
   9926                     if (miCat.id < ProcessList.SERVICE_ADJ
   9927                             || miCat.id == ProcessList.HOME_APP_ADJ
   9928                             || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
   9929                         if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
   9930                             outTag.append(" / ");
   9931                         }
   9932                         if (outStack != null) {
   9933                             if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
   9934                                 if (firstLine) {
   9935                                     outStack.append(":");
   9936                                     firstLine = false;
   9937                                 }
   9938                                 outStack.append("\n\t at ");
   9939                             } else {
   9940                                 outStack.append("$");
   9941                             }
   9942                         }
   9943                         for (int j=0; j<miCat.subitems.size(); j++) {
   9944                             MemItem mi = miCat.subitems.get(j);
   9945                             if (j > 0) {
   9946                                 if (outTag != null) {
   9947                                     outTag.append(" ");
   9948                                 }
   9949                                 if (outStack != null) {
   9950                                     outStack.append("$");
   9951                                 }
   9952                             }
   9953                             if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
   9954                                 appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
   9955                             }
   9956                             if (outStack != null) {
   9957                                 appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
   9958                             }
   9959                         }
   9960                         if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
   9961                             outStack.append("(");
   9962                             for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
   9963                                 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
   9964                                     outStack.append(DUMP_MEM_OOM_LABEL[k]);
   9965                                     outStack.append(":");
   9966                                     outStack.append(DUMP_MEM_OOM_ADJ[k]);
   9967                                 }
   9968                             }
   9969                             outStack.append(")");
   9970                         }
   9971                     }
   9972                 }
   9973             }
   9974 
   9975             if (!brief && !oomOnly) {
   9976                 pw.println();
   9977                 pw.println("Total PSS by process:");
   9978                 dumpMemItems(pw, "  ", procMems, true);
   9979                 pw.println();
   9980             }
   9981             pw.println("Total PSS by OOM adjustment:");
   9982             dumpMemItems(pw, "  ", oomMems, false);
   9983             if (!oomOnly) {
   9984                 PrintWriter out = categoryPw != null ? categoryPw : pw;
   9985                 out.println();
   9986                 out.println("Total PSS by category:");
   9987                 dumpMemItems(out, "  ", catMems, true);
   9988             }
   9989             pw.println();
   9990             pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
   9991         }
   9992     }
   9993 
   9994     /**
   9995      * Searches array of arguments for the specified string
   9996      * @param args array of argument strings
   9997      * @param value value to search for
   9998      * @return true if the value is contained in the array
   9999      */
   10000     private static boolean scanArgs(String[] args, String value) {
   10001         if (args != null) {
   10002             for (String arg : args) {
   10003                 if (value.equals(arg)) {
   10004                     return true;
   10005                 }
   10006             }
   10007         }
   10008         return false;
   10009     }
   10010 
   10011     private final void killServicesLocked(ProcessRecord app,
   10012             boolean allowRestart) {
   10013         // Report disconnected services.
   10014         if (false) {
   10015             // XXX we are letting the client link to the service for
   10016             // death notifications.
   10017             if (app.services.size() > 0) {
   10018                 Iterator<ServiceRecord> it = app.services.iterator();
   10019                 while (it.hasNext()) {
   10020                     ServiceRecord r = it.next();
   10021                     if (r.connections.size() > 0) {
   10022                         Iterator<ArrayList<ConnectionRecord>> jt
   10023                                 = r.connections.values().iterator();
   10024                         while (jt.hasNext()) {
   10025                             ArrayList<ConnectionRecord> cl = jt.next();
   10026                             for (int i=0; i<cl.size(); i++) {
   10027                                 ConnectionRecord c = cl.get(i);
   10028                                 if (c.binding.client != app) {
   10029                                     try {
   10030                                         //c.conn.connected(r.className, null);
   10031                                     } catch (Exception e) {
   10032                                         // todo: this should be asynchronous!
   10033                                         Slog.w(TAG, "Exception thrown disconnected servce "
   10034                                               + r.shortName
   10035                                               + " from app " + app.processName, e);
   10036                                     }
   10037                                 }
   10038                             }
   10039                         }
   10040                     }
   10041                 }
   10042             }
   10043         }
   10044 
   10045         // Clean up any connections this application has to other services.
   10046         if (app.connections.size() > 0) {
   10047             Iterator<ConnectionRecord> it = app.connections.iterator();
   10048             while (it.hasNext()) {
   10049                 ConnectionRecord r = it.next();
   10050                 removeConnectionLocked(r, app, null);
   10051             }
   10052         }
   10053         app.connections.clear();
   10054 
   10055         if (app.services.size() != 0) {
   10056             // Any services running in the application need to be placed
   10057             // back in the pending list.
   10058             Iterator<ServiceRecord> it = app.services.iterator();
   10059             while (it.hasNext()) {
   10060                 ServiceRecord sr = it.next();
   10061                 synchronized (sr.stats.getBatteryStats()) {
   10062                     sr.stats.stopLaunchedLocked();
   10063                 }
   10064                 sr.app = null;
   10065                 sr.executeNesting = 0;
   10066                 if (mStoppingServices.remove(sr)) {
   10067                     if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
   10068                 }
   10069 
   10070                 boolean hasClients = sr.bindings.size() > 0;
   10071                 if (hasClients) {
   10072                     Iterator<IntentBindRecord> bindings
   10073                             = sr.bindings.values().iterator();
   10074                     while (bindings.hasNext()) {
   10075                         IntentBindRecord b = bindings.next();
   10076                         if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
   10077                                 + ": shouldUnbind=" + b.hasBound);
   10078                         b.binder = null;
   10079                         b.requested = b.received = b.hasBound = false;
   10080                     }
   10081                 }
   10082 
   10083                 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
   10084                         &ApplicationInfo.FLAG_PERSISTENT) == 0) {
   10085                     Slog.w(TAG, "Service crashed " + sr.crashCount
   10086                             + " times, stopping: " + sr);
   10087                     EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
   10088                             sr.crashCount, sr.shortName, app.pid);
   10089                     bringDownServiceLocked(sr, true);
   10090                 } else if (!allowRestart) {
   10091                     bringDownServiceLocked(sr, true);
   10092                 } else {
   10093                     boolean canceled = scheduleServiceRestartLocked(sr, true);
   10094 
   10095                     // Should the service remain running?  Note that in the
   10096                     // extreme case of so many attempts to deliver a command
   10097                     // that it failed we also will stop it here.
   10098                     if (sr.startRequested && (sr.stopIfKilled || canceled)) {
   10099                         if (sr.pendingStarts.size() == 0) {
   10100                             sr.startRequested = false;
   10101                             if (!hasClients) {
   10102                                 // Whoops, no reason to restart!
   10103                                 bringDownServiceLocked(sr, true);
   10104                             }
   10105                         }
   10106                     }
   10107                 }
   10108             }
   10109 
   10110             if (!allowRestart) {
   10111                 app.services.clear();
   10112             }
   10113         }
   10114 
   10115         // Make sure we have no more records on the stopping list.
   10116         int i = mStoppingServices.size();
   10117         while (i > 0) {
   10118             i--;
   10119             ServiceRecord sr = mStoppingServices.get(i);
   10120             if (sr.app == app) {
   10121                 mStoppingServices.remove(i);
   10122                 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
   10123             }
   10124         }
   10125 
   10126         app.executingServices.clear();
   10127     }
   10128 
   10129     private final void removeDyingProviderLocked(ProcessRecord proc,
   10130             ContentProviderRecord cpr) {
   10131         synchronized (cpr) {
   10132             cpr.launchingApp = null;
   10133             cpr.notifyAll();
   10134         }
   10135 
   10136         mProvidersByClass.remove(cpr.name);
   10137         String names[] = cpr.info.authority.split(";");
   10138         for (int j = 0; j < names.length; j++) {
   10139             mProvidersByName.remove(names[j]);
   10140         }
   10141 
   10142         Iterator<ProcessRecord> cit = cpr.clients.iterator();
   10143         while (cit.hasNext()) {
   10144             ProcessRecord capp = cit.next();
   10145             if (!capp.persistent && capp.thread != null
   10146                     && capp.pid != 0
   10147                     && capp.pid != MY_PID) {
   10148                 Slog.i(TAG, "Kill " + capp.processName
   10149                         + " (pid " + capp.pid + "): provider " + cpr.info.name
   10150                         + " in dying process " + (proc != null ? proc.processName : "??"));
   10151                 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
   10152                         capp.processName, capp.setAdj, "dying provider "
   10153                                 + cpr.name.toShortString());
   10154                 Process.killProcessQuiet(capp.pid);
   10155             }
   10156         }
   10157 
   10158         mLaunchingProviders.remove(cpr);
   10159     }
   10160 
   10161     /**
   10162      * Main code for cleaning up a process when it has gone away.  This is
   10163      * called both as a result of the process dying, or directly when stopping
   10164      * a process when running in single process mode.
   10165      */
   10166     private final void cleanUpApplicationRecordLocked(ProcessRecord app,
   10167             boolean restarting, boolean allowRestart, int index) {
   10168         if (index >= 0) {
   10169             mLruProcesses.remove(index);
   10170         }
   10171 
   10172         mProcessesToGc.remove(app);
   10173 
   10174         // Dismiss any open dialogs.
   10175         if (app.crashDialog != null) {
   10176             app.crashDialog.dismiss();
   10177             app.crashDialog = null;
   10178         }
   10179         if (app.anrDialog != null) {
   10180             app.anrDialog.dismiss();
   10181             app.anrDialog = null;
   10182         }
   10183         if (app.waitDialog != null) {
   10184             app.waitDialog.dismiss();
   10185             app.waitDialog = null;
   10186         }
   10187 
   10188         app.crashing = false;
   10189         app.notResponding = false;
   10190 
   10191         app.resetPackageList();
   10192         app.unlinkDeathRecipient();
   10193         app.thread = null;
   10194         app.forcingToForeground = null;
   10195         app.foregroundServices = false;
   10196         app.foregroundActivities = false;
   10197         app.hasShownUi = false;
   10198         app.hasAboveClient = false;
   10199 
   10200         killServicesLocked(app, allowRestart);
   10201 
   10202         boolean restart = false;
   10203 
   10204         int NL = mLaunchingProviders.size();
   10205 
   10206         // Remove published content providers.
   10207         if (!app.pubProviders.isEmpty()) {
   10208             Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
   10209             while (it.hasNext()) {
   10210                 ContentProviderRecord cpr = it.next();
   10211                 cpr.provider = null;
   10212                 cpr.proc = null;
   10213 
   10214                 // See if someone is waiting for this provider...  in which
   10215                 // case we don't remove it, but just let it restart.
   10216                 int i = 0;
   10217                 if (!app.bad && allowRestart) {
   10218                     for (; i<NL; i++) {
   10219                         if (mLaunchingProviders.get(i) == cpr) {
   10220                             restart = true;
   10221                             break;
   10222                         }
   10223                     }
   10224                 } else {
   10225                     i = NL;
   10226                 }
   10227 
   10228                 if (i >= NL) {
   10229                     removeDyingProviderLocked(app, cpr);
   10230                     NL = mLaunchingProviders.size();
   10231                 }
   10232             }
   10233             app.pubProviders.clear();
   10234         }
   10235 
   10236         // Take care of any launching providers waiting for this process.
   10237         if (checkAppInLaunchingProvidersLocked(app, false)) {
   10238             restart = true;
   10239         }
   10240 
   10241         // Unregister from connected content providers.
   10242         if (!app.conProviders.isEmpty()) {
   10243             Iterator it = app.conProviders.keySet().iterator();
   10244             while (it.hasNext()) {
   10245                 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
   10246                 cpr.clients.remove(app);
   10247             }
   10248             app.conProviders.clear();
   10249         }
   10250 
   10251         // At this point there may be remaining entries in mLaunchingProviders
   10252         // where we were the only one waiting, so they are no longer of use.
   10253         // Look for these and clean up if found.
   10254         // XXX Commented out for now.  Trying to figure out a way to reproduce
   10255         // the actual situation to identify what is actually going on.
   10256         if (false) {
   10257             for (int i=0; i<NL; i++) {
   10258                 ContentProviderRecord cpr = (ContentProviderRecord)
   10259                         mLaunchingProviders.get(i);
   10260                 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
   10261                     synchronized (cpr) {
   10262                         cpr.launchingApp = null;
   10263                         cpr.notifyAll();
   10264                     }
   10265                 }
   10266             }
   10267         }
   10268 
   10269         skipCurrentReceiverLocked(app);
   10270 
   10271         // Unregister any receivers.
   10272         if (app.receivers.size() > 0) {
   10273             Iterator<ReceiverList> it = app.receivers.iterator();
   10274             while (it.hasNext()) {
   10275                 removeReceiverLocked(it.next());
   10276             }
   10277             app.receivers.clear();
   10278         }
   10279 
   10280         // If the app is undergoing backup, tell the backup manager about it
   10281         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
   10282             if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
   10283             try {
   10284                 IBackupManager bm = IBackupManager.Stub.asInterface(
   10285                         ServiceManager.getService(Context.BACKUP_SERVICE));
   10286                 bm.agentDisconnected(app.info.packageName);
   10287             } catch (RemoteException e) {
   10288                 // can't happen; backup manager is local
   10289             }
   10290         }
   10291 
   10292         mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
   10293 
   10294         // If the caller is restarting this app, then leave it in its
   10295         // current lists and let the caller take care of it.
   10296         if (restarting) {
   10297             return;
   10298         }
   10299 
   10300         if (!app.persistent) {
   10301             if (DEBUG_PROCESSES) Slog.v(TAG,
   10302                     "Removing non-persistent process during cleanup: " + app);
   10303             mProcessNames.remove(app.processName, app.info.uid);
   10304             if (mHeavyWeightProcess == app) {
   10305                 mHeavyWeightProcess = null;
   10306                 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
   10307             }
   10308         } else if (!app.removed) {
   10309             // This app is persistent, so we need to keep its record around.
   10310             // If it is not already on the pending app list, add it there
   10311             // and start a new process for it.
   10312             if (mPersistentStartingProcesses.indexOf(app) < 0) {
   10313                 mPersistentStartingProcesses.add(app);
   10314                 restart = true;
   10315             }
   10316         }
   10317         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   10318                 "Clean-up removing on hold: " + app);
   10319         mProcessesOnHold.remove(app);
   10320 
   10321         if (app == mHomeProcess) {
   10322             mHomeProcess = null;
   10323         }
   10324         if (app == mPreviousProcess) {
   10325             mPreviousProcess = null;
   10326         }
   10327 
   10328         if (restart) {
   10329             // We have components that still need to be running in the
   10330             // process, so re-launch it.
   10331             mProcessNames.put(app.processName, app.info.uid, app);
   10332             startProcessLocked(app, "restart", app.processName);
   10333         } else if (app.pid > 0 && app.pid != MY_PID) {
   10334             // Goodbye!
   10335             synchronized (mPidsSelfLocked) {
   10336                 mPidsSelfLocked.remove(app.pid);
   10337                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   10338             }
   10339             app.setPid(0);
   10340         }
   10341     }
   10342 
   10343     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
   10344         // Look through the content providers we are waiting to have launched,
   10345         // and if any run in this process then either schedule a restart of
   10346         // the process or kill the client waiting for it if this process has
   10347         // gone bad.
   10348         int NL = mLaunchingProviders.size();
   10349         boolean restart = false;
   10350         for (int i=0; i<NL; i++) {
   10351             ContentProviderRecord cpr = mLaunchingProviders.get(i);
   10352             if (cpr.launchingApp == app) {
   10353                 if (!alwaysBad && !app.bad) {
   10354                     restart = true;
   10355                 } else {
   10356                     removeDyingProviderLocked(app, cpr);
   10357                     NL = mLaunchingProviders.size();
   10358                 }
   10359             }
   10360         }
   10361         return restart;
   10362     }
   10363 
   10364     // =========================================================
   10365     // SERVICES
   10366     // =========================================================
   10367 
   10368     ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
   10369         ActivityManager.RunningServiceInfo info =
   10370             new ActivityManager.RunningServiceInfo();
   10371         info.service = r.name;
   10372         if (r.app != null) {
   10373             info.pid = r.app.pid;
   10374         }
   10375         info.uid = r.appInfo.uid;
   10376         info.process = r.processName;
   10377         info.foreground = r.isForeground;
   10378         info.activeSince = r.createTime;
   10379         info.started = r.startRequested;
   10380         info.clientCount = r.connections.size();
   10381         info.crashCount = r.crashCount;
   10382         info.lastActivityTime = r.lastActivity;
   10383         if (r.isForeground) {
   10384             info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
   10385         }
   10386         if (r.startRequested) {
   10387             info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
   10388         }
   10389         if (r.app != null && r.app.pid == MY_PID) {
   10390             info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
   10391         }
   10392         if (r.app != null && r.app.persistent) {
   10393             info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
   10394         }
   10395 
   10396         for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
   10397             for (int i=0; i<connl.size(); i++) {
   10398                 ConnectionRecord conn = connl.get(i);
   10399                 if (conn.clientLabel != 0) {
   10400                     info.clientPackage = conn.binding.client.info.packageName;
   10401                     info.clientLabel = conn.clientLabel;
   10402                     return info;
   10403                 }
   10404             }
   10405         }
   10406         return info;
   10407     }
   10408 
   10409     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
   10410             int flags) {
   10411         synchronized (this) {
   10412             ArrayList<ActivityManager.RunningServiceInfo> res
   10413                     = new ArrayList<ActivityManager.RunningServiceInfo>();
   10414 
   10415             if (mServices.size() > 0) {
   10416                 Iterator<ServiceRecord> it = mServices.values().iterator();
   10417                 while (it.hasNext() && res.size() < maxNum) {
   10418                     res.add(makeRunningServiceInfoLocked(it.next()));
   10419                 }
   10420             }
   10421 
   10422             for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
   10423                 ServiceRecord r = mRestartingServices.get(i);
   10424                 ActivityManager.RunningServiceInfo info =
   10425                         makeRunningServiceInfoLocked(r);
   10426                 info.restarting = r.nextRestartTime;
   10427                 res.add(info);
   10428             }
   10429 
   10430             return res;
   10431         }
   10432     }
   10433 
   10434     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
   10435         synchronized (this) {
   10436             ServiceRecord r = mServices.get(name);
   10437             if (r != null) {
   10438                 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
   10439                     for (int i=0; i<conn.size(); i++) {
   10440                         if (conn.get(i).clientIntent != null) {
   10441                             return conn.get(i).clientIntent;
   10442                         }
   10443                     }
   10444                 }
   10445             }
   10446         }
   10447         return null;
   10448     }
   10449 
   10450     private final ServiceRecord findServiceLocked(ComponentName name,
   10451             IBinder token) {
   10452         ServiceRecord r = mServices.get(name);
   10453         return r == token ? r : null;
   10454     }
   10455 
   10456     private final class ServiceLookupResult {
   10457         final ServiceRecord record;
   10458         final String permission;
   10459 
   10460         ServiceLookupResult(ServiceRecord _record, String _permission) {
   10461             record = _record;
   10462             permission = _permission;
   10463         }
   10464     };
   10465 
   10466     private ServiceLookupResult findServiceLocked(Intent service,
   10467             String resolvedType) {
   10468         ServiceRecord r = null;
   10469         if (service.getComponent() != null) {
   10470             r = mServices.get(service.getComponent());
   10471         }
   10472         if (r == null) {
   10473             Intent.FilterComparison filter = new Intent.FilterComparison(service);
   10474             r = mServicesByIntent.get(filter);
   10475         }
   10476 
   10477         if (r == null) {
   10478             try {
   10479                 ResolveInfo rInfo =
   10480                     AppGlobals.getPackageManager().resolveService(
   10481                             service, resolvedType, 0);
   10482                 ServiceInfo sInfo =
   10483                     rInfo != null ? rInfo.serviceInfo : null;
   10484                 if (sInfo == null) {
   10485                     return null;
   10486                 }
   10487 
   10488                 ComponentName name = new ComponentName(
   10489                         sInfo.applicationInfo.packageName, sInfo.name);
   10490                 r = mServices.get(name);
   10491             } catch (RemoteException ex) {
   10492                 // pm is in same process, this will never happen.
   10493             }
   10494         }
   10495         if (r != null) {
   10496             int callingPid = Binder.getCallingPid();
   10497             int callingUid = Binder.getCallingUid();
   10498             if (checkComponentPermission(r.permission,
   10499                     callingPid, callingUid, r.appInfo.uid, r.exported)
   10500                     != PackageManager.PERMISSION_GRANTED) {
   10501                 if (!r.exported) {
   10502                     Slog.w(TAG, "Permission Denial: Accessing service " + r.name
   10503                             + " from pid=" + callingPid
   10504                             + ", uid=" + callingUid
   10505                             + " that is not exported from uid " + r.appInfo.uid);
   10506                     return new ServiceLookupResult(null, "not exported from uid "
   10507                             + r.appInfo.uid);
   10508                 }
   10509                 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
   10510                         + " from pid=" + callingPid
   10511                         + ", uid=" + callingUid
   10512                         + " requires " + r.permission);
   10513                 return new ServiceLookupResult(null, r.permission);
   10514             }
   10515             return new ServiceLookupResult(r, null);
   10516         }
   10517         return null;
   10518     }
   10519 
   10520     private class ServiceRestarter implements Runnable {
   10521         private ServiceRecord mService;
   10522 
   10523         void setService(ServiceRecord service) {
   10524             mService = service;
   10525         }
   10526 
   10527         public void run() {
   10528             synchronized(ActivityManagerService.this) {
   10529                 performServiceRestartLocked(mService);
   10530             }
   10531         }
   10532     }
   10533 
   10534     private ServiceLookupResult retrieveServiceLocked(Intent service,
   10535             String resolvedType, int callingPid, int callingUid) {
   10536         ServiceRecord r = null;
   10537         if (service.getComponent() != null) {
   10538             r = mServices.get(service.getComponent());
   10539         }
   10540         Intent.FilterComparison filter = new Intent.FilterComparison(service);
   10541         r = mServicesByIntent.get(filter);
   10542         if (r == null) {
   10543             try {
   10544                 ResolveInfo rInfo =
   10545                     AppGlobals.getPackageManager().resolveService(
   10546                             service, resolvedType, STOCK_PM_FLAGS);
   10547                 ServiceInfo sInfo =
   10548                     rInfo != null ? rInfo.serviceInfo : null;
   10549                 if (sInfo == null) {
   10550                     Slog.w(TAG, "Unable to start service " + service +
   10551                           ": not found");
   10552                     return null;
   10553                 }
   10554 
   10555                 ComponentName name = new ComponentName(
   10556                         sInfo.applicationInfo.packageName, sInfo.name);
   10557                 r = mServices.get(name);
   10558                 if (r == null) {
   10559                     filter = new Intent.FilterComparison(service.cloneFilter());
   10560                     ServiceRestarter res = new ServiceRestarter();
   10561                     BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   10562                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   10563                     synchronized (stats) {
   10564                         ss = stats.getServiceStatsLocked(
   10565                                 sInfo.applicationInfo.uid, sInfo.packageName,
   10566                                 sInfo.name);
   10567                     }
   10568                     r = new ServiceRecord(this, ss, name, filter, sInfo, res);
   10569                     res.setService(r);
   10570                     mServices.put(name, r);
   10571                     mServicesByIntent.put(filter, r);
   10572 
   10573                     // Make sure this component isn't in the pending list.
   10574                     int N = mPendingServices.size();
   10575                     for (int i=0; i<N; i++) {
   10576                         ServiceRecord pr = mPendingServices.get(i);
   10577                         if (pr.name.equals(name)) {
   10578                             mPendingServices.remove(i);
   10579                             i--;
   10580                             N--;
   10581                         }
   10582                     }
   10583                 }
   10584             } catch (RemoteException ex) {
   10585                 // pm is in same process, this will never happen.
   10586             }
   10587         }
   10588         if (r != null) {
   10589             if (checkComponentPermission(r.permission,
   10590                     callingPid, callingUid, r.appInfo.uid, r.exported)
   10591                     != PackageManager.PERMISSION_GRANTED) {
   10592                 if (!r.exported) {
   10593                     Slog.w(TAG, "Permission Denial: Accessing service " + r.name
   10594                             + " from pid=" + callingPid
   10595                             + ", uid=" + callingUid
   10596                             + " that is not exported from uid " + r.appInfo.uid);
   10597                     return new ServiceLookupResult(null, "not exported from uid "
   10598                             + r.appInfo.uid);
   10599                 }
   10600                 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
   10601                         + " from pid=" + callingPid
   10602                         + ", uid=" + callingUid
   10603                         + " requires " + r.permission);
   10604                 return new ServiceLookupResult(null, r.permission);
   10605             }
   10606             return new ServiceLookupResult(r, null);
   10607         }
   10608         return null;
   10609     }
   10610 
   10611     private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
   10612         if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
   10613                 + why + " of " + r + " in app " + r.app);
   10614         else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
   10615                 + why + " of " + r.shortName);
   10616         long now = SystemClock.uptimeMillis();
   10617         if (r.executeNesting == 0 && r.app != null) {
   10618             if (r.app.executingServices.size() == 0) {
   10619                 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   10620                 msg.obj = r.app;
   10621                 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
   10622             }
   10623             r.app.executingServices.add(r);
   10624         }
   10625         r.executeNesting++;
   10626         r.executingStart = now;
   10627     }
   10628 
   10629     private final void sendServiceArgsLocked(ServiceRecord r,
   10630             boolean oomAdjusted) {
   10631         final int N = r.pendingStarts.size();
   10632         if (N == 0) {
   10633             return;
   10634         }
   10635 
   10636         while (r.pendingStarts.size() > 0) {
   10637             try {
   10638                 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
   10639                 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
   10640                         + r + " " + r.intent + " args=" + si.intent);
   10641                 if (si.intent == null && N > 1) {
   10642                     // If somehow we got a dummy null intent in the middle,
   10643                     // then skip it.  DO NOT skip a null intent when it is
   10644                     // the only one in the list -- this is to support the
   10645                     // onStartCommand(null) case.
   10646                     continue;
   10647                 }
   10648                 si.deliveredTime = SystemClock.uptimeMillis();
   10649                 r.deliveredStarts.add(si);
   10650                 si.deliveryCount++;
   10651                 if (si.targetPermissionUid >= 0 && si.intent != null) {
   10652                     grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
   10653                             r.packageName, si.intent, si.getUriPermissionsLocked());
   10654                 }
   10655                 bumpServiceExecutingLocked(r, "start");
   10656                 if (!oomAdjusted) {
   10657                     oomAdjusted = true;
   10658                     updateOomAdjLocked(r.app);
   10659                 }
   10660                 int flags = 0;
   10661                 if (si.deliveryCount > 0) {
   10662                     flags |= Service.START_FLAG_RETRY;
   10663                 }
   10664                 if (si.doneExecutingCount > 0) {
   10665                     flags |= Service.START_FLAG_REDELIVERY;
   10666                 }
   10667                 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
   10668             } catch (RemoteException e) {
   10669                 // Remote process gone...  we'll let the normal cleanup take
   10670                 // care of this.
   10671                 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
   10672                 break;
   10673             } catch (Exception e) {
   10674                 Slog.w(TAG, "Unexpected exception", e);
   10675                 break;
   10676             }
   10677         }
   10678     }
   10679 
   10680     private final boolean requestServiceBindingLocked(ServiceRecord r,
   10681             IntentBindRecord i, boolean rebind) {
   10682         if (r.app == null || r.app.thread == null) {
   10683             // If service is not currently running, can't yet bind.
   10684             return false;
   10685         }
   10686         if ((!i.requested || rebind) && i.apps.size() > 0) {
   10687             try {
   10688                 bumpServiceExecutingLocked(r, "bind");
   10689                 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
   10690                 if (!rebind) {
   10691                     i.requested = true;
   10692                 }
   10693                 i.hasBound = true;
   10694                 i.doRebind = false;
   10695             } catch (RemoteException e) {
   10696                 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
   10697                 return false;
   10698             }
   10699         }
   10700         return true;
   10701     }
   10702 
   10703     private final void requestServiceBindingsLocked(ServiceRecord r) {
   10704         Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
   10705         while (bindings.hasNext()) {
   10706             IntentBindRecord i = bindings.next();
   10707             if (!requestServiceBindingLocked(r, i, false)) {
   10708                 break;
   10709             }
   10710         }
   10711     }
   10712 
   10713     private final void realStartServiceLocked(ServiceRecord r,
   10714             ProcessRecord app) throws RemoteException {
   10715         if (app.thread == null) {
   10716             throw new RemoteException();
   10717         }
   10718 
   10719         r.app = app;
   10720         r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
   10721 
   10722         app.services.add(r);
   10723         bumpServiceExecutingLocked(r, "create");
   10724         updateLruProcessLocked(app, true, true);
   10725 
   10726         boolean created = false;
   10727         try {
   10728             mStringBuilder.setLength(0);
   10729             r.intent.getIntent().toShortString(mStringBuilder, true, false, true);
   10730             EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
   10731                     System.identityHashCode(r), r.shortName,
   10732                     mStringBuilder.toString(), r.app.pid);
   10733             synchronized (r.stats.getBatteryStats()) {
   10734                 r.stats.startLaunchedLocked();
   10735             }
   10736             ensurePackageDexOpt(r.serviceInfo.packageName);
   10737             app.thread.scheduleCreateService(r, r.serviceInfo,
   10738                     compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
   10739             r.postNotification();
   10740             created = true;
   10741         } finally {
   10742             if (!created) {
   10743                 app.services.remove(r);
   10744                 scheduleServiceRestartLocked(r, false);
   10745             }
   10746         }
   10747 
   10748         requestServiceBindingsLocked(r);
   10749 
   10750         // If the service is in the started state, and there are no
   10751         // pending arguments, then fake up one so its onStartCommand() will
   10752         // be called.
   10753         if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
   10754             r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
   10755                     null, -1));
   10756         }
   10757 
   10758         sendServiceArgsLocked(r, true);
   10759     }
   10760 
   10761     private final boolean scheduleServiceRestartLocked(ServiceRecord r,
   10762             boolean allowCancel) {
   10763         boolean canceled = false;
   10764 
   10765         final long now = SystemClock.uptimeMillis();
   10766         long minDuration = SERVICE_RESTART_DURATION;
   10767         long resetTime = SERVICE_RESET_RUN_DURATION;
   10768 
   10769         if ((r.serviceInfo.applicationInfo.flags
   10770                 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
   10771             minDuration /= 4;
   10772         }
   10773 
   10774         // Any delivered but not yet finished starts should be put back
   10775         // on the pending list.
   10776         final int N = r.deliveredStarts.size();
   10777         if (N > 0) {
   10778             for (int i=N-1; i>=0; i--) {
   10779                 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
   10780                 si.removeUriPermissionsLocked();
   10781                 if (si.intent == null) {
   10782                     // We'll generate this again if needed.
   10783                 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
   10784                         && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
   10785                     r.pendingStarts.add(0, si);
   10786                     long dur = SystemClock.uptimeMillis() - si.deliveredTime;
   10787                     dur *= 2;
   10788                     if (minDuration < dur) minDuration = dur;
   10789                     if (resetTime < dur) resetTime = dur;
   10790                 } else {
   10791                     Slog.w(TAG, "Canceling start item " + si.intent + " in service "
   10792                             + r.name);
   10793                     canceled = true;
   10794                 }
   10795             }
   10796             r.deliveredStarts.clear();
   10797         }
   10798 
   10799         r.totalRestartCount++;
   10800         if (r.restartDelay == 0) {
   10801             r.restartCount++;
   10802             r.restartDelay = minDuration;
   10803         } else {
   10804             // If it has been a "reasonably long time" since the service
   10805             // was started, then reset our restart duration back to
   10806             // the beginning, so we don't infinitely increase the duration
   10807             // on a service that just occasionally gets killed (which is
   10808             // a normal case, due to process being killed to reclaim memory).
   10809             if (now > (r.restartTime+resetTime)) {
   10810                 r.restartCount = 1;
   10811                 r.restartDelay = minDuration;
   10812             } else {
   10813                 if ((r.serviceInfo.applicationInfo.flags
   10814                         &ApplicationInfo.FLAG_PERSISTENT) != 0) {
   10815                     // Services in peristent processes will restart much more
   10816                     // quickly, since they are pretty important.  (Think SystemUI).
   10817                     r.restartDelay += minDuration/2;
   10818                 } else {
   10819                     r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
   10820                     if (r.restartDelay < minDuration) {
   10821                         r.restartDelay = minDuration;
   10822                     }
   10823                 }
   10824             }
   10825         }
   10826 
   10827         r.nextRestartTime = now + r.restartDelay;
   10828 
   10829         // Make sure that we don't end up restarting a bunch of services
   10830         // all at the same time.
   10831         boolean repeat;
   10832         do {
   10833             repeat = false;
   10834             for (int i=mRestartingServices.size()-1; i>=0; i--) {
   10835                 ServiceRecord r2 = mRestartingServices.get(i);
   10836                 if (r2 != r && r.nextRestartTime
   10837                         >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
   10838                         && r.nextRestartTime
   10839                         < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
   10840                     r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
   10841                     r.restartDelay = r.nextRestartTime - now;
   10842                     repeat = true;
   10843                     break;
   10844                 }
   10845             }
   10846         } while (repeat);
   10847 
   10848         if (!mRestartingServices.contains(r)) {
   10849             mRestartingServices.add(r);
   10850         }
   10851 
   10852         r.cancelNotification();
   10853 
   10854         mHandler.removeCallbacks(r.restarter);
   10855         mHandler.postAtTime(r.restarter, r.nextRestartTime);
   10856         r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
   10857         Slog.w(TAG, "Scheduling restart of crashed service "
   10858                 + r.shortName + " in " + r.restartDelay + "ms");
   10859         EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
   10860                 r.shortName, r.restartDelay);
   10861 
   10862         return canceled;
   10863     }
   10864 
   10865     final void performServiceRestartLocked(ServiceRecord r) {
   10866         if (!mRestartingServices.contains(r)) {
   10867             return;
   10868         }
   10869         bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
   10870     }
   10871 
   10872     private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
   10873         if (r.restartDelay == 0) {
   10874             return false;
   10875         }
   10876         r.resetRestartCounter();
   10877         mRestartingServices.remove(r);
   10878         mHandler.removeCallbacks(r.restarter);
   10879         return true;
   10880     }
   10881 
   10882     private final boolean bringUpServiceLocked(ServiceRecord r,
   10883             int intentFlags, boolean whileRestarting) {
   10884         //Slog.i(TAG, "Bring up service:");
   10885         //r.dump("  ");
   10886 
   10887         if (r.app != null && r.app.thread != null) {
   10888             sendServiceArgsLocked(r, false);
   10889             return true;
   10890         }
   10891 
   10892         if (!whileRestarting && r.restartDelay > 0) {
   10893             // If waiting for a restart, then do nothing.
   10894             return true;
   10895         }
   10896 
   10897         if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
   10898 
   10899         // We are now bringing the service up, so no longer in the
   10900         // restarting state.
   10901         mRestartingServices.remove(r);
   10902 
   10903         // Service is now being launched, its package can't be stopped.
   10904         try {
   10905             AppGlobals.getPackageManager().setPackageStoppedState(
   10906                     r.packageName, false);
   10907         } catch (RemoteException e) {
   10908         } catch (IllegalArgumentException e) {
   10909             Slog.w(TAG, "Failed trying to unstop package "
   10910                     + r.packageName + ": " + e);
   10911         }
   10912 
   10913         final String appName = r.processName;
   10914         ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
   10915         if (app != null && app.thread != null) {
   10916             try {
   10917                 app.addPackage(r.appInfo.packageName);
   10918                 realStartServiceLocked(r, app);
   10919                 return true;
   10920             } catch (RemoteException e) {
   10921                 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
   10922             }
   10923 
   10924             // If a dead object exception was thrown -- fall through to
   10925             // restart the application.
   10926         }
   10927 
   10928         // Not running -- get it started, and enqueue this service record
   10929         // to be executed when the app comes up.
   10930         if (startProcessLocked(appName, r.appInfo, true, intentFlags,
   10931                 "service", r.name, false) == null) {
   10932             Slog.w(TAG, "Unable to launch app "
   10933                     + r.appInfo.packageName + "/"
   10934                     + r.appInfo.uid + " for service "
   10935                     + r.intent.getIntent() + ": process is bad");
   10936             bringDownServiceLocked(r, true);
   10937             return false;
   10938         }
   10939 
   10940         if (!mPendingServices.contains(r)) {
   10941             mPendingServices.add(r);
   10942         }
   10943 
   10944         return true;
   10945     }
   10946 
   10947     private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
   10948         //Slog.i(TAG, "Bring down service:");
   10949         //r.dump("  ");
   10950 
   10951         // Does it still need to run?
   10952         if (!force && r.startRequested) {
   10953             return;
   10954         }
   10955         if (r.connections.size() > 0) {
   10956             if (!force) {
   10957                 // XXX should probably keep a count of the number of auto-create
   10958                 // connections directly in the service.
   10959                 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
   10960                 while (it.hasNext()) {
   10961                     ArrayList<ConnectionRecord> cr = it.next();
   10962                     for (int i=0; i<cr.size(); i++) {
   10963                         if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
   10964                             return;
   10965                         }
   10966                     }
   10967                 }
   10968             }
   10969 
   10970             // Report to all of the connections that the service is no longer
   10971             // available.
   10972             Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
   10973             while (it.hasNext()) {
   10974                 ArrayList<ConnectionRecord> c = it.next();
   10975                 for (int i=0; i<c.size(); i++) {
   10976                     ConnectionRecord cr = c.get(i);
   10977                     // There is still a connection to the service that is
   10978                     // being brought down.  Mark it as dead.
   10979                     cr.serviceDead = true;
   10980                     try {
   10981                         cr.conn.connected(r.name, null);
   10982                     } catch (Exception e) {
   10983                         Slog.w(TAG, "Failure disconnecting service " + r.name +
   10984                               " to connection " + c.get(i).conn.asBinder() +
   10985                               " (in " + c.get(i).binding.client.processName + ")", e);
   10986                     }
   10987                 }
   10988             }
   10989         }
   10990 
   10991         // Tell the service that it has been unbound.
   10992         if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
   10993             Iterator<IntentBindRecord> it = r.bindings.values().iterator();
   10994             while (it.hasNext()) {
   10995                 IntentBindRecord ibr = it.next();
   10996                 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
   10997                         + ": hasBound=" + ibr.hasBound);
   10998                 if (r.app != null && r.app.thread != null && ibr.hasBound) {
   10999                     try {
   11000                         bumpServiceExecutingLocked(r, "bring down unbind");
   11001                         updateOomAdjLocked(r.app);
   11002                         ibr.hasBound = false;
   11003                         r.app.thread.scheduleUnbindService(r,
   11004                                 ibr.intent.getIntent());
   11005                     } catch (Exception e) {
   11006                         Slog.w(TAG, "Exception when unbinding service "
   11007                                 + r.shortName, e);
   11008                         serviceDoneExecutingLocked(r, true);
   11009                     }
   11010                 }
   11011             }
   11012         }
   11013 
   11014         if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
   11015         EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
   11016                 System.identityHashCode(r), r.shortName,
   11017                 (r.app != null) ? r.app.pid : -1);
   11018 
   11019         mServices.remove(r.name);
   11020         mServicesByIntent.remove(r.intent);
   11021         r.totalRestartCount = 0;
   11022         unscheduleServiceRestartLocked(r);
   11023 
   11024         // Also make sure it is not on the pending list.
   11025         int N = mPendingServices.size();
   11026         for (int i=0; i<N; i++) {
   11027             if (mPendingServices.get(i) == r) {
   11028                 mPendingServices.remove(i);
   11029                 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
   11030                 i--;
   11031                 N--;
   11032             }
   11033         }
   11034 
   11035         r.cancelNotification();
   11036         r.isForeground = false;
   11037         r.foregroundId = 0;
   11038         r.foregroundNoti = null;
   11039 
   11040         // Clear start entries.
   11041         r.clearDeliveredStartsLocked();
   11042         r.pendingStarts.clear();
   11043 
   11044         if (r.app != null) {
   11045             synchronized (r.stats.getBatteryStats()) {
   11046                 r.stats.stopLaunchedLocked();
   11047             }
   11048             r.app.services.remove(r);
   11049             if (r.app.thread != null) {
   11050                 try {
   11051                     bumpServiceExecutingLocked(r, "stop");
   11052                     mStoppingServices.add(r);
   11053                     updateOomAdjLocked(r.app);
   11054                     r.app.thread.scheduleStopService(r);
   11055                 } catch (Exception e) {
   11056                     Slog.w(TAG, "Exception when stopping service "
   11057                             + r.shortName, e);
   11058                     serviceDoneExecutingLocked(r, true);
   11059                 }
   11060                 updateServiceForegroundLocked(r.app, false);
   11061             } else {
   11062                 if (DEBUG_SERVICE) Slog.v(
   11063                     TAG, "Removed service that has no process: " + r);
   11064             }
   11065         } else {
   11066             if (DEBUG_SERVICE) Slog.v(
   11067                 TAG, "Removed service that is not running: " + r);
   11068         }
   11069 
   11070         if (r.bindings.size() > 0) {
   11071             r.bindings.clear();
   11072         }
   11073 
   11074         if (r.restarter instanceof ServiceRestarter) {
   11075            ((ServiceRestarter)r.restarter).setService(null);
   11076         }
   11077     }
   11078 
   11079     ComponentName startServiceLocked(IApplicationThread caller,
   11080             Intent service, String resolvedType,
   11081             int callingPid, int callingUid) {
   11082         synchronized(this) {
   11083             if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
   11084                     + " type=" + resolvedType + " args=" + service.getExtras());
   11085 
   11086             if (caller != null) {
   11087                 final ProcessRecord callerApp = getRecordForAppLocked(caller);
   11088                 if (callerApp == null) {
   11089                     throw new SecurityException(
   11090                             "Unable to find app for caller " + caller
   11091                             + " (pid=" + Binder.getCallingPid()
   11092                             + ") when starting service " + service);
   11093                 }
   11094             }
   11095 
   11096             ServiceLookupResult res =
   11097                 retrieveServiceLocked(service, resolvedType,
   11098                         callingPid, callingUid);
   11099             if (res == null) {
   11100                 return null;
   11101             }
   11102             if (res.record == null) {
   11103                 return new ComponentName("!", res.permission != null
   11104                         ? res.permission : "private to package");
   11105             }
   11106             ServiceRecord r = res.record;
   11107             int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
   11108                     callingUid, r.packageName, service);
   11109             if (unscheduleServiceRestartLocked(r)) {
   11110                 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
   11111             }
   11112             r.startRequested = true;
   11113             r.callStart = false;
   11114             r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
   11115                     service, targetPermissionUid));
   11116             r.lastActivity = SystemClock.uptimeMillis();
   11117             synchronized (r.stats.getBatteryStats()) {
   11118                 r.stats.startRunningLocked();
   11119             }
   11120             if (!bringUpServiceLocked(r, service.getFlags(), false)) {
   11121                 return new ComponentName("!", "Service process is bad");
   11122             }
   11123             return r.name;
   11124         }
   11125     }
   11126 
   11127     public ComponentName startService(IApplicationThread caller, Intent service,
   11128             String resolvedType) {
   11129         // Refuse possible leaked file descriptors
   11130         if (service != null && service.hasFileDescriptors() == true) {
   11131             throw new IllegalArgumentException("File descriptors passed in Intent");
   11132         }
   11133 
   11134         synchronized(this) {
   11135             final int callingPid = Binder.getCallingPid();
   11136             final int callingUid = Binder.getCallingUid();
   11137             final long origId = Binder.clearCallingIdentity();
   11138             ComponentName res = startServiceLocked(caller, service,
   11139                     resolvedType, callingPid, callingUid);
   11140             Binder.restoreCallingIdentity(origId);
   11141             return res;
   11142         }
   11143     }
   11144 
   11145     ComponentName startServiceInPackage(int uid,
   11146             Intent service, String resolvedType) {
   11147         synchronized(this) {
   11148             final long origId = Binder.clearCallingIdentity();
   11149             ComponentName res = startServiceLocked(null, service,
   11150                     resolvedType, -1, uid);
   11151             Binder.restoreCallingIdentity(origId);
   11152             return res;
   11153         }
   11154     }
   11155 
   11156     private void stopServiceLocked(ServiceRecord service) {
   11157         synchronized (service.stats.getBatteryStats()) {
   11158             service.stats.stopRunningLocked();
   11159         }
   11160         service.startRequested = false;
   11161         service.callStart = false;
   11162         bringDownServiceLocked(service, false);
   11163     }
   11164 
   11165     public int stopService(IApplicationThread caller, Intent service,
   11166             String resolvedType) {
   11167         // Refuse possible leaked file descriptors
   11168         if (service != null && service.hasFileDescriptors() == true) {
   11169             throw new IllegalArgumentException("File descriptors passed in Intent");
   11170         }
   11171 
   11172         synchronized(this) {
   11173             if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
   11174                     + " type=" + resolvedType);
   11175 
   11176             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   11177             if (caller != null && callerApp == null) {
   11178                 throw new SecurityException(
   11179                         "Unable to find app for caller " + caller
   11180                         + " (pid=" + Binder.getCallingPid()
   11181                         + ") when stopping service " + service);
   11182             }
   11183 
   11184             // If this service is active, make sure it is stopped.
   11185             ServiceLookupResult r = findServiceLocked(service, resolvedType);
   11186             if (r != null) {
   11187                 if (r.record != null) {
   11188                     final long origId = Binder.clearCallingIdentity();
   11189                     try {
   11190                         stopServiceLocked(r.record);
   11191                     } finally {
   11192                         Binder.restoreCallingIdentity(origId);
   11193                     }
   11194                     return 1;
   11195                 }
   11196                 return -1;
   11197             }
   11198         }
   11199 
   11200         return 0;
   11201     }
   11202 
   11203     public IBinder peekService(Intent service, String resolvedType) {
   11204         // Refuse possible leaked file descriptors
   11205         if (service != null && service.hasFileDescriptors() == true) {
   11206             throw new IllegalArgumentException("File descriptors passed in Intent");
   11207         }
   11208 
   11209         IBinder ret = null;
   11210 
   11211         synchronized(this) {
   11212             ServiceLookupResult r = findServiceLocked(service, resolvedType);
   11213 
   11214             if (r != null) {
   11215                 // r.record is null if findServiceLocked() failed the caller permission check
   11216                 if (r.record == null) {
   11217                     throw new SecurityException(
   11218                             "Permission Denial: Accessing service " + r.record.name
   11219                             + " from pid=" + Binder.getCallingPid()
   11220                             + ", uid=" + Binder.getCallingUid()
   11221                             + " requires " + r.permission);
   11222                 }
   11223                 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
   11224                 if (ib != null) {
   11225                     ret = ib.binder;
   11226                 }
   11227             }
   11228         }
   11229 
   11230         return ret;
   11231     }
   11232 
   11233     public boolean stopServiceToken(ComponentName className, IBinder token,
   11234             int startId) {
   11235         synchronized(this) {
   11236             if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
   11237                     + " " + token + " startId=" + startId);
   11238             ServiceRecord r = findServiceLocked(className, token);
   11239             if (r != null) {
   11240                 if (startId >= 0) {
   11241                     // Asked to only stop if done with all work.  Note that
   11242                     // to avoid leaks, we will take this as dropping all
   11243                     // start items up to and including this one.
   11244                     ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
   11245                     if (si != null) {
   11246                         while (r.deliveredStarts.size() > 0) {
   11247                             ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
   11248                             cur.removeUriPermissionsLocked();
   11249                             if (cur == si) {
   11250                                 break;
   11251                             }
   11252                         }
   11253                     }
   11254 
   11255                     if (r.getLastStartId() != startId) {
   11256                         return false;
   11257                     }
   11258 
   11259                     if (r.deliveredStarts.size() > 0) {
   11260                         Slog.w(TAG, "stopServiceToken startId " + startId
   11261                                 + " is last, but have " + r.deliveredStarts.size()
   11262                                 + " remaining args");
   11263                     }
   11264                 }
   11265 
   11266                 synchronized (r.stats.getBatteryStats()) {
   11267                     r.stats.stopRunningLocked();
   11268                     r.startRequested = false;
   11269                     r.callStart = false;
   11270                 }
   11271                 final long origId = Binder.clearCallingIdentity();
   11272                 bringDownServiceLocked(r, false);
   11273                 Binder.restoreCallingIdentity(origId);
   11274                 return true;
   11275             }
   11276         }
   11277         return false;
   11278     }
   11279 
   11280     public void setServiceForeground(ComponentName className, IBinder token,
   11281             int id, Notification notification, boolean removeNotification) {
   11282         final long origId = Binder.clearCallingIdentity();
   11283         try {
   11284         synchronized(this) {
   11285             ServiceRecord r = findServiceLocked(className, token);
   11286             if (r != null) {
   11287                 if (id != 0) {
   11288                     if (notification == null) {
   11289                         throw new IllegalArgumentException("null notification");
   11290                     }
   11291                     if (r.foregroundId != id) {
   11292                         r.cancelNotification();
   11293                         r.foregroundId = id;
   11294                     }
   11295                     notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
   11296                     r.foregroundNoti = notification;
   11297                     r.isForeground = true;
   11298                     r.postNotification();
   11299                     if (r.app != null) {
   11300                         updateServiceForegroundLocked(r.app, true);
   11301                     }
   11302                 } else {
   11303                     if (r.isForeground) {
   11304                         r.isForeground = false;
   11305                         if (r.app != null) {
   11306                             updateLruProcessLocked(r.app, false, true);
   11307                             updateServiceForegroundLocked(r.app, true);
   11308                         }
   11309                     }
   11310                     if (removeNotification) {
   11311                         r.cancelNotification();
   11312                         r.foregroundId = 0;
   11313                         r.foregroundNoti = null;
   11314                     }
   11315                 }
   11316             }
   11317         }
   11318         } finally {
   11319             Binder.restoreCallingIdentity(origId);
   11320         }
   11321     }
   11322 
   11323     public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
   11324         boolean anyForeground = false;
   11325         for (ServiceRecord sr : proc.services) {
   11326             if (sr.isForeground) {
   11327                 anyForeground = true;
   11328                 break;
   11329             }
   11330         }
   11331         if (anyForeground != proc.foregroundServices) {
   11332             proc.foregroundServices = anyForeground;
   11333             if (oomAdj) {
   11334                 updateOomAdjLocked();
   11335             }
   11336         }
   11337     }
   11338 
   11339     public int bindService(IApplicationThread caller, IBinder token,
   11340             Intent service, String resolvedType,
   11341             IServiceConnection connection, int flags) {
   11342         // Refuse possible leaked file descriptors
   11343         if (service != null && service.hasFileDescriptors() == true) {
   11344             throw new IllegalArgumentException("File descriptors passed in Intent");
   11345         }
   11346 
   11347         synchronized(this) {
   11348             if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
   11349                     + " type=" + resolvedType + " conn=" + connection.asBinder()
   11350                     + " flags=0x" + Integer.toHexString(flags));
   11351             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   11352             if (callerApp == null) {
   11353                 throw new SecurityException(
   11354                         "Unable to find app for caller " + caller
   11355                         + " (pid=" + Binder.getCallingPid()
   11356                         + ") when binding service " + service);
   11357             }
   11358 
   11359             ActivityRecord activity = null;
   11360             if (token != null) {
   11361                 activity = mMainStack.isInStackLocked(token);
   11362                 if (activity == null) {
   11363                     Slog.w(TAG, "Binding with unknown activity: " + token);
   11364                     return 0;
   11365                 }
   11366             }
   11367 
   11368             int clientLabel = 0;
   11369             PendingIntent clientIntent = null;
   11370 
   11371             if (callerApp.info.uid == Process.SYSTEM_UID) {
   11372                 // Hacky kind of thing -- allow system stuff to tell us
   11373                 // what they are, so we can report this elsewhere for
   11374                 // others to know why certain services are running.
   11375                 try {
   11376                     clientIntent = (PendingIntent)service.getParcelableExtra(
   11377                             Intent.EXTRA_CLIENT_INTENT);
   11378                 } catch (RuntimeException e) {
   11379                 }
   11380                 if (clientIntent != null) {
   11381                     clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
   11382                     if (clientLabel != 0) {
   11383                         // There are no useful extras in the intent, trash them.
   11384                         // System code calling with this stuff just needs to know
   11385                         // this will happen.
   11386                         service = service.cloneFilter();
   11387                     }
   11388                 }
   11389             }
   11390 
   11391             ServiceLookupResult res =
   11392                 retrieveServiceLocked(service, resolvedType,
   11393                         Binder.getCallingPid(), Binder.getCallingUid());
   11394             if (res == null) {
   11395                 return 0;
   11396             }
   11397             if (res.record == null) {
   11398                 return -1;
   11399             }
   11400             ServiceRecord s = res.record;
   11401 
   11402             final long origId = Binder.clearCallingIdentity();
   11403 
   11404             if (unscheduleServiceRestartLocked(s)) {
   11405                 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
   11406                         + s);
   11407             }
   11408 
   11409             AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
   11410             ConnectionRecord c = new ConnectionRecord(b, activity,
   11411                     connection, flags, clientLabel, clientIntent);
   11412 
   11413             IBinder binder = connection.asBinder();
   11414             ArrayList<ConnectionRecord> clist = s.connections.get(binder);
   11415             if (clist == null) {
   11416                 clist = new ArrayList<ConnectionRecord>();
   11417                 s.connections.put(binder, clist);
   11418             }
   11419             clist.add(c);
   11420             b.connections.add(c);
   11421             if (activity != null) {
   11422                 if (activity.connections == null) {
   11423                     activity.connections = new HashSet<ConnectionRecord>();
   11424                 }
   11425                 activity.connections.add(c);
   11426             }
   11427             b.client.connections.add(c);
   11428             if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
   11429                 b.client.hasAboveClient = true;
   11430             }
   11431             clist = mServiceConnections.get(binder);
   11432             if (clist == null) {
   11433                 clist = new ArrayList<ConnectionRecord>();
   11434                 mServiceConnections.put(binder, clist);
   11435             }
   11436             clist.add(c);
   11437 
   11438             if ((flags&Context.BIND_AUTO_CREATE) != 0) {
   11439                 s.lastActivity = SystemClock.uptimeMillis();
   11440                 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
   11441                     return 0;
   11442                 }
   11443             }
   11444 
   11445             if (s.app != null) {
   11446                 // This could have made the service more important.
   11447                 updateOomAdjLocked(s.app);
   11448             }
   11449 
   11450             if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
   11451                     + ": received=" + b.intent.received
   11452                     + " apps=" + b.intent.apps.size()
   11453                     + " doRebind=" + b.intent.doRebind);
   11454 
   11455             if (s.app != null && b.intent.received) {
   11456                 // Service is already running, so we can immediately
   11457                 // publish the connection.
   11458                 try {
   11459                     c.conn.connected(s.name, b.intent.binder);
   11460                 } catch (Exception e) {
   11461                     Slog.w(TAG, "Failure sending service " + s.shortName
   11462                             + " to connection " + c.conn.asBinder()
   11463                             + " (in " + c.binding.client.processName + ")", e);
   11464                 }
   11465 
   11466                 // If this is the first app connected back to this binding,
   11467                 // and the service had previously asked to be told when
   11468                 // rebound, then do so.
   11469                 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
   11470                     requestServiceBindingLocked(s, b.intent, true);
   11471                 }
   11472             } else if (!b.intent.requested) {
   11473                 requestServiceBindingLocked(s, b.intent, false);
   11474             }
   11475 
   11476             Binder.restoreCallingIdentity(origId);
   11477         }
   11478 
   11479         return 1;
   11480     }
   11481 
   11482     void removeConnectionLocked(
   11483         ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
   11484         IBinder binder = c.conn.asBinder();
   11485         AppBindRecord b = c.binding;
   11486         ServiceRecord s = b.service;
   11487         ArrayList<ConnectionRecord> clist = s.connections.get(binder);
   11488         if (clist != null) {
   11489             clist.remove(c);
   11490             if (clist.size() == 0) {
   11491                 s.connections.remove(binder);
   11492             }
   11493         }
   11494         b.connections.remove(c);
   11495         if (c.activity != null && c.activity != skipAct) {
   11496             if (c.activity.connections != null) {
   11497                 c.activity.connections.remove(c);
   11498             }
   11499         }
   11500         if (b.client != skipApp) {
   11501             b.client.connections.remove(c);
   11502             if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
   11503                 b.client.updateHasAboveClientLocked();
   11504             }
   11505         }
   11506         clist = mServiceConnections.get(binder);
   11507         if (clist != null) {
   11508             clist.remove(c);
   11509             if (clist.size() == 0) {
   11510                 mServiceConnections.remove(binder);
   11511             }
   11512         }
   11513 
   11514         if (b.connections.size() == 0) {
   11515             b.intent.apps.remove(b.client);
   11516         }
   11517 
   11518         if (!c.serviceDead) {
   11519             if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
   11520                     + ": shouldUnbind=" + b.intent.hasBound);
   11521             if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
   11522                     && b.intent.hasBound) {
   11523                 try {
   11524                     bumpServiceExecutingLocked(s, "unbind");
   11525                     updateOomAdjLocked(s.app);
   11526                     b.intent.hasBound = false;
   11527                     // Assume the client doesn't want to know about a rebind;
   11528                     // we will deal with that later if it asks for one.
   11529                     b.intent.doRebind = false;
   11530                     s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
   11531                 } catch (Exception e) {
   11532                     Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
   11533                     serviceDoneExecutingLocked(s, true);
   11534                 }
   11535             }
   11536 
   11537             if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
   11538                 bringDownServiceLocked(s, false);
   11539             }
   11540         }
   11541     }
   11542 
   11543     public boolean unbindService(IServiceConnection connection) {
   11544         synchronized (this) {
   11545             IBinder binder = connection.asBinder();
   11546             if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
   11547             ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
   11548             if (clist == null) {
   11549                 Slog.w(TAG, "Unbind failed: could not find connection for "
   11550                       + connection.asBinder());
   11551                 return false;
   11552             }
   11553 
   11554             final long origId = Binder.clearCallingIdentity();
   11555 
   11556             while (clist.size() > 0) {
   11557                 ConnectionRecord r = clist.get(0);
   11558                 removeConnectionLocked(r, null, null);
   11559 
   11560                 if (r.binding.service.app != null) {
   11561                     // This could have made the service less important.
   11562                     updateOomAdjLocked(r.binding.service.app);
   11563                 }
   11564             }
   11565 
   11566             Binder.restoreCallingIdentity(origId);
   11567         }
   11568 
   11569         return true;
   11570     }
   11571 
   11572     public void publishService(IBinder token, Intent intent, IBinder service) {
   11573         // Refuse possible leaked file descriptors
   11574         if (intent != null && intent.hasFileDescriptors() == true) {
   11575             throw new IllegalArgumentException("File descriptors passed in Intent");
   11576         }
   11577 
   11578         synchronized(this) {
   11579             if (!(token instanceof ServiceRecord)) {
   11580                 throw new IllegalArgumentException("Invalid service token");
   11581             }
   11582             ServiceRecord r = (ServiceRecord)token;
   11583 
   11584             final long origId = Binder.clearCallingIdentity();
   11585 
   11586             if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
   11587                     + " " + intent + ": " + service);
   11588             if (r != null) {
   11589                 Intent.FilterComparison filter
   11590                         = new Intent.FilterComparison(intent);
   11591                 IntentBindRecord b = r.bindings.get(filter);
   11592                 if (b != null && !b.received) {
   11593                     b.binder = service;
   11594                     b.requested = true;
   11595                     b.received = true;
   11596                     if (r.connections.size() > 0) {
   11597                         Iterator<ArrayList<ConnectionRecord>> it
   11598                                 = r.connections.values().iterator();
   11599                         while (it.hasNext()) {
   11600                             ArrayList<ConnectionRecord> clist = it.next();
   11601                             for (int i=0; i<clist.size(); i++) {
   11602                                 ConnectionRecord c = clist.get(i);
   11603                                 if (!filter.equals(c.binding.intent.intent)) {
   11604                                     if (DEBUG_SERVICE) Slog.v(
   11605                                             TAG, "Not publishing to: " + c);
   11606                                     if (DEBUG_SERVICE) Slog.v(
   11607                                             TAG, "Bound intent: " + c.binding.intent.intent);
   11608                                     if (DEBUG_SERVICE) Slog.v(
   11609                                             TAG, "Published intent: " + intent);
   11610                                     continue;
   11611                                 }
   11612                                 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
   11613                                 try {
   11614                                     c.conn.connected(r.name, service);
   11615                                 } catch (Exception e) {
   11616                                     Slog.w(TAG, "Failure sending service " + r.name +
   11617                                           " to connection " + c.conn.asBinder() +
   11618                                           " (in " + c.binding.client.processName + ")", e);
   11619                                 }
   11620                             }
   11621                         }
   11622                     }
   11623                 }
   11624 
   11625                 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
   11626 
   11627                 Binder.restoreCallingIdentity(origId);
   11628             }
   11629         }
   11630     }
   11631 
   11632     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
   11633         // Refuse possible leaked file descriptors
   11634         if (intent != null && intent.hasFileDescriptors() == true) {
   11635             throw new IllegalArgumentException("File descriptors passed in Intent");
   11636         }
   11637 
   11638         synchronized(this) {
   11639             if (!(token instanceof ServiceRecord)) {
   11640                 throw new IllegalArgumentException("Invalid service token");
   11641             }
   11642             ServiceRecord r = (ServiceRecord)token;
   11643 
   11644             final long origId = Binder.clearCallingIdentity();
   11645 
   11646             if (r != null) {
   11647                 Intent.FilterComparison filter
   11648                         = new Intent.FilterComparison(intent);
   11649                 IntentBindRecord b = r.bindings.get(filter);
   11650                 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
   11651                         + " at " + b + ": apps="
   11652                         + (b != null ? b.apps.size() : 0));
   11653 
   11654                 boolean inStopping = mStoppingServices.contains(r);
   11655                 if (b != null) {
   11656                     if (b.apps.size() > 0 && !inStopping) {
   11657                         // Applications have already bound since the last
   11658                         // unbind, so just rebind right here.
   11659                         requestServiceBindingLocked(r, b, true);
   11660                     } else {
   11661                         // Note to tell the service the next time there is
   11662                         // a new client.
   11663                         b.doRebind = true;
   11664                     }
   11665                 }
   11666 
   11667                 serviceDoneExecutingLocked(r, inStopping);
   11668 
   11669                 Binder.restoreCallingIdentity(origId);
   11670             }
   11671         }
   11672     }
   11673 
   11674     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
   11675         synchronized(this) {
   11676             if (!(token instanceof ServiceRecord)) {
   11677                 throw new IllegalArgumentException("Invalid service token");
   11678             }
   11679             ServiceRecord r = (ServiceRecord)token;
   11680             boolean inStopping = mStoppingServices.contains(token);
   11681             if (r != null) {
   11682                 if (r != token) {
   11683                     Slog.w(TAG, "Done executing service " + r.name
   11684                           + " with incorrect token: given " + token
   11685                           + ", expected " + r);
   11686                     return;
   11687                 }
   11688 
   11689                 if (type == 1) {
   11690                     // This is a call from a service start...  take care of
   11691                     // book-keeping.
   11692                     r.callStart = true;
   11693                     switch (res) {
   11694                         case Service.START_STICKY_COMPATIBILITY:
   11695                         case Service.START_STICKY: {
   11696                             // We are done with the associated start arguments.
   11697                             r.findDeliveredStart(startId, true);
   11698                             // Don't stop if killed.
   11699                             r.stopIfKilled = false;
   11700                             break;
   11701                         }
   11702                         case Service.START_NOT_STICKY: {
   11703                             // We are done with the associated start arguments.
   11704                             r.findDeliveredStart(startId, true);
   11705                             if (r.getLastStartId() == startId) {
   11706                                 // There is no more work, and this service
   11707                                 // doesn't want to hang around if killed.
   11708                                 r.stopIfKilled = true;
   11709                             }
   11710                             break;
   11711                         }
   11712                         case Service.START_REDELIVER_INTENT: {
   11713                             // We'll keep this item until they explicitly
   11714                             // call stop for it, but keep track of the fact
   11715                             // that it was delivered.
   11716                             ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
   11717                             if (si != null) {
   11718                                 si.deliveryCount = 0;
   11719                                 si.doneExecutingCount++;
   11720                                 // Don't stop if killed.
   11721                                 r.stopIfKilled = true;
   11722                             }
   11723                             break;
   11724                         }
   11725                         case Service.START_TASK_REMOVED_COMPLETE: {
   11726                             // Special processing for onTaskRemoved().  Don't
   11727                             // impact normal onStartCommand() processing.
   11728                             r.findDeliveredStart(startId, true);
   11729                             break;
   11730                         }
   11731                         default:
   11732                             throw new IllegalArgumentException(
   11733                                     "Unknown service start result: " + res);
   11734                     }
   11735                     if (res == Service.START_STICKY_COMPATIBILITY) {
   11736                         r.callStart = false;
   11737                     }
   11738                 }
   11739 
   11740                 final long origId = Binder.clearCallingIdentity();
   11741                 serviceDoneExecutingLocked(r, inStopping);
   11742                 Binder.restoreCallingIdentity(origId);
   11743             } else {
   11744                 Slog.w(TAG, "Done executing unknown service from pid "
   11745                         + Binder.getCallingPid());
   11746             }
   11747         }
   11748     }
   11749 
   11750     public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
   11751         if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
   11752                 + ": nesting=" + r.executeNesting
   11753                 + ", inStopping=" + inStopping + ", app=" + r.app);
   11754         else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
   11755         r.executeNesting--;
   11756         if (r.executeNesting <= 0 && r.app != null) {
   11757             if (DEBUG_SERVICE) Slog.v(TAG,
   11758                     "Nesting at 0 of " + r.shortName);
   11759             r.app.executingServices.remove(r);
   11760             if (r.app.executingServices.size() == 0) {
   11761                 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
   11762                         "No more executingServices of " + r.shortName);
   11763                 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
   11764             }
   11765             if (inStopping) {
   11766                 if (DEBUG_SERVICE) Slog.v(TAG,
   11767                         "doneExecuting remove stopping " + r);
   11768                 mStoppingServices.remove(r);
   11769                 r.bindings.clear();
   11770             }
   11771             updateOomAdjLocked(r.app);
   11772         }
   11773     }
   11774 
   11775     void serviceTimeout(ProcessRecord proc) {
   11776         String anrMessage = null;
   11777 
   11778         synchronized(this) {
   11779             if (proc.executingServices.size() == 0 || proc.thread == null) {
   11780                 return;
   11781             }
   11782             long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
   11783             Iterator<ServiceRecord> it = proc.executingServices.iterator();
   11784             ServiceRecord timeout = null;
   11785             long nextTime = 0;
   11786             while (it.hasNext()) {
   11787                 ServiceRecord sr = it.next();
   11788                 if (sr.executingStart < maxTime) {
   11789                     timeout = sr;
   11790                     break;
   11791                 }
   11792                 if (sr.executingStart > nextTime) {
   11793                     nextTime = sr.executingStart;
   11794                 }
   11795             }
   11796             if (timeout != null && mLruProcesses.contains(proc)) {
   11797                 Slog.w(TAG, "Timeout executing service: " + timeout);
   11798                 anrMessage = "Executing service " + timeout.shortName;
   11799             } else {
   11800                 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   11801                 msg.obj = proc;
   11802                 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
   11803             }
   11804         }
   11805 
   11806         if (anrMessage != null) {
   11807             appNotResponding(proc, null, null, anrMessage);
   11808         }
   11809     }
   11810 
   11811     // =========================================================
   11812     // BACKUP AND RESTORE
   11813     // =========================================================
   11814 
   11815     // Cause the target app to be launched if necessary and its backup agent
   11816     // instantiated.  The backup agent will invoke backupAgentCreated() on the
   11817     // activity manager to announce its creation.
   11818     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
   11819         if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
   11820         enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
   11821 
   11822         synchronized(this) {
   11823             // !!! TODO: currently no check here that we're already bound
   11824             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   11825             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   11826             synchronized (stats) {
   11827                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
   11828             }
   11829 
   11830             // Backup agent is now in use, its package can't be stopped.
   11831             try {
   11832                 AppGlobals.getPackageManager().setPackageStoppedState(
   11833                         app.packageName, false);
   11834             } catch (RemoteException e) {
   11835             } catch (IllegalArgumentException e) {
   11836                 Slog.w(TAG, "Failed trying to unstop package "
   11837                         + app.packageName + ": " + e);
   11838             }
   11839 
   11840             BackupRecord r = new BackupRecord(ss, app, backupMode);
   11841             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
   11842                     ? new ComponentName(app.packageName, app.backupAgentName)
   11843                     : new ComponentName("android", "FullBackupAgent");
   11844             // startProcessLocked() returns existing proc's record if it's already running
   11845             ProcessRecord proc = startProcessLocked(app.processName, app,
   11846                     false, 0, "backup", hostingName, false);
   11847             if (proc == null) {
   11848                 Slog.e(TAG, "Unable to start backup agent process " + r);
   11849                 return false;
   11850             }
   11851 
   11852             r.app = proc;
   11853             mBackupTarget = r;
   11854             mBackupAppName = app.packageName;
   11855 
   11856             // Try not to kill the process during backup
   11857             updateOomAdjLocked(proc);
   11858 
   11859             // If the process is already attached, schedule the creation of the backup agent now.
   11860             // If it is not yet live, this will be done when it attaches to the framework.
   11861             if (proc.thread != null) {
   11862                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
   11863                 try {
   11864                     proc.thread.scheduleCreateBackupAgent(app,
   11865                             compatibilityInfoForPackageLocked(app), backupMode);
   11866                 } catch (RemoteException e) {
   11867                     // Will time out on the backup manager side
   11868                 }
   11869             } else {
   11870                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
   11871             }
   11872             // Invariants: at this point, the target app process exists and the application
   11873             // is either already running or in the process of coming up.  mBackupTarget and
   11874             // mBackupAppName describe the app, so that when it binds back to the AM we
   11875             // know that it's scheduled for a backup-agent operation.
   11876         }
   11877 
   11878         return true;
   11879     }
   11880 
   11881     // A backup agent has just come up
   11882     public void backupAgentCreated(String agentPackageName, IBinder agent) {
   11883         if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
   11884                 + " = " + agent);
   11885 
   11886         synchronized(this) {
   11887             if (!agentPackageName.equals(mBackupAppName)) {
   11888                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
   11889                 return;
   11890             }
   11891         }
   11892 
   11893         long oldIdent = Binder.clearCallingIdentity();
   11894         try {
   11895             IBackupManager bm = IBackupManager.Stub.asInterface(
   11896                     ServiceManager.getService(Context.BACKUP_SERVICE));
   11897             bm.agentConnected(agentPackageName, agent);
   11898         } catch (RemoteException e) {
   11899             // can't happen; the backup manager service is local
   11900         } catch (Exception e) {
   11901             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
   11902             e.printStackTrace();
   11903         } finally {
   11904             Binder.restoreCallingIdentity(oldIdent);
   11905         }
   11906     }
   11907 
   11908     // done with this agent
   11909     public void unbindBackupAgent(ApplicationInfo appInfo) {
   11910         if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
   11911         if (appInfo == null) {
   11912             Slog.w(TAG, "unbind backup agent for null app");
   11913             return;
   11914         }
   11915 
   11916         synchronized(this) {
   11917             if (mBackupAppName == null) {
   11918                 Slog.w(TAG, "Unbinding backup agent with no active backup");
   11919                 return;
   11920             }
   11921 
   11922             if (!mBackupAppName.equals(appInfo.packageName)) {
   11923                 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
   11924                 return;
   11925             }
   11926 
   11927             ProcessRecord proc = mBackupTarget.app;
   11928             mBackupTarget = null;
   11929             mBackupAppName = null;
   11930 
   11931             // Not backing this app up any more; reset its OOM adjustment
   11932             updateOomAdjLocked(proc);
   11933 
   11934             // If the app crashed during backup, 'thread' will be null here
   11935             if (proc.thread != null) {
   11936                 try {
   11937                     proc.thread.scheduleDestroyBackupAgent(appInfo,
   11938                             compatibilityInfoForPackageLocked(appInfo));
   11939                 } catch (Exception e) {
   11940                     Slog.e(TAG, "Exception when unbinding backup agent:");
   11941                     e.printStackTrace();
   11942                 }
   11943             }
   11944         }
   11945     }
   11946     // =========================================================
   11947     // BROADCASTS
   11948     // =========================================================
   11949 
   11950     private final List getStickiesLocked(String action, IntentFilter filter,
   11951             List cur) {
   11952         final ContentResolver resolver = mContext.getContentResolver();
   11953         final ArrayList<Intent> list = mStickyBroadcasts.get(action);
   11954         if (list == null) {
   11955             return cur;
   11956         }
   11957         int N = list.size();
   11958         for (int i=0; i<N; i++) {
   11959             Intent intent = list.get(i);
   11960             if (filter.match(resolver, intent, true, TAG) >= 0) {
   11961                 if (cur == null) {
   11962                     cur = new ArrayList<Intent>();
   11963                 }
   11964                 cur.add(intent);
   11965             }
   11966         }
   11967         return cur;
   11968     }
   11969 
   11970     private final void scheduleBroadcastsLocked() {
   11971         if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
   11972                 + mBroadcastsScheduled);
   11973 
   11974         if (mBroadcastsScheduled) {
   11975             return;
   11976         }
   11977         mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
   11978         mBroadcastsScheduled = true;
   11979     }
   11980 
   11981     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
   11982             IIntentReceiver receiver, IntentFilter filter, String permission) {
   11983         synchronized(this) {
   11984             ProcessRecord callerApp = null;
   11985             if (caller != null) {
   11986                 callerApp = getRecordForAppLocked(caller);
   11987                 if (callerApp == null) {
   11988                     throw new SecurityException(
   11989                             "Unable to find app for caller " + caller
   11990                             + " (pid=" + Binder.getCallingPid()
   11991                             + ") when registering receiver " + receiver);
   11992                 }
   11993                 if (callerApp.info.uid != Process.SYSTEM_UID &&
   11994                         !callerApp.pkgList.contains(callerPackage)) {
   11995                     throw new SecurityException("Given caller package " + callerPackage
   11996                             + " is not running in process " + callerApp);
   11997                 }
   11998             } else {
   11999                 callerPackage = null;
   12000             }
   12001 
   12002             List allSticky = null;
   12003 
   12004             // Look for any matching sticky broadcasts...
   12005             Iterator actions = filter.actionsIterator();
   12006             if (actions != null) {
   12007                 while (actions.hasNext()) {
   12008                     String action = (String)actions.next();
   12009                     allSticky = getStickiesLocked(action, filter, allSticky);
   12010                 }
   12011             } else {
   12012                 allSticky = getStickiesLocked(null, filter, allSticky);
   12013             }
   12014 
   12015             // The first sticky in the list is returned directly back to
   12016             // the client.
   12017             Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
   12018 
   12019             if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
   12020                     + ": " + sticky);
   12021 
   12022             if (receiver == null) {
   12023                 return sticky;
   12024             }
   12025 
   12026             ReceiverList rl
   12027                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   12028             if (rl == null) {
   12029                 rl = new ReceiverList(this, callerApp,
   12030                         Binder.getCallingPid(),
   12031                         Binder.getCallingUid(), receiver);
   12032                 if (rl.app != null) {
   12033                     rl.app.receivers.add(rl);
   12034                 } else {
   12035                     try {
   12036                         receiver.asBinder().linkToDeath(rl, 0);
   12037                     } catch (RemoteException e) {
   12038                         return sticky;
   12039                     }
   12040                     rl.linkedToDeath = true;
   12041                 }
   12042                 mRegisteredReceivers.put(receiver.asBinder(), rl);
   12043             }
   12044             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
   12045             rl.add(bf);
   12046             if (!bf.debugCheck()) {
   12047                 Slog.w(TAG, "==> For Dynamic broadast");
   12048             }
   12049             mReceiverResolver.addFilter(bf);
   12050 
   12051             // Enqueue broadcasts for all existing stickies that match
   12052             // this filter.
   12053             if (allSticky != null) {
   12054                 ArrayList receivers = new ArrayList();
   12055                 receivers.add(bf);
   12056 
   12057                 int N = allSticky.size();
   12058                 for (int i=0; i<N; i++) {
   12059                     Intent intent = (Intent)allSticky.get(i);
   12060                     BroadcastRecord r = new BroadcastRecord(intent, null,
   12061                             null, -1, -1, null, receivers, null, 0, null, null,
   12062                             false, true, true);
   12063                     if (mParallelBroadcasts.size() == 0) {
   12064                         scheduleBroadcastsLocked();
   12065                     }
   12066                     mParallelBroadcasts.add(r);
   12067                 }
   12068             }
   12069 
   12070             return sticky;
   12071         }
   12072     }
   12073 
   12074     public void unregisterReceiver(IIntentReceiver receiver) {
   12075         if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
   12076 
   12077         boolean doNext = false;
   12078 
   12079         synchronized(this) {
   12080             ReceiverList rl
   12081                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   12082             if (rl != null) {
   12083                 if (rl.curBroadcast != null) {
   12084                     BroadcastRecord r = rl.curBroadcast;
   12085                     doNext = finishReceiverLocked(
   12086                         receiver.asBinder(), r.resultCode, r.resultData,
   12087                         r.resultExtras, r.resultAbort, true);
   12088                 }
   12089 
   12090                 if (rl.app != null) {
   12091                     rl.app.receivers.remove(rl);
   12092                 }
   12093                 removeReceiverLocked(rl);
   12094                 if (rl.linkedToDeath) {
   12095                     rl.linkedToDeath = false;
   12096                     rl.receiver.asBinder().unlinkToDeath(rl, 0);
   12097                 }
   12098             }
   12099         }
   12100 
   12101         if (!doNext) {
   12102             return;
   12103         }
   12104 
   12105         final long origId = Binder.clearCallingIdentity();
   12106         processNextBroadcast(false);
   12107         trimApplications();
   12108         Binder.restoreCallingIdentity(origId);
   12109     }
   12110 
   12111     void removeReceiverLocked(ReceiverList rl) {
   12112         mRegisteredReceivers.remove(rl.receiver.asBinder());
   12113         int N = rl.size();
   12114         for (int i=0; i<N; i++) {
   12115             mReceiverResolver.removeFilter(rl.get(i));
   12116         }
   12117     }
   12118 
   12119     private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
   12120         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   12121             ProcessRecord r = mLruProcesses.get(i);
   12122             if (r.thread != null) {
   12123                 try {
   12124                     r.thread.dispatchPackageBroadcast(cmd, packages);
   12125                 } catch (RemoteException ex) {
   12126                 }
   12127             }
   12128         }
   12129     }
   12130 
   12131     private final int broadcastIntentLocked(ProcessRecord callerApp,
   12132             String callerPackage, Intent intent, String resolvedType,
   12133             IIntentReceiver resultTo, int resultCode, String resultData,
   12134             Bundle map, String requiredPermission,
   12135             boolean ordered, boolean sticky, int callingPid, int callingUid) {
   12136         intent = new Intent(intent);
   12137 
   12138         // By default broadcasts do not go to stopped apps.
   12139         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
   12140 
   12141         if (DEBUG_BROADCAST_LIGHT) Slog.v(
   12142             TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
   12143             + " ordered=" + ordered);
   12144         if ((resultTo != null) && !ordered) {
   12145             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
   12146         }
   12147 
   12148         // Handle special intents: if this broadcast is from the package
   12149         // manager about a package being removed, we need to remove all of
   12150         // its activities from the history stack.
   12151         final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
   12152                 intent.getAction());
   12153         if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
   12154                 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
   12155                 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
   12156                 || uidRemoved) {
   12157             if (checkComponentPermission(
   12158                     android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
   12159                     callingPid, callingUid, -1, true)
   12160                     == PackageManager.PERMISSION_GRANTED) {
   12161                 if (uidRemoved) {
   12162                     final Bundle intentExtras = intent.getExtras();
   12163                     final int uid = intentExtras != null
   12164                             ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
   12165                     if (uid >= 0) {
   12166                         BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
   12167                         synchronized (bs) {
   12168                             bs.removeUidStatsLocked(uid);
   12169                         }
   12170                     }
   12171                 } else {
   12172                     // If resources are unvailble just force stop all
   12173                     // those packages and flush the attribute cache as well.
   12174                     if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
   12175                         String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   12176                         if (list != null && (list.length > 0)) {
   12177                             for (String pkg : list) {
   12178                                 forceStopPackageLocked(pkg, -1, false, true, true, false);
   12179                             }
   12180                             sendPackageBroadcastLocked(
   12181                                     IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
   12182                         }
   12183                     } else {
   12184                         Uri data = intent.getData();
   12185                         String ssp;
   12186                         if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   12187                             if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
   12188                                 forceStopPackageLocked(ssp,
   12189                                         intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
   12190                             }
   12191                             if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
   12192                                 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
   12193                                         new String[] {ssp});
   12194                             }
   12195                         }
   12196                     }
   12197                 }
   12198             } else {
   12199                 String msg = "Permission Denial: " + intent.getAction()
   12200                         + " broadcast from " + callerPackage + " (pid=" + callingPid
   12201                         + ", uid=" + callingUid + ")"
   12202                         + " requires "
   12203                         + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
   12204                 Slog.w(TAG, msg);
   12205                 throw new SecurityException(msg);
   12206             }
   12207 
   12208         // Special case for adding a package: by default turn on compatibility
   12209         // mode.
   12210         } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
   12211             Uri data = intent.getData();
   12212             String ssp;
   12213             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   12214                 mCompatModePackages.handlePackageAddedLocked(ssp,
   12215                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
   12216             }
   12217         }
   12218 
   12219         /*
   12220          * If this is the time zone changed action, queue up a message that will reset the timezone
   12221          * of all currently running processes. This message will get queued up before the broadcast
   12222          * happens.
   12223          */
   12224         if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
   12225             mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
   12226         }
   12227 
   12228         if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
   12229             mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
   12230         }
   12231 
   12232         if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
   12233             ProxyProperties proxy = intent.getParcelableExtra("proxy");
   12234             mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
   12235         }
   12236 
   12237         /*
   12238          * Prevent non-system code (defined here to be non-persistent
   12239          * processes) from sending protected broadcasts.
   12240          */
   12241         if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
   12242                 || callingUid == Process.SHELL_UID || callingUid == 0) {
   12243             // Always okay.
   12244         } else if (callerApp == null || !callerApp.persistent) {
   12245             try {
   12246                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
   12247                         intent.getAction())) {
   12248                     String msg = "Permission Denial: not allowed to send broadcast "
   12249                             + intent.getAction() + " from pid="
   12250                             + callingPid + ", uid=" + callingUid;
   12251                     Slog.w(TAG, msg);
   12252                     throw new SecurityException(msg);
   12253                 }
   12254             } catch (RemoteException e) {
   12255                 Slog.w(TAG, "Remote exception", e);
   12256                 return BROADCAST_SUCCESS;
   12257             }
   12258         }
   12259 
   12260         // Add to the sticky list if requested.
   12261         if (sticky) {
   12262             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
   12263                     callingPid, callingUid)
   12264                     != PackageManager.PERMISSION_GRANTED) {
   12265                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
   12266                         + callingPid + ", uid=" + callingUid
   12267                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   12268                 Slog.w(TAG, msg);
   12269                 throw new SecurityException(msg);
   12270             }
   12271             if (requiredPermission != null) {
   12272                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
   12273                         + " and enforce permission " + requiredPermission);
   12274                 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
   12275             }
   12276             if (intent.getComponent() != null) {
   12277                 throw new SecurityException(
   12278                         "Sticky broadcasts can't target a specific component");
   12279             }
   12280             ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
   12281             if (list == null) {
   12282                 list = new ArrayList<Intent>();
   12283                 mStickyBroadcasts.put(intent.getAction(), list);
   12284             }
   12285             int N = list.size();
   12286             int i;
   12287             for (i=0; i<N; i++) {
   12288                 if (intent.filterEquals(list.get(i))) {
   12289                     // This sticky already exists, replace it.
   12290                     list.set(i, new Intent(intent));
   12291                     break;
   12292                 }
   12293             }
   12294             if (i >= N) {
   12295                 list.add(new Intent(intent));
   12296             }
   12297         }
   12298 
   12299         // Figure out who all will receive this broadcast.
   12300         List receivers = null;
   12301         List<BroadcastFilter> registeredReceivers = null;
   12302         try {
   12303             if (intent.getComponent() != null) {
   12304                 // Broadcast is going to one specific receiver class...
   12305                 ActivityInfo ai = AppGlobals.getPackageManager().
   12306                     getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
   12307                 if (ai != null) {
   12308                     receivers = new ArrayList();
   12309                     ResolveInfo ri = new ResolveInfo();
   12310                     ri.activityInfo = ai;
   12311                     receivers.add(ri);
   12312                 }
   12313             } else {
   12314                 // Need to resolve the intent to interested receivers...
   12315                 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
   12316                          == 0) {
   12317                     receivers =
   12318                         AppGlobals.getPackageManager().queryIntentReceivers(
   12319                                 intent, resolvedType, STOCK_PM_FLAGS);
   12320                 }
   12321                 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
   12322             }
   12323         } catch (RemoteException ex) {
   12324             // pm is in same process, this will never happen.
   12325         }
   12326 
   12327         final boolean replacePending =
   12328                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
   12329 
   12330         if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
   12331                 + " replacePending=" + replacePending);
   12332 
   12333         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
   12334         if (!ordered && NR > 0) {
   12335             // If we are not serializing this broadcast, then send the
   12336             // registered receivers separately so they don't wait for the
   12337             // components to be launched.
   12338             BroadcastRecord r = new BroadcastRecord(intent, callerApp,
   12339                     callerPackage, callingPid, callingUid, requiredPermission,
   12340                     registeredReceivers, resultTo, resultCode, resultData, map,
   12341                     ordered, sticky, false);
   12342             if (DEBUG_BROADCAST) Slog.v(
   12343                     TAG, "Enqueueing parallel broadcast " + r
   12344                     + ": prev had " + mParallelBroadcasts.size());
   12345             boolean replaced = false;
   12346             if (replacePending) {
   12347                 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
   12348                     if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
   12349                         if (DEBUG_BROADCAST) Slog.v(TAG,
   12350                                 "***** DROPPING PARALLEL: " + intent);
   12351                         mParallelBroadcasts.set(i, r);
   12352                         replaced = true;
   12353                         break;
   12354                     }
   12355                 }
   12356             }
   12357             if (!replaced) {
   12358                 mParallelBroadcasts.add(r);
   12359                 scheduleBroadcastsLocked();
   12360             }
   12361             registeredReceivers = null;
   12362             NR = 0;
   12363         }
   12364 
   12365         // Merge into one list.
   12366         int ir = 0;
   12367         if (receivers != null) {
   12368             // A special case for PACKAGE_ADDED: do not allow the package
   12369             // being added to see this broadcast.  This prevents them from
   12370             // using this as a back door to get run as soon as they are
   12371             // installed.  Maybe in the future we want to have a special install
   12372             // broadcast or such for apps, but we'd like to deliberately make
   12373             // this decision.
   12374             String skipPackages[] = null;
   12375             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
   12376                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
   12377                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
   12378                 Uri data = intent.getData();
   12379                 if (data != null) {
   12380                     String pkgName = data.getSchemeSpecificPart();
   12381                     if (pkgName != null) {
   12382                         skipPackages = new String[] { pkgName };
   12383                     }
   12384                 }
   12385             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
   12386                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   12387             }
   12388             if (skipPackages != null && (skipPackages.length > 0)) {
   12389                 for (String skipPackage : skipPackages) {
   12390                     if (skipPackage != null) {
   12391                         int NT = receivers.size();
   12392                         for (int it=0; it<NT; it++) {
   12393                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
   12394                             if (curt.activityInfo.packageName.equals(skipPackage)) {
   12395                                 receivers.remove(it);
   12396                                 it--;
   12397                                 NT--;
   12398                             }
   12399                         }
   12400                     }
   12401                 }
   12402             }
   12403 
   12404             int NT = receivers != null ? receivers.size() : 0;
   12405             int it = 0;
   12406             ResolveInfo curt = null;
   12407             BroadcastFilter curr = null;
   12408             while (it < NT && ir < NR) {
   12409                 if (curt == null) {
   12410                     curt = (ResolveInfo)receivers.get(it);
   12411                 }
   12412                 if (curr == null) {
   12413                     curr = registeredReceivers.get(ir);
   12414                 }
   12415                 if (curr.getPriority() >= curt.priority) {
   12416                     // Insert this broadcast record into the final list.
   12417                     receivers.add(it, curr);
   12418                     ir++;
   12419                     curr = null;
   12420                     it++;
   12421                     NT++;
   12422                 } else {
   12423                     // Skip to the next ResolveInfo in the final list.
   12424                     it++;
   12425                     curt = null;
   12426                 }
   12427             }
   12428         }
   12429         while (ir < NR) {
   12430             if (receivers == null) {
   12431                 receivers = new ArrayList();
   12432             }
   12433             receivers.add(registeredReceivers.get(ir));
   12434             ir++;
   12435         }
   12436 
   12437         if ((receivers != null && receivers.size() > 0)
   12438                 || resultTo != null) {
   12439             BroadcastRecord r = new BroadcastRecord(intent, callerApp,
   12440                     callerPackage, callingPid, callingUid, requiredPermission,
   12441                     receivers, resultTo, resultCode, resultData, map, ordered,
   12442                     sticky, false);
   12443             if (DEBUG_BROADCAST) Slog.v(
   12444                     TAG, "Enqueueing ordered broadcast " + r
   12445                     + ": prev had " + mOrderedBroadcasts.size());
   12446             if (DEBUG_BROADCAST) {
   12447                 int seq = r.intent.getIntExtra("seq", -1);
   12448                 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
   12449             }
   12450             boolean replaced = false;
   12451             if (replacePending) {
   12452                 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
   12453                     if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
   12454                         if (DEBUG_BROADCAST) Slog.v(TAG,
   12455                                 "***** DROPPING ORDERED: " + intent);
   12456                         mOrderedBroadcasts.set(i, r);
   12457                         replaced = true;
   12458                         break;
   12459                     }
   12460                 }
   12461             }
   12462             if (!replaced) {
   12463                 mOrderedBroadcasts.add(r);
   12464                 scheduleBroadcastsLocked();
   12465             }
   12466         }
   12467 
   12468         return BROADCAST_SUCCESS;
   12469     }
   12470 
   12471     final Intent verifyBroadcastLocked(Intent intent) {
   12472         // Refuse possible leaked file descriptors
   12473         if (intent != null && intent.hasFileDescriptors() == true) {
   12474             throw new IllegalArgumentException("File descriptors passed in Intent");
   12475         }
   12476 
   12477         int flags = intent.getFlags();
   12478 
   12479         if (!mProcessesReady) {
   12480             // if the caller really truly claims to know what they're doing, go
   12481             // ahead and allow the broadcast without launching any receivers
   12482             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
   12483                 intent = new Intent(intent);
   12484                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   12485             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
   12486                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
   12487                         + " before boot completion");
   12488                 throw new IllegalStateException("Cannot broadcast before boot completed");
   12489             }
   12490         }
   12491 
   12492         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   12493             throw new IllegalArgumentException(
   12494                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   12495         }
   12496 
   12497         return intent;
   12498     }
   12499 
   12500     public final int broadcastIntent(IApplicationThread caller,
   12501             Intent intent, String resolvedType, IIntentReceiver resultTo,
   12502             int resultCode, String resultData, Bundle map,
   12503             String requiredPermission, boolean serialized, boolean sticky) {
   12504         synchronized(this) {
   12505             intent = verifyBroadcastLocked(intent);
   12506 
   12507             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   12508             final int callingPid = Binder.getCallingPid();
   12509             final int callingUid = Binder.getCallingUid();
   12510             final long origId = Binder.clearCallingIdentity();
   12511             int res = broadcastIntentLocked(callerApp,
   12512                     callerApp != null ? callerApp.info.packageName : null,
   12513                     intent, resolvedType, resultTo,
   12514                     resultCode, resultData, map, requiredPermission, serialized,
   12515                     sticky, callingPid, callingUid);
   12516             Binder.restoreCallingIdentity(origId);
   12517             return res;
   12518         }
   12519     }
   12520 
   12521     int broadcastIntentInPackage(String packageName, int uid,
   12522             Intent intent, String resolvedType, IIntentReceiver resultTo,
   12523             int resultCode, String resultData, Bundle map,
   12524             String requiredPermission, boolean serialized, boolean sticky) {
   12525         synchronized(this) {
   12526             intent = verifyBroadcastLocked(intent);
   12527 
   12528             final long origId = Binder.clearCallingIdentity();
   12529             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
   12530                     resultTo, resultCode, resultData, map, requiredPermission,
   12531                     serialized, sticky, -1, uid);
   12532             Binder.restoreCallingIdentity(origId);
   12533             return res;
   12534         }
   12535     }
   12536 
   12537     public final void unbroadcastIntent(IApplicationThread caller,
   12538             Intent intent) {
   12539         // Refuse possible leaked file descriptors
   12540         if (intent != null && intent.hasFileDescriptors() == true) {
   12541             throw new IllegalArgumentException("File descriptors passed in Intent");
   12542         }
   12543 
   12544         synchronized(this) {
   12545             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
   12546                     != PackageManager.PERMISSION_GRANTED) {
   12547                 String msg = "Permission Denial: unbroadcastIntent() from pid="
   12548                         + Binder.getCallingPid()
   12549                         + ", uid=" + Binder.getCallingUid()
   12550                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   12551                 Slog.w(TAG, msg);
   12552                 throw new SecurityException(msg);
   12553             }
   12554             ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
   12555             if (list != null) {
   12556                 int N = list.size();
   12557                 int i;
   12558                 for (i=0; i<N; i++) {
   12559                     if (intent.filterEquals(list.get(i))) {
   12560                         list.remove(i);
   12561                         break;
   12562                     }
   12563                 }
   12564             }
   12565         }
   12566     }
   12567 
   12568     private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
   12569             String resultData, Bundle resultExtras, boolean resultAbort,
   12570             boolean explicit) {
   12571         if (mOrderedBroadcasts.size() == 0) {
   12572             if (explicit) {
   12573                 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
   12574             }
   12575             return false;
   12576         }
   12577         BroadcastRecord r = mOrderedBroadcasts.get(0);
   12578         if (r.receiver == null) {
   12579             if (explicit) {
   12580                 Slog.w(TAG, "finishReceiver called but none active");
   12581             }
   12582             return false;
   12583         }
   12584         if (r.receiver != receiver) {
   12585             Slog.w(TAG, "finishReceiver called but active receiver is different");
   12586             return false;
   12587         }
   12588         int state = r.state;
   12589         r.state = BroadcastRecord.IDLE;
   12590         if (state == BroadcastRecord.IDLE) {
   12591             if (explicit) {
   12592                 Slog.w(TAG, "finishReceiver called but state is IDLE");
   12593             }
   12594         }
   12595         r.receiver = null;
   12596         r.intent.setComponent(null);
   12597         if (r.curApp != null) {
   12598             r.curApp.curReceiver = null;
   12599         }
   12600         if (r.curFilter != null) {
   12601             r.curFilter.receiverList.curBroadcast = null;
   12602         }
   12603         r.curFilter = null;
   12604         r.curApp = null;
   12605         r.curComponent = null;
   12606         r.curReceiver = null;
   12607         mPendingBroadcast = null;
   12608 
   12609         r.resultCode = resultCode;
   12610         r.resultData = resultData;
   12611         r.resultExtras = resultExtras;
   12612         r.resultAbort = resultAbort;
   12613 
   12614         // We will process the next receiver right now if this is finishing
   12615         // an app receiver (which is always asynchronous) or after we have
   12616         // come back from calling a receiver.
   12617         return state == BroadcastRecord.APP_RECEIVE
   12618                 || state == BroadcastRecord.CALL_DONE_RECEIVE;
   12619     }
   12620 
   12621     public void finishReceiver(IBinder who, int resultCode, String resultData,
   12622             Bundle resultExtras, boolean resultAbort) {
   12623         if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
   12624 
   12625         // Refuse possible leaked file descriptors
   12626         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
   12627             throw new IllegalArgumentException("File descriptors passed in Bundle");
   12628         }
   12629 
   12630         boolean doNext;
   12631 
   12632         final long origId = Binder.clearCallingIdentity();
   12633 
   12634         synchronized(this) {
   12635             doNext = finishReceiverLocked(
   12636                 who, resultCode, resultData, resultExtras, resultAbort, true);
   12637         }
   12638 
   12639         if (doNext) {
   12640             processNextBroadcast(false);
   12641         }
   12642         trimApplications();
   12643 
   12644         Binder.restoreCallingIdentity(origId);
   12645     }
   12646 
   12647     private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
   12648         if (r.nextReceiver > 0) {
   12649             Object curReceiver = r.receivers.get(r.nextReceiver-1);
   12650             if (curReceiver instanceof BroadcastFilter) {
   12651                 BroadcastFilter bf = (BroadcastFilter) curReceiver;
   12652                 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
   12653                         System.identityHashCode(r),
   12654                         r.intent.getAction(),
   12655                         r.nextReceiver - 1,
   12656                         System.identityHashCode(bf));
   12657             } else {
   12658                 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
   12659                         System.identityHashCode(r),
   12660                         r.intent.getAction(),
   12661                         r.nextReceiver - 1,
   12662                         ((ResolveInfo)curReceiver).toString());
   12663             }
   12664         } else {
   12665             Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
   12666                     + r);
   12667             EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
   12668                     System.identityHashCode(r),
   12669                     r.intent.getAction(),
   12670                     r.nextReceiver,
   12671                     "NONE");
   12672         }
   12673     }
   12674 
   12675     private final void setBroadcastTimeoutLocked(long timeoutTime) {
   12676         if (! mPendingBroadcastTimeoutMessage) {
   12677             Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
   12678             mHandler.sendMessageAtTime(msg, timeoutTime);
   12679             mPendingBroadcastTimeoutMessage = true;
   12680         }
   12681     }
   12682 
   12683     private final void cancelBroadcastTimeoutLocked() {
   12684         if (mPendingBroadcastTimeoutMessage) {
   12685             mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
   12686             mPendingBroadcastTimeoutMessage = false;
   12687         }
   12688     }
   12689 
   12690     private final void broadcastTimeoutLocked(boolean fromMsg) {
   12691         if (fromMsg) {
   12692             mPendingBroadcastTimeoutMessage = false;
   12693         }
   12694 
   12695         if (mOrderedBroadcasts.size() == 0) {
   12696             return;
   12697         }
   12698 
   12699         long now = SystemClock.uptimeMillis();
   12700         BroadcastRecord r = mOrderedBroadcasts.get(0);
   12701         if (fromMsg) {
   12702             if (mDidDexOpt) {
   12703                 // Delay timeouts until dexopt finishes.
   12704                 mDidDexOpt = false;
   12705                 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
   12706                 setBroadcastTimeoutLocked(timeoutTime);
   12707                 return;
   12708             }
   12709             if (! mProcessesReady) {
   12710                 // Only process broadcast timeouts if the system is ready. That way
   12711                 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
   12712                 // to do heavy lifting for system up.
   12713                 return;
   12714             }
   12715 
   12716             long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
   12717             if (timeoutTime > now) {
   12718                 // We can observe premature timeouts because we do not cancel and reset the
   12719                 // broadcast timeout message after each receiver finishes.  Instead, we set up
   12720                 // an initial timeout then kick it down the road a little further as needed
   12721                 // when it expires.
   12722                 if (DEBUG_BROADCAST) Slog.v(TAG,
   12723                         "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
   12724                         + timeoutTime);
   12725                 setBroadcastTimeoutLocked(timeoutTime);
   12726                 return;
   12727             }
   12728         }
   12729 
   12730         Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
   12731                 + ", started " + (now - r.receiverTime) + "ms ago");
   12732         r.receiverTime = now;
   12733         r.anrCount++;
   12734 
   12735         // Current receiver has passed its expiration date.
   12736         if (r.nextReceiver <= 0) {
   12737             Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
   12738             return;
   12739         }
   12740 
   12741         ProcessRecord app = null;
   12742         String anrMessage = null;
   12743 
   12744         Object curReceiver = r.receivers.get(r.nextReceiver-1);
   12745         Slog.w(TAG, "Receiver during timeout: " + curReceiver);
   12746         logBroadcastReceiverDiscardLocked(r);
   12747         if (curReceiver instanceof BroadcastFilter) {
   12748             BroadcastFilter bf = (BroadcastFilter)curReceiver;
   12749             if (bf.receiverList.pid != 0
   12750                     && bf.receiverList.pid != MY_PID) {
   12751                 synchronized (this.mPidsSelfLocked) {
   12752                     app = this.mPidsSelfLocked.get(
   12753                             bf.receiverList.pid);
   12754                 }
   12755             }
   12756         } else {
   12757             app = r.curApp;
   12758         }
   12759 
   12760         if (app != null) {
   12761             anrMessage = "Broadcast of " + r.intent.toString();
   12762         }
   12763 
   12764         if (mPendingBroadcast == r) {
   12765             mPendingBroadcast = null;
   12766         }
   12767 
   12768         // Move on to the next receiver.
   12769         finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
   12770                 r.resultExtras, r.resultAbort, true);
   12771         scheduleBroadcastsLocked();
   12772 
   12773         if (anrMessage != null) {
   12774             // Post the ANR to the handler since we do not want to process ANRs while
   12775             // potentially holding our lock.
   12776             mHandler.post(new AppNotResponding(app, anrMessage));
   12777         }
   12778     }
   12779 
   12780     private final void processCurBroadcastLocked(BroadcastRecord r,
   12781             ProcessRecord app) throws RemoteException {
   12782         if (DEBUG_BROADCAST)  Slog.v(TAG,
   12783                 "Process cur broadcast " + r + " for app " + app);
   12784         if (app.thread == null) {
   12785             throw new RemoteException();
   12786         }
   12787         r.receiver = app.thread.asBinder();
   12788         r.curApp = app;
   12789         app.curReceiver = r;
   12790         updateLruProcessLocked(app, true, true);
   12791 
   12792         // Tell the application to launch this receiver.
   12793         r.intent.setComponent(r.curComponent);
   12794 
   12795         boolean started = false;
   12796         try {
   12797             if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
   12798                     "Delivering to component " + r.curComponent
   12799                     + ": " + r);
   12800             ensurePackageDexOpt(r.intent.getComponent().getPackageName());
   12801             app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
   12802                     compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
   12803                     r.resultCode, r.resultData, r.resultExtras, r.ordered);
   12804             if (DEBUG_BROADCAST)  Slog.v(TAG,
   12805                     "Process cur broadcast " + r + " DELIVERED for app " + app);
   12806             started = true;
   12807         } finally {
   12808             if (!started) {
   12809                 if (DEBUG_BROADCAST)  Slog.v(TAG,
   12810                         "Process cur broadcast " + r + ": NOT STARTED!");
   12811                 r.receiver = null;
   12812                 r.curApp = null;
   12813                 app.curReceiver = null;
   12814             }
   12815         }
   12816 
   12817     }
   12818 
   12819     static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
   12820             Intent intent, int resultCode, String data, Bundle extras,
   12821             boolean ordered, boolean sticky) throws RemoteException {
   12822         // Send the intent to the receiver asynchronously using one-way binder calls.
   12823         if (app != null && app.thread != null) {
   12824             // If we have an app thread, do the call through that so it is
   12825             // correctly ordered with other one-way calls.
   12826             app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
   12827                     data, extras, ordered, sticky);
   12828         } else {
   12829             receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
   12830         }
   12831     }
   12832 
   12833     private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
   12834             BroadcastFilter filter, boolean ordered) {
   12835         boolean skip = false;
   12836         if (filter.requiredPermission != null) {
   12837             int perm = checkComponentPermission(filter.requiredPermission,
   12838                     r.callingPid, r.callingUid, -1, true);
   12839             if (perm != PackageManager.PERMISSION_GRANTED) {
   12840                 Slog.w(TAG, "Permission Denial: broadcasting "
   12841                         + r.intent.toString()
   12842                         + " from " + r.callerPackage + " (pid="
   12843                         + r.callingPid + ", uid=" + r.callingUid + ")"
   12844                         + " requires " + filter.requiredPermission
   12845                         + " due to registered receiver " + filter);
   12846                 skip = true;
   12847             }
   12848         }
   12849         if (r.requiredPermission != null) {
   12850             int perm = checkComponentPermission(r.requiredPermission,
   12851                     filter.receiverList.pid, filter.receiverList.uid, -1, true);
   12852             if (perm != PackageManager.PERMISSION_GRANTED) {
   12853                 Slog.w(TAG, "Permission Denial: receiving "
   12854                         + r.intent.toString()
   12855                         + " to " + filter.receiverList.app
   12856                         + " (pid=" + filter.receiverList.pid
   12857                         + ", uid=" + filter.receiverList.uid + ")"
   12858                         + " requires " + r.requiredPermission
   12859                         + " due to sender " + r.callerPackage
   12860                         + " (uid " + r.callingUid + ")");
   12861                 skip = true;
   12862             }
   12863         }
   12864 
   12865         if (!skip) {
   12866             // If this is not being sent as an ordered broadcast, then we
   12867             // don't want to touch the fields that keep track of the current
   12868             // state of ordered broadcasts.
   12869             if (ordered) {
   12870                 r.receiver = filter.receiverList.receiver.asBinder();
   12871                 r.curFilter = filter;
   12872                 filter.receiverList.curBroadcast = r;
   12873                 r.state = BroadcastRecord.CALL_IN_RECEIVE;
   12874                 if (filter.receiverList.app != null) {
   12875                     // Bump hosting application to no longer be in background
   12876                     // scheduling class.  Note that we can't do that if there
   12877                     // isn't an app...  but we can only be in that case for
   12878                     // things that directly call the IActivityManager API, which
   12879                     // are already core system stuff so don't matter for this.
   12880                     r.curApp = filter.receiverList.app;
   12881                     filter.receiverList.app.curReceiver = r;
   12882                     updateOomAdjLocked();
   12883                 }
   12884             }
   12885             try {
   12886                 if (DEBUG_BROADCAST_LIGHT) {
   12887                     int seq = r.intent.getIntExtra("seq", -1);
   12888                     Slog.i(TAG, "Delivering to " + filter
   12889                             + " (seq=" + seq + "): " + r);
   12890                 }
   12891                 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
   12892                     new Intent(r.intent), r.resultCode,
   12893                     r.resultData, r.resultExtras, r.ordered, r.initialSticky);
   12894                 if (ordered) {
   12895                     r.state = BroadcastRecord.CALL_DONE_RECEIVE;
   12896                 }
   12897             } catch (RemoteException e) {
   12898                 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
   12899                 if (ordered) {
   12900                     r.receiver = null;
   12901                     r.curFilter = null;
   12902                     filter.receiverList.curBroadcast = null;
   12903                     if (filter.receiverList.app != null) {
   12904                         filter.receiverList.app.curReceiver = null;
   12905                     }
   12906                 }
   12907             }
   12908         }
   12909     }
   12910 
   12911     private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
   12912         if (r.callingUid < 0) {
   12913             // This was from a registerReceiver() call; ignore it.
   12914             return;
   12915         }
   12916         System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
   12917                 MAX_BROADCAST_HISTORY-1);
   12918         r.finishTime = SystemClock.uptimeMillis();
   12919         mBroadcastHistory[0] = r;
   12920     }
   12921 
   12922     private final void processNextBroadcast(boolean fromMsg) {
   12923         synchronized(this) {
   12924             BroadcastRecord r;
   12925 
   12926             if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
   12927                     + mParallelBroadcasts.size() + " broadcasts, "
   12928                     + mOrderedBroadcasts.size() + " ordered broadcasts");
   12929 
   12930             updateCpuStats();
   12931 
   12932             if (fromMsg) {
   12933                 mBroadcastsScheduled = false;
   12934             }
   12935 
   12936             // First, deliver any non-serialized broadcasts right away.
   12937             while (mParallelBroadcasts.size() > 0) {
   12938                 r = mParallelBroadcasts.remove(0);
   12939                 r.dispatchTime = SystemClock.uptimeMillis();
   12940                 r.dispatchClockTime = System.currentTimeMillis();
   12941                 final int N = r.receivers.size();
   12942                 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
   12943                         + r);
   12944                 for (int i=0; i<N; i++) {
   12945                     Object target = r.receivers.get(i);
   12946                     if (DEBUG_BROADCAST)  Slog.v(TAG,
   12947                             "Delivering non-ordered to registered "
   12948                             + target + ": " + r);
   12949                     deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
   12950                 }
   12951                 addBroadcastToHistoryLocked(r);
   12952                 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
   12953                         + r);
   12954             }
   12955 
   12956             // Now take care of the next serialized one...
   12957 
   12958             // If we are waiting for a process to come up to handle the next
   12959             // broadcast, then do nothing at this point.  Just in case, we
   12960             // check that the process we're waiting for still exists.
   12961             if (mPendingBroadcast != null) {
   12962                 if (DEBUG_BROADCAST_LIGHT) {
   12963                     Slog.v(TAG, "processNextBroadcast: waiting for "
   12964                             + mPendingBroadcast.curApp);
   12965                 }
   12966 
   12967                 boolean isDead;
   12968                 synchronized (mPidsSelfLocked) {
   12969                     isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
   12970                 }
   12971                 if (!isDead) {
   12972                     // It's still alive, so keep waiting
   12973                     return;
   12974                 } else {
   12975                     Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
   12976                             + " died before responding to broadcast");
   12977                     mPendingBroadcast.state = BroadcastRecord.IDLE;
   12978                     mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
   12979                     mPendingBroadcast = null;
   12980                 }
   12981             }
   12982 
   12983             boolean looped = false;
   12984 
   12985             do {
   12986                 if (mOrderedBroadcasts.size() == 0) {
   12987                     // No more broadcasts pending, so all done!
   12988                     scheduleAppGcsLocked();
   12989                     if (looped) {
   12990                         // If we had finished the last ordered broadcast, then
   12991                         // make sure all processes have correct oom and sched
   12992                         // adjustments.
   12993                         updateOomAdjLocked();
   12994                     }
   12995                     return;
   12996                 }
   12997                 r = mOrderedBroadcasts.get(0);
   12998                 boolean forceReceive = false;
   12999 
   13000                 // Ensure that even if something goes awry with the timeout
   13001                 // detection, we catch "hung" broadcasts here, discard them,
   13002                 // and continue to make progress.
   13003                 //
   13004                 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
   13005                 // receivers don't get executed with timeouts. They're intended for
   13006                 // one time heavy lifting after system upgrades and can take
   13007                 // significant amounts of time.
   13008                 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
   13009                 if (mProcessesReady && r.dispatchTime > 0) {
   13010                     long now = SystemClock.uptimeMillis();
   13011                     if ((numReceivers > 0) &&
   13012                             (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
   13013                         Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
   13014                                 + " now=" + now
   13015                                 + " dispatchTime=" + r.dispatchTime
   13016                                 + " startTime=" + r.receiverTime
   13017                                 + " intent=" + r.intent
   13018                                 + " numReceivers=" + numReceivers
   13019                                 + " nextReceiver=" + r.nextReceiver
   13020                                 + " state=" + r.state);
   13021                         broadcastTimeoutLocked(false); // forcibly finish this broadcast
   13022                         forceReceive = true;
   13023                         r.state = BroadcastRecord.IDLE;
   13024                     }
   13025                 }
   13026 
   13027                 if (r.state != BroadcastRecord.IDLE) {
   13028                     if (DEBUG_BROADCAST) Slog.d(TAG,
   13029                             "processNextBroadcast() called when not idle (state="
   13030                             + r.state + ")");
   13031                     return;
   13032                 }
   13033 
   13034                 if (r.receivers == null || r.nextReceiver >= numReceivers
   13035                         || r.resultAbort || forceReceive) {
   13036                     // No more receivers for this broadcast!  Send the final
   13037                     // result if requested...
   13038                     if (r.resultTo != null) {
   13039                         try {
   13040                             if (DEBUG_BROADCAST) {
   13041                                 int seq = r.intent.getIntExtra("seq", -1);
   13042                                 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
   13043                                         + " seq=" + seq + " app=" + r.callerApp);
   13044                             }
   13045                             performReceiveLocked(r.callerApp, r.resultTo,
   13046                                 new Intent(r.intent), r.resultCode,
   13047                                 r.resultData, r.resultExtras, false, false);
   13048                             // Set this to null so that the reference
   13049                             // (local and remote) isnt kept in the mBroadcastHistory.
   13050                             r.resultTo = null;
   13051                         } catch (RemoteException e) {
   13052                             Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
   13053                         }
   13054                     }
   13055 
   13056                     if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
   13057                     cancelBroadcastTimeoutLocked();
   13058 
   13059                     if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
   13060                             + r);
   13061 
   13062                     // ... and on to the next...
   13063                     addBroadcastToHistoryLocked(r);
   13064                     mOrderedBroadcasts.remove(0);
   13065                     r = null;
   13066                     looped = true;
   13067                     continue;
   13068                 }
   13069             } while (r == null);
   13070 
   13071             // Get the next receiver...
   13072             int recIdx = r.nextReceiver++;
   13073 
   13074             // Keep track of when this receiver started, and make sure there
   13075             // is a timeout message pending to kill it if need be.
   13076             r.receiverTime = SystemClock.uptimeMillis();
   13077             if (recIdx == 0) {
   13078                 r.dispatchTime = r.receiverTime;
   13079                 r.dispatchClockTime = System.currentTimeMillis();
   13080                 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
   13081                         + r);
   13082             }
   13083             if (! mPendingBroadcastTimeoutMessage) {
   13084                 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
   13085                 if (DEBUG_BROADCAST) Slog.v(TAG,
   13086                         "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
   13087                 setBroadcastTimeoutLocked(timeoutTime);
   13088             }
   13089 
   13090             Object nextReceiver = r.receivers.get(recIdx);
   13091             if (nextReceiver instanceof BroadcastFilter) {
   13092                 // Simple case: this is a registered receiver who gets
   13093                 // a direct call.
   13094                 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
   13095                 if (DEBUG_BROADCAST)  Slog.v(TAG,
   13096                         "Delivering ordered to registered "
   13097                         + filter + ": " + r);
   13098                 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
   13099                 if (r.receiver == null || !r.ordered) {
   13100                     // The receiver has already finished, so schedule to
   13101                     // process the next one.
   13102                     if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
   13103                             + r.ordered + " receiver=" + r.receiver);
   13104                     r.state = BroadcastRecord.IDLE;
   13105                     scheduleBroadcastsLocked();
   13106                 }
   13107                 return;
   13108             }
   13109 
   13110             // Hard case: need to instantiate the receiver, possibly
   13111             // starting its application process to host it.
   13112 
   13113             ResolveInfo info =
   13114                 (ResolveInfo)nextReceiver;
   13115 
   13116             boolean skip = false;
   13117             int perm = checkComponentPermission(info.activityInfo.permission,
   13118                     r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
   13119                     info.activityInfo.exported);
   13120             if (perm != PackageManager.PERMISSION_GRANTED) {
   13121                 if (!info.activityInfo.exported) {
   13122                     Slog.w(TAG, "Permission Denial: broadcasting "
   13123                             + r.intent.toString()
   13124                             + " from " + r.callerPackage + " (pid=" + r.callingPid
   13125                             + ", uid=" + r.callingUid + ")"
   13126                             + " is not exported from uid " + info.activityInfo.applicationInfo.uid
   13127                             + " due to receiver " + info.activityInfo.packageName
   13128                             + "/" + info.activityInfo.name);
   13129                 } else {
   13130                     Slog.w(TAG, "Permission Denial: broadcasting "
   13131                             + r.intent.toString()
   13132                             + " from " + r.callerPackage + " (pid=" + r.callingPid
   13133                             + ", uid=" + r.callingUid + ")"
   13134                             + " requires " + info.activityInfo.permission
   13135                             + " due to receiver " + info.activityInfo.packageName
   13136                             + "/" + info.activityInfo.name);
   13137                 }
   13138                 skip = true;
   13139             }
   13140             if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
   13141                 r.requiredPermission != null) {
   13142                 try {
   13143                     perm = AppGlobals.getPackageManager().
   13144                             checkPermission(r.requiredPermission,
   13145                                     info.activityInfo.applicationInfo.packageName);
   13146                 } catch (RemoteException e) {
   13147                     perm = PackageManager.PERMISSION_DENIED;
   13148                 }
   13149                 if (perm != PackageManager.PERMISSION_GRANTED) {
   13150                     Slog.w(TAG, "Permission Denial: receiving "
   13151                             + r.intent + " to "
   13152                             + info.activityInfo.applicationInfo.packageName
   13153                             + " requires " + r.requiredPermission
   13154                             + " due to sender " + r.callerPackage
   13155                             + " (uid " + r.callingUid + ")");
   13156                     skip = true;
   13157                 }
   13158             }
   13159             if (r.curApp != null && r.curApp.crashing) {
   13160                 // If the target process is crashing, just skip it.
   13161                 if (DEBUG_BROADCAST)  Slog.v(TAG,
   13162                         "Skipping deliver ordered " + r + " to " + r.curApp
   13163                         + ": process crashing");
   13164                 skip = true;
   13165             }
   13166 
   13167             if (skip) {
   13168                 if (DEBUG_BROADCAST)  Slog.v(TAG,
   13169                         "Skipping delivery of ordered " + r + " for whatever reason");
   13170                 r.receiver = null;
   13171                 r.curFilter = null;
   13172                 r.state = BroadcastRecord.IDLE;
   13173                 scheduleBroadcastsLocked();
   13174                 return;
   13175             }
   13176 
   13177             r.state = BroadcastRecord.APP_RECEIVE;
   13178             String targetProcess = info.activityInfo.processName;
   13179             r.curComponent = new ComponentName(
   13180                     info.activityInfo.applicationInfo.packageName,
   13181                     info.activityInfo.name);
   13182             r.curReceiver = info.activityInfo;
   13183 
   13184             // Broadcast is being executed, its package can't be stopped.
   13185             try {
   13186                 AppGlobals.getPackageManager().setPackageStoppedState(
   13187                         r.curComponent.getPackageName(), false);
   13188             } catch (RemoteException e) {
   13189             } catch (IllegalArgumentException e) {
   13190                 Slog.w(TAG, "Failed trying to unstop package "
   13191                         + r.curComponent.getPackageName() + ": " + e);
   13192             }
   13193 
   13194             // Is this receiver's application already running?
   13195             ProcessRecord app = getProcessRecordLocked(targetProcess,
   13196                     info.activityInfo.applicationInfo.uid);
   13197             if (app != null && app.thread != null) {
   13198                 try {
   13199                     app.addPackage(info.activityInfo.packageName);
   13200                     processCurBroadcastLocked(r, app);
   13201                     return;
   13202                 } catch (RemoteException e) {
   13203                     Slog.w(TAG, "Exception when sending broadcast to "
   13204                           + r.curComponent, e);
   13205                 }
   13206 
   13207                 // If a dead object exception was thrown -- fall through to
   13208                 // restart the application.
   13209             }
   13210 
   13211             // Not running -- get it started, to be executed when the app comes up.
   13212             if (DEBUG_BROADCAST)  Slog.v(TAG,
   13213                     "Need to start app " + targetProcess + " for broadcast " + r);
   13214             if ((r.curApp=startProcessLocked(targetProcess,
   13215                     info.activityInfo.applicationInfo, true,
   13216                     r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
   13217                     "broadcast", r.curComponent,
   13218                     (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
   13219                             == null) {
   13220                 // Ah, this recipient is unavailable.  Finish it if necessary,
   13221                 // and mark the broadcast record as ready for the next.
   13222                 Slog.w(TAG, "Unable to launch app "
   13223                         + info.activityInfo.applicationInfo.packageName + "/"
   13224                         + info.activityInfo.applicationInfo.uid + " for broadcast "
   13225                         + r.intent + ": process is bad");
   13226                 logBroadcastReceiverDiscardLocked(r);
   13227                 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
   13228                         r.resultExtras, r.resultAbort, true);
   13229                 scheduleBroadcastsLocked();
   13230                 r.state = BroadcastRecord.IDLE;
   13231                 return;
   13232             }
   13233 
   13234             mPendingBroadcast = r;
   13235             mPendingBroadcastRecvIndex = recIdx;
   13236         }
   13237     }
   13238 
   13239     // =========================================================
   13240     // INSTRUMENTATION
   13241     // =========================================================
   13242 
   13243     public boolean startInstrumentation(ComponentName className,
   13244             String profileFile, int flags, Bundle arguments,
   13245             IInstrumentationWatcher watcher) {
   13246         // Refuse possible leaked file descriptors
   13247         if (arguments != null && arguments.hasFileDescriptors()) {
   13248             throw new IllegalArgumentException("File descriptors passed in Bundle");
   13249         }
   13250 
   13251         synchronized(this) {
   13252             InstrumentationInfo ii = null;
   13253             ApplicationInfo ai = null;
   13254             try {
   13255                 ii = mContext.getPackageManager().getInstrumentationInfo(
   13256                     className, STOCK_PM_FLAGS);
   13257                 ai = mContext.getPackageManager().getApplicationInfo(
   13258                     ii.targetPackage, STOCK_PM_FLAGS);
   13259             } catch (PackageManager.NameNotFoundException e) {
   13260             }
   13261             if (ii == null) {
   13262                 reportStartInstrumentationFailure(watcher, className,
   13263                         "Unable to find instrumentation info for: " + className);
   13264                 return false;
   13265             }
   13266             if (ai == null) {
   13267                 reportStartInstrumentationFailure(watcher, className,
   13268                         "Unable to find instrumentation target package: " + ii.targetPackage);
   13269                 return false;
   13270             }
   13271 
   13272             int match = mContext.getPackageManager().checkSignatures(
   13273                     ii.targetPackage, ii.packageName);
   13274             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
   13275                 String msg = "Permission Denial: starting instrumentation "
   13276                         + className + " from pid="
   13277                         + Binder.getCallingPid()
   13278                         + ", uid=" + Binder.getCallingPid()
   13279                         + " not allowed because package " + ii.packageName
   13280                         + " does not have a signature matching the target "
   13281                         + ii.targetPackage;
   13282                 reportStartInstrumentationFailure(watcher, className, msg);
   13283                 throw new SecurityException(msg);
   13284             }
   13285 
   13286             final long origId = Binder.clearCallingIdentity();
   13287             // Instrumentation can kill and relaunch even persistent processes
   13288             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
   13289             ProcessRecord app = addAppLocked(ai);
   13290             app.instrumentationClass = className;
   13291             app.instrumentationInfo = ai;
   13292             app.instrumentationProfileFile = profileFile;
   13293             app.instrumentationArguments = arguments;
   13294             app.instrumentationWatcher = watcher;
   13295             app.instrumentationResultClass = className;
   13296             Binder.restoreCallingIdentity(origId);
   13297         }
   13298 
   13299         return true;
   13300     }
   13301 
   13302     /**
   13303      * Report errors that occur while attempting to start Instrumentation.  Always writes the
   13304      * error to the logs, but if somebody is watching, send the report there too.  This enables
   13305      * the "am" command to report errors with more information.
   13306      *
   13307      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
   13308      * @param cn The component name of the instrumentation.
   13309      * @param report The error report.
   13310      */
   13311     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
   13312             ComponentName cn, String report) {
   13313         Slog.w(TAG, report);
   13314         try {
   13315             if (watcher != null) {
   13316                 Bundle results = new Bundle();
   13317                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
   13318                 results.putString("Error", report);
   13319                 watcher.instrumentationStatus(cn, -1, results);
   13320             }
   13321         } catch (RemoteException e) {
   13322             Slog.w(TAG, e);
   13323         }
   13324     }
   13325 
   13326     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
   13327         if (app.instrumentationWatcher != null) {
   13328             try {
   13329                 // NOTE:  IInstrumentationWatcher *must* be oneway here
   13330                 app.instrumentationWatcher.instrumentationFinished(
   13331                     app.instrumentationClass,
   13332                     resultCode,
   13333                     results);
   13334             } catch (RemoteException e) {
   13335             }
   13336         }
   13337         app.instrumentationWatcher = null;
   13338         app.instrumentationClass = null;
   13339         app.instrumentationInfo = null;
   13340         app.instrumentationProfileFile = null;
   13341         app.instrumentationArguments = null;
   13342 
   13343         forceStopPackageLocked(app.processName, -1, false, false, true, true);
   13344     }
   13345 
   13346     public void finishInstrumentation(IApplicationThread target,
   13347             int resultCode, Bundle results) {
   13348         // Refuse possible leaked file descriptors
   13349         if (results != null && results.hasFileDescriptors()) {
   13350             throw new IllegalArgumentException("File descriptors passed in Intent");
   13351         }
   13352 
   13353         synchronized(this) {
   13354             ProcessRecord app = getRecordForAppLocked(target);
   13355             if (app == null) {
   13356                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
   13357                 return;
   13358             }
   13359             final long origId = Binder.clearCallingIdentity();
   13360             finishInstrumentationLocked(app, resultCode, results);
   13361             Binder.restoreCallingIdentity(origId);
   13362         }
   13363     }
   13364 
   13365     // =========================================================
   13366     // CONFIGURATION
   13367     // =========================================================
   13368 
   13369     public ConfigurationInfo getDeviceConfigurationInfo() {
   13370         ConfigurationInfo config = new ConfigurationInfo();
   13371         synchronized (this) {
   13372             config.reqTouchScreen = mConfiguration.touchscreen;
   13373             config.reqKeyboardType = mConfiguration.keyboard;
   13374             config.reqNavigation = mConfiguration.navigation;
   13375             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
   13376                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
   13377                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
   13378             }
   13379             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
   13380                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
   13381                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
   13382             }
   13383             config.reqGlEsVersion = GL_ES_VERSION;
   13384         }
   13385         return config;
   13386     }
   13387 
   13388     public Configuration getConfiguration() {
   13389         Configuration ci;
   13390         synchronized(this) {
   13391             ci = new Configuration(mConfiguration);
   13392         }
   13393         return ci;
   13394     }
   13395 
   13396     public void updatePersistentConfiguration(Configuration values) {
   13397         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   13398                 "updateConfiguration()");
   13399         enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
   13400                 "updateConfiguration()");
   13401         if (values == null) {
   13402             throw new NullPointerException("Configuration must not be null");
   13403         }
   13404 
   13405         synchronized(this) {
   13406             final long origId = Binder.clearCallingIdentity();
   13407             updateConfigurationLocked(values, null, true, false);
   13408             Binder.restoreCallingIdentity(origId);
   13409         }
   13410     }
   13411 
   13412     public void updateConfiguration(Configuration values) {
   13413         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   13414                 "updateConfiguration()");
   13415 
   13416         synchronized(this) {
   13417             if (values == null && mWindowManager != null) {
   13418                 // sentinel: fetch the current configuration from the window manager
   13419                 values = mWindowManager.computeNewConfiguration();
   13420             }
   13421 
   13422             if (mWindowManager != null) {
   13423                 mProcessList.applyDisplaySize(mWindowManager);
   13424             }
   13425 
   13426             final long origId = Binder.clearCallingIdentity();
   13427             if (values != null) {
   13428                 Settings.System.clearConfiguration(values);
   13429             }
   13430             updateConfigurationLocked(values, null, false, false);
   13431             Binder.restoreCallingIdentity(origId);
   13432         }
   13433     }
   13434 
   13435     /**
   13436      * Do either or both things: (1) change the current configuration, and (2)
   13437      * make sure the given activity is running with the (now) current
   13438      * configuration.  Returns true if the activity has been left running, or
   13439      * false if <var>starting</var> is being destroyed to match the new
   13440      * configuration.
   13441      * @param persistent TODO
   13442      */
   13443     public boolean updateConfigurationLocked(Configuration values,
   13444             ActivityRecord starting, boolean persistent, boolean initLocale) {
   13445         int changes = 0;
   13446 
   13447         boolean kept = true;
   13448 
   13449         if (values != null) {
   13450             Configuration newConfig = new Configuration(mConfiguration);
   13451             changes = newConfig.updateFrom(values);
   13452             if (changes != 0) {
   13453                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
   13454                     Slog.i(TAG, "Updating configuration to: " + values);
   13455                 }
   13456 
   13457                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
   13458 
   13459                 if (values.locale != null && !initLocale) {
   13460                     saveLocaleLocked(values.locale,
   13461                                      !values.locale.equals(mConfiguration.locale),
   13462                                      values.userSetLocale);
   13463                 }
   13464 
   13465                 mConfigurationSeq++;
   13466                 if (mConfigurationSeq <= 0) {
   13467                     mConfigurationSeq = 1;
   13468                 }
   13469                 newConfig.seq = mConfigurationSeq;
   13470                 mConfiguration = newConfig;
   13471                 Slog.i(TAG, "Config changed: " + newConfig);
   13472 
   13473                 final Configuration configCopy = new Configuration(mConfiguration);
   13474 
   13475                 AttributeCache ac = AttributeCache.instance();
   13476                 if (ac != null) {
   13477                     ac.updateConfiguration(configCopy);
   13478                 }
   13479 
   13480                 // Make sure all resources in our process are updated
   13481                 // right now, so that anyone who is going to retrieve
   13482                 // resource values after we return will be sure to get
   13483                 // the new ones.  This is especially important during
   13484                 // boot, where the first config change needs to guarantee
   13485                 // all resources have that config before following boot
   13486                 // code is executed.
   13487                 mSystemThread.applyConfigurationToResources(configCopy);
   13488 
   13489                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
   13490                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
   13491                     msg.obj = new Configuration(configCopy);
   13492                     mHandler.sendMessage(msg);
   13493                 }
   13494 
   13495                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   13496                     ProcessRecord app = mLruProcesses.get(i);
   13497                     try {
   13498                         if (app.thread != null) {
   13499                             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
   13500                                     + app.processName + " new config " + mConfiguration);
   13501                             app.thread.scheduleConfigurationChanged(configCopy);
   13502                         }
   13503                     } catch (Exception e) {
   13504                     }
   13505                 }
   13506                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
   13507                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   13508                         | Intent.FLAG_RECEIVER_REPLACE_PENDING);
   13509                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
   13510                         null, false, false, MY_PID, Process.SYSTEM_UID);
   13511                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
   13512                     broadcastIntentLocked(null, null,
   13513                             new Intent(Intent.ACTION_LOCALE_CHANGED),
   13514                             null, null, 0, null, null,
   13515                             null, false, false, MY_PID, Process.SYSTEM_UID);
   13516                 }
   13517             }
   13518         }
   13519 
   13520         if (changes != 0 && starting == null) {
   13521             // If the configuration changed, and the caller is not already
   13522             // in the process of starting an activity, then find the top
   13523             // activity to check if its configuration needs to change.
   13524             starting = mMainStack.topRunningActivityLocked(null);
   13525         }
   13526 
   13527         if (starting != null) {
   13528             kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
   13529             // And we need to make sure at this point that all other activities
   13530             // are made visible with the correct configuration.
   13531             mMainStack.ensureActivitiesVisibleLocked(starting, changes);
   13532         }
   13533 
   13534         if (values != null && mWindowManager != null) {
   13535             mWindowManager.setNewConfiguration(mConfiguration);
   13536         }
   13537 
   13538         return kept;
   13539     }
   13540 
   13541     /**
   13542      * Save the locale.  You must be inside a synchronized (this) block.
   13543      */
   13544     private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
   13545         if(isDiff) {
   13546             SystemProperties.set("user.language", l.getLanguage());
   13547             SystemProperties.set("user.region", l.getCountry());
   13548         }
   13549 
   13550         if(isPersist) {
   13551             SystemProperties.set("persist.sys.language", l.getLanguage());
   13552             SystemProperties.set("persist.sys.country", l.getCountry());
   13553             SystemProperties.set("persist.sys.localevar", l.getVariant());
   13554         }
   13555     }
   13556 
   13557     // =========================================================
   13558     // LIFETIME MANAGEMENT
   13559     // =========================================================
   13560 
   13561     private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
   13562             ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
   13563         if (mAdjSeq == app.adjSeq) {
   13564             // This adjustment has already been computed.  If we are calling
   13565             // from the top, we may have already computed our adjustment with
   13566             // an earlier hidden adjustment that isn't really for us... if
   13567             // so, use the new hidden adjustment.
   13568             if (!recursed && app.hidden) {
   13569                 app.curAdj = app.curRawAdj = hiddenAdj;
   13570             }
   13571             return app.curRawAdj;
   13572         }
   13573 
   13574         if (app.thread == null) {
   13575             app.adjSeq = mAdjSeq;
   13576             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13577             return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
   13578         }
   13579 
   13580         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
   13581         app.adjSource = null;
   13582         app.adjTarget = null;
   13583         app.empty = false;
   13584         app.hidden = false;
   13585 
   13586         final int activitiesSize = app.activities.size();
   13587 
   13588         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   13589             // The max adjustment doesn't allow this app to be anything
   13590             // below foreground, so it is not worth doing work for it.
   13591             app.adjType = "fixed";
   13592             app.adjSeq = mAdjSeq;
   13593             app.curRawAdj = app.maxAdj;
   13594             app.foregroundActivities = false;
   13595             app.keeping = true;
   13596             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
   13597             // System process can do UI, and when they do we want to have
   13598             // them trim their memory after the user leaves the UI.  To
   13599             // facilitate this, here we need to determine whether or not it
   13600             // is currently showing UI.
   13601             app.systemNoUi = true;
   13602             if (app == TOP_APP) {
   13603                 app.systemNoUi = false;
   13604             } else if (activitiesSize > 0) {
   13605                 for (int j = 0; j < activitiesSize; j++) {
   13606                     final ActivityRecord r = app.activities.get(j);
   13607                     if (r.visible) {
   13608                         app.systemNoUi = false;
   13609                         break;
   13610                     }
   13611                 }
   13612             }
   13613             return (app.curAdj=app.maxAdj);
   13614         }
   13615 
   13616         final boolean hadForegroundActivities = app.foregroundActivities;
   13617 
   13618         app.foregroundActivities = false;
   13619         app.keeping = false;
   13620         app.systemNoUi = false;
   13621 
   13622         // Determine the importance of the process, starting with most
   13623         // important to least, and assign an appropriate OOM adjustment.
   13624         int adj;
   13625         int schedGroup;
   13626         if (app == TOP_APP) {
   13627             // The last app on the list is the foreground app.
   13628             adj = ProcessList.FOREGROUND_APP_ADJ;
   13629             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13630             app.adjType = "top-activity";
   13631             app.foregroundActivities = true;
   13632         } else if (app.instrumentationClass != null) {
   13633             // Don't want to kill running instrumentation.
   13634             adj = ProcessList.FOREGROUND_APP_ADJ;
   13635             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13636             app.adjType = "instrumentation";
   13637         } else if (app.curReceiver != null ||
   13638                 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
   13639             // An app that is currently receiving a broadcast also
   13640             // counts as being in the foreground.
   13641             adj = ProcessList.FOREGROUND_APP_ADJ;
   13642             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13643             app.adjType = "broadcast";
   13644         } else if (app.executingServices.size() > 0) {
   13645             // An app that is currently executing a service callback also
   13646             // counts as being in the foreground.
   13647             adj = ProcessList.FOREGROUND_APP_ADJ;
   13648             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13649             app.adjType = "exec-service";
   13650         } else if (activitiesSize > 0) {
   13651             // This app is in the background with paused activities.
   13652             // We inspect activities to potentially upgrade adjustment further below.
   13653             adj = hiddenAdj;
   13654             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13655             app.hidden = true;
   13656             app.adjType = "bg-activities";
   13657         } else {
   13658             // A very not-needed process.  If this is lower in the lru list,
   13659             // we will push it in to the empty bucket.
   13660             adj = hiddenAdj;
   13661             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13662             app.hidden = true;
   13663             app.empty = true;
   13664             app.adjType = "bg-empty";
   13665         }
   13666 
   13667         // Examine all activities if not already foreground.
   13668         if (!app.foregroundActivities && activitiesSize > 0) {
   13669             for (int j = 0; j < activitiesSize; j++) {
   13670                 final ActivityRecord r = app.activities.get(j);
   13671                 if (r.visible) {
   13672                     // App has a visible activity; only upgrade adjustment.
   13673                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   13674                         adj = ProcessList.VISIBLE_APP_ADJ;
   13675                         app.adjType = "visible";
   13676                     }
   13677                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   13678                     app.hidden = false;
   13679                     app.foregroundActivities = true;
   13680                     break;
   13681                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
   13682                         || r.state == ActivityState.STOPPING) {
   13683                     // Only upgrade adjustment.
   13684                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   13685                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   13686                         app.adjType = "stopping";
   13687                     }
   13688                     app.hidden = false;
   13689                     app.foregroundActivities = true;
   13690                 }
   13691             }
   13692         }
   13693 
   13694         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   13695             if (app.foregroundServices) {
   13696                 // The user is aware of this app, so make it visible.
   13697                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   13698                 app.hidden = false;
   13699                 app.adjType = "foreground-service";
   13700                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   13701             } else if (app.forcingToForeground != null) {
   13702                 // The user is aware of this app, so make it visible.
   13703                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   13704                 app.hidden = false;
   13705                 app.adjType = "force-foreground";
   13706                 app.adjSource = app.forcingToForeground;
   13707                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   13708             }
   13709         }
   13710 
   13711         if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
   13712             // We don't want to kill the current heavy-weight process.
   13713             adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
   13714             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13715             app.hidden = false;
   13716             app.adjType = "heavy";
   13717         }
   13718 
   13719         if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
   13720             // This process is hosting what we currently consider to be the
   13721             // home app, so we don't want to let it go into the background.
   13722             adj = ProcessList.HOME_APP_ADJ;
   13723             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13724             app.hidden = false;
   13725             app.adjType = "home";
   13726         }
   13727 
   13728         if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
   13729                 && app.activities.size() > 0) {
   13730             // This was the previous process that showed UI to the user.
   13731             // We want to try to keep it around more aggressively, to give
   13732             // a good experience around switching between two apps.
   13733             adj = ProcessList.PREVIOUS_APP_ADJ;
   13734             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13735             app.hidden = false;
   13736             app.adjType = "previous";
   13737         }
   13738 
   13739         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
   13740                 + " reason=" + app.adjType);
   13741 
   13742         // By default, we use the computed adjustment.  It may be changed if
   13743         // there are applications dependent on our services or providers, but
   13744         // this gives us a baseline and makes sure we don't get into an
   13745         // infinite recursion.
   13746         app.adjSeq = mAdjSeq;
   13747         app.curRawAdj = adj;
   13748 
   13749         if (mBackupTarget != null && app == mBackupTarget.app) {
   13750             // If possible we want to avoid killing apps while they're being backed up
   13751             if (adj > ProcessList.BACKUP_APP_ADJ) {
   13752                 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
   13753                 adj = ProcessList.BACKUP_APP_ADJ;
   13754                 app.adjType = "backup";
   13755                 app.hidden = false;
   13756             }
   13757         }
   13758 
   13759         if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   13760                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   13761             final long now = SystemClock.uptimeMillis();
   13762             // This process is more important if the top activity is
   13763             // bound to the service.
   13764             Iterator<ServiceRecord> jt = app.services.iterator();
   13765             while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
   13766                 ServiceRecord s = jt.next();
   13767                 if (s.startRequested) {
   13768                     if (app.hasShownUi && app != mHomeProcess) {
   13769                         // If this process has shown some UI, let it immediately
   13770                         // go to the LRU list because it may be pretty heavy with
   13771                         // UI stuff.  We'll tag it with a label just to help
   13772                         // debug and understand what is going on.
   13773                         if (adj > ProcessList.SERVICE_ADJ) {
   13774                             app.adjType = "started-bg-ui-services";
   13775                         }
   13776                     } else {
   13777                         if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
   13778                             // This service has seen some activity within
   13779                             // recent memory, so we will keep its process ahead
   13780                             // of the background processes.
   13781                             if (adj > ProcessList.SERVICE_ADJ) {
   13782                                 adj = ProcessList.SERVICE_ADJ;
   13783                                 app.adjType = "started-services";
   13784                                 app.hidden = false;
   13785                             }
   13786                         }
   13787                         // If we have let the service slide into the background
   13788                         // state, still have some text describing what it is doing
   13789                         // even though the service no longer has an impact.
   13790                         if (adj > ProcessList.SERVICE_ADJ) {
   13791                             app.adjType = "started-bg-services";
   13792                         }
   13793                     }
   13794                     // Don't kill this process because it is doing work; it
   13795                     // has said it is doing work.
   13796                     app.keeping = true;
   13797                 }
   13798                 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   13799                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   13800                     Iterator<ArrayList<ConnectionRecord>> kt
   13801                             = s.connections.values().iterator();
   13802                     while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
   13803                         ArrayList<ConnectionRecord> clist = kt.next();
   13804                         for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
   13805                             // XXX should compute this based on the max of
   13806                             // all connected clients.
   13807                             ConnectionRecord cr = clist.get(i);
   13808                             if (cr.binding.client == app) {
   13809                                 // Binding to ourself is not interesting.
   13810                                 continue;
   13811                             }
   13812                             if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
   13813                                 ProcessRecord client = cr.binding.client;
   13814                                 int clientAdj = adj;
   13815                                 int myHiddenAdj = hiddenAdj;
   13816                                 if (myHiddenAdj > client.hiddenAdj) {
   13817                                     if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
   13818                                         myHiddenAdj = client.hiddenAdj;
   13819                                     } else {
   13820                                         myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
   13821                                     }
   13822                                 }
   13823                                 clientAdj = computeOomAdjLocked(
   13824                                     client, myHiddenAdj, TOP_APP, true, doingAll);
   13825                                 String adjType = null;
   13826                                 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
   13827                                     // Not doing bind OOM management, so treat
   13828                                     // this guy more like a started service.
   13829                                     if (app.hasShownUi && app != mHomeProcess) {
   13830                                         // If this process has shown some UI, let it immediately
   13831                                         // go to the LRU list because it may be pretty heavy with
   13832                                         // UI stuff.  We'll tag it with a label just to help
   13833                                         // debug and understand what is going on.
   13834                                         if (adj > clientAdj) {
   13835                                             adjType = "bound-bg-ui-services";
   13836                                         }
   13837                                         app.hidden = false;
   13838                                         clientAdj = adj;
   13839                                     } else {
   13840                                         if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
   13841                                             // This service has not seen activity within
   13842                                             // recent memory, so allow it to drop to the
   13843                                             // LRU list if there is no other reason to keep
   13844                                             // it around.  We'll also tag it with a label just
   13845                                             // to help debug and undertand what is going on.
   13846                                             if (adj > clientAdj) {
   13847                                                 adjType = "bound-bg-services";
   13848                                             }
   13849                                             clientAdj = adj;
   13850                                         }
   13851                                     }
   13852                                 }
   13853                                 if (adj > clientAdj) {
   13854                                     // If this process has recently shown UI, and
   13855                                     // the process that is binding to it is less
   13856                                     // important than being visible, then we don't
   13857                                     // care about the binding as much as we care
   13858                                     // about letting this process get into the LRU
   13859                                     // list to be killed and restarted if needed for
   13860                                     // memory.
   13861                                     if (app.hasShownUi && app != mHomeProcess
   13862                                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   13863                                         adjType = "bound-bg-ui-services";
   13864                                     } else {
   13865                                         if ((cr.flags&(Context.BIND_ABOVE_CLIENT
   13866                                                 |Context.BIND_IMPORTANT)) != 0) {
   13867                                             adj = clientAdj;
   13868                                         } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
   13869                                                 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
   13870                                                 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   13871                                             adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   13872                                         } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
   13873                                             adj = clientAdj;
   13874                                         } else {
   13875                                             app.pendingUiClean = true;
   13876                                             if (adj > ProcessList.VISIBLE_APP_ADJ) {
   13877                                                 adj = ProcessList.VISIBLE_APP_ADJ;
   13878                                             }
   13879                                         }
   13880                                         if (!client.hidden) {
   13881                                             app.hidden = false;
   13882                                         }
   13883                                         if (client.keeping) {
   13884                                             app.keeping = true;
   13885                                         }
   13886                                         adjType = "service";
   13887                                     }
   13888                                 }
   13889                                 if (adjType != null) {
   13890                                     app.adjType = adjType;
   13891                                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   13892                                             .REASON_SERVICE_IN_USE;
   13893                                     app.adjSource = cr.binding.client;
   13894                                     app.adjSourceOom = clientAdj;
   13895                                     app.adjTarget = s.name;
   13896                                 }
   13897                                 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   13898                                     if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   13899                                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   13900                                     }
   13901                                 }
   13902                             }
   13903                             if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
   13904                                 ActivityRecord a = cr.activity;
   13905                                 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
   13906                                         (a.visible || a.state == ActivityState.RESUMED
   13907                                          || a.state == ActivityState.PAUSING)) {
   13908                                     adj = ProcessList.FOREGROUND_APP_ADJ;
   13909                                     if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   13910                                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   13911                                     }
   13912                                     app.hidden = false;
   13913                                     app.adjType = "service";
   13914                                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   13915                                             .REASON_SERVICE_IN_USE;
   13916                                     app.adjSource = a;
   13917                                     app.adjSourceOom = adj;
   13918                                     app.adjTarget = s.name;
   13919                                 }
   13920                             }
   13921                         }
   13922                     }
   13923                 }
   13924             }
   13925 
   13926             // Finally, if this process has active services running in it, we
   13927             // would like to avoid killing it unless it would prevent the current
   13928             // application from running.  By default we put the process in
   13929             // with the rest of the background processes; as we scan through
   13930             // its services we may bump it up from there.
   13931             if (adj > hiddenAdj) {
   13932                 adj = hiddenAdj;
   13933                 app.hidden = false;
   13934                 app.adjType = "bg-services";
   13935             }
   13936         }
   13937 
   13938         if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   13939                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   13940             Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
   13941             while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
   13942                     || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   13943                 ContentProviderRecord cpr = jt.next();
   13944                 if (cpr.clients.size() != 0) {
   13945                     Iterator<ProcessRecord> kt = cpr.clients.iterator();
   13946                     while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
   13947                         ProcessRecord client = kt.next();
   13948                         if (client == app) {
   13949                             // Being our own client is not interesting.
   13950                             continue;
   13951                         }
   13952                         int myHiddenAdj = hiddenAdj;
   13953                         if (myHiddenAdj > client.hiddenAdj) {
   13954                             if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
   13955                                 myHiddenAdj = client.hiddenAdj;
   13956                             } else {
   13957                                 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
   13958                             }
   13959                         }
   13960                         int clientAdj = computeOomAdjLocked(
   13961                             client, myHiddenAdj, TOP_APP, true, doingAll);
   13962                         if (adj > clientAdj) {
   13963                             if (app.hasShownUi && app != mHomeProcess
   13964                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   13965                                 app.adjType = "bg-ui-provider";
   13966                             } else {
   13967                                 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
   13968                                         ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
   13969                                 app.adjType = "provider";
   13970                             }
   13971                             if (!client.hidden) {
   13972                                 app.hidden = false;
   13973                             }
   13974                             if (client.keeping) {
   13975                                 app.keeping = true;
   13976                             }
   13977                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   13978                                     .REASON_PROVIDER_IN_USE;
   13979                             app.adjSource = client;
   13980                             app.adjSourceOom = clientAdj;
   13981                             app.adjTarget = cpr.name;
   13982                         }
   13983                         if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   13984                             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13985                         }
   13986                     }
   13987                 }
   13988                 // If the provider has external (non-framework) process
   13989                 // dependencies, ensure that its adjustment is at least
   13990                 // FOREGROUND_APP_ADJ.
   13991                 if (cpr.externals != 0) {
   13992                     if (adj > ProcessList.FOREGROUND_APP_ADJ) {
   13993                         adj = ProcessList.FOREGROUND_APP_ADJ;
   13994                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   13995                         app.hidden = false;
   13996                         app.keeping = true;
   13997                         app.adjType = "provider";
   13998                         app.adjTarget = cpr.name;
   13999                     }
   14000                 }
   14001             }
   14002         }
   14003 
   14004         app.curRawAdj = adj;
   14005 
   14006         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
   14007         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
   14008         if (adj > app.maxAdj) {
   14009             adj = app.maxAdj;
   14010             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   14011                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   14012             }
   14013         }
   14014         if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
   14015             app.keeping = true;
   14016         }
   14017 
   14018         if (app.hasAboveClient) {
   14019             // If this process has bound to any services with BIND_ABOVE_CLIENT,
   14020             // then we need to drop its adjustment to be lower than the service's
   14021             // in order to honor the request.  We want to drop it by one adjustment
   14022             // level...  but there is special meaning applied to various levels so
   14023             // we will skip some of them.
   14024             if (adj < ProcessList.FOREGROUND_APP_ADJ) {
   14025                 // System process will not get dropped, ever
   14026             } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
   14027                 adj = ProcessList.VISIBLE_APP_ADJ;
   14028             } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
   14029                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   14030             } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
   14031                 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
   14032             } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
   14033                 adj++;
   14034             }
   14035         }
   14036 
   14037         if (adj == ProcessList.SERVICE_ADJ) {
   14038             if (doingAll) {
   14039                 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
   14040                 mNewNumServiceProcs++;
   14041             }
   14042             if (app.serviceb) {
   14043                 adj = ProcessList.SERVICE_B_ADJ;
   14044             }
   14045         } else {
   14046             app.serviceb = false;
   14047         }
   14048 
   14049         app.curAdj = adj;
   14050         app.curSchedGroup = schedGroup;
   14051 
   14052         if (hadForegroundActivities != app.foregroundActivities) {
   14053             mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
   14054                     app.foregroundActivities).sendToTarget();
   14055         }
   14056 
   14057         return app.curRawAdj;
   14058     }
   14059 
   14060     /**
   14061      * Ask a given process to GC right now.
   14062      */
   14063     final void performAppGcLocked(ProcessRecord app) {
   14064         try {
   14065             app.lastRequestedGc = SystemClock.uptimeMillis();
   14066             if (app.thread != null) {
   14067                 if (app.reportLowMemory) {
   14068                     app.reportLowMemory = false;
   14069                     app.thread.scheduleLowMemory();
   14070                 } else {
   14071                     app.thread.processInBackground();
   14072                 }
   14073             }
   14074         } catch (Exception e) {
   14075             // whatever.
   14076         }
   14077     }
   14078 
   14079     /**
   14080      * Returns true if things are idle enough to perform GCs.
   14081      */
   14082     private final boolean canGcNowLocked() {
   14083         return mParallelBroadcasts.size() == 0
   14084                 && mOrderedBroadcasts.size() == 0
   14085                 && (mSleeping || (mMainStack.mResumedActivity != null &&
   14086                         mMainStack.mResumedActivity.idle));
   14087     }
   14088 
   14089     /**
   14090      * Perform GCs on all processes that are waiting for it, but only
   14091      * if things are idle.
   14092      */
   14093     final void performAppGcsLocked() {
   14094         final int N = mProcessesToGc.size();
   14095         if (N <= 0) {
   14096             return;
   14097         }
   14098         if (canGcNowLocked()) {
   14099             while (mProcessesToGc.size() > 0) {
   14100                 ProcessRecord proc = mProcessesToGc.remove(0);
   14101                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
   14102                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
   14103                             <= SystemClock.uptimeMillis()) {
   14104                         // To avoid spamming the system, we will GC processes one
   14105                         // at a time, waiting a few seconds between each.
   14106                         performAppGcLocked(proc);
   14107                         scheduleAppGcsLocked();
   14108                         return;
   14109                     } else {
   14110                         // It hasn't been long enough since we last GCed this
   14111                         // process...  put it in the list to wait for its time.
   14112                         addProcessToGcListLocked(proc);
   14113                         break;
   14114                     }
   14115                 }
   14116             }
   14117 
   14118             scheduleAppGcsLocked();
   14119         }
   14120     }
   14121 
   14122     /**
   14123      * If all looks good, perform GCs on all processes waiting for them.
   14124      */
   14125     final void performAppGcsIfAppropriateLocked() {
   14126         if (canGcNowLocked()) {
   14127             performAppGcsLocked();
   14128             return;
   14129         }
   14130         // Still not idle, wait some more.
   14131         scheduleAppGcsLocked();
   14132     }
   14133 
   14134     /**
   14135      * Schedule the execution of all pending app GCs.
   14136      */
   14137     final void scheduleAppGcsLocked() {
   14138         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
   14139 
   14140         if (mProcessesToGc.size() > 0) {
   14141             // Schedule a GC for the time to the next process.
   14142             ProcessRecord proc = mProcessesToGc.get(0);
   14143             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
   14144 
   14145             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
   14146             long now = SystemClock.uptimeMillis();
   14147             if (when < (now+GC_TIMEOUT)) {
   14148                 when = now + GC_TIMEOUT;
   14149             }
   14150             mHandler.sendMessageAtTime(msg, when);
   14151         }
   14152     }
   14153 
   14154     /**
   14155      * Add a process to the array of processes waiting to be GCed.  Keeps the
   14156      * list in sorted order by the last GC time.  The process can't already be
   14157      * on the list.
   14158      */
   14159     final void addProcessToGcListLocked(ProcessRecord proc) {
   14160         boolean added = false;
   14161         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
   14162             if (mProcessesToGc.get(i).lastRequestedGc <
   14163                     proc.lastRequestedGc) {
   14164                 added = true;
   14165                 mProcessesToGc.add(i+1, proc);
   14166                 break;
   14167             }
   14168         }
   14169         if (!added) {
   14170             mProcessesToGc.add(0, proc);
   14171         }
   14172     }
   14173 
   14174     /**
   14175      * Set up to ask a process to GC itself.  This will either do it
   14176      * immediately, or put it on the list of processes to gc the next
   14177      * time things are idle.
   14178      */
   14179     final void scheduleAppGcLocked(ProcessRecord app) {
   14180         long now = SystemClock.uptimeMillis();
   14181         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
   14182             return;
   14183         }
   14184         if (!mProcessesToGc.contains(app)) {
   14185             addProcessToGcListLocked(app);
   14186             scheduleAppGcsLocked();
   14187         }
   14188     }
   14189 
   14190     final void checkExcessivePowerUsageLocked(boolean doKills) {
   14191         updateCpuStatsNow();
   14192 
   14193         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   14194         boolean doWakeKills = doKills;
   14195         boolean doCpuKills = doKills;
   14196         if (mLastPowerCheckRealtime == 0) {
   14197             doWakeKills = false;
   14198         }
   14199         if (mLastPowerCheckUptime == 0) {
   14200             doCpuKills = false;
   14201         }
   14202         if (stats.isScreenOn()) {
   14203             doWakeKills = false;
   14204         }
   14205         final long curRealtime = SystemClock.elapsedRealtime();
   14206         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
   14207         final long curUptime = SystemClock.uptimeMillis();
   14208         final long uptimeSince = curUptime - mLastPowerCheckUptime;
   14209         mLastPowerCheckRealtime = curRealtime;
   14210         mLastPowerCheckUptime = curUptime;
   14211         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
   14212             doWakeKills = false;
   14213         }
   14214         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
   14215             doCpuKills = false;
   14216         }
   14217         int i = mLruProcesses.size();
   14218         while (i > 0) {
   14219             i--;
   14220             ProcessRecord app = mLruProcesses.get(i);
   14221             if (!app.keeping) {
   14222                 long wtime;
   14223                 synchronized (stats) {
   14224                     wtime = stats.getProcessWakeTime(app.info.uid,
   14225                             app.pid, curRealtime);
   14226                 }
   14227                 long wtimeUsed = wtime - app.lastWakeTime;
   14228                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
   14229                 if (DEBUG_POWER) {
   14230                     StringBuilder sb = new StringBuilder(128);
   14231                     sb.append("Wake for ");
   14232                     app.toShortString(sb);
   14233                     sb.append(": over ");
   14234                     TimeUtils.formatDuration(realtimeSince, sb);
   14235                     sb.append(" used ");
   14236                     TimeUtils.formatDuration(wtimeUsed, sb);
   14237                     sb.append(" (");
   14238                     sb.append((wtimeUsed*100)/realtimeSince);
   14239                     sb.append("%)");
   14240                     Slog.i(TAG, sb.toString());
   14241                     sb.setLength(0);
   14242                     sb.append("CPU for ");
   14243                     app.toShortString(sb);
   14244                     sb.append(": over ");
   14245                     TimeUtils.formatDuration(uptimeSince, sb);
   14246                     sb.append(" used ");
   14247                     TimeUtils.formatDuration(cputimeUsed, sb);
   14248                     sb.append(" (");
   14249                     sb.append((cputimeUsed*100)/uptimeSince);
   14250                     sb.append("%)");
   14251                     Slog.i(TAG, sb.toString());
   14252                 }
   14253                 // If a process has held a wake lock for more
   14254                 // than 50% of the time during this period,
   14255                 // that sounds pad.  Kill!
   14256                 if (doWakeKills && realtimeSince > 0
   14257                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
   14258                     synchronized (stats) {
   14259                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
   14260                                 realtimeSince, wtimeUsed);
   14261                     }
   14262                     Slog.w(TAG, "Excessive wake lock in " + app.processName
   14263                             + " (pid " + app.pid + "): held " + wtimeUsed
   14264                             + " during " + realtimeSince);
   14265                     EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   14266                             app.processName, app.setAdj, "excessive wake lock");
   14267                     Process.killProcessQuiet(app.pid);
   14268                 } else if (doCpuKills && uptimeSince > 0
   14269                         && ((cputimeUsed*100)/uptimeSince) >= 50) {
   14270                     synchronized (stats) {
   14271                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
   14272                                 uptimeSince, cputimeUsed);
   14273                     }
   14274                     Slog.w(TAG, "Excessive CPU in " + app.processName
   14275                             + " (pid " + app.pid + "): used " + cputimeUsed
   14276                             + " during " + uptimeSince);
   14277                     EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   14278                             app.processName, app.setAdj, "excessive cpu");
   14279                     Process.killProcessQuiet(app.pid);
   14280                 } else {
   14281                     app.lastWakeTime = wtime;
   14282                     app.lastCpuTime = app.curCpuTime;
   14283                 }
   14284             }
   14285         }
   14286     }
   14287 
   14288     private final boolean updateOomAdjLocked(
   14289             ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
   14290         app.hiddenAdj = hiddenAdj;
   14291 
   14292         if (app.thread == null) {
   14293             return false;
   14294         }
   14295 
   14296         final boolean wasKeeping = app.keeping;
   14297 
   14298         boolean success = true;
   14299 
   14300         computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
   14301 
   14302         if (app.curRawAdj != app.setRawAdj) {
   14303             if (false) {
   14304                 // Removing for now.  Forcing GCs is not so useful anymore
   14305                 // with Dalvik, and the new memory level hint facility is
   14306                 // better for what we need to do these days.
   14307                 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
   14308                         && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   14309                     // If this app is transitioning from foreground to
   14310                     // non-foreground, have it do a gc.
   14311                     scheduleAppGcLocked(app);
   14312                 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
   14313                         && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
   14314                     // Likewise do a gc when an app is moving in to the
   14315                     // background (such as a service stopping).
   14316                     scheduleAppGcLocked(app);
   14317                 }
   14318             }
   14319 
   14320             if (wasKeeping && !app.keeping) {
   14321                 // This app is no longer something we want to keep.  Note
   14322                 // its current wake lock time to later know to kill it if
   14323                 // it is not behaving well.
   14324                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   14325                 synchronized (stats) {
   14326                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
   14327                             app.pid, SystemClock.elapsedRealtime());
   14328                 }
   14329                 app.lastCpuTime = app.curCpuTime;
   14330             }
   14331 
   14332             app.setRawAdj = app.curRawAdj;
   14333         }
   14334 
   14335         if (app.curAdj != app.setAdj) {
   14336             if (Process.setOomAdj(app.pid, app.curAdj)) {
   14337                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
   14338                     TAG, "Set " + app.pid + " " + app.processName +
   14339                     " adj " + app.curAdj + ": " + app.adjType);
   14340                 app.setAdj = app.curAdj;
   14341             } else {
   14342                 success = false;
   14343                 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
   14344             }
   14345         }
   14346         if (app.setSchedGroup != app.curSchedGroup) {
   14347             app.setSchedGroup = app.curSchedGroup;
   14348             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   14349                     "Setting process group of " + app.processName
   14350                     + " to " + app.curSchedGroup);
   14351             if (app.waitingToKill != null &&
   14352                     app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
   14353                 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
   14354                 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   14355                         app.processName, app.setAdj, app.waitingToKill);
   14356                 Process.killProcessQuiet(app.pid);
   14357                 success = false;
   14358             } else {
   14359                 if (true) {
   14360                     long oldId = Binder.clearCallingIdentity();
   14361                     try {
   14362                         Process.setProcessGroup(app.pid, app.curSchedGroup);
   14363                     } catch (Exception e) {
   14364                         Slog.w(TAG, "Failed setting process group of " + app.pid
   14365                                 + " to " + app.curSchedGroup);
   14366                         e.printStackTrace();
   14367                     } finally {
   14368                         Binder.restoreCallingIdentity(oldId);
   14369                     }
   14370                 } else {
   14371                     if (app.thread != null) {
   14372                         try {
   14373                             app.thread.setSchedulingGroup(app.curSchedGroup);
   14374                         } catch (RemoteException e) {
   14375                         }
   14376                     }
   14377                 }
   14378             }
   14379         }
   14380         return success;
   14381     }
   14382 
   14383     private final ActivityRecord resumedAppLocked() {
   14384         ActivityRecord resumedActivity = mMainStack.mResumedActivity;
   14385         if (resumedActivity == null || resumedActivity.app == null) {
   14386             resumedActivity = mMainStack.mPausingActivity;
   14387             if (resumedActivity == null || resumedActivity.app == null) {
   14388                 resumedActivity = mMainStack.topRunningActivityLocked(null);
   14389             }
   14390         }
   14391         return resumedActivity;
   14392     }
   14393 
   14394     private final boolean updateOomAdjLocked(ProcessRecord app) {
   14395         final ActivityRecord TOP_ACT = resumedAppLocked();
   14396         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   14397         int curAdj = app.curAdj;
   14398         final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
   14399             && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
   14400 
   14401         mAdjSeq++;
   14402 
   14403         boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
   14404         final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
   14405             && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
   14406         if (nowHidden != wasHidden) {
   14407             // Changed to/from hidden state, so apps after it in the LRU
   14408             // list may also be changed.
   14409             updateOomAdjLocked();
   14410         }
   14411         return success;
   14412     }
   14413 
   14414     final void updateOomAdjLocked() {
   14415         final ActivityRecord TOP_ACT = resumedAppLocked();
   14416         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   14417 
   14418         if (false) {
   14419             RuntimeException e = new RuntimeException();
   14420             e.fillInStackTrace();
   14421             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
   14422         }
   14423 
   14424         mAdjSeq++;
   14425         mNewNumServiceProcs = 0;
   14426 
   14427         // Let's determine how many processes we have running vs.
   14428         // how many slots we have for background processes; we may want
   14429         // to put multiple processes in a slot of there are enough of
   14430         // them.
   14431         int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
   14432         int factor = (mLruProcesses.size()-4)/numSlots;
   14433         if (factor < 1) factor = 1;
   14434         int step = 0;
   14435         int numHidden = 0;
   14436 
   14437         // First update the OOM adjustment for each of the
   14438         // application processes based on their current state.
   14439         int i = mLruProcesses.size();
   14440         int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
   14441         while (i > 0) {
   14442             i--;
   14443             ProcessRecord app = mLruProcesses.get(i);
   14444             //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
   14445             updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
   14446             if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
   14447                 && app.curAdj == curHiddenAdj) {
   14448                 step++;
   14449                 if (step >= factor) {
   14450                     step = 0;
   14451                     curHiddenAdj++;
   14452                 }
   14453             }
   14454             if (!app.killedBackground) {
   14455                 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   14456                     numHidden++;
   14457                     if (numHidden > mProcessLimit) {
   14458                         Slog.i(TAG, "No longer want " + app.processName
   14459                                 + " (pid " + app.pid + "): hidden #" + numHidden);
   14460                         EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   14461                                 app.processName, app.setAdj, "too many background");
   14462                         app.killedBackground = true;
   14463                         Process.killProcessQuiet(app.pid);
   14464                     }
   14465                 }
   14466             }
   14467         }
   14468 
   14469         mNumServiceProcs = mNewNumServiceProcs;
   14470 
   14471         // Now determine the memory trimming level of background processes.
   14472         // Unfortunately we need to start at the back of the list to do this
   14473         // properly.  We only do this if the number of background apps we
   14474         // are managing to keep around is less than half the maximum we desire;
   14475         // if we are keeping a good number around, we'll let them use whatever
   14476         // memory they want.
   14477         if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
   14478             final int N = mLruProcesses.size();
   14479             factor = numHidden/3;
   14480             int minFactor = 2;
   14481             if (mHomeProcess != null) minFactor++;
   14482             if (mPreviousProcess != null) minFactor++;
   14483             if (factor < minFactor) factor = minFactor;
   14484             step = 0;
   14485             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
   14486             for (i=0; i<N; i++) {
   14487                 ProcessRecord app = mLruProcesses.get(i);
   14488                 if (app.curAdj >= ProcessList.HOME_APP_ADJ
   14489                         && app.curAdj != ProcessList.SERVICE_B_ADJ
   14490                         && !app.killedBackground) {
   14491                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
   14492                         try {
   14493                             app.thread.scheduleTrimMemory(curLevel);
   14494                         } catch (RemoteException e) {
   14495                         }
   14496                         if (false) {
   14497                             // For now we won't do this; our memory trimming seems
   14498                             // to be good enough at this point that destroying
   14499                             // activities causes more harm than good.
   14500                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
   14501                                     && app != mHomeProcess && app != mPreviousProcess) {
   14502                                 // For these apps we will also finish their activities
   14503                                 // to help them free memory.
   14504                                 mMainStack.destroyActivitiesLocked(app, false, "trim");
   14505                             }
   14506                         }
   14507                     }
   14508                     app.trimMemoryLevel = curLevel;
   14509                     step++;
   14510                     if (step >= factor) {
   14511                         switch (curLevel) {
   14512                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
   14513                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
   14514                                 break;
   14515                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
   14516                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   14517                                 break;
   14518                         }
   14519                     }
   14520                 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   14521                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
   14522                             && app.thread != null) {
   14523                         try {
   14524                             app.thread.scheduleTrimMemory(
   14525                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   14526                         } catch (RemoteException e) {
   14527                         }
   14528                     }
   14529                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   14530                 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
   14531                         && app.pendingUiClean) {
   14532                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
   14533                             && app.thread != null) {
   14534                         try {
   14535                             app.thread.scheduleTrimMemory(
   14536                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   14537                         } catch (RemoteException e) {
   14538                         }
   14539                     }
   14540                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
   14541                     app.pendingUiClean = false;
   14542                 } else {
   14543                     app.trimMemoryLevel = 0;
   14544                 }
   14545             }
   14546         } else {
   14547             final int N = mLruProcesses.size();
   14548             for (i=0; i<N; i++) {
   14549                 ProcessRecord app = mLruProcesses.get(i);
   14550                 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
   14551                         && app.pendingUiClean) {
   14552                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
   14553                             && app.thread != null) {
   14554                         try {
   14555                             app.thread.scheduleTrimMemory(
   14556                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   14557                         } catch (RemoteException e) {
   14558                         }
   14559                     }
   14560                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
   14561                     app.pendingUiClean = false;
   14562                 } else {
   14563                     app.trimMemoryLevel = 0;
   14564                 }
   14565             }
   14566         }
   14567 
   14568         if (mAlwaysFinishActivities) {
   14569             mMainStack.destroyActivitiesLocked(null, false, "always-finish");
   14570         }
   14571     }
   14572 
   14573     final void trimApplications() {
   14574         synchronized (this) {
   14575             int i;
   14576 
   14577             // First remove any unused application processes whose package
   14578             // has been removed.
   14579             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
   14580                 final ProcessRecord app = mRemovedProcesses.get(i);
   14581                 if (app.activities.size() == 0
   14582                         && app.curReceiver == null && app.services.size() == 0) {
   14583                     Slog.i(
   14584                         TAG, "Exiting empty application process "
   14585                         + app.processName + " ("
   14586                         + (app.thread != null ? app.thread.asBinder() : null)
   14587                         + ")\n");
   14588                     if (app.pid > 0 && app.pid != MY_PID) {
   14589                         EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   14590                                 app.processName, app.setAdj, "empty");
   14591                         Process.killProcessQuiet(app.pid);
   14592                     } else {
   14593                         try {
   14594                             app.thread.scheduleExit();
   14595                         } catch (Exception e) {
   14596                             // Ignore exceptions.
   14597                         }
   14598                     }
   14599                     cleanUpApplicationRecordLocked(app, false, true, -1);
   14600                     mRemovedProcesses.remove(i);
   14601 
   14602                     if (app.persistent) {
   14603                         if (app.persistent) {
   14604                             addAppLocked(app.info);
   14605                         }
   14606                     }
   14607                 }
   14608             }
   14609 
   14610             // Now update the oom adj for all processes.
   14611             updateOomAdjLocked();
   14612         }
   14613     }
   14614 
   14615     /** This method sends the specified signal to each of the persistent apps */
   14616     public void signalPersistentProcesses(int sig) throws RemoteException {
   14617         if (sig != Process.SIGNAL_USR1) {
   14618             throw new SecurityException("Only SIGNAL_USR1 is allowed");
   14619         }
   14620 
   14621         synchronized (this) {
   14622             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
   14623                     != PackageManager.PERMISSION_GRANTED) {
   14624                 throw new SecurityException("Requires permission "
   14625                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
   14626             }
   14627 
   14628             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   14629                 ProcessRecord r = mLruProcesses.get(i);
   14630                 if (r.thread != null && r.persistent) {
   14631                     Process.sendSignal(r.pid, sig);
   14632                 }
   14633             }
   14634         }
   14635     }
   14636 
   14637     private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
   14638         if (proc == null || proc == mProfileProc) {
   14639             proc = mProfileProc;
   14640             path = mProfileFile;
   14641             profileType = mProfileType;
   14642             clearProfilerLocked();
   14643         }
   14644         if (proc == null) {
   14645             return;
   14646         }
   14647         try {
   14648             proc.thread.profilerControl(false, path, null, profileType);
   14649         } catch (RemoteException e) {
   14650             throw new IllegalStateException("Process disappeared");
   14651         }
   14652     }
   14653 
   14654     private void clearProfilerLocked() {
   14655         if (mProfileFd != null) {
   14656             try {
   14657                 mProfileFd.close();
   14658             } catch (IOException e) {
   14659             }
   14660         }
   14661         mProfileApp = null;
   14662         mProfileProc = null;
   14663         mProfileFile = null;
   14664         mProfileType = 0;
   14665         mAutoStopProfiler = false;
   14666     }
   14667 
   14668     public boolean profileControl(String process, boolean start,
   14669             String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
   14670 
   14671         try {
   14672             synchronized (this) {
   14673                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   14674                 // its own permission.
   14675                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   14676                         != PackageManager.PERMISSION_GRANTED) {
   14677                     throw new SecurityException("Requires permission "
   14678                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   14679                 }
   14680 
   14681                 if (start && fd == null) {
   14682                     throw new IllegalArgumentException("null fd");
   14683                 }
   14684 
   14685                 ProcessRecord proc = null;
   14686                 if (process != null) {
   14687                     try {
   14688                         int pid = Integer.parseInt(process);
   14689                         synchronized (mPidsSelfLocked) {
   14690                             proc = mPidsSelfLocked.get(pid);
   14691                         }
   14692                     } catch (NumberFormatException e) {
   14693                     }
   14694 
   14695                     if (proc == null) {
   14696                         HashMap<String, SparseArray<ProcessRecord>> all
   14697                                 = mProcessNames.getMap();
   14698                         SparseArray<ProcessRecord> procs = all.get(process);
   14699                         if (procs != null && procs.size() > 0) {
   14700                             proc = procs.valueAt(0);
   14701                         }
   14702                     }
   14703                 }
   14704 
   14705                 if (start && (proc == null || proc.thread == null)) {
   14706                     throw new IllegalArgumentException("Unknown process: " + process);
   14707                 }
   14708 
   14709                 if (start) {
   14710                     stopProfilerLocked(null, null, 0);
   14711                     setProfileApp(proc.info, proc.processName, path, fd, false);
   14712                     mProfileProc = proc;
   14713                     mProfileType = profileType;
   14714                     try {
   14715                         fd = fd.dup();
   14716                     } catch (IOException e) {
   14717                         fd = null;
   14718                     }
   14719                     proc.thread.profilerControl(start, path, fd, profileType);
   14720                     fd = null;
   14721                     mProfileFd = null;
   14722                 } else {
   14723                     stopProfilerLocked(proc, path, profileType);
   14724                     if (fd != null) {
   14725                         try {
   14726                             fd.close();
   14727                         } catch (IOException e) {
   14728                         }
   14729                     }
   14730                 }
   14731 
   14732                 return true;
   14733             }
   14734         } catch (RemoteException e) {
   14735             throw new IllegalStateException("Process disappeared");
   14736         } finally {
   14737             if (fd != null) {
   14738                 try {
   14739                     fd.close();
   14740                 } catch (IOException e) {
   14741                 }
   14742             }
   14743         }
   14744     }
   14745 
   14746     public boolean dumpHeap(String process, boolean managed,
   14747             String path, ParcelFileDescriptor fd) throws RemoteException {
   14748 
   14749         try {
   14750             synchronized (this) {
   14751                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   14752                 // its own permission (same as profileControl).
   14753                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   14754                         != PackageManager.PERMISSION_GRANTED) {
   14755                     throw new SecurityException("Requires permission "
   14756                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   14757                 }
   14758 
   14759                 if (fd == null) {
   14760                     throw new IllegalArgumentException("null fd");
   14761                 }
   14762 
   14763                 ProcessRecord proc = null;
   14764                 try {
   14765                     int pid = Integer.parseInt(process);
   14766                     synchronized (mPidsSelfLocked) {
   14767                         proc = mPidsSelfLocked.get(pid);
   14768                     }
   14769                 } catch (NumberFormatException e) {
   14770                 }
   14771 
   14772                 if (proc == null) {
   14773                     HashMap<String, SparseArray<ProcessRecord>> all
   14774                             = mProcessNames.getMap();
   14775                     SparseArray<ProcessRecord> procs = all.get(process);
   14776                     if (procs != null && procs.size() > 0) {
   14777                         proc = procs.valueAt(0);
   14778                     }
   14779                 }
   14780 
   14781                 if (proc == null || proc.thread == null) {
   14782                     throw new IllegalArgumentException("Unknown process: " + process);
   14783                 }
   14784 
   14785                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   14786                 if (!isDebuggable) {
   14787                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   14788                         throw new SecurityException("Process not debuggable: " + proc);
   14789                     }
   14790                 }
   14791 
   14792                 proc.thread.dumpHeap(managed, path, fd);
   14793                 fd = null;
   14794                 return true;
   14795             }
   14796         } catch (RemoteException e) {
   14797             throw new IllegalStateException("Process disappeared");
   14798         } finally {
   14799             if (fd != null) {
   14800                 try {
   14801                     fd.close();
   14802                 } catch (IOException e) {
   14803                 }
   14804             }
   14805         }
   14806     }
   14807 
   14808     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
   14809     public void monitor() {
   14810         synchronized (this) { }
   14811     }
   14812 
   14813     public void onCoreSettingsChange(Bundle settings) {
   14814         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   14815             ProcessRecord processRecord = mLruProcesses.get(i);
   14816             try {
   14817                 if (processRecord.thread != null) {
   14818                     processRecord.thread.setCoreSettings(settings);
   14819                 }
   14820             } catch (RemoteException re) {
   14821                 /* ignore */
   14822             }
   14823         }
   14824     }
   14825 
   14826     // Multi-user methods
   14827 
   14828     public boolean switchUser(int userid) {
   14829         // TODO
   14830         return true;
   14831     }
   14832 }
   14833