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 static android.content.pm.PackageManager.PERMISSION_GRANTED;
     20 
     21 import com.android.internal.R;
     22 import com.android.internal.os.BatteryStatsImpl;
     23 import com.android.internal.os.ProcessStats;
     24 import com.android.server.AttributeCache;
     25 import com.android.server.IntentResolver;
     26 import com.android.server.ProcessMap;
     27 import com.android.server.SystemServer;
     28 import com.android.server.Watchdog;
     29 import com.android.server.am.ActivityStack.ActivityState;
     30 import com.android.server.wm.WindowManagerService;
     31 
     32 import dalvik.system.Zygote;
     33 
     34 import android.app.Activity;
     35 import android.app.ActivityManager;
     36 import android.app.ActivityManagerNative;
     37 import android.app.ActivityOptions;
     38 import android.app.ActivityThread;
     39 import android.app.AlertDialog;
     40 import android.app.AppGlobals;
     41 import android.app.ApplicationErrorReport;
     42 import android.app.Dialog;
     43 import android.app.IActivityController;
     44 import android.app.IApplicationThread;
     45 import android.app.IInstrumentationWatcher;
     46 import android.app.INotificationManager;
     47 import android.app.IProcessObserver;
     48 import android.app.IServiceConnection;
     49 import android.app.IThumbnailReceiver;
     50 import android.app.Instrumentation;
     51 import android.app.Notification;
     52 import android.app.NotificationManager;
     53 import android.app.PendingIntent;
     54 import android.app.Service;
     55 import android.app.backup.IBackupManager;
     56 import android.content.ActivityNotFoundException;
     57 import android.content.BroadcastReceiver;
     58 import android.content.ClipData;
     59 import android.content.ComponentCallbacks2;
     60 import android.content.ComponentName;
     61 import android.content.ContentProvider;
     62 import android.content.ContentResolver;
     63 import android.content.Context;
     64 import android.content.DialogInterface;
     65 import android.content.IContentProvider;
     66 import android.content.IIntentReceiver;
     67 import android.content.IIntentSender;
     68 import android.content.Intent;
     69 import android.content.IntentFilter;
     70 import android.content.IntentSender;
     71 import android.content.pm.ActivityInfo;
     72 import android.content.pm.ApplicationInfo;
     73 import android.content.pm.ConfigurationInfo;
     74 import android.content.pm.IPackageDataObserver;
     75 import android.content.pm.IPackageManager;
     76 import android.content.pm.InstrumentationInfo;
     77 import android.content.pm.PackageInfo;
     78 import android.content.pm.PackageManager;
     79 import android.content.pm.PackageManager.NameNotFoundException;
     80 import android.content.pm.PathPermission;
     81 import android.content.pm.ProviderInfo;
     82 import android.content.pm.ResolveInfo;
     83 import android.content.pm.ServiceInfo;
     84 import android.content.pm.UserInfo;
     85 import android.content.res.CompatibilityInfo;
     86 import android.content.res.Configuration;
     87 import android.graphics.Bitmap;
     88 import android.net.Proxy;
     89 import android.net.ProxyProperties;
     90 import android.net.Uri;
     91 import android.os.Binder;
     92 import android.os.Build;
     93 import android.os.Bundle;
     94 import android.os.Debug;
     95 import android.os.DropBoxManager;
     96 import android.os.Environment;
     97 import android.os.FileObserver;
     98 import android.os.FileUtils;
     99 import android.os.Handler;
    100 import android.os.IBinder;
    101 import android.os.IPermissionController;
    102 import android.os.Looper;
    103 import android.os.Message;
    104 import android.os.Parcel;
    105 import android.os.ParcelFileDescriptor;
    106 import android.os.Process;
    107 import android.os.RemoteCallbackList;
    108 import android.os.RemoteException;
    109 import android.os.ServiceManager;
    110 import android.os.StrictMode;
    111 import android.os.SystemClock;
    112 import android.os.SystemProperties;
    113 import android.os.UserId;
    114 import android.provider.Settings;
    115 import android.text.format.Time;
    116 import android.util.EventLog;
    117 import android.util.Log;
    118 import android.util.Pair;
    119 import android.util.PrintWriterPrinter;
    120 import android.util.Slog;
    121 import android.util.SparseArray;
    122 import android.util.SparseIntArray;
    123 import android.util.TimeUtils;
    124 import android.view.Gravity;
    125 import android.view.LayoutInflater;
    126 import android.view.View;
    127 import android.view.WindowManager;
    128 import android.view.WindowManagerPolicy;
    129 
    130 import java.io.BufferedInputStream;
    131 import java.io.BufferedOutputStream;
    132 import java.io.BufferedReader;
    133 import java.io.DataInputStream;
    134 import java.io.DataOutputStream;
    135 import java.io.File;
    136 import java.io.FileDescriptor;
    137 import java.io.FileInputStream;
    138 import java.io.FileNotFoundException;
    139 import java.io.FileOutputStream;
    140 import java.io.IOException;
    141 import java.io.InputStreamReader;
    142 import java.io.PrintWriter;
    143 import java.io.StringWriter;
    144 import java.lang.ref.WeakReference;
    145 import java.util.ArrayList;
    146 import java.util.Collection;
    147 import java.util.Collections;
    148 import java.util.Comparator;
    149 import java.util.HashMap;
    150 import java.util.HashSet;
    151 import java.util.Iterator;
    152 import java.util.List;
    153 import java.util.Locale;
    154 import java.util.Map;
    155 import java.util.Map.Entry;
    156 import java.util.Set;
    157 import java.util.concurrent.atomic.AtomicBoolean;
    158 import java.util.concurrent.atomic.AtomicLong;
    159 
    160 public final class ActivityManagerService extends ActivityManagerNative
    161         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    162     private static final String USER_DATA_DIR = "/data/user/";
    163     static final String TAG = "ActivityManager";
    164     static final String TAG_MU = "ActivityManagerServiceMU";
    165     static final boolean DEBUG = false;
    166     static final boolean localLOGV = DEBUG;
    167     static final boolean DEBUG_SWITCH = localLOGV || false;
    168     static final boolean DEBUG_TASKS = localLOGV || false;
    169     static final boolean DEBUG_PAUSE = localLOGV || false;
    170     static final boolean DEBUG_OOM_ADJ = localLOGV || false;
    171     static final boolean DEBUG_TRANSITION = localLOGV || false;
    172     static final boolean DEBUG_BROADCAST = localLOGV || false;
    173     static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
    174     static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
    175     static final boolean DEBUG_SERVICE = localLOGV || false;
    176     static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
    177     static final boolean DEBUG_VISBILITY = localLOGV || false;
    178     static final boolean DEBUG_PROCESSES = localLOGV || false;
    179     static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
    180     static final boolean DEBUG_PROVIDER = localLOGV || false;
    181     static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
    182     static final boolean DEBUG_USER_LEAVING = localLOGV || false;
    183     static final boolean DEBUG_RESULTS = localLOGV || false;
    184     static final boolean DEBUG_BACKUP = localLOGV || false;
    185     static final boolean DEBUG_CONFIGURATION = localLOGV || false;
    186     static final boolean DEBUG_POWER = localLOGV || false;
    187     static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
    188     static final boolean DEBUG_MU = localLOGV || false;
    189     static final boolean VALIDATE_TOKENS = false;
    190     static final boolean SHOW_ACTIVITY_START_TIME = true;
    191 
    192     // Control over CPU and battery monitoring.
    193     static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
    194     static final boolean MONITOR_CPU_USAGE = true;
    195     static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
    196     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
    197     static final boolean MONITOR_THREAD_CPU_USAGE = false;
    198 
    199     // The flags that are set for all calls we make to the package manager.
    200     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
    201 
    202     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
    203 
    204     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
    205 
    206     // Maximum number of recent tasks that we can remember.
    207     static final int MAX_RECENT_TASKS = 20;
    208 
    209     // Amount of time after a call to stopAppSwitches() during which we will
    210     // prevent further untrusted switches from happening.
    211     static final long APP_SWITCH_DELAY_TIME = 5*1000;
    212 
    213     // How long we wait for a launched process to attach to the activity manager
    214     // before we decide it's never going to come up for real.
    215     static final int PROC_START_TIMEOUT = 10*1000;
    216 
    217     // How long we wait for a launched process to attach to the activity manager
    218     // before we decide it's never going to come up for real, when the process was
    219     // started with a wrapper for instrumentation (such as Valgrind) because it
    220     // could take much longer than usual.
    221     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
    222 
    223     // How long to wait after going idle before forcing apps to GC.
    224     static final int GC_TIMEOUT = 5*1000;
    225 
    226     // The minimum amount of time between successive GC requests for a process.
    227     static final int GC_MIN_INTERVAL = 60*1000;
    228 
    229     // The rate at which we check for apps using excessive power -- 15 mins.
    230     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
    231 
    232     // The minimum sample duration we will allow before deciding we have
    233     // enough data on wake locks to start killing things.
    234     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    235 
    236     // The minimum sample duration we will allow before deciding we have
    237     // enough data on CPU usage to start killing things.
    238     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    239 
    240     // How long we allow a receiver to run before giving up on it.
    241     static final int BROADCAST_FG_TIMEOUT = 10*1000;
    242     static final int BROADCAST_BG_TIMEOUT = 60*1000;
    243 
    244     // How long we wait for a service to finish executing.
    245     static final int SERVICE_TIMEOUT = 20*1000;
    246 
    247     // How long a service needs to be running until restarting its process
    248     // is no longer considered to be a relaunch of the service.
    249     static final int SERVICE_RESTART_DURATION = 5*1000;
    250 
    251     // How long a service needs to be running until it will start back at
    252     // SERVICE_RESTART_DURATION after being killed.
    253     static final int SERVICE_RESET_RUN_DURATION = 60*1000;
    254 
    255     // Multiplying factor to increase restart duration time by, for each time
    256     // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
    257     static final int SERVICE_RESTART_DURATION_FACTOR = 4;
    258 
    259     // The minimum amount of time between restarting services that we allow.
    260     // That is, when multiple services are restarting, we won't allow each
    261     // to restart less than this amount of time from the last one.
    262     static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
    263 
    264     // Maximum amount of time for there to be no activity on a service before
    265     // we consider it non-essential and allow its process to go on the
    266     // LRU background list.
    267     static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
    268 
    269     // How long we wait until we timeout on key dispatching.
    270     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
    271 
    272     // How long we wait until we timeout on key dispatching during instrumentation.
    273     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
    274 
    275     static final int MY_PID = Process.myPid();
    276 
    277     static final String[] EMPTY_STRING_ARRAY = new String[0];
    278 
    279     public ActivityStack mMainStack;
    280 
    281     private final boolean mHeadless;
    282 
    283     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
    284     // default actuion automatically.  Important for devices without direct input
    285     // devices.
    286     private boolean mShowDialogs = true;
    287 
    288     /**
    289      * Description of a request to start a new activity, which has been held
    290      * due to app switches being disabled.
    291      */
    292     static class PendingActivityLaunch {
    293         ActivityRecord r;
    294         ActivityRecord sourceRecord;
    295         int startFlags;
    296     }
    297 
    298     final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
    299             = new ArrayList<PendingActivityLaunch>();
    300 
    301 
    302     BroadcastQueue mFgBroadcastQueue;
    303     BroadcastQueue mBgBroadcastQueue;
    304     // Convenient for easy iteration over the queues. Foreground is first
    305     // so that dispatch of foreground broadcasts gets precedence.
    306     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
    307 
    308     BroadcastQueue broadcastQueueForIntent(Intent intent) {
    309         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
    310         if (DEBUG_BACKGROUND_BROADCAST) {
    311             Slog.i(TAG, "Broadcast intent " + intent + " on "
    312                     + (isFg ? "foreground" : "background")
    313                     + " queue");
    314         }
    315         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
    316     }
    317 
    318     BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
    319         for (BroadcastQueue queue : mBroadcastQueues) {
    320             BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
    321             if (r != null) {
    322                 return r;
    323             }
    324         }
    325         return null;
    326     }
    327 
    328     /**
    329      * Activity we have told the window manager to have key focus.
    330      */
    331     ActivityRecord mFocusedActivity = null;
    332     /**
    333      * List of intents that were used to start the most recent tasks.
    334      */
    335     final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
    336 
    337     /**
    338      * Process management.
    339      */
    340     final ProcessList mProcessList = new ProcessList();
    341 
    342     /**
    343      * All of the applications we currently have running organized by name.
    344      * The keys are strings of the application package name (as
    345      * returned by the package manager), and the keys are ApplicationRecord
    346      * objects.
    347      */
    348     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
    349 
    350     /**
    351      * The currently running isolated processes.
    352      */
    353     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
    354 
    355     /**
    356      * Counter for assigning isolated process uids, to avoid frequently reusing the
    357      * same ones.
    358      */
    359     int mNextIsolatedProcessUid = 0;
    360 
    361     /**
    362      * The currently running heavy-weight process, if any.
    363      */
    364     ProcessRecord mHeavyWeightProcess = null;
    365 
    366     /**
    367      * The last time that various processes have crashed.
    368      */
    369     final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
    370 
    371     /**
    372      * Set of applications that we consider to be bad, and will reject
    373      * incoming broadcasts from (which the user has no control over).
    374      * Processes are added to this set when they have crashed twice within
    375      * a minimum amount of time; they are removed from it when they are
    376      * later restarted (hopefully due to some user action).  The value is the
    377      * time it was added to the list.
    378      */
    379     final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
    380 
    381     /**
    382      * All of the processes we currently have running organized by pid.
    383      * The keys are the pid running the application.
    384      *
    385      * <p>NOTE: This object is protected by its own lock, NOT the global
    386      * activity manager lock!
    387      */
    388     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
    389 
    390     /**
    391      * All of the processes that have been forced to be foreground.  The key
    392      * is the pid of the caller who requested it (we hold a death
    393      * link on it).
    394      */
    395     abstract class ForegroundToken implements IBinder.DeathRecipient {
    396         int pid;
    397         IBinder token;
    398     }
    399     final SparseArray<ForegroundToken> mForegroundProcesses
    400             = new SparseArray<ForegroundToken>();
    401 
    402     /**
    403      * List of records for processes that someone had tried to start before the
    404      * system was ready.  We don't start them at that point, but ensure they
    405      * are started by the time booting is complete.
    406      */
    407     final ArrayList<ProcessRecord> mProcessesOnHold
    408             = new ArrayList<ProcessRecord>();
    409 
    410     /**
    411      * List of persistent applications that are in the process
    412      * of being started.
    413      */
    414     final ArrayList<ProcessRecord> mPersistentStartingProcesses
    415             = new ArrayList<ProcessRecord>();
    416 
    417     /**
    418      * Processes that are being forcibly torn down.
    419      */
    420     final ArrayList<ProcessRecord> mRemovedProcesses
    421             = new ArrayList<ProcessRecord>();
    422 
    423     /**
    424      * List of running applications, sorted by recent usage.
    425      * The first entry in the list is the least recently used.
    426      * It contains ApplicationRecord objects.  This list does NOT include
    427      * any persistent application records (since we never want to exit them).
    428      */
    429     final ArrayList<ProcessRecord> mLruProcesses
    430             = new ArrayList<ProcessRecord>();
    431 
    432     /**
    433      * List of processes that should gc as soon as things are idle.
    434      */
    435     final ArrayList<ProcessRecord> mProcessesToGc
    436             = new ArrayList<ProcessRecord>();
    437 
    438     /**
    439      * This is the process holding what we currently consider to be
    440      * the "home" activity.
    441      */
    442     ProcessRecord mHomeProcess;
    443 
    444     /**
    445      * This is the process holding the activity the user last visited that
    446      * is in a different process from the one they are currently in.
    447      */
    448     ProcessRecord mPreviousProcess;
    449 
    450     /**
    451      * The time at which the previous process was last visible.
    452      */
    453     long mPreviousProcessVisibleTime;
    454 
    455     /**
    456      * Packages that the user has asked to have run in screen size
    457      * compatibility mode instead of filling the screen.
    458      */
    459     final CompatModePackages mCompatModePackages;
    460 
    461     /**
    462      * Set of PendingResultRecord objects that are currently active.
    463      */
    464     final HashSet mPendingResultRecords = new HashSet();
    465 
    466     /**
    467      * Set of IntentSenderRecord objects that are currently active.
    468      */
    469     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
    470             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
    471 
    472     /**
    473      * Fingerprints (hashCode()) of stack traces that we've
    474      * already logged DropBox entries for.  Guarded by itself.  If
    475      * something (rogue user app) forces this over
    476      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
    477      */
    478     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
    479     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
    480 
    481     /**
    482      * Strict Mode background batched logging state.
    483      *
    484      * The string buffer is guarded by itself, and its lock is also
    485      * used to determine if another batched write is already
    486      * in-flight.
    487      */
    488     private final StringBuilder mStrictModeBuffer = new StringBuilder();
    489 
    490     /**
    491      * Keeps track of all IIntentReceivers that have been registered for
    492      * broadcasts.  Hash keys are the receiver IBinder, hash value is
    493      * a ReceiverList.
    494      */
    495     final HashMap mRegisteredReceivers = new HashMap();
    496 
    497     /**
    498      * Resolver for broadcast intents to registered receivers.
    499      * Holds BroadcastFilter (subclass of IntentFilter).
    500      */
    501     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
    502             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
    503         @Override
    504         protected boolean allowFilterResult(
    505                 BroadcastFilter filter, List<BroadcastFilter> dest) {
    506             IBinder target = filter.receiverList.receiver.asBinder();
    507             for (int i=dest.size()-1; i>=0; i--) {
    508                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
    509                     return false;
    510                 }
    511             }
    512             return true;
    513         }
    514 
    515         @Override
    516         protected String packageForFilter(BroadcastFilter filter) {
    517             return filter.packageName;
    518         }
    519     };
    520 
    521     /**
    522      * State of all active sticky broadcasts.  Keys are the action of the
    523      * sticky Intent, values are an ArrayList of all broadcasted intents with
    524      * that action (which should usually be one).
    525      */
    526     final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
    527             new HashMap<String, ArrayList<Intent>>();
    528 
    529     final ServiceMap mServiceMap = new ServiceMap();
    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     final ProviderMap mProviderMap = new ProviderMap();
    578 
    579     /**
    580      * List of content providers who have clients waiting for them.  The
    581      * application is currently being launched and the provider will be
    582      * removed from this list once it is published.
    583      */
    584     final ArrayList<ContentProviderRecord> mLaunchingProviders
    585             = new ArrayList<ContentProviderRecord>();
    586 
    587     /**
    588      * Global set of specific Uri permissions that have been granted.
    589      */
    590     final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
    591             = new SparseArray<HashMap<Uri, UriPermission>>();
    592 
    593     CoreSettingsObserver mCoreSettingsObserver;
    594 
    595     /**
    596      * Thread-local storage used to carry caller permissions over through
    597      * indirect content-provider access.
    598      * @see #ActivityManagerService.openContentUri()
    599      */
    600     private class Identity {
    601         public int pid;
    602         public int uid;
    603 
    604         Identity(int _pid, int _uid) {
    605             pid = _pid;
    606             uid = _uid;
    607         }
    608     }
    609 
    610     private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
    611 
    612     /**
    613      * All information we have collected about the runtime performance of
    614      * any user id that can impact battery performance.
    615      */
    616     final BatteryStatsService mBatteryStatsService;
    617 
    618     /**
    619      * information about component usage
    620      */
    621     final UsageStatsService mUsageStatsService;
    622 
    623     /**
    624      * Current configuration information.  HistoryRecord objects are given
    625      * a reference to this object to indicate which configuration they are
    626      * currently running in, so this object must be kept immutable.
    627      */
    628     Configuration mConfiguration = new Configuration();
    629 
    630     /**
    631      * Current sequencing integer of the configuration, for skipping old
    632      * configurations.
    633      */
    634     int mConfigurationSeq = 0;
    635 
    636     /**
    637      * Hardware-reported OpenGLES version.
    638      */
    639     final int GL_ES_VERSION;
    640 
    641     /**
    642      * List of initialization arguments to pass to all processes when binding applications to them.
    643      * For example, references to the commonly used services.
    644      */
    645     HashMap<String, IBinder> mAppBindArgs;
    646 
    647     /**
    648      * Temporary to avoid allocations.  Protected by main lock.
    649      */
    650     final StringBuilder mStringBuilder = new StringBuilder(256);
    651 
    652     /**
    653      * Used to control how we initialize the service.
    654      */
    655     boolean mStartRunning = false;
    656     ComponentName mTopComponent;
    657     String mTopAction;
    658     String mTopData;
    659     boolean mProcessesReady = false;
    660     boolean mSystemReady = false;
    661     boolean mBooting = false;
    662     boolean mWaitingUpdate = false;
    663     boolean mDidUpdate = false;
    664     boolean mOnBattery = false;
    665     boolean mLaunchWarningShown = false;
    666 
    667     Context mContext;
    668 
    669     int mFactoryTest;
    670 
    671     boolean mCheckedForSetup;
    672 
    673     /**
    674      * The time at which we will allow normal application switches again,
    675      * after a call to {@link #stopAppSwitches()}.
    676      */
    677     long mAppSwitchesAllowedTime;
    678 
    679     /**
    680      * This is set to true after the first switch after mAppSwitchesAllowedTime
    681      * is set; any switches after that will clear the time.
    682      */
    683     boolean mDidAppSwitch;
    684 
    685     /**
    686      * Last time (in realtime) at which we checked for power usage.
    687      */
    688     long mLastPowerCheckRealtime;
    689 
    690     /**
    691      * Last time (in uptime) at which we checked for power usage.
    692      */
    693     long mLastPowerCheckUptime;
    694 
    695     /**
    696      * Set while we are wanting to sleep, to prevent any
    697      * activities from being started/resumed.
    698      */
    699     boolean mSleeping = false;
    700 
    701     /**
    702      * State of external calls telling us if the device is asleep.
    703      */
    704     boolean mWentToSleep = false;
    705 
    706     /**
    707      * State of external call telling us if the lock screen is shown.
    708      */
    709     boolean mLockScreenShown = false;
    710 
    711     /**
    712      * Set if we are shutting down the system, similar to sleeping.
    713      */
    714     boolean mShuttingDown = false;
    715 
    716     /**
    717      * Task identifier that activities are currently being started
    718      * in.  Incremented each time a new task is created.
    719      * todo: Replace this with a TokenSpace class that generates non-repeating
    720      * integers that won't wrap.
    721      */
    722     int mCurTask = 1;
    723 
    724     /**
    725      * Current sequence id for oom_adj computation traversal.
    726      */
    727     int mAdjSeq = 0;
    728 
    729     /**
    730      * Current sequence id for process LRU updating.
    731      */
    732     int mLruSeq = 0;
    733 
    734     /**
    735      * Keep track of the number of service processes we last found, to
    736      * determine on the next iteration which should be B services.
    737      */
    738     int mNumServiceProcs = 0;
    739     int mNewNumServiceProcs = 0;
    740 
    741     /**
    742      * System monitoring: number of processes that died since the last
    743      * N procs were started.
    744      */
    745     int[] mProcDeaths = new int[20];
    746 
    747     /**
    748      * This is set if we had to do a delayed dexopt of an app before launching
    749      * it, to increasing the ANR timeouts in that case.
    750      */
    751     boolean mDidDexOpt;
    752 
    753     String mDebugApp = null;
    754     boolean mWaitForDebugger = false;
    755     boolean mDebugTransient = false;
    756     String mOrigDebugApp = null;
    757     boolean mOrigWaitForDebugger = false;
    758     boolean mAlwaysFinishActivities = false;
    759     IActivityController mController = null;
    760     String mProfileApp = null;
    761     ProcessRecord mProfileProc = null;
    762     String mProfileFile;
    763     ParcelFileDescriptor mProfileFd;
    764     int mProfileType = 0;
    765     boolean mAutoStopProfiler = false;
    766     String mOpenGlTraceApp = null;
    767 
    768     static class ProcessChangeItem {
    769         static final int CHANGE_ACTIVITIES = 1<<0;
    770         static final int CHANGE_IMPORTANCE= 1<<1;
    771         int changes;
    772         int uid;
    773         int pid;
    774         int importance;
    775         boolean foregroundActivities;
    776     }
    777 
    778     final RemoteCallbackList<IProcessObserver> mProcessObservers
    779             = new RemoteCallbackList<IProcessObserver>();
    780     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
    781 
    782     final ArrayList<ProcessChangeItem> mPendingProcessChanges
    783             = new ArrayList<ProcessChangeItem>();
    784     final ArrayList<ProcessChangeItem> mAvailProcessChanges
    785             = new ArrayList<ProcessChangeItem>();
    786 
    787     /**
    788      * Callback of last caller to {@link #requestPss}.
    789      */
    790     Runnable mRequestPssCallback;
    791 
    792     /**
    793      * Remaining processes for which we are waiting results from the last
    794      * call to {@link #requestPss}.
    795      */
    796     final ArrayList<ProcessRecord> mRequestPssList
    797             = new ArrayList<ProcessRecord>();
    798 
    799     /**
    800      * Runtime statistics collection thread.  This object's lock is used to
    801      * protect all related state.
    802      */
    803     final Thread mProcessStatsThread;
    804 
    805     /**
    806      * Used to collect process stats when showing not responding dialog.
    807      * Protected by mProcessStatsThread.
    808      */
    809     final ProcessStats mProcessStats = new ProcessStats(
    810             MONITOR_THREAD_CPU_USAGE);
    811     final AtomicLong mLastCpuTime = new AtomicLong(0);
    812     final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
    813 
    814     long mLastWriteTime = 0;
    815 
    816     /**
    817      * Set to true after the system has finished booting.
    818      */
    819     boolean mBooted = false;
    820 
    821     int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
    822     int mProcessLimitOverride = -1;
    823 
    824     WindowManagerService mWindowManager;
    825 
    826     static ActivityManagerService mSelf;
    827     static ActivityThread mSystemThread;
    828 
    829     private final class AppDeathRecipient implements IBinder.DeathRecipient {
    830         final ProcessRecord mApp;
    831         final int mPid;
    832         final IApplicationThread mAppThread;
    833 
    834         AppDeathRecipient(ProcessRecord app, int pid,
    835                 IApplicationThread thread) {
    836             if (localLOGV) Slog.v(
    837                 TAG, "New death recipient " + this
    838                 + " for thread " + thread.asBinder());
    839             mApp = app;
    840             mPid = pid;
    841             mAppThread = thread;
    842         }
    843 
    844         public void binderDied() {
    845             if (localLOGV) Slog.v(
    846                 TAG, "Death received in " + this
    847                 + " for thread " + mAppThread.asBinder());
    848             synchronized(ActivityManagerService.this) {
    849                 appDiedLocked(mApp, mPid, mAppThread);
    850             }
    851         }
    852     }
    853 
    854     static final int SHOW_ERROR_MSG = 1;
    855     static final int SHOW_NOT_RESPONDING_MSG = 2;
    856     static final int SHOW_FACTORY_ERROR_MSG = 3;
    857     static final int UPDATE_CONFIGURATION_MSG = 4;
    858     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
    859     static final int WAIT_FOR_DEBUGGER_MSG = 6;
    860     static final int SERVICE_TIMEOUT_MSG = 12;
    861     static final int UPDATE_TIME_ZONE = 13;
    862     static final int SHOW_UID_ERROR_MSG = 14;
    863     static final int IM_FEELING_LUCKY_MSG = 15;
    864     static final int PROC_START_TIMEOUT_MSG = 20;
    865     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
    866     static final int KILL_APPLICATION_MSG = 22;
    867     static final int FINALIZE_PENDING_INTENT_MSG = 23;
    868     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
    869     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
    870     static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
    871     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
    872     static final int CLEAR_DNS_CACHE = 28;
    873     static final int UPDATE_HTTP_PROXY = 29;
    874     static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
    875     static final int DISPATCH_PROCESSES_CHANGED = 31;
    876     static final int DISPATCH_PROCESS_DIED = 32;
    877     static final int REPORT_MEM_USAGE = 33;
    878 
    879     static final int FIRST_ACTIVITY_STACK_MSG = 100;
    880     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
    881     static final int FIRST_COMPAT_MODE_MSG = 300;
    882 
    883     AlertDialog mUidAlert;
    884     CompatModeDialog mCompatModeDialog;
    885     long mLastMemUsageReportTime = 0;
    886 
    887     final Handler mHandler = new Handler() {
    888         //public Handler() {
    889         //    if (localLOGV) Slog.v(TAG, "Handler started!");
    890         //}
    891 
    892         public void handleMessage(Message msg) {
    893             switch (msg.what) {
    894             case SHOW_ERROR_MSG: {
    895                 HashMap data = (HashMap) msg.obj;
    896                 synchronized (ActivityManagerService.this) {
    897                     ProcessRecord proc = (ProcessRecord)data.get("app");
    898                     if (proc != null && proc.crashDialog != null) {
    899                         Slog.e(TAG, "App already has crash dialog: " + proc);
    900                         return;
    901                     }
    902                     AppErrorResult res = (AppErrorResult) data.get("result");
    903                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
    904                         Dialog d = new AppErrorDialog(mContext, res, proc);
    905                         d.show();
    906                         proc.crashDialog = d;
    907                     } else {
    908                         // The device is asleep, so just pretend that the user
    909                         // saw a crash dialog and hit "force quit".
    910                         res.set(0);
    911                     }
    912                 }
    913 
    914                 ensureBootCompleted();
    915             } break;
    916             case SHOW_NOT_RESPONDING_MSG: {
    917                 synchronized (ActivityManagerService.this) {
    918                     HashMap data = (HashMap) msg.obj;
    919                     ProcessRecord proc = (ProcessRecord)data.get("app");
    920                     if (proc != null && proc.anrDialog != null) {
    921                         Slog.e(TAG, "App already has anr dialog: " + proc);
    922                         return;
    923                     }
    924 
    925                     Intent intent = new Intent("android.intent.action.ANR");
    926                     if (!mProcessesReady) {
    927                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
    928                                 | Intent.FLAG_RECEIVER_FOREGROUND);
    929                     }
    930                     broadcastIntentLocked(null, null, intent,
    931                             null, null, 0, null, null, null,
    932                             false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
    933 
    934                     if (mShowDialogs) {
    935                         Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
    936                                 mContext, proc, (ActivityRecord)data.get("activity"));
    937                         d.show();
    938                         proc.anrDialog = d;
    939                     } else {
    940                         // Just kill the app if there is no dialog to be shown.
    941                         killAppAtUsersRequest(proc, null);
    942                     }
    943                 }
    944 
    945                 ensureBootCompleted();
    946             } break;
    947             case SHOW_STRICT_MODE_VIOLATION_MSG: {
    948                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
    949                 synchronized (ActivityManagerService.this) {
    950                     ProcessRecord proc = (ProcessRecord) data.get("app");
    951                     if (proc == null) {
    952                         Slog.e(TAG, "App not found when showing strict mode dialog.");
    953                         break;
    954                     }
    955                     if (proc.crashDialog != null) {
    956                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
    957                         return;
    958                     }
    959                     AppErrorResult res = (AppErrorResult) data.get("result");
    960                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
    961                         Dialog d = new StrictModeViolationDialog(mContext, res, proc);
    962                         d.show();
    963                         proc.crashDialog = d;
    964                     } else {
    965                         // The device is asleep, so just pretend that the user
    966                         // saw a crash dialog and hit "force quit".
    967                         res.set(0);
    968                     }
    969                 }
    970                 ensureBootCompleted();
    971             } break;
    972             case SHOW_FACTORY_ERROR_MSG: {
    973                 Dialog d = new FactoryErrorDialog(
    974                     mContext, msg.getData().getCharSequence("msg"));
    975                 d.show();
    976                 ensureBootCompleted();
    977             } break;
    978             case UPDATE_CONFIGURATION_MSG: {
    979                 final ContentResolver resolver = mContext.getContentResolver();
    980                 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
    981             } break;
    982             case GC_BACKGROUND_PROCESSES_MSG: {
    983                 synchronized (ActivityManagerService.this) {
    984                     performAppGcsIfAppropriateLocked();
    985                 }
    986             } break;
    987             case WAIT_FOR_DEBUGGER_MSG: {
    988                 synchronized (ActivityManagerService.this) {
    989                     ProcessRecord app = (ProcessRecord)msg.obj;
    990                     if (msg.arg1 != 0) {
    991                         if (!app.waitedForDebugger) {
    992                             Dialog d = new AppWaitingForDebuggerDialog(
    993                                     ActivityManagerService.this,
    994                                     mContext, app);
    995                             app.waitDialog = d;
    996                             app.waitedForDebugger = true;
    997                             d.show();
    998                         }
    999                     } else {
   1000                         if (app.waitDialog != null) {
   1001                             app.waitDialog.dismiss();
   1002                             app.waitDialog = null;
   1003                         }
   1004                     }
   1005                 }
   1006             } break;
   1007             case SERVICE_TIMEOUT_MSG: {
   1008                 if (mDidDexOpt) {
   1009                     mDidDexOpt = false;
   1010                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   1011                     nmsg.obj = msg.obj;
   1012                     mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
   1013                     return;
   1014                 }
   1015                 serviceTimeout((ProcessRecord)msg.obj);
   1016             } break;
   1017             case UPDATE_TIME_ZONE: {
   1018                 synchronized (ActivityManagerService.this) {
   1019                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1020                         ProcessRecord r = mLruProcesses.get(i);
   1021                         if (r.thread != null) {
   1022                             try {
   1023                                 r.thread.updateTimeZone();
   1024                             } catch (RemoteException ex) {
   1025                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
   1026                             }
   1027                         }
   1028                     }
   1029                 }
   1030             } break;
   1031             case CLEAR_DNS_CACHE: {
   1032                 synchronized (ActivityManagerService.this) {
   1033                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1034                         ProcessRecord r = mLruProcesses.get(i);
   1035                         if (r.thread != null) {
   1036                             try {
   1037                                 r.thread.clearDnsCache();
   1038                             } catch (RemoteException ex) {
   1039                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
   1040                             }
   1041                         }
   1042                     }
   1043                 }
   1044             } break;
   1045             case UPDATE_HTTP_PROXY: {
   1046                 ProxyProperties proxy = (ProxyProperties)msg.obj;
   1047                 String host = "";
   1048                 String port = "";
   1049                 String exclList = "";
   1050                 if (proxy != null) {
   1051                     host = proxy.getHost();
   1052                     port = Integer.toString(proxy.getPort());
   1053                     exclList = proxy.getExclusionList();
   1054                 }
   1055                 synchronized (ActivityManagerService.this) {
   1056                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1057                         ProcessRecord r = mLruProcesses.get(i);
   1058                         if (r.thread != null) {
   1059                             try {
   1060                                 r.thread.setHttpProxy(host, port, exclList);
   1061                             } catch (RemoteException ex) {
   1062                                 Slog.w(TAG, "Failed to update http proxy for: " +
   1063                                         r.info.processName);
   1064                             }
   1065                         }
   1066                     }
   1067                 }
   1068             } break;
   1069             case SHOW_UID_ERROR_MSG: {
   1070                 String title = "System UIDs Inconsistent";
   1071                 String text = "UIDs on the system are inconsistent, you need to wipe your"
   1072                         + " data partition or your device will be unstable.";
   1073                 Log.e(TAG, title + ": " + text);
   1074                 if (mShowDialogs) {
   1075                     // XXX This is a temporary dialog, no need to localize.
   1076                     AlertDialog d = new BaseErrorDialog(mContext);
   1077                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
   1078                     d.setCancelable(false);
   1079                     d.setTitle(title);
   1080                     d.setMessage(text);
   1081                     d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
   1082                             mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
   1083                     mUidAlert = d;
   1084                     d.show();
   1085                 }
   1086             } break;
   1087             case IM_FEELING_LUCKY_MSG: {
   1088                 if (mUidAlert != null) {
   1089                     mUidAlert.dismiss();
   1090                     mUidAlert = null;
   1091                 }
   1092             } break;
   1093             case PROC_START_TIMEOUT_MSG: {
   1094                 if (mDidDexOpt) {
   1095                     mDidDexOpt = false;
   1096                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   1097                     nmsg.obj = msg.obj;
   1098                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
   1099                     return;
   1100                 }
   1101                 ProcessRecord app = (ProcessRecord)msg.obj;
   1102                 synchronized (ActivityManagerService.this) {
   1103                     processStartTimedOutLocked(app);
   1104                 }
   1105             } break;
   1106             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
   1107                 synchronized (ActivityManagerService.this) {
   1108                     doPendingActivityLaunchesLocked(true);
   1109                 }
   1110             } break;
   1111             case KILL_APPLICATION_MSG: {
   1112                 synchronized (ActivityManagerService.this) {
   1113                     int uid = msg.arg1;
   1114                     boolean restart = (msg.arg2 == 1);
   1115                     String pkg = (String) msg.obj;
   1116                     forceStopPackageLocked(pkg, uid, restart, false, true, false,
   1117                             UserId.getUserId(uid));
   1118                 }
   1119             } break;
   1120             case FINALIZE_PENDING_INTENT_MSG: {
   1121                 ((PendingIntentRecord)msg.obj).completeFinalize();
   1122             } break;
   1123             case POST_HEAVY_NOTIFICATION_MSG: {
   1124                 INotificationManager inm = NotificationManager.getService();
   1125                 if (inm == null) {
   1126                     return;
   1127                 }
   1128 
   1129                 ActivityRecord root = (ActivityRecord)msg.obj;
   1130                 ProcessRecord process = root.app;
   1131                 if (process == null) {
   1132                     return;
   1133                 }
   1134 
   1135                 try {
   1136                     Context context = mContext.createPackageContext(process.info.packageName, 0);
   1137                     String text = mContext.getString(R.string.heavy_weight_notification,
   1138                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
   1139                     Notification notification = new Notification();
   1140                     notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
   1141                     notification.when = 0;
   1142                     notification.flags = Notification.FLAG_ONGOING_EVENT;
   1143                     notification.tickerText = text;
   1144                     notification.defaults = 0; // please be quiet
   1145                     notification.sound = null;
   1146                     notification.vibrate = null;
   1147                     notification.setLatestEventInfo(context, text,
   1148                             mContext.getText(R.string.heavy_weight_notification_detail),
   1149                             PendingIntent.getActivity(mContext, 0, root.intent,
   1150                                     PendingIntent.FLAG_CANCEL_CURRENT));
   1151 
   1152                     try {
   1153                         int[] outId = new int[1];
   1154                         inm.enqueueNotification("android", R.string.heavy_weight_notification,
   1155                                 notification, outId);
   1156                     } catch (RuntimeException e) {
   1157                         Slog.w(ActivityManagerService.TAG,
   1158                                 "Error showing notification for heavy-weight app", e);
   1159                     } catch (RemoteException e) {
   1160                     }
   1161                 } catch (NameNotFoundException e) {
   1162                     Slog.w(TAG, "Unable to create context for heavy notification", e);
   1163                 }
   1164             } break;
   1165             case CANCEL_HEAVY_NOTIFICATION_MSG: {
   1166                 INotificationManager inm = NotificationManager.getService();
   1167                 if (inm == null) {
   1168                     return;
   1169                 }
   1170                 try {
   1171                     inm.cancelNotification("android",
   1172                             R.string.heavy_weight_notification);
   1173                 } catch (RuntimeException e) {
   1174                     Slog.w(ActivityManagerService.TAG,
   1175                             "Error canceling notification for service", e);
   1176                 } catch (RemoteException e) {
   1177                 }
   1178             } break;
   1179             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
   1180                 synchronized (ActivityManagerService.this) {
   1181                     checkExcessivePowerUsageLocked(true);
   1182                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1183                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1184                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   1185                 }
   1186             } break;
   1187             case SHOW_COMPAT_MODE_DIALOG_MSG: {
   1188                 synchronized (ActivityManagerService.this) {
   1189                     ActivityRecord ar = (ActivityRecord)msg.obj;
   1190                     if (mCompatModeDialog != null) {
   1191                         if (mCompatModeDialog.mAppInfo.packageName.equals(
   1192                                 ar.info.applicationInfo.packageName)) {
   1193                             return;
   1194                         }
   1195                         mCompatModeDialog.dismiss();
   1196                         mCompatModeDialog = null;
   1197                     }
   1198                     if (ar != null && false) {
   1199                         if (mCompatModePackages.getPackageAskCompatModeLocked(
   1200                                 ar.packageName)) {
   1201                             int mode = mCompatModePackages.computeCompatModeLocked(
   1202                                     ar.info.applicationInfo);
   1203                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
   1204                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
   1205                                 mCompatModeDialog = new CompatModeDialog(
   1206                                         ActivityManagerService.this, mContext,
   1207                                         ar.info.applicationInfo);
   1208                                 mCompatModeDialog.show();
   1209                             }
   1210                         }
   1211                     }
   1212                 }
   1213                 break;
   1214             }
   1215             case DISPATCH_PROCESSES_CHANGED: {
   1216                 dispatchProcessesChanged();
   1217                 break;
   1218             }
   1219             case DISPATCH_PROCESS_DIED: {
   1220                 final int pid = msg.arg1;
   1221                 final int uid = msg.arg2;
   1222                 dispatchProcessDied(pid, uid);
   1223                 break;
   1224             }
   1225             case REPORT_MEM_USAGE: {
   1226                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   1227                 if (!isDebuggable) {
   1228                     return;
   1229                 }
   1230                 synchronized (ActivityManagerService.this) {
   1231                     long now = SystemClock.uptimeMillis();
   1232                     if (now < (mLastMemUsageReportTime+5*60*1000)) {
   1233                         // Don't report more than every 5 minutes to somewhat
   1234                         // avoid spamming.
   1235                         return;
   1236                     }
   1237                     mLastMemUsageReportTime = now;
   1238                 }
   1239                 Thread thread = new Thread() {
   1240                     @Override public void run() {
   1241                         StringBuilder dropBuilder = new StringBuilder(1024);
   1242                         StringBuilder logBuilder = new StringBuilder(1024);
   1243                         StringWriter oomSw = new StringWriter();
   1244                         PrintWriter oomPw = new PrintWriter(oomSw);
   1245                         StringWriter catSw = new StringWriter();
   1246                         PrintWriter catPw = new PrintWriter(catSw);
   1247                         String[] emptyArgs = new String[] { };
   1248                         StringBuilder tag = new StringBuilder(128);
   1249                         StringBuilder stack = new StringBuilder(128);
   1250                         tag.append("Low on memory -- ");
   1251                         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
   1252                                 tag, stack);
   1253                         dropBuilder.append(stack);
   1254                         dropBuilder.append('\n');
   1255                         dropBuilder.append('\n');
   1256                         String oomString = oomSw.toString();
   1257                         dropBuilder.append(oomString);
   1258                         dropBuilder.append('\n');
   1259                         logBuilder.append(oomString);
   1260                         try {
   1261                             java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
   1262                                     "procrank", });
   1263                             final InputStreamReader converter = new InputStreamReader(
   1264                                     proc.getInputStream());
   1265                             BufferedReader in = new BufferedReader(converter);
   1266                             String line;
   1267                             while (true) {
   1268                                 line = in.readLine();
   1269                                 if (line == null) {
   1270                                     break;
   1271                                 }
   1272                                 if (line.length() > 0) {
   1273                                     logBuilder.append(line);
   1274                                     logBuilder.append('\n');
   1275                                 }
   1276                                 dropBuilder.append(line);
   1277                                 dropBuilder.append('\n');
   1278                             }
   1279                             converter.close();
   1280                         } catch (IOException e) {
   1281                         }
   1282                         synchronized (ActivityManagerService.this) {
   1283                             catPw.println();
   1284                             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
   1285                             catPw.println();
   1286                             dumpServicesLocked(null, catPw, emptyArgs, 0, false, false, null);
   1287                             catPw.println();
   1288                             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
   1289                         }
   1290                         dropBuilder.append(catSw.toString());
   1291                         addErrorToDropBox("lowmem", null, "system_server", null,
   1292                                 null, tag.toString(), dropBuilder.toString(), null, null);
   1293                         Slog.i(TAG, logBuilder.toString());
   1294                         synchronized (ActivityManagerService.this) {
   1295                             long now = SystemClock.uptimeMillis();
   1296                             if (mLastMemUsageReportTime < now) {
   1297                                 mLastMemUsageReportTime = now;
   1298                             }
   1299                         }
   1300                     }
   1301                 };
   1302                 thread.start();
   1303                 break;
   1304             }
   1305             }
   1306         }
   1307     };
   1308 
   1309     public static void setSystemProcess() {
   1310         try {
   1311             ActivityManagerService m = mSelf;
   1312 
   1313             ServiceManager.addService("activity", m, true);
   1314             ServiceManager.addService("meminfo", new MemBinder(m));
   1315             ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
   1316             ServiceManager.addService("dbinfo", new DbBinder(m));
   1317             if (MONITOR_CPU_USAGE) {
   1318                 ServiceManager.addService("cpuinfo", new CpuBinder(m));
   1319             }
   1320             ServiceManager.addService("permission", new PermissionController(m));
   1321 
   1322             ApplicationInfo info =
   1323                 mSelf.mContext.getPackageManager().getApplicationInfo(
   1324                             "android", STOCK_PM_FLAGS);
   1325             mSystemThread.installSystemApplicationInfo(info);
   1326 
   1327             synchronized (mSelf) {
   1328                 ProcessRecord app = mSelf.newProcessRecordLocked(
   1329                         mSystemThread.getApplicationThread(), info,
   1330                         info.processName, false);
   1331                 app.persistent = true;
   1332                 app.pid = MY_PID;
   1333                 app.maxAdj = ProcessList.SYSTEM_ADJ;
   1334                 mSelf.mProcessNames.put(app.processName, app.uid, app);
   1335                 synchronized (mSelf.mPidsSelfLocked) {
   1336                     mSelf.mPidsSelfLocked.put(app.pid, app);
   1337                 }
   1338                 mSelf.updateLruProcessLocked(app, true, true);
   1339             }
   1340         } catch (PackageManager.NameNotFoundException e) {
   1341             throw new RuntimeException(
   1342                     "Unable to find android system package", e);
   1343         }
   1344     }
   1345 
   1346     public void setWindowManager(WindowManagerService wm) {
   1347         mWindowManager = wm;
   1348     }
   1349 
   1350     public static final Context main(int factoryTest) {
   1351         AThread thr = new AThread();
   1352         thr.start();
   1353 
   1354         synchronized (thr) {
   1355             while (thr.mService == null) {
   1356                 try {
   1357                     thr.wait();
   1358                 } catch (InterruptedException e) {
   1359                 }
   1360             }
   1361         }
   1362 
   1363         ActivityManagerService m = thr.mService;
   1364         mSelf = m;
   1365         ActivityThread at = ActivityThread.systemMain();
   1366         mSystemThread = at;
   1367         Context context = at.getSystemContext();
   1368         context.setTheme(android.R.style.Theme_Holo);
   1369         m.mContext = context;
   1370         m.mFactoryTest = factoryTest;
   1371         m.mMainStack = new ActivityStack(m, context, true);
   1372 
   1373         m.mBatteryStatsService.publish(context);
   1374         m.mUsageStatsService.publish(context);
   1375 
   1376         synchronized (thr) {
   1377             thr.mReady = true;
   1378             thr.notifyAll();
   1379         }
   1380 
   1381         m.startRunning(null, null, null, null);
   1382 
   1383         return context;
   1384     }
   1385 
   1386     public static ActivityManagerService self() {
   1387         return mSelf;
   1388     }
   1389 
   1390     static class AThread extends Thread {
   1391         ActivityManagerService mService;
   1392         boolean mReady = false;
   1393 
   1394         public AThread() {
   1395             super("ActivityManager");
   1396         }
   1397 
   1398         public void run() {
   1399             Looper.prepare();
   1400 
   1401             android.os.Process.setThreadPriority(
   1402                     android.os.Process.THREAD_PRIORITY_FOREGROUND);
   1403             android.os.Process.setCanSelfBackground(false);
   1404 
   1405             ActivityManagerService m = new ActivityManagerService();
   1406 
   1407             synchronized (this) {
   1408                 mService = m;
   1409                 notifyAll();
   1410             }
   1411 
   1412             synchronized (this) {
   1413                 while (!mReady) {
   1414                     try {
   1415                         wait();
   1416                     } catch (InterruptedException e) {
   1417                     }
   1418                 }
   1419             }
   1420 
   1421             // For debug builds, log event loop stalls to dropbox for analysis.
   1422             if (StrictMode.conditionallyEnableDebugLogging()) {
   1423                 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
   1424             }
   1425 
   1426             Looper.loop();
   1427         }
   1428     }
   1429 
   1430     static class MemBinder extends Binder {
   1431         ActivityManagerService mActivityManagerService;
   1432         MemBinder(ActivityManagerService activityManagerService) {
   1433             mActivityManagerService = activityManagerService;
   1434         }
   1435 
   1436         @Override
   1437         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1438             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1439                     != PackageManager.PERMISSION_GRANTED) {
   1440                 pw.println("Permission Denial: can't dump meminfo from from pid="
   1441                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1442                         + " without permission " + android.Manifest.permission.DUMP);
   1443                 return;
   1444             }
   1445 
   1446             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
   1447                     false, null, null, null);
   1448         }
   1449     }
   1450 
   1451     static class GraphicsBinder extends Binder {
   1452         ActivityManagerService mActivityManagerService;
   1453         GraphicsBinder(ActivityManagerService activityManagerService) {
   1454             mActivityManagerService = activityManagerService;
   1455         }
   1456 
   1457         @Override
   1458         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1459             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1460                     != PackageManager.PERMISSION_GRANTED) {
   1461                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
   1462                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1463                         + " without permission " + android.Manifest.permission.DUMP);
   1464                 return;
   1465             }
   1466 
   1467             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
   1468         }
   1469     }
   1470 
   1471     static class DbBinder extends Binder {
   1472         ActivityManagerService mActivityManagerService;
   1473         DbBinder(ActivityManagerService activityManagerService) {
   1474             mActivityManagerService = activityManagerService;
   1475         }
   1476 
   1477         @Override
   1478         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1479             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1480                     != PackageManager.PERMISSION_GRANTED) {
   1481                 pw.println("Permission Denial: can't dump dbinfo from from pid="
   1482                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1483                         + " without permission " + android.Manifest.permission.DUMP);
   1484                 return;
   1485             }
   1486 
   1487             mActivityManagerService.dumpDbInfo(fd, pw, args);
   1488         }
   1489     }
   1490 
   1491     static class CpuBinder extends Binder {
   1492         ActivityManagerService mActivityManagerService;
   1493         CpuBinder(ActivityManagerService activityManagerService) {
   1494             mActivityManagerService = activityManagerService;
   1495         }
   1496 
   1497         @Override
   1498         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1499             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1500                     != PackageManager.PERMISSION_GRANTED) {
   1501                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
   1502                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1503                         + " without permission " + android.Manifest.permission.DUMP);
   1504                 return;
   1505             }
   1506 
   1507             synchronized (mActivityManagerService.mProcessStatsThread) {
   1508                 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
   1509                 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
   1510                         SystemClock.uptimeMillis()));
   1511             }
   1512         }
   1513     }
   1514 
   1515     private ActivityManagerService() {
   1516         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
   1517 
   1518         mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
   1519         mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
   1520         mBroadcastQueues[0] = mFgBroadcastQueue;
   1521         mBroadcastQueues[1] = mBgBroadcastQueue;
   1522 
   1523         File dataDir = Environment.getDataDirectory();
   1524         File systemDir = new File(dataDir, "system");
   1525         systemDir.mkdirs();
   1526         mBatteryStatsService = new BatteryStatsService(new File(
   1527                 systemDir, "batterystats.bin").toString());
   1528         mBatteryStatsService.getActiveStatistics().readLocked();
   1529         mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
   1530         mOnBattery = DEBUG_POWER ? true
   1531                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
   1532         mBatteryStatsService.getActiveStatistics().setCallback(this);
   1533 
   1534         mUsageStatsService = new UsageStatsService(new File(
   1535                 systemDir, "usagestats").toString());
   1536         mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
   1537 
   1538         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
   1539             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
   1540 
   1541         mConfiguration.setToDefaults();
   1542         mConfiguration.locale = Locale.getDefault();
   1543         mConfigurationSeq = mConfiguration.seq = 1;
   1544         mProcessStats.init();
   1545 
   1546         mCompatModePackages = new CompatModePackages(this, systemDir);
   1547 
   1548         // Add ourself to the Watchdog monitors.
   1549         Watchdog.getInstance().addMonitor(this);
   1550 
   1551         mProcessStatsThread = new Thread("ProcessStats") {
   1552             public void run() {
   1553                 while (true) {
   1554                     try {
   1555                         try {
   1556                             synchronized(this) {
   1557                                 final long now = SystemClock.uptimeMillis();
   1558                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
   1559                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
   1560                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
   1561                                 //        + ", write delay=" + nextWriteDelay);
   1562                                 if (nextWriteDelay < nextCpuDelay) {
   1563                                     nextCpuDelay = nextWriteDelay;
   1564                                 }
   1565                                 if (nextCpuDelay > 0) {
   1566                                     mProcessStatsMutexFree.set(true);
   1567                                     this.wait(nextCpuDelay);
   1568                                 }
   1569                             }
   1570                         } catch (InterruptedException e) {
   1571                         }
   1572                         updateCpuStatsNow();
   1573                     } catch (Exception e) {
   1574                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
   1575                     }
   1576                 }
   1577             }
   1578         };
   1579         mProcessStatsThread.start();
   1580     }
   1581 
   1582     @Override
   1583     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   1584             throws RemoteException {
   1585         if (code == SYSPROPS_TRANSACTION) {
   1586             // We need to tell all apps about the system property change.
   1587             ArrayList<IBinder> procs = new ArrayList<IBinder>();
   1588             synchronized(this) {
   1589                 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   1590                     final int NA = apps.size();
   1591                     for (int ia=0; ia<NA; ia++) {
   1592                         ProcessRecord app = apps.valueAt(ia);
   1593                         if (app.thread != null) {
   1594                             procs.add(app.thread.asBinder());
   1595                         }
   1596                     }
   1597                 }
   1598             }
   1599 
   1600             int N = procs.size();
   1601             for (int i=0; i<N; i++) {
   1602                 Parcel data2 = Parcel.obtain();
   1603                 try {
   1604                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
   1605                 } catch (RemoteException e) {
   1606                 }
   1607                 data2.recycle();
   1608             }
   1609         }
   1610         try {
   1611             return super.onTransact(code, data, reply, flags);
   1612         } catch (RuntimeException e) {
   1613             // The activity manager only throws security exceptions, so let's
   1614             // log all others.
   1615             if (!(e instanceof SecurityException)) {
   1616                 Slog.e(TAG, "Activity Manager Crash", e);
   1617             }
   1618             throw e;
   1619         }
   1620     }
   1621 
   1622     void updateCpuStats() {
   1623         final long now = SystemClock.uptimeMillis();
   1624         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
   1625             return;
   1626         }
   1627         if (mProcessStatsMutexFree.compareAndSet(true, false)) {
   1628             synchronized (mProcessStatsThread) {
   1629                 mProcessStatsThread.notify();
   1630             }
   1631         }
   1632     }
   1633 
   1634     void updateCpuStatsNow() {
   1635         synchronized (mProcessStatsThread) {
   1636             mProcessStatsMutexFree.set(false);
   1637             final long now = SystemClock.uptimeMillis();
   1638             boolean haveNewCpuStats = false;
   1639 
   1640             if (MONITOR_CPU_USAGE &&
   1641                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
   1642                 mLastCpuTime.set(now);
   1643                 haveNewCpuStats = true;
   1644                 mProcessStats.update();
   1645                 //Slog.i(TAG, mProcessStats.printCurrentState());
   1646                 //Slog.i(TAG, "Total CPU usage: "
   1647                 //        + mProcessStats.getTotalCpuPercent() + "%");
   1648 
   1649                 // Slog the cpu usage if the property is set.
   1650                 if ("true".equals(SystemProperties.get("events.cpu"))) {
   1651                     int user = mProcessStats.getLastUserTime();
   1652                     int system = mProcessStats.getLastSystemTime();
   1653                     int iowait = mProcessStats.getLastIoWaitTime();
   1654                     int irq = mProcessStats.getLastIrqTime();
   1655                     int softIrq = mProcessStats.getLastSoftIrqTime();
   1656                     int idle = mProcessStats.getLastIdleTime();
   1657 
   1658                     int total = user + system + iowait + irq + softIrq + idle;
   1659                     if (total == 0) total = 1;
   1660 
   1661                     EventLog.writeEvent(EventLogTags.CPU,
   1662                             ((user+system+iowait+irq+softIrq) * 100) / total,
   1663                             (user * 100) / total,
   1664                             (system * 100) / total,
   1665                             (iowait * 100) / total,
   1666                             (irq * 100) / total,
   1667                             (softIrq * 100) / total);
   1668                 }
   1669             }
   1670 
   1671             long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
   1672             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
   1673             synchronized(bstats) {
   1674                 synchronized(mPidsSelfLocked) {
   1675                     if (haveNewCpuStats) {
   1676                         if (mOnBattery) {
   1677                             int perc = bstats.startAddingCpuLocked();
   1678                             int totalUTime = 0;
   1679                             int totalSTime = 0;
   1680                             final int N = mProcessStats.countStats();
   1681                             for (int i=0; i<N; i++) {
   1682                                 ProcessStats.Stats st = mProcessStats.getStats(i);
   1683                                 if (!st.working) {
   1684                                     continue;
   1685                                 }
   1686                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
   1687                                 int otherUTime = (st.rel_utime*perc)/100;
   1688                                 int otherSTime = (st.rel_stime*perc)/100;
   1689                                 totalUTime += otherUTime;
   1690                                 totalSTime += otherSTime;
   1691                                 if (pr != null) {
   1692                                     BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
   1693                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
   1694                                             st.rel_stime-otherSTime);
   1695                                     ps.addSpeedStepTimes(cpuSpeedTimes);
   1696                                     pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
   1697                                 } else {
   1698                                     BatteryStatsImpl.Uid.Proc ps =
   1699                                             bstats.getProcessStatsLocked(st.name, st.pid);
   1700                                     if (ps != null) {
   1701                                         ps.addCpuTimeLocked(st.rel_utime-otherUTime,
   1702                                                 st.rel_stime-otherSTime);
   1703                                         ps.addSpeedStepTimes(cpuSpeedTimes);
   1704                                     }
   1705                                 }
   1706                             }
   1707                             bstats.finishAddingCpuLocked(perc, totalUTime,
   1708                                     totalSTime, cpuSpeedTimes);
   1709                         }
   1710                     }
   1711                 }
   1712 
   1713                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
   1714                     mLastWriteTime = now;
   1715                     mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
   1716                 }
   1717             }
   1718         }
   1719     }
   1720 
   1721     @Override
   1722     public void batteryNeedsCpuUpdate() {
   1723         updateCpuStatsNow();
   1724     }
   1725 
   1726     @Override
   1727     public void batteryPowerChanged(boolean onBattery) {
   1728         // When plugging in, update the CPU stats first before changing
   1729         // the plug state.
   1730         updateCpuStatsNow();
   1731         synchronized (this) {
   1732             synchronized(mPidsSelfLocked) {
   1733                 mOnBattery = DEBUG_POWER ? true : onBattery;
   1734             }
   1735         }
   1736     }
   1737 
   1738     /**
   1739      * Initialize the application bind args. These are passed to each
   1740      * process when the bindApplication() IPC is sent to the process. They're
   1741      * lazily setup to make sure the services are running when they're asked for.
   1742      */
   1743     private HashMap<String, IBinder> getCommonServicesLocked() {
   1744         if (mAppBindArgs == null) {
   1745             mAppBindArgs = new HashMap<String, IBinder>();
   1746 
   1747             // Setup the application init args
   1748             mAppBindArgs.put("package", ServiceManager.getService("package"));
   1749             mAppBindArgs.put("window", ServiceManager.getService("window"));
   1750             mAppBindArgs.put(Context.ALARM_SERVICE,
   1751                     ServiceManager.getService(Context.ALARM_SERVICE));
   1752         }
   1753         return mAppBindArgs;
   1754     }
   1755 
   1756     final void setFocusedActivityLocked(ActivityRecord r) {
   1757         if (mFocusedActivity != r) {
   1758             mFocusedActivity = r;
   1759             if (r != null) {
   1760                 mWindowManager.setFocusedApp(r.appToken, true);
   1761             }
   1762         }
   1763     }
   1764 
   1765     private final void updateLruProcessInternalLocked(ProcessRecord app,
   1766             boolean oomAdj, boolean updateActivityTime, int bestPos) {
   1767         // put it on the LRU to keep track of when it should be exited.
   1768         int lrui = mLruProcesses.indexOf(app);
   1769         if (lrui >= 0) mLruProcesses.remove(lrui);
   1770 
   1771         int i = mLruProcesses.size()-1;
   1772         int skipTop = 0;
   1773 
   1774         app.lruSeq = mLruSeq;
   1775 
   1776         // compute the new weight for this process.
   1777         if (updateActivityTime) {
   1778             app.lastActivityTime = SystemClock.uptimeMillis();
   1779         }
   1780         if (app.activities.size() > 0) {
   1781             // If this process has activities, we more strongly want to keep
   1782             // it around.
   1783             app.lruWeight = app.lastActivityTime;
   1784         } else if (app.pubProviders.size() > 0) {
   1785             // If this process contains content providers, we want to keep
   1786             // it a little more strongly.
   1787             app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
   1788             // Also don't let it kick out the first few "real" hidden processes.
   1789             skipTop = ProcessList.MIN_HIDDEN_APPS;
   1790         } else {
   1791             // If this process doesn't have activities, we less strongly
   1792             // want to keep it around, and generally want to avoid getting
   1793             // in front of any very recently used activities.
   1794             app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
   1795             // Also don't let it kick out the first few "real" hidden processes.
   1796             skipTop = ProcessList.MIN_HIDDEN_APPS;
   1797         }
   1798 
   1799         while (i >= 0) {
   1800             ProcessRecord p = mLruProcesses.get(i);
   1801             // If this app shouldn't be in front of the first N background
   1802             // apps, then skip over that many that are currently hidden.
   1803             if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   1804                 skipTop--;
   1805             }
   1806             if (p.lruWeight <= app.lruWeight || i < bestPos) {
   1807                 mLruProcesses.add(i+1, app);
   1808                 break;
   1809             }
   1810             i--;
   1811         }
   1812         if (i < 0) {
   1813             mLruProcesses.add(0, app);
   1814         }
   1815 
   1816         // If the app is currently using a content provider or service,
   1817         // bump those processes as well.
   1818         if (app.connections.size() > 0) {
   1819             for (ConnectionRecord cr : app.connections) {
   1820                 if (cr.binding != null && cr.binding.service != null
   1821                         && cr.binding.service.app != null
   1822                         && cr.binding.service.app.lruSeq != mLruSeq) {
   1823                     updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
   1824                             updateActivityTime, i+1);
   1825                 }
   1826             }
   1827         }
   1828         for (int j=app.conProviders.size()-1; j>=0; j--) {
   1829             ContentProviderRecord cpr = app.conProviders.get(j).provider;
   1830             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
   1831                 updateLruProcessInternalLocked(cpr.proc, oomAdj,
   1832                         updateActivityTime, i+1);
   1833             }
   1834         }
   1835 
   1836         //Slog.i(TAG, "Putting proc to front: " + app.processName);
   1837         if (oomAdj) {
   1838             updateOomAdjLocked();
   1839         }
   1840     }
   1841 
   1842     final void updateLruProcessLocked(ProcessRecord app,
   1843             boolean oomAdj, boolean updateActivityTime) {
   1844         mLruSeq++;
   1845         updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
   1846     }
   1847 
   1848     final ProcessRecord getProcessRecordLocked(
   1849             String processName, int uid) {
   1850         if (uid == Process.SYSTEM_UID) {
   1851             // The system gets to run in any process.  If there are multiple
   1852             // processes with the same uid, just pick the first (this
   1853             // should never happen).
   1854             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
   1855                     processName);
   1856             if (procs == null) return null;
   1857             final int N = procs.size();
   1858             for (int i = 0; i < N; i++) {
   1859                 if (UserId.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
   1860             }
   1861         }
   1862         ProcessRecord proc = mProcessNames.get(processName, uid);
   1863         return proc;
   1864     }
   1865 
   1866     void ensurePackageDexOpt(String packageName) {
   1867         IPackageManager pm = AppGlobals.getPackageManager();
   1868         try {
   1869             if (pm.performDexOpt(packageName)) {
   1870                 mDidDexOpt = true;
   1871             }
   1872         } catch (RemoteException e) {
   1873         }
   1874     }
   1875 
   1876     boolean isNextTransitionForward() {
   1877         int transit = mWindowManager.getPendingAppTransition();
   1878         return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
   1879                 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
   1880                 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
   1881     }
   1882 
   1883     final ProcessRecord startProcessLocked(String processName,
   1884             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
   1885             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
   1886             boolean isolated) {
   1887         ProcessRecord app;
   1888         if (!isolated) {
   1889             app = getProcessRecordLocked(processName, info.uid);
   1890         } else {
   1891             // If this is an isolated process, it can't re-use an existing process.
   1892             app = null;
   1893         }
   1894         // We don't have to do anything more if:
   1895         // (1) There is an existing application record; and
   1896         // (2) The caller doesn't think it is dead, OR there is no thread
   1897         //     object attached to it so we know it couldn't have crashed; and
   1898         // (3) There is a pid assigned to it, so it is either starting or
   1899         //     already running.
   1900         if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
   1901                 + " app=" + app + " knownToBeDead=" + knownToBeDead
   1902                 + " thread=" + (app != null ? app.thread : null)
   1903                 + " pid=" + (app != null ? app.pid : -1));
   1904         if (app != null && app.pid > 0) {
   1905             if (!knownToBeDead || app.thread == null) {
   1906                 // We already have the app running, or are waiting for it to
   1907                 // come up (we have a pid but not yet its thread), so keep it.
   1908                 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
   1909                 // If this is a new package in the process, add the package to the list
   1910                 app.addPackage(info.packageName);
   1911                 return app;
   1912             } else {
   1913                 // An application record is attached to a previous process,
   1914                 // clean it up now.
   1915                 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
   1916                 handleAppDiedLocked(app, true, true);
   1917             }
   1918         }
   1919 
   1920         String hostingNameStr = hostingName != null
   1921                 ? hostingName.flattenToShortString() : null;
   1922 
   1923         if (!isolated) {
   1924             if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
   1925                 // If we are in the background, then check to see if this process
   1926                 // is bad.  If so, we will just silently fail.
   1927                 if (mBadProcesses.get(info.processName, info.uid) != null) {
   1928                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
   1929                             + "/" + info.processName);
   1930                     return null;
   1931                 }
   1932             } else {
   1933                 // When the user is explicitly starting a process, then clear its
   1934                 // crash count so that we won't make it bad until they see at
   1935                 // least one crash dialog again, and make the process good again
   1936                 // if it had been bad.
   1937                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
   1938                         + "/" + info.processName);
   1939                 mProcessCrashTimes.remove(info.processName, info.uid);
   1940                 if (mBadProcesses.get(info.processName, info.uid) != null) {
   1941                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
   1942                             info.processName);
   1943                     mBadProcesses.remove(info.processName, info.uid);
   1944                     if (app != null) {
   1945                         app.bad = false;
   1946                     }
   1947                 }
   1948             }
   1949         }
   1950 
   1951         if (app == null) {
   1952             app = newProcessRecordLocked(null, info, processName, isolated);
   1953             if (app == null) {
   1954                 Slog.w(TAG, "Failed making new process record for "
   1955                         + processName + "/" + info.uid + " isolated=" + isolated);
   1956                 return null;
   1957             }
   1958             mProcessNames.put(processName, app.uid, app);
   1959             if (isolated) {
   1960                 mIsolatedProcesses.put(app.uid, app);
   1961             }
   1962         } else {
   1963             // If this is a new package in the process, add the package to the list
   1964             app.addPackage(info.packageName);
   1965         }
   1966 
   1967         // If the system is not ready yet, then hold off on starting this
   1968         // process until it is.
   1969         if (!mProcessesReady
   1970                 && !isAllowedWhileBooting(info)
   1971                 && !allowWhileBooting) {
   1972             if (!mProcessesOnHold.contains(app)) {
   1973                 mProcessesOnHold.add(app);
   1974             }
   1975             if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
   1976             return app;
   1977         }
   1978 
   1979         startProcessLocked(app, hostingType, hostingNameStr);
   1980         return (app.pid != 0) ? app : null;
   1981     }
   1982 
   1983     boolean isAllowedWhileBooting(ApplicationInfo ai) {
   1984         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
   1985     }
   1986 
   1987     private final void startProcessLocked(ProcessRecord app,
   1988             String hostingType, String hostingNameStr) {
   1989         if (app.pid > 0 && app.pid != MY_PID) {
   1990             synchronized (mPidsSelfLocked) {
   1991                 mPidsSelfLocked.remove(app.pid);
   1992                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   1993             }
   1994             app.pid = 0;
   1995         }
   1996 
   1997         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   1998                 "startProcessLocked removing on hold: " + app);
   1999         mProcessesOnHold.remove(app);
   2000 
   2001         updateCpuStats();
   2002 
   2003         System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
   2004         mProcDeaths[0] = 0;
   2005 
   2006         try {
   2007             int uid = app.uid;
   2008 
   2009             int[] gids = null;
   2010             if (!app.isolated) {
   2011                 try {
   2012                     gids = mContext.getPackageManager().getPackageGids(
   2013                             app.info.packageName);
   2014                 } catch (PackageManager.NameNotFoundException e) {
   2015                     Slog.w(TAG, "Unable to retrieve gids", e);
   2016                 }
   2017             }
   2018             if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
   2019                 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
   2020                         && mTopComponent != null
   2021                         && app.processName.equals(mTopComponent.getPackageName())) {
   2022                     uid = 0;
   2023                 }
   2024                 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
   2025                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
   2026                     uid = 0;
   2027                 }
   2028             }
   2029             int debugFlags = 0;
   2030             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   2031                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
   2032                 // Also turn on CheckJNI for debuggable apps. It's quite
   2033                 // awkward to turn on otherwise.
   2034                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   2035             }
   2036             // Run the app in safe mode if its manifest requests so or the
   2037             // system is booted in safe mode.
   2038             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
   2039                 Zygote.systemInSafeMode == true) {
   2040                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
   2041             }
   2042             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
   2043                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   2044             }
   2045             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
   2046                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
   2047             }
   2048             if ("1".equals(SystemProperties.get("debug.assert"))) {
   2049                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
   2050             }
   2051 
   2052             // Start the process.  It will either succeed and return a result containing
   2053             // the PID of the new process, or else throw a RuntimeException.
   2054             Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
   2055                     app.processName, uid, uid, gids, debugFlags,
   2056                     app.info.targetSdkVersion, null);
   2057 
   2058             BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
   2059             synchronized (bs) {
   2060                 if (bs.isOnBattery()) {
   2061                     app.batteryStats.incStartsLocked();
   2062                 }
   2063             }
   2064 
   2065             EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
   2066                     app.processName, hostingType,
   2067                     hostingNameStr != null ? hostingNameStr : "");
   2068 
   2069             if (app.persistent) {
   2070                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
   2071             }
   2072 
   2073             StringBuilder buf = mStringBuilder;
   2074             buf.setLength(0);
   2075             buf.append("Start proc ");
   2076             buf.append(app.processName);
   2077             buf.append(" for ");
   2078             buf.append(hostingType);
   2079             if (hostingNameStr != null) {
   2080                 buf.append(" ");
   2081                 buf.append(hostingNameStr);
   2082             }
   2083             buf.append(": pid=");
   2084             buf.append(startResult.pid);
   2085             buf.append(" uid=");
   2086             buf.append(uid);
   2087             buf.append(" gids={");
   2088             if (gids != null) {
   2089                 for (int gi=0; gi<gids.length; gi++) {
   2090                     if (gi != 0) buf.append(", ");
   2091                     buf.append(gids[gi]);
   2092 
   2093                 }
   2094             }
   2095             buf.append("}");
   2096             Slog.i(TAG, buf.toString());
   2097             app.pid = startResult.pid;
   2098             app.usingWrapper = startResult.usingWrapper;
   2099             app.removed = false;
   2100             synchronized (mPidsSelfLocked) {
   2101                 this.mPidsSelfLocked.put(startResult.pid, app);
   2102                 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   2103                 msg.obj = app;
   2104                 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
   2105                         ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
   2106             }
   2107         } catch (RuntimeException e) {
   2108             // XXX do better error recovery.
   2109             app.pid = 0;
   2110             Slog.e(TAG, "Failure starting process " + app.processName, e);
   2111         }
   2112     }
   2113 
   2114     void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
   2115         if (resumed) {
   2116             mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
   2117         } else {
   2118             mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
   2119         }
   2120     }
   2121 
   2122     boolean startHomeActivityLocked(int userId) {
   2123         if (mHeadless) {
   2124             // Added because none of the other calls to ensureBootCompleted seem to fire
   2125             // when running headless.
   2126             ensureBootCompleted();
   2127             return false;
   2128         }
   2129 
   2130         if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
   2131                 && mTopAction == null) {
   2132             // We are running in factory test mode, but unable to find
   2133             // the factory test app, so just sit around displaying the
   2134             // error message and don't try to start anything.
   2135             return false;
   2136         }
   2137         Intent intent = new Intent(
   2138             mTopAction,
   2139             mTopData != null ? Uri.parse(mTopData) : null);
   2140         intent.setComponent(mTopComponent);
   2141         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   2142             intent.addCategory(Intent.CATEGORY_HOME);
   2143         }
   2144         ActivityInfo aInfo =
   2145             intent.resolveActivityInfo(mContext.getPackageManager(),
   2146                     STOCK_PM_FLAGS);
   2147         if (aInfo != null) {
   2148             intent.setComponent(new ComponentName(
   2149                     aInfo.applicationInfo.packageName, aInfo.name));
   2150             // Don't do this if the home app is currently being
   2151             // instrumented.
   2152             aInfo = new ActivityInfo(aInfo);
   2153             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
   2154             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
   2155                     aInfo.applicationInfo.uid);
   2156             if (app == null || app.instrumentationClass == null) {
   2157                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
   2158                 mMainStack.startActivityLocked(null, intent, null, aInfo,
   2159                         null, null, 0, 0, 0, 0, null, false, null);
   2160             }
   2161         }
   2162 
   2163         return true;
   2164     }
   2165 
   2166     /**
   2167      * Starts the "new version setup screen" if appropriate.
   2168      */
   2169     void startSetupActivityLocked() {
   2170         // Only do this once per boot.
   2171         if (mCheckedForSetup) {
   2172             return;
   2173         }
   2174 
   2175         // We will show this screen if the current one is a different
   2176         // version than the last one shown, and we are not running in
   2177         // low-level factory test mode.
   2178         final ContentResolver resolver = mContext.getContentResolver();
   2179         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
   2180                 Settings.Secure.getInt(resolver,
   2181                         Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
   2182             mCheckedForSetup = true;
   2183 
   2184             // See if we should be showing the platform update setup UI.
   2185             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
   2186             List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
   2187                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
   2188 
   2189             // We don't allow third party apps to replace this.
   2190             ResolveInfo ri = null;
   2191             for (int i=0; ris != null && i<ris.size(); i++) {
   2192                 if ((ris.get(i).activityInfo.applicationInfo.flags
   2193                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
   2194                     ri = ris.get(i);
   2195                     break;
   2196                 }
   2197             }
   2198 
   2199             if (ri != null) {
   2200                 String vers = ri.activityInfo.metaData != null
   2201                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
   2202                         : null;
   2203                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
   2204                     vers = ri.activityInfo.applicationInfo.metaData.getString(
   2205                             Intent.METADATA_SETUP_VERSION);
   2206                 }
   2207                 String lastVers = Settings.Secure.getString(
   2208                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
   2209                 if (vers != null && !vers.equals(lastVers)) {
   2210                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   2211                     intent.setComponent(new ComponentName(
   2212                             ri.activityInfo.packageName, ri.activityInfo.name));
   2213                     mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
   2214                             null, null, 0, 0, 0, 0, null, false, null);
   2215                 }
   2216             }
   2217         }
   2218     }
   2219 
   2220     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
   2221         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
   2222     }
   2223 
   2224     void enforceNotIsolatedCaller(String caller) {
   2225         if (UserId.isIsolated(Binder.getCallingUid())) {
   2226             throw new SecurityException("Isolated process not allowed to call " + caller);
   2227         }
   2228     }
   2229 
   2230     public int getFrontActivityScreenCompatMode() {
   2231         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
   2232         synchronized (this) {
   2233             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
   2234         }
   2235     }
   2236 
   2237     public void setFrontActivityScreenCompatMode(int mode) {
   2238         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   2239                 "setFrontActivityScreenCompatMode");
   2240         synchronized (this) {
   2241             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
   2242         }
   2243     }
   2244 
   2245     public int getPackageScreenCompatMode(String packageName) {
   2246         enforceNotIsolatedCaller("getPackageScreenCompatMode");
   2247         synchronized (this) {
   2248             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
   2249         }
   2250     }
   2251 
   2252     public void setPackageScreenCompatMode(String packageName, int mode) {
   2253         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   2254                 "setPackageScreenCompatMode");
   2255         synchronized (this) {
   2256             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
   2257         }
   2258     }
   2259 
   2260     public boolean getPackageAskScreenCompat(String packageName) {
   2261         enforceNotIsolatedCaller("getPackageAskScreenCompat");
   2262         synchronized (this) {
   2263             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
   2264         }
   2265     }
   2266 
   2267     public void setPackageAskScreenCompat(String packageName, boolean ask) {
   2268         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   2269                 "setPackageAskScreenCompat");
   2270         synchronized (this) {
   2271             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
   2272         }
   2273     }
   2274 
   2275     void reportResumedActivityLocked(ActivityRecord r) {
   2276         //Slog.i(TAG, "**** REPORT RESUME: " + r);
   2277         updateUsageStats(r, true);
   2278     }
   2279 
   2280     private void dispatchProcessesChanged() {
   2281         int N;
   2282         synchronized (this) {
   2283             N = mPendingProcessChanges.size();
   2284             if (mActiveProcessChanges.length < N) {
   2285                 mActiveProcessChanges = new ProcessChangeItem[N];
   2286             }
   2287             mPendingProcessChanges.toArray(mActiveProcessChanges);
   2288             mAvailProcessChanges.addAll(mPendingProcessChanges);
   2289             mPendingProcessChanges.clear();
   2290             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
   2291         }
   2292         int i = mProcessObservers.beginBroadcast();
   2293         while (i > 0) {
   2294             i--;
   2295             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   2296             if (observer != null) {
   2297                 try {
   2298                     for (int j=0; j<N; j++) {
   2299                         ProcessChangeItem item = mActiveProcessChanges[j];
   2300                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
   2301                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
   2302                                     + item.pid + " uid=" + item.uid + ": "
   2303                                     + item.foregroundActivities);
   2304                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
   2305                                     item.foregroundActivities);
   2306                         }
   2307                         if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
   2308                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
   2309                                     + item.pid + " uid=" + item.uid + ": " + item.importance);
   2310                             observer.onImportanceChanged(item.pid, item.uid,
   2311                                     item.importance);
   2312                         }
   2313                     }
   2314                 } catch (RemoteException e) {
   2315                 }
   2316             }
   2317         }
   2318         mProcessObservers.finishBroadcast();
   2319     }
   2320 
   2321     private void dispatchProcessDied(int pid, int uid) {
   2322         int i = mProcessObservers.beginBroadcast();
   2323         while (i > 0) {
   2324             i--;
   2325             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   2326             if (observer != null) {
   2327                 try {
   2328                     observer.onProcessDied(pid, uid);
   2329                 } catch (RemoteException e) {
   2330                 }
   2331             }
   2332         }
   2333         mProcessObservers.finishBroadcast();
   2334     }
   2335 
   2336     final void doPendingActivityLaunchesLocked(boolean doResume) {
   2337         final int N = mPendingActivityLaunches.size();
   2338         if (N <= 0) {
   2339             return;
   2340         }
   2341         for (int i=0; i<N; i++) {
   2342             PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
   2343             mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
   2344                     pal.startFlags, doResume && i == (N-1), null);
   2345         }
   2346         mPendingActivityLaunches.clear();
   2347     }
   2348 
   2349     public final int startActivity(IApplicationThread caller,
   2350             Intent intent, String resolvedType, IBinder resultTo,
   2351             String resultWho, int requestCode, int startFlags,
   2352             String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
   2353         enforceNotIsolatedCaller("startActivity");
   2354         int userId = 0;
   2355         if (intent.getCategories() != null && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
   2356             // Requesting home, set the identity to the current user
   2357             // HACK!
   2358             userId = mCurrentUserId;
   2359         } else {
   2360             // TODO: Fix this in a better way - calls coming from SystemUI should probably carry
   2361             // the current user's userId
   2362             if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) {
   2363                 userId = 0;
   2364             } else {
   2365                 userId = Binder.getOrigCallingUser();
   2366             }
   2367         }
   2368         return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
   2369                 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
   2370                 null, null, options, userId);
   2371     }
   2372 
   2373     public final WaitResult startActivityAndWait(IApplicationThread caller,
   2374             Intent intent, String resolvedType, IBinder resultTo,
   2375             String resultWho, int requestCode, int startFlags, String profileFile,
   2376             ParcelFileDescriptor profileFd, Bundle options) {
   2377         enforceNotIsolatedCaller("startActivityAndWait");
   2378         WaitResult res = new WaitResult();
   2379         int userId = Binder.getOrigCallingUser();
   2380         mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
   2381                 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
   2382                 res, null, options, userId);
   2383         return res;
   2384     }
   2385 
   2386     public final int startActivityWithConfig(IApplicationThread caller,
   2387             Intent intent, String resolvedType, IBinder resultTo,
   2388             String resultWho, int requestCode, int startFlags, Configuration config,
   2389             Bundle options) {
   2390         enforceNotIsolatedCaller("startActivityWithConfig");
   2391         int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
   2392                 resultTo, resultWho, requestCode, startFlags,
   2393                 null, null, null, config, options, Binder.getOrigCallingUser());
   2394         return ret;
   2395     }
   2396 
   2397     public int startActivityIntentSender(IApplicationThread caller,
   2398             IntentSender intent, Intent fillInIntent, String resolvedType,
   2399             IBinder resultTo, String resultWho, int requestCode,
   2400             int flagsMask, int flagsValues, Bundle options) {
   2401         enforceNotIsolatedCaller("startActivityIntentSender");
   2402         // Refuse possible leaked file descriptors
   2403         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
   2404             throw new IllegalArgumentException("File descriptors passed in Intent");
   2405         }
   2406 
   2407         IIntentSender sender = intent.getTarget();
   2408         if (!(sender instanceof PendingIntentRecord)) {
   2409             throw new IllegalArgumentException("Bad PendingIntent object");
   2410         }
   2411 
   2412         PendingIntentRecord pir = (PendingIntentRecord)sender;
   2413 
   2414         synchronized (this) {
   2415             // If this is coming from the currently resumed activity, it is
   2416             // effectively saying that app switches are allowed at this point.
   2417             if (mMainStack.mResumedActivity != null
   2418                     && mMainStack.mResumedActivity.info.applicationInfo.uid ==
   2419                             Binder.getCallingUid()) {
   2420                 mAppSwitchesAllowedTime = 0;
   2421             }
   2422         }
   2423         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
   2424                 resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
   2425         return ret;
   2426     }
   2427 
   2428     public boolean startNextMatchingActivity(IBinder callingActivity,
   2429             Intent intent, Bundle options) {
   2430         // Refuse possible leaked file descriptors
   2431         if (intent != null && intent.hasFileDescriptors() == true) {
   2432             throw new IllegalArgumentException("File descriptors passed in Intent");
   2433         }
   2434 
   2435         synchronized (this) {
   2436             ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
   2437             if (r == null) {
   2438                 ActivityOptions.abort(options);
   2439                 return false;
   2440             }
   2441             if (r.app == null || r.app.thread == null) {
   2442                 // The caller is not running...  d'oh!
   2443                 ActivityOptions.abort(options);
   2444                 return false;
   2445             }
   2446             intent = new Intent(intent);
   2447             // The caller is not allowed to change the data.
   2448             intent.setDataAndType(r.intent.getData(), r.intent.getType());
   2449             // And we are resetting to find the next component...
   2450             intent.setComponent(null);
   2451 
   2452             ActivityInfo aInfo = null;
   2453             try {
   2454                 List<ResolveInfo> resolves =
   2455                     AppGlobals.getPackageManager().queryIntentActivities(
   2456                             intent, r.resolvedType,
   2457                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
   2458                             UserId.getCallingUserId());
   2459 
   2460                 // Look for the original activity in the list...
   2461                 final int N = resolves != null ? resolves.size() : 0;
   2462                 for (int i=0; i<N; i++) {
   2463                     ResolveInfo rInfo = resolves.get(i);
   2464                     if (rInfo.activityInfo.packageName.equals(r.packageName)
   2465                             && rInfo.activityInfo.name.equals(r.info.name)) {
   2466                         // We found the current one...  the next matching is
   2467                         // after it.
   2468                         i++;
   2469                         if (i<N) {
   2470                             aInfo = resolves.get(i).activityInfo;
   2471                         }
   2472                         break;
   2473                     }
   2474                 }
   2475             } catch (RemoteException e) {
   2476             }
   2477 
   2478             if (aInfo == null) {
   2479                 // Nobody who is next!
   2480                 ActivityOptions.abort(options);
   2481                 return false;
   2482             }
   2483 
   2484             intent.setComponent(new ComponentName(
   2485                     aInfo.applicationInfo.packageName, aInfo.name));
   2486             intent.setFlags(intent.getFlags()&~(
   2487                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
   2488                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
   2489                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
   2490                     Intent.FLAG_ACTIVITY_NEW_TASK));
   2491 
   2492             // Okay now we need to start the new activity, replacing the
   2493             // currently running activity.  This is a little tricky because
   2494             // we want to start the new one as if the current one is finished,
   2495             // but not finish the current one first so that there is no flicker.
   2496             // And thus...
   2497             final boolean wasFinishing = r.finishing;
   2498             r.finishing = true;
   2499 
   2500             // Propagate reply information over to the new activity.
   2501             final ActivityRecord resultTo = r.resultTo;
   2502             final String resultWho = r.resultWho;
   2503             final int requestCode = r.requestCode;
   2504             r.resultTo = null;
   2505             if (resultTo != null) {
   2506                 resultTo.removeResultsLocked(r, resultWho, requestCode);
   2507             }
   2508 
   2509             final long origId = Binder.clearCallingIdentity();
   2510             int res = mMainStack.startActivityLocked(r.app.thread, intent,
   2511                     r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
   2512                     resultWho, requestCode, -1, r.launchedFromUid, 0,
   2513                     options, false, null);
   2514             Binder.restoreCallingIdentity(origId);
   2515 
   2516             r.finishing = wasFinishing;
   2517             if (res != ActivityManager.START_SUCCESS) {
   2518                 return false;
   2519             }
   2520             return true;
   2521         }
   2522     }
   2523 
   2524     public final int startActivityInPackage(int uid,
   2525             Intent intent, String resolvedType, IBinder resultTo,
   2526             String resultWho, int requestCode, int startFlags, Bundle options) {
   2527 
   2528         // This is so super not safe, that only the system (or okay root)
   2529         // can do it.
   2530         int userId = Binder.getOrigCallingUser();
   2531         final int callingUid = Binder.getCallingUid();
   2532         if (callingUid != 0 && callingUid != Process.myUid()) {
   2533             throw new SecurityException(
   2534                     "startActivityInPackage only available to the system");
   2535         }
   2536 
   2537         int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
   2538                 resultTo, resultWho, requestCode, startFlags,
   2539                 null, null, null, null, options, userId);
   2540         return ret;
   2541     }
   2542 
   2543     public final int startActivities(IApplicationThread caller,
   2544             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
   2545         enforceNotIsolatedCaller("startActivities");
   2546         int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
   2547                 options, Binder.getOrigCallingUser());
   2548         return ret;
   2549     }
   2550 
   2551     public final int startActivitiesInPackage(int uid,
   2552             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
   2553             Bundle options) {
   2554 
   2555         // This is so super not safe, that only the system (or okay root)
   2556         // can do it.
   2557         final int callingUid = Binder.getCallingUid();
   2558         if (callingUid != 0 && callingUid != Process.myUid()) {
   2559             throw new SecurityException(
   2560                     "startActivityInPackage only available to the system");
   2561         }
   2562         int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
   2563                 options, UserId.getUserId(uid));
   2564         return ret;
   2565     }
   2566 
   2567     final void addRecentTaskLocked(TaskRecord task) {
   2568         int N = mRecentTasks.size();
   2569         // Quick case: check if the top-most recent task is the same.
   2570         if (N > 0 && mRecentTasks.get(0) == task) {
   2571             return;
   2572         }
   2573         // Remove any existing entries that are the same kind of task.
   2574         for (int i=0; i<N; i++) {
   2575             TaskRecord tr = mRecentTasks.get(i);
   2576             if (task.userId == tr.userId
   2577                     && ((task.affinity != null && task.affinity.equals(tr.affinity))
   2578                     || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
   2579                 mRecentTasks.remove(i);
   2580                 i--;
   2581                 N--;
   2582                 if (task.intent == null) {
   2583                     // If the new recent task we are adding is not fully
   2584                     // specified, then replace it with the existing recent task.
   2585                     task = tr;
   2586                 }
   2587             }
   2588         }
   2589         if (N >= MAX_RECENT_TASKS) {
   2590             mRecentTasks.remove(N-1);
   2591         }
   2592         mRecentTasks.add(0, task);
   2593     }
   2594 
   2595     public void setRequestedOrientation(IBinder token,
   2596             int requestedOrientation) {
   2597         synchronized (this) {
   2598             ActivityRecord r = mMainStack.isInStackLocked(token);
   2599             if (r == null) {
   2600                 return;
   2601             }
   2602             final long origId = Binder.clearCallingIdentity();
   2603             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
   2604             Configuration config = mWindowManager.updateOrientationFromAppTokens(
   2605                     mConfiguration,
   2606                     r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
   2607             if (config != null) {
   2608                 r.frozenBeforeDestroy = true;
   2609                 if (!updateConfigurationLocked(config, r, false, false)) {
   2610                     mMainStack.resumeTopActivityLocked(null);
   2611                 }
   2612             }
   2613             Binder.restoreCallingIdentity(origId);
   2614         }
   2615     }
   2616 
   2617     public int getRequestedOrientation(IBinder token) {
   2618         synchronized (this) {
   2619             ActivityRecord r = mMainStack.isInStackLocked(token);
   2620             if (r == null) {
   2621                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
   2622             }
   2623             return mWindowManager.getAppOrientation(r.appToken);
   2624         }
   2625     }
   2626 
   2627     /**
   2628      * This is the internal entry point for handling Activity.finish().
   2629      *
   2630      * @param token The Binder token referencing the Activity we want to finish.
   2631      * @param resultCode Result code, if any, from this Activity.
   2632      * @param resultData Result data (Intent), if any, from this Activity.
   2633      *
   2634      * @return Returns true if the activity successfully finished, or false if it is still running.
   2635      */
   2636     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
   2637         // Refuse possible leaked file descriptors
   2638         if (resultData != null && resultData.hasFileDescriptors() == true) {
   2639             throw new IllegalArgumentException("File descriptors passed in Intent");
   2640         }
   2641 
   2642         synchronized(this) {
   2643             if (mController != null) {
   2644                 // Find the first activity that is not finishing.
   2645                 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
   2646                 if (next != null) {
   2647                     // ask watcher if this is allowed
   2648                     boolean resumeOK = true;
   2649                     try {
   2650                         resumeOK = mController.activityResuming(next.packageName);
   2651                     } catch (RemoteException e) {
   2652                         mController = null;
   2653                     }
   2654 
   2655                     if (!resumeOK) {
   2656                         return false;
   2657                     }
   2658                 }
   2659             }
   2660             final long origId = Binder.clearCallingIdentity();
   2661             boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
   2662                     resultData, "app-request");
   2663             Binder.restoreCallingIdentity(origId);
   2664             return res;
   2665         }
   2666     }
   2667 
   2668     public final void finishHeavyWeightApp() {
   2669         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   2670                 != PackageManager.PERMISSION_GRANTED) {
   2671             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
   2672                     + Binder.getCallingPid()
   2673                     + ", uid=" + Binder.getCallingUid()
   2674                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   2675             Slog.w(TAG, msg);
   2676             throw new SecurityException(msg);
   2677         }
   2678 
   2679         synchronized(this) {
   2680             if (mHeavyWeightProcess == null) {
   2681                 return;
   2682             }
   2683 
   2684             ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
   2685                     mHeavyWeightProcess.activities);
   2686             for (int i=0; i<activities.size(); i++) {
   2687                 ActivityRecord r = activities.get(i);
   2688                 if (!r.finishing) {
   2689                     int index = mMainStack.indexOfTokenLocked(r.appToken);
   2690                     if (index >= 0) {
   2691                         mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
   2692                                 null, "finish-heavy");
   2693                     }
   2694                 }
   2695             }
   2696 
   2697             mHeavyWeightProcess = null;
   2698             mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
   2699         }
   2700     }
   2701 
   2702     public void crashApplication(int uid, int initialPid, String packageName,
   2703             String message) {
   2704         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   2705                 != PackageManager.PERMISSION_GRANTED) {
   2706             String msg = "Permission Denial: crashApplication() from pid="
   2707                     + Binder.getCallingPid()
   2708                     + ", uid=" + Binder.getCallingUid()
   2709                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   2710             Slog.w(TAG, msg);
   2711             throw new SecurityException(msg);
   2712         }
   2713 
   2714         synchronized(this) {
   2715             ProcessRecord proc = null;
   2716 
   2717             // Figure out which process to kill.  We don't trust that initialPid
   2718             // still has any relation to current pids, so must scan through the
   2719             // list.
   2720             synchronized (mPidsSelfLocked) {
   2721                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   2722                     ProcessRecord p = mPidsSelfLocked.valueAt(i);
   2723                     if (p.uid != uid) {
   2724                         continue;
   2725                     }
   2726                     if (p.pid == initialPid) {
   2727                         proc = p;
   2728                         break;
   2729                     }
   2730                     for (String str : p.pkgList) {
   2731                         if (str.equals(packageName)) {
   2732                             proc = p;
   2733                         }
   2734                     }
   2735                 }
   2736             }
   2737 
   2738             if (proc == null) {
   2739                 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
   2740                         + " initialPid=" + initialPid
   2741                         + " packageName=" + packageName);
   2742                 return;
   2743             }
   2744 
   2745             if (proc.thread != null) {
   2746                 if (proc.pid == Process.myPid()) {
   2747                     Log.w(TAG, "crashApplication: trying to crash self!");
   2748                     return;
   2749                 }
   2750                 long ident = Binder.clearCallingIdentity();
   2751                 try {
   2752                     proc.thread.scheduleCrash(message);
   2753                 } catch (RemoteException e) {
   2754                 }
   2755                 Binder.restoreCallingIdentity(ident);
   2756             }
   2757         }
   2758     }
   2759 
   2760     public final void finishSubActivity(IBinder token, String resultWho,
   2761             int requestCode) {
   2762         synchronized(this) {
   2763             final long origId = Binder.clearCallingIdentity();
   2764             mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
   2765             Binder.restoreCallingIdentity(origId);
   2766         }
   2767     }
   2768 
   2769     public boolean finishActivityAffinity(IBinder token) {
   2770         synchronized(this) {
   2771             final long origId = Binder.clearCallingIdentity();
   2772             boolean res = mMainStack.finishActivityAffinityLocked(token);
   2773             Binder.restoreCallingIdentity(origId);
   2774             return res;
   2775         }
   2776     }
   2777 
   2778     public boolean willActivityBeVisible(IBinder token) {
   2779         synchronized(this) {
   2780             int i;
   2781             for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
   2782                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   2783                 if (r.appToken == token) {
   2784                     return true;
   2785                 }
   2786                 if (r.fullscreen && !r.finishing) {
   2787                     return false;
   2788                 }
   2789             }
   2790             return true;
   2791         }
   2792     }
   2793 
   2794     public void overridePendingTransition(IBinder token, String packageName,
   2795             int enterAnim, int exitAnim) {
   2796         synchronized(this) {
   2797             ActivityRecord self = mMainStack.isInStackLocked(token);
   2798             if (self == null) {
   2799                 return;
   2800             }
   2801 
   2802             final long origId = Binder.clearCallingIdentity();
   2803 
   2804             if (self.state == ActivityState.RESUMED
   2805                     || self.state == ActivityState.PAUSING) {
   2806                 mWindowManager.overridePendingAppTransition(packageName,
   2807                         enterAnim, exitAnim, null);
   2808             }
   2809 
   2810             Binder.restoreCallingIdentity(origId);
   2811         }
   2812     }
   2813 
   2814     /**
   2815      * Main function for removing an existing process from the activity manager
   2816      * as a result of that process going away.  Clears out all connections
   2817      * to the process.
   2818      */
   2819     private final void handleAppDiedLocked(ProcessRecord app,
   2820             boolean restarting, boolean allowRestart) {
   2821         cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
   2822         if (!restarting) {
   2823             mLruProcesses.remove(app);
   2824         }
   2825 
   2826         if (mProfileProc == app) {
   2827             clearProfilerLocked();
   2828         }
   2829 
   2830         // Just in case...
   2831         if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
   2832             if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
   2833             mMainStack.mPausingActivity = null;
   2834         }
   2835         if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
   2836             mMainStack.mLastPausedActivity = null;
   2837         }
   2838 
   2839         // Remove this application's activities from active lists.
   2840         mMainStack.removeHistoryRecordsForAppLocked(app);
   2841 
   2842         boolean atTop = true;
   2843         boolean hasVisibleActivities = false;
   2844 
   2845         // Clean out the history list.
   2846         int i = mMainStack.mHistory.size();
   2847         if (localLOGV) Slog.v(
   2848             TAG, "Removing app " + app + " from history with " + i + " entries");
   2849         while (i > 0) {
   2850             i--;
   2851             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   2852             if (localLOGV) Slog.v(
   2853                 TAG, "Record #" + i + " " + r + ": app=" + r.app);
   2854             if (r.app == app) {
   2855                 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
   2856                     if (ActivityStack.DEBUG_ADD_REMOVE) {
   2857                         RuntimeException here = new RuntimeException("here");
   2858                         here.fillInStackTrace();
   2859                         Slog.i(TAG, "Removing activity " + r + " from stack at " + i
   2860                                 + ": haveState=" + r.haveState
   2861                                 + " stateNotNeeded=" + r.stateNotNeeded
   2862                                 + " finishing=" + r.finishing
   2863                                 + " state=" + r.state, here);
   2864                     }
   2865                     if (!r.finishing) {
   2866                         Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
   2867                         EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
   2868                                 System.identityHashCode(r),
   2869                                 r.task.taskId, r.shortComponentName,
   2870                                 "proc died without state saved");
   2871                     }
   2872                     mMainStack.removeActivityFromHistoryLocked(r);
   2873 
   2874                 } else {
   2875                     // We have the current state for this activity, so
   2876                     // it can be restarted later when needed.
   2877                     if (localLOGV) Slog.v(
   2878                         TAG, "Keeping entry, setting app to null");
   2879                     if (r.visible) {
   2880                         hasVisibleActivities = true;
   2881                     }
   2882                     r.app = null;
   2883                     r.nowVisible = false;
   2884                     if (!r.haveState) {
   2885                         if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
   2886                                 "App died, clearing saved state of " + r);
   2887                         r.icicle = null;
   2888                     }
   2889                 }
   2890 
   2891                 r.stack.cleanUpActivityLocked(r, true, true);
   2892             }
   2893             atTop = false;
   2894         }
   2895 
   2896         app.activities.clear();
   2897 
   2898         if (app.instrumentationClass != null) {
   2899             Slog.w(TAG, "Crash of app " + app.processName
   2900                   + " running instrumentation " + app.instrumentationClass);
   2901             Bundle info = new Bundle();
   2902             info.putString("shortMsg", "Process crashed.");
   2903             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
   2904         }
   2905 
   2906         if (!restarting) {
   2907             if (!mMainStack.resumeTopActivityLocked(null)) {
   2908                 // If there was nothing to resume, and we are not already
   2909                 // restarting this process, but there is a visible activity that
   2910                 // is hosted by the process...  then make sure all visible
   2911                 // activities are running, taking care of restarting this
   2912                 // process.
   2913                 if (hasVisibleActivities) {
   2914                     mMainStack.ensureActivitiesVisibleLocked(null, 0);
   2915                 }
   2916             }
   2917         }
   2918     }
   2919 
   2920     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
   2921         IBinder threadBinder = thread.asBinder();
   2922         // Find the application record.
   2923         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   2924             ProcessRecord rec = mLruProcesses.get(i);
   2925             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
   2926                 return i;
   2927             }
   2928         }
   2929         return -1;
   2930     }
   2931 
   2932     final ProcessRecord getRecordForAppLocked(
   2933             IApplicationThread thread) {
   2934         if (thread == null) {
   2935             return null;
   2936         }
   2937 
   2938         int appIndex = getLRURecordIndexForAppLocked(thread);
   2939         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
   2940     }
   2941 
   2942     final void appDiedLocked(ProcessRecord app, int pid,
   2943             IApplicationThread thread) {
   2944 
   2945         mProcDeaths[0]++;
   2946 
   2947         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   2948         synchronized (stats) {
   2949             stats.noteProcessDiedLocked(app.info.uid, pid);
   2950         }
   2951 
   2952         // Clean up already done if the process has been re-started.
   2953         if (app.pid == pid && app.thread != null &&
   2954                 app.thread.asBinder() == thread.asBinder()) {
   2955             if (!app.killedBackground) {
   2956                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   2957                         + ") has died.");
   2958             }
   2959             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
   2960             if (localLOGV) Slog.v(
   2961                 TAG, "Dying app: " + app + ", pid: " + pid
   2962                 + ", thread: " + thread.asBinder());
   2963             boolean doLowMem = app.instrumentationClass == null;
   2964             handleAppDiedLocked(app, false, true);
   2965 
   2966             if (doLowMem) {
   2967                 // If there are no longer any background processes running,
   2968                 // and the app that died was not running instrumentation,
   2969                 // then tell everyone we are now low on memory.
   2970                 boolean haveBg = false;
   2971                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   2972                     ProcessRecord rec = mLruProcesses.get(i);
   2973                     if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   2974                         haveBg = true;
   2975                         break;
   2976                     }
   2977                 }
   2978 
   2979                 if (!haveBg) {
   2980                     EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
   2981                     long now = SystemClock.uptimeMillis();
   2982                     for (int i=mLruProcesses.size()-1; i>=0; i--) {
   2983                         ProcessRecord rec = mLruProcesses.get(i);
   2984                         if (rec != app && rec.thread != null &&
   2985                                 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
   2986                             // The low memory report is overriding any current
   2987                             // state for a GC request.  Make sure to do
   2988                             // heavy/important/visible/foreground processes first.
   2989                             if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   2990                                 rec.lastRequestedGc = 0;
   2991                             } else {
   2992                                 rec.lastRequestedGc = rec.lastLowMemory;
   2993                             }
   2994                             rec.reportLowMemory = true;
   2995                             rec.lastLowMemory = now;
   2996                             mProcessesToGc.remove(rec);
   2997                             addProcessToGcListLocked(rec);
   2998                         }
   2999                     }
   3000                     mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
   3001                     scheduleAppGcsLocked();
   3002                 }
   3003             }
   3004         } else if (app.pid != pid) {
   3005             // A new process has already been started.
   3006             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   3007                     + ") has died and restarted (pid " + app.pid + ").");
   3008             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
   3009         } else if (DEBUG_PROCESSES) {
   3010             Slog.d(TAG, "Received spurious death notification for thread "
   3011                     + thread.asBinder());
   3012         }
   3013     }
   3014 
   3015     /**
   3016      * If a stack trace dump file is configured, dump process stack traces.
   3017      * @param clearTraces causes the dump file to be erased prior to the new
   3018      *    traces being written, if true; when false, the new traces will be
   3019      *    appended to any existing file content.
   3020      * @param firstPids of dalvik VM processes to dump stack traces for first
   3021      * @param lastPids of dalvik VM processes to dump stack traces for last
   3022      * @param nativeProcs optional list of native process names to dump stack crawls
   3023      * @return file containing stack traces, or null if no dump file is configured
   3024      */
   3025     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
   3026             ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
   3027         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   3028         if (tracesPath == null || tracesPath.length() == 0) {
   3029             return null;
   3030         }
   3031 
   3032         File tracesFile = new File(tracesPath);
   3033         try {
   3034             File tracesDir = tracesFile.getParentFile();
   3035             if (!tracesDir.exists()) tracesFile.mkdirs();
   3036             FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
   3037 
   3038             if (clearTraces && tracesFile.exists()) tracesFile.delete();
   3039             tracesFile.createNewFile();
   3040             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   3041         } catch (IOException e) {
   3042             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
   3043             return null;
   3044         }
   3045 
   3046         dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
   3047         return tracesFile;
   3048     }
   3049 
   3050     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
   3051             ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
   3052         // Use a FileObserver to detect when traces finish writing.
   3053         // The order of traces is considered important to maintain for legibility.
   3054         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
   3055             public synchronized void onEvent(int event, String path) { notify(); }
   3056         };
   3057 
   3058         try {
   3059             observer.startWatching();
   3060 
   3061             // First collect all of the stacks of the most important pids.
   3062             if (firstPids != null) {
   3063                 try {
   3064                     int num = firstPids.size();
   3065                     for (int i = 0; i < num; i++) {
   3066                         synchronized (observer) {
   3067                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
   3068                             observer.wait(200);  // Wait for write-close, give up after 200msec
   3069                         }
   3070                     }
   3071                 } catch (InterruptedException e) {
   3072                     Log.wtf(TAG, e);
   3073                 }
   3074             }
   3075 
   3076             // Next measure CPU usage.
   3077             if (processStats != null) {
   3078                 processStats.init();
   3079                 System.gc();
   3080                 processStats.update();
   3081                 try {
   3082                     synchronized (processStats) {
   3083                         processStats.wait(500); // measure over 1/2 second.
   3084                     }
   3085                 } catch (InterruptedException e) {
   3086                 }
   3087                 processStats.update();
   3088 
   3089                 // We'll take the stack crawls of just the top apps using CPU.
   3090                 final int N = processStats.countWorkingStats();
   3091                 int numProcs = 0;
   3092                 for (int i=0; i<N && numProcs<5; i++) {
   3093                     ProcessStats.Stats stats = processStats.getWorkingStats(i);
   3094                     if (lastPids.indexOfKey(stats.pid) >= 0) {
   3095                         numProcs++;
   3096                         try {
   3097                             synchronized (observer) {
   3098                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
   3099                                 observer.wait(200);  // Wait for write-close, give up after 200msec
   3100                             }
   3101                         } catch (InterruptedException e) {
   3102                             Log.wtf(TAG, e);
   3103                         }
   3104 
   3105                     }
   3106                 }
   3107             }
   3108 
   3109         } finally {
   3110             observer.stopWatching();
   3111         }
   3112 
   3113         if (nativeProcs != null) {
   3114             int[] pids = Process.getPidsForCommands(nativeProcs);
   3115             if (pids != null) {
   3116                 for (int pid : pids) {
   3117                     Debug.dumpNativeBacktraceToFile(pid, tracesPath);
   3118                 }
   3119             }
   3120         }
   3121     }
   3122 
   3123     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
   3124         if (true || IS_USER_BUILD) {
   3125             return;
   3126         }
   3127         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   3128         if (tracesPath == null || tracesPath.length() == 0) {
   3129             return;
   3130         }
   3131 
   3132         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
   3133         StrictMode.allowThreadDiskWrites();
   3134         try {
   3135             final File tracesFile = new File(tracesPath);
   3136             final File tracesDir = tracesFile.getParentFile();
   3137             final File tracesTmp = new File(tracesDir, "__tmp__");
   3138             try {
   3139                 if (!tracesDir.exists()) tracesFile.mkdirs();
   3140                 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
   3141 
   3142                 if (tracesFile.exists()) {
   3143                     tracesTmp.delete();
   3144                     tracesFile.renameTo(tracesTmp);
   3145                 }
   3146                 StringBuilder sb = new StringBuilder();
   3147                 Time tobj = new Time();
   3148                 tobj.set(System.currentTimeMillis());
   3149                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
   3150                 sb.append(": ");
   3151                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
   3152                 sb.append(" since ");
   3153                 sb.append(msg);
   3154                 FileOutputStream fos = new FileOutputStream(tracesFile);
   3155                 fos.write(sb.toString().getBytes());
   3156                 if (app == null) {
   3157                     fos.write("\n*** No application process!".getBytes());
   3158                 }
   3159                 fos.close();
   3160                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   3161             } catch (IOException e) {
   3162                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
   3163                 return;
   3164             }
   3165 
   3166             if (app != null) {
   3167                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
   3168                 firstPids.add(app.pid);
   3169                 dumpStackTraces(tracesPath, firstPids, null, null, null);
   3170             }
   3171 
   3172             File lastTracesFile = null;
   3173             File curTracesFile = null;
   3174             for (int i=9; i>=0; i--) {
   3175                 String name = String.format("slow%02d.txt", i);
   3176                 curTracesFile = new File(tracesDir, name);
   3177                 if (curTracesFile.exists()) {
   3178                     if (lastTracesFile != null) {
   3179                         curTracesFile.renameTo(lastTracesFile);
   3180                     } else {
   3181                         curTracesFile.delete();
   3182                     }
   3183                 }
   3184                 lastTracesFile = curTracesFile;
   3185             }
   3186             tracesFile.renameTo(curTracesFile);
   3187             if (tracesTmp.exists()) {
   3188                 tracesTmp.renameTo(tracesFile);
   3189             }
   3190         } finally {
   3191             StrictMode.setThreadPolicy(oldPolicy);
   3192         }
   3193     }
   3194 
   3195     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
   3196             ActivityRecord parent, final String annotation) {
   3197         ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
   3198         SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
   3199 
   3200         if (mController != null) {
   3201             try {
   3202                 // 0 == continue, -1 = kill process immediately
   3203                 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
   3204                 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
   3205             } catch (RemoteException e) {
   3206                 mController = null;
   3207             }
   3208         }
   3209 
   3210         long anrTime = SystemClock.uptimeMillis();
   3211         if (MONITOR_CPU_USAGE) {
   3212             updateCpuStatsNow();
   3213         }
   3214 
   3215         synchronized (this) {
   3216             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
   3217             if (mShuttingDown) {
   3218                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
   3219                 return;
   3220             } else if (app.notResponding) {
   3221                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
   3222                 return;
   3223             } else if (app.crashing) {
   3224                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
   3225                 return;
   3226             }
   3227 
   3228             // In case we come through here for the same app before completing
   3229             // this one, mark as anring now so we will bail out.
   3230             app.notResponding = true;
   3231 
   3232             // Log the ANR to the event log.
   3233             EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
   3234                     annotation);
   3235 
   3236             // Dump thread traces as quickly as we can, starting with "interesting" processes.
   3237             firstPids.add(app.pid);
   3238 
   3239             int parentPid = app.pid;
   3240             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
   3241             if (parentPid != app.pid) firstPids.add(parentPid);
   3242 
   3243             if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
   3244 
   3245             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   3246                 ProcessRecord r = mLruProcesses.get(i);
   3247                 if (r != null && r.thread != null) {
   3248                     int pid = r.pid;
   3249                     if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
   3250                         if (r.persistent) {
   3251                             firstPids.add(pid);
   3252                         } else {
   3253                             lastPids.put(pid, Boolean.TRUE);
   3254                         }
   3255                     }
   3256                 }
   3257             }
   3258         }
   3259 
   3260         // Log the ANR to the main log.
   3261         StringBuilder info = new StringBuilder();
   3262         info.setLength(0);
   3263         info.append("ANR in ").append(app.processName);
   3264         if (activity != null && activity.shortComponentName != null) {
   3265             info.append(" (").append(activity.shortComponentName).append(")");
   3266         }
   3267         info.append("\n");
   3268         if (annotation != null) {
   3269             info.append("Reason: ").append(annotation).append("\n");
   3270         }
   3271         if (parent != null && parent != activity) {
   3272             info.append("Parent: ").append(parent.shortComponentName).append("\n");
   3273         }
   3274 
   3275         final ProcessStats processStats = new ProcessStats(true);
   3276 
   3277         File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
   3278 
   3279         String cpuInfo = null;
   3280         if (MONITOR_CPU_USAGE) {
   3281             updateCpuStatsNow();
   3282             synchronized (mProcessStatsThread) {
   3283                 cpuInfo = mProcessStats.printCurrentState(anrTime);
   3284             }
   3285             info.append(processStats.printCurrentLoad());
   3286             info.append(cpuInfo);
   3287         }
   3288 
   3289         info.append(processStats.printCurrentState(anrTime));
   3290 
   3291         Slog.e(TAG, info.toString());
   3292         if (tracesFile == null) {
   3293             // There is no trace file, so dump (only) the alleged culprit's threads to the log
   3294             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
   3295         }
   3296 
   3297         addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
   3298                 cpuInfo, tracesFile, null);
   3299 
   3300         if (mController != null) {
   3301             try {
   3302                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
   3303                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
   3304                 if (res != 0) {
   3305                     if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
   3306                     return;
   3307                 }
   3308             } catch (RemoteException e) {
   3309                 mController = null;
   3310             }
   3311         }
   3312 
   3313         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
   3314         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
   3315                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
   3316 
   3317         synchronized (this) {
   3318             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
   3319                 Slog.w(TAG, "Killing " + app + ": background ANR");
   3320                 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   3321                         app.processName, app.setAdj, "background ANR");
   3322                 Process.killProcessQuiet(app.pid);
   3323                 return;
   3324             }
   3325 
   3326             // Set the app's notResponding state, and look up the errorReportReceiver
   3327             makeAppNotRespondingLocked(app,
   3328                     activity != null ? activity.shortComponentName : null,
   3329                     annotation != null ? "ANR " + annotation : "ANR",
   3330                     info.toString());
   3331 
   3332             // Bring up the infamous App Not Responding dialog
   3333             Message msg = Message.obtain();
   3334             HashMap map = new HashMap();
   3335             msg.what = SHOW_NOT_RESPONDING_MSG;
   3336             msg.obj = map;
   3337             map.put("app", app);
   3338             if (activity != null) {
   3339                 map.put("activity", activity);
   3340             }
   3341 
   3342             mHandler.sendMessage(msg);
   3343         }
   3344     }
   3345 
   3346     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
   3347         if (!mLaunchWarningShown) {
   3348             mLaunchWarningShown = true;
   3349             mHandler.post(new Runnable() {
   3350                 @Override
   3351                 public void run() {
   3352                     synchronized (ActivityManagerService.this) {
   3353                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
   3354                         d.show();
   3355                         mHandler.postDelayed(new Runnable() {
   3356                             @Override
   3357                             public void run() {
   3358                                 synchronized (ActivityManagerService.this) {
   3359                                     d.dismiss();
   3360                                     mLaunchWarningShown = false;
   3361                                 }
   3362                             }
   3363                         }, 4000);
   3364                     }
   3365                 }
   3366             });
   3367         }
   3368     }
   3369 
   3370     public boolean clearApplicationUserData(final String packageName,
   3371             final IPackageDataObserver observer, final int userId) {
   3372         enforceNotIsolatedCaller("clearApplicationUserData");
   3373         int uid = Binder.getCallingUid();
   3374         int pid = Binder.getCallingPid();
   3375         long callingId = Binder.clearCallingIdentity();
   3376         try {
   3377             IPackageManager pm = AppGlobals.getPackageManager();
   3378             int pkgUid = -1;
   3379             synchronized(this) {
   3380                 try {
   3381                     pkgUid = pm.getPackageUid(packageName, userId);
   3382                 } catch (RemoteException e) {
   3383                 }
   3384                 if (pkgUid == -1) {
   3385                     Slog.w(TAG, "Invalid packageName:" + packageName);
   3386                     return false;
   3387                 }
   3388                 if (uid == pkgUid || checkComponentPermission(
   3389                         android.Manifest.permission.CLEAR_APP_USER_DATA,
   3390                         pid, uid, -1, true)
   3391                         == PackageManager.PERMISSION_GRANTED) {
   3392                     forceStopPackageLocked(packageName, pkgUid);
   3393                 } else {
   3394                     throw new SecurityException(pid+" does not have permission:"+
   3395                             android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
   3396                                     "for process:"+packageName);
   3397                 }
   3398             }
   3399 
   3400             try {
   3401                 //clear application user data
   3402                 pm.clearApplicationUserData(packageName, observer, userId);
   3403                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
   3404                         Uri.fromParts("package", packageName, null));
   3405                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
   3406                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
   3407                         null, null, 0, null, null, null, false, false, userId);
   3408             } catch (RemoteException e) {
   3409             }
   3410         } finally {
   3411             Binder.restoreCallingIdentity(callingId);
   3412         }
   3413         return true;
   3414     }
   3415 
   3416     public void killBackgroundProcesses(final String packageName) {
   3417         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   3418                 != PackageManager.PERMISSION_GRANTED &&
   3419                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
   3420                         != PackageManager.PERMISSION_GRANTED) {
   3421             String msg = "Permission Denial: killBackgroundProcesses() from pid="
   3422                     + Binder.getCallingPid()
   3423                     + ", uid=" + Binder.getCallingUid()
   3424                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   3425             Slog.w(TAG, msg);
   3426             throw new SecurityException(msg);
   3427         }
   3428 
   3429         int userId = UserId.getCallingUserId();
   3430         long callingId = Binder.clearCallingIdentity();
   3431         try {
   3432             IPackageManager pm = AppGlobals.getPackageManager();
   3433             int pkgUid = -1;
   3434             synchronized(this) {
   3435                 try {
   3436                     pkgUid = pm.getPackageUid(packageName, userId);
   3437                 } catch (RemoteException e) {
   3438                 }
   3439                 if (pkgUid == -1) {
   3440                     Slog.w(TAG, "Invalid packageName: " + packageName);
   3441                     return;
   3442                 }
   3443                 killPackageProcessesLocked(packageName, pkgUid,
   3444                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
   3445             }
   3446         } finally {
   3447             Binder.restoreCallingIdentity(callingId);
   3448         }
   3449     }
   3450 
   3451     public void killAllBackgroundProcesses() {
   3452         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   3453                 != PackageManager.PERMISSION_GRANTED) {
   3454             String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
   3455                     + Binder.getCallingPid()
   3456                     + ", uid=" + Binder.getCallingUid()
   3457                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   3458             Slog.w(TAG, msg);
   3459             throw new SecurityException(msg);
   3460         }
   3461 
   3462         long callingId = Binder.clearCallingIdentity();
   3463         try {
   3464             synchronized(this) {
   3465                 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   3466                 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   3467                     final int NA = apps.size();
   3468                     for (int ia=0; ia<NA; ia++) {
   3469                         ProcessRecord app = apps.valueAt(ia);
   3470                         if (app.persistent) {
   3471                             // we don't kill persistent processes
   3472                             continue;
   3473                         }
   3474                         if (app.removed) {
   3475                             procs.add(app);
   3476                         } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   3477                             app.removed = true;
   3478                             procs.add(app);
   3479                         }
   3480                     }
   3481                 }
   3482 
   3483                 int N = procs.size();
   3484                 for (int i=0; i<N; i++) {
   3485                     removeProcessLocked(procs.get(i), false, true, "kill all background");
   3486                 }
   3487             }
   3488         } finally {
   3489             Binder.restoreCallingIdentity(callingId);
   3490         }
   3491     }
   3492 
   3493     public void forceStopPackage(final String packageName) {
   3494         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   3495                 != PackageManager.PERMISSION_GRANTED) {
   3496             String msg = "Permission Denial: forceStopPackage() from pid="
   3497                     + Binder.getCallingPid()
   3498                     + ", uid=" + Binder.getCallingUid()
   3499                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   3500             Slog.w(TAG, msg);
   3501             throw new SecurityException(msg);
   3502         }
   3503         final int userId = UserId.getCallingUserId();
   3504         long callingId = Binder.clearCallingIdentity();
   3505         try {
   3506             IPackageManager pm = AppGlobals.getPackageManager();
   3507             int pkgUid = -1;
   3508             synchronized(this) {
   3509                 try {
   3510                     pkgUid = pm.getPackageUid(packageName, userId);
   3511                 } catch (RemoteException e) {
   3512                 }
   3513                 if (pkgUid == -1) {
   3514                     Slog.w(TAG, "Invalid packageName: " + packageName);
   3515                     return;
   3516                 }
   3517                 forceStopPackageLocked(packageName, pkgUid);
   3518                 try {
   3519                     pm.setPackageStoppedState(packageName, true, userId);
   3520                 } catch (RemoteException e) {
   3521                 } catch (IllegalArgumentException e) {
   3522                     Slog.w(TAG, "Failed trying to unstop package "
   3523                             + packageName + ": " + e);
   3524                 }
   3525             }
   3526         } finally {
   3527             Binder.restoreCallingIdentity(callingId);
   3528         }
   3529     }
   3530 
   3531     /*
   3532      * The pkg name and uid have to be specified.
   3533      * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
   3534      */
   3535     public void killApplicationWithUid(String pkg, int uid) {
   3536         if (pkg == null) {
   3537             return;
   3538         }
   3539         // Make sure the uid is valid.
   3540         if (uid < 0) {
   3541             Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
   3542             return;
   3543         }
   3544         int callerUid = Binder.getCallingUid();
   3545         // Only the system server can kill an application
   3546         if (callerUid == Process.SYSTEM_UID) {
   3547             // Post an aysnc message to kill the application
   3548             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
   3549             msg.arg1 = uid;
   3550             msg.arg2 = 0;
   3551             msg.obj = pkg;
   3552             mHandler.sendMessage(msg);
   3553         } else {
   3554             throw new SecurityException(callerUid + " cannot kill pkg: " +
   3555                     pkg);
   3556         }
   3557     }
   3558 
   3559     public void closeSystemDialogs(String reason) {
   3560         enforceNotIsolatedCaller("closeSystemDialogs");
   3561 
   3562         final int uid = Binder.getCallingUid();
   3563         final long origId = Binder.clearCallingIdentity();
   3564         synchronized (this) {
   3565             closeSystemDialogsLocked(uid, reason);
   3566         }
   3567         Binder.restoreCallingIdentity(origId);
   3568     }
   3569 
   3570     void closeSystemDialogsLocked(int callingUid, String reason) {
   3571         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
   3572         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   3573         if (reason != null) {
   3574             intent.putExtra("reason", reason);
   3575         }
   3576         mWindowManager.closeSystemDialogs(reason);
   3577 
   3578         for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
   3579             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   3580             if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
   3581                 r.stack.finishActivityLocked(r, i,
   3582                         Activity.RESULT_CANCELED, null, "close-sys");
   3583             }
   3584         }
   3585 
   3586         broadcastIntentLocked(null, null, intent, null,
   3587                 null, 0, null, null, null, false, false, -1,
   3588                 callingUid, 0 /* TODO: Verify */);
   3589     }
   3590 
   3591     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
   3592             throws RemoteException {
   3593         enforceNotIsolatedCaller("getProcessMemoryInfo");
   3594         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
   3595         for (int i=pids.length-1; i>=0; i--) {
   3596             infos[i] = new Debug.MemoryInfo();
   3597             Debug.getMemoryInfo(pids[i], infos[i]);
   3598         }
   3599         return infos;
   3600     }
   3601 
   3602     public long[] getProcessPss(int[] pids) throws RemoteException {
   3603         enforceNotIsolatedCaller("getProcessPss");
   3604         long[] pss = new long[pids.length];
   3605         for (int i=pids.length-1; i>=0; i--) {
   3606             pss[i] = Debug.getPss(pids[i]);
   3607         }
   3608         return pss;
   3609     }
   3610 
   3611     public void killApplicationProcess(String processName, int uid) {
   3612         if (processName == null) {
   3613             return;
   3614         }
   3615 
   3616         int callerUid = Binder.getCallingUid();
   3617         // Only the system server can kill an application
   3618         if (callerUid == Process.SYSTEM_UID) {
   3619             synchronized (this) {
   3620                 ProcessRecord app = getProcessRecordLocked(processName, uid);
   3621                 if (app != null && app.thread != null) {
   3622                     try {
   3623                         app.thread.scheduleSuicide();
   3624                     } catch (RemoteException e) {
   3625                         // If the other end already died, then our work here is done.
   3626                     }
   3627                 } else {
   3628                     Slog.w(TAG, "Process/uid not found attempting kill of "
   3629                             + processName + " / " + uid);
   3630                 }
   3631             }
   3632         } else {
   3633             throw new SecurityException(callerUid + " cannot kill app process: " +
   3634                     processName);
   3635         }
   3636     }
   3637 
   3638     private void forceStopPackageLocked(final String packageName, int uid) {
   3639         forceStopPackageLocked(packageName, uid, false, false, true, false, UserId.getUserId(uid));
   3640         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
   3641                 Uri.fromParts("package", packageName, null));
   3642         if (!mProcessesReady) {
   3643             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   3644         }
   3645         intent.putExtra(Intent.EXTRA_UID, uid);
   3646         broadcastIntentLocked(null, null, intent,
   3647                 null, null, 0, null, null, null,
   3648                 false, false,
   3649                 MY_PID, Process.SYSTEM_UID, UserId.getUserId(uid));
   3650     }
   3651 
   3652     private final boolean killPackageProcessesLocked(String packageName, int uid,
   3653             int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
   3654             boolean evenPersistent, String reason) {
   3655         ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   3656 
   3657         // Remove all processes this package may have touched: all with the
   3658         // same UID (except for the system or root user), and all whose name
   3659         // matches the package name.
   3660         final String procNamePrefix = packageName + ":";
   3661         for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   3662             final int NA = apps.size();
   3663             for (int ia=0; ia<NA; ia++) {
   3664                 ProcessRecord app = apps.valueAt(ia);
   3665                 if (app.persistent && !evenPersistent) {
   3666                     // we don't kill persistent processes
   3667                     continue;
   3668                 }
   3669                 if (app.removed) {
   3670                     if (doit) {
   3671                         procs.add(app);
   3672                     }
   3673                 // If uid is specified and the uid and process name match
   3674                 // Or, the uid is not specified and the process name matches
   3675                 } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
   3676                             || ((app.processName.equals(packageName)
   3677                                  || app.processName.startsWith(procNamePrefix))
   3678                                 && uid < 0))) {
   3679                     if (app.setAdj >= minOomAdj) {
   3680                         if (!doit) {
   3681                             return true;
   3682                         }
   3683                         app.removed = true;
   3684                         procs.add(app);
   3685                     }
   3686                 }
   3687             }
   3688         }
   3689 
   3690         int N = procs.size();
   3691         for (int i=0; i<N; i++) {
   3692             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
   3693         }
   3694         return N > 0;
   3695     }
   3696 
   3697     private final boolean forceStopPackageLocked(String name, int uid,
   3698             boolean callerWillRestart, boolean purgeCache, boolean doit,
   3699             boolean evenPersistent, int userId) {
   3700         int i;
   3701         int N;
   3702 
   3703         if (uid < 0) {
   3704             try {
   3705                 uid = AppGlobals.getPackageManager().getPackageUid(name, userId);
   3706             } catch (RemoteException e) {
   3707             }
   3708         }
   3709 
   3710         if (doit) {
   3711             Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
   3712 
   3713             Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
   3714             while (badApps.hasNext()) {
   3715                 SparseArray<Long> ba = badApps.next();
   3716                 if (ba.get(uid) != null) {
   3717                     badApps.remove();
   3718                 }
   3719             }
   3720         }
   3721 
   3722         boolean didSomething = killPackageProcessesLocked(name, uid, -100,
   3723                 callerWillRestart, false, doit, evenPersistent, "force stop");
   3724 
   3725         TaskRecord lastTask = null;
   3726         for (i=0; i<mMainStack.mHistory.size(); i++) {
   3727             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   3728             final boolean samePackage = r.packageName.equals(name);
   3729             if (r.userId == userId
   3730                     && (samePackage || r.task == lastTask)
   3731                     && (r.app == null || evenPersistent || !r.app.persistent)) {
   3732                 if (!doit) {
   3733                     if (r.finishing) {
   3734                         // If this activity is just finishing, then it is not
   3735                         // interesting as far as something to stop.
   3736                         continue;
   3737                     }
   3738                     return true;
   3739                 }
   3740                 didSomething = true;
   3741                 Slog.i(TAG, "  Force finishing activity " + r);
   3742                 if (samePackage) {
   3743                     if (r.app != null) {
   3744                         r.app.removed = true;
   3745                     }
   3746                     r.app = null;
   3747                 }
   3748                 lastTask = r.task;
   3749                 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
   3750                         null, "force-stop", true)) {
   3751                     i--;
   3752                 }
   3753             }
   3754         }
   3755 
   3756         ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
   3757         for (ServiceRecord service : mServiceMap.getAllServices(userId)) {
   3758             if (service.packageName.equals(name)
   3759                     && (service.app == null || evenPersistent || !service.app.persistent)) {
   3760                 if (!doit) {
   3761                     return true;
   3762                 }
   3763                 didSomething = true;
   3764                 Slog.i(TAG, "  Force stopping service " + service);
   3765                 if (service.app != null) {
   3766                     service.app.removed = true;
   3767                 }
   3768                 service.app = null;
   3769                 service.isolatedProc = null;
   3770                 services.add(service);
   3771             }
   3772         }
   3773 
   3774         N = services.size();
   3775         for (i=0; i<N; i++) {
   3776             bringDownServiceLocked(services.get(i), true);
   3777         }
   3778 
   3779         ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
   3780         for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) {
   3781             if (provider.info.packageName.equals(name)
   3782                     && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
   3783                 if (!doit) {
   3784                     return true;
   3785                 }
   3786                 didSomething = true;
   3787                 providers.add(provider);
   3788             }
   3789         }
   3790 
   3791         N = providers.size();
   3792         for (i=0; i<N; i++) {
   3793             removeDyingProviderLocked(null, providers.get(i), true);
   3794         }
   3795 
   3796         if (doit) {
   3797             if (purgeCache) {
   3798                 AttributeCache ac = AttributeCache.instance();
   3799                 if (ac != null) {
   3800                     ac.removePackage(name);
   3801                 }
   3802             }
   3803             if (mBooted) {
   3804                 mMainStack.resumeTopActivityLocked(null);
   3805                 mMainStack.scheduleIdleLocked();
   3806             }
   3807         }
   3808 
   3809         return didSomething;
   3810     }
   3811 
   3812     private final boolean removeProcessLocked(ProcessRecord app,
   3813             boolean callerWillRestart, boolean allowRestart, String reason) {
   3814         final String name = app.processName;
   3815         final int uid = app.uid;
   3816         if (DEBUG_PROCESSES) Slog.d(
   3817             TAG, "Force removing proc " + app.toShortString() + " (" + name
   3818             + "/" + uid + ")");
   3819 
   3820         mProcessNames.remove(name, uid);
   3821         mIsolatedProcesses.remove(app.uid);
   3822         if (mHeavyWeightProcess == app) {
   3823             mHeavyWeightProcess = null;
   3824             mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
   3825         }
   3826         boolean needRestart = false;
   3827         if (app.pid > 0 && app.pid != MY_PID) {
   3828             int pid = app.pid;
   3829             synchronized (mPidsSelfLocked) {
   3830                 mPidsSelfLocked.remove(pid);
   3831                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   3832             }
   3833             Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
   3834             handleAppDiedLocked(app, true, allowRestart);
   3835             mLruProcesses.remove(app);
   3836             Process.killProcessQuiet(pid);
   3837 
   3838             if (app.persistent && !app.isolated) {
   3839                 if (!callerWillRestart) {
   3840                     addAppLocked(app.info, false);
   3841                 } else {
   3842                     needRestart = true;
   3843                 }
   3844             }
   3845         } else {
   3846             mRemovedProcesses.add(app);
   3847         }
   3848 
   3849         return needRestart;
   3850     }
   3851 
   3852     private final void processStartTimedOutLocked(ProcessRecord app) {
   3853         final int pid = app.pid;
   3854         boolean gone = false;
   3855         synchronized (mPidsSelfLocked) {
   3856             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
   3857             if (knownApp != null && knownApp.thread == null) {
   3858                 mPidsSelfLocked.remove(pid);
   3859                 gone = true;
   3860             }
   3861         }
   3862 
   3863         if (gone) {
   3864             Slog.w(TAG, "Process " + app + " failed to attach");
   3865             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
   3866                     app.processName);
   3867             mProcessNames.remove(app.processName, app.uid);
   3868             mIsolatedProcesses.remove(app.uid);
   3869             if (mHeavyWeightProcess == app) {
   3870                 mHeavyWeightProcess = null;
   3871                 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
   3872             }
   3873             // Take care of any launching providers waiting for this process.
   3874             checkAppInLaunchingProvidersLocked(app, true);
   3875             // Take care of any services that are waiting for the process.
   3876             for (int i=0; i<mPendingServices.size(); i++) {
   3877                 ServiceRecord sr = mPendingServices.get(i);
   3878                 if ((app.uid == sr.appInfo.uid
   3879                         && app.processName.equals(sr.processName))
   3880                         || sr.isolatedProc == app) {
   3881                     Slog.w(TAG, "Forcing bringing down service: " + sr);
   3882                     sr.isolatedProc = null;
   3883                     mPendingServices.remove(i);
   3884                     i--;
   3885                     bringDownServiceLocked(sr, true);
   3886                 }
   3887             }
   3888             EventLog.writeEvent(EventLogTags.AM_KILL, pid,
   3889                     app.processName, app.setAdj, "start timeout");
   3890             Process.killProcessQuiet(pid);
   3891             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
   3892                 Slog.w(TAG, "Unattached app died before backup, skipping");
   3893                 try {
   3894                     IBackupManager bm = IBackupManager.Stub.asInterface(
   3895                             ServiceManager.getService(Context.BACKUP_SERVICE));
   3896                     bm.agentDisconnected(app.info.packageName);
   3897                 } catch (RemoteException e) {
   3898                     // Can't happen; the backup manager is local
   3899                 }
   3900             }
   3901             if (isPendingBroadcastProcessLocked(pid)) {
   3902                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   3903                 skipPendingBroadcastLocked(pid);
   3904             }
   3905         } else {
   3906             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
   3907         }
   3908     }
   3909 
   3910     private final boolean attachApplicationLocked(IApplicationThread thread,
   3911             int pid) {
   3912 
   3913         // Find the application record that is being attached...  either via
   3914         // the pid if we are running in multiple processes, or just pull the
   3915         // next app record if we are emulating process with anonymous threads.
   3916         ProcessRecord app;
   3917         if (pid != MY_PID && pid >= 0) {
   3918             synchronized (mPidsSelfLocked) {
   3919                 app = mPidsSelfLocked.get(pid);
   3920             }
   3921         } else {
   3922             app = null;
   3923         }
   3924 
   3925         if (app == null) {
   3926             Slog.w(TAG, "No pending application record for pid " + pid
   3927                     + " (IApplicationThread " + thread + "); dropping process");
   3928             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
   3929             if (pid > 0 && pid != MY_PID) {
   3930                 Process.killProcessQuiet(pid);
   3931             } else {
   3932                 try {
   3933                     thread.scheduleExit();
   3934                 } catch (Exception e) {
   3935                     // Ignore exceptions.
   3936                 }
   3937             }
   3938             return false;
   3939         }
   3940 
   3941         // If this application record is still attached to a previous
   3942         // process, clean it up now.
   3943         if (app.thread != null) {
   3944             handleAppDiedLocked(app, true, true);
   3945         }
   3946 
   3947         // Tell the process all about itself.
   3948 
   3949         if (localLOGV) Slog.v(
   3950                 TAG, "Binding process pid " + pid + " to record " + app);
   3951 
   3952         String processName = app.processName;
   3953         try {
   3954             AppDeathRecipient adr = new AppDeathRecipient(
   3955                     app, pid, thread);
   3956             thread.asBinder().linkToDeath(adr, 0);
   3957             app.deathRecipient = adr;
   3958         } catch (RemoteException e) {
   3959             app.resetPackageList();
   3960             startProcessLocked(app, "link fail", processName);
   3961             return false;
   3962         }
   3963 
   3964         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
   3965 
   3966         app.thread = thread;
   3967         app.curAdj = app.setAdj = -100;
   3968         app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
   3969         app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   3970         app.forcingToForeground = null;
   3971         app.foregroundServices = false;
   3972         app.hasShownUi = false;
   3973         app.debugging = false;
   3974 
   3975         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   3976 
   3977         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
   3978         List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
   3979 
   3980         if (!normalMode) {
   3981             Slog.i(TAG, "Launching preboot mode app: " + app);
   3982         }
   3983 
   3984         if (localLOGV) Slog.v(
   3985             TAG, "New app record " + app
   3986             + " thread=" + thread.asBinder() + " pid=" + pid);
   3987         try {
   3988             int testMode = IApplicationThread.DEBUG_OFF;
   3989             if (mDebugApp != null && mDebugApp.equals(processName)) {
   3990                 testMode = mWaitForDebugger
   3991                     ? IApplicationThread.DEBUG_WAIT
   3992                     : IApplicationThread.DEBUG_ON;
   3993                 app.debugging = true;
   3994                 if (mDebugTransient) {
   3995                     mDebugApp = mOrigDebugApp;
   3996                     mWaitForDebugger = mOrigWaitForDebugger;
   3997                 }
   3998             }
   3999             String profileFile = app.instrumentationProfileFile;
   4000             ParcelFileDescriptor profileFd = null;
   4001             boolean profileAutoStop = false;
   4002             if (mProfileApp != null && mProfileApp.equals(processName)) {
   4003                 mProfileProc = app;
   4004                 profileFile = mProfileFile;
   4005                 profileFd = mProfileFd;
   4006                 profileAutoStop = mAutoStopProfiler;
   4007             }
   4008             boolean enableOpenGlTrace = false;
   4009             if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
   4010                 enableOpenGlTrace = true;
   4011                 mOpenGlTraceApp = null;
   4012             }
   4013 
   4014             // If the app is being launched for restore or full backup, set it up specially
   4015             boolean isRestrictedBackupMode = false;
   4016             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
   4017                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
   4018                         || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
   4019                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
   4020             }
   4021 
   4022             ensurePackageDexOpt(app.instrumentationInfo != null
   4023                     ? app.instrumentationInfo.packageName
   4024                     : app.info.packageName);
   4025             if (app.instrumentationClass != null) {
   4026                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
   4027             }
   4028             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
   4029                     + processName + " with config " + mConfiguration);
   4030             ApplicationInfo appInfo = app.instrumentationInfo != null
   4031                     ? app.instrumentationInfo : app.info;
   4032             app.compat = compatibilityInfoForPackageLocked(appInfo);
   4033             if (profileFd != null) {
   4034                 profileFd = profileFd.dup();
   4035             }
   4036             thread.bindApplication(processName, appInfo, providers,
   4037                     app.instrumentationClass, profileFile, profileFd, profileAutoStop,
   4038                     app.instrumentationArguments, app.instrumentationWatcher, testMode,
   4039                     enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
   4040                     new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
   4041                     mCoreSettingsObserver.getCoreSettingsLocked());
   4042             updateLruProcessLocked(app, false, true);
   4043             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
   4044         } catch (Exception e) {
   4045             // todo: Yikes!  What should we do?  For now we will try to
   4046             // start another process, but that could easily get us in
   4047             // an infinite loop of restarting processes...
   4048             Slog.w(TAG, "Exception thrown during bind!", e);
   4049 
   4050             app.resetPackageList();
   4051             app.unlinkDeathRecipient();
   4052             startProcessLocked(app, "bind fail", processName);
   4053             return false;
   4054         }
   4055 
   4056         // Remove this record from the list of starting applications.
   4057         mPersistentStartingProcesses.remove(app);
   4058         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   4059                 "Attach application locked removing on hold: " + app);
   4060         mProcessesOnHold.remove(app);
   4061 
   4062         boolean badApp = false;
   4063         boolean didSomething = false;
   4064 
   4065         // See if the top visible activity is waiting to run in this process...
   4066         ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
   4067         if (hr != null && normalMode) {
   4068             if (hr.app == null && app.uid == hr.info.applicationInfo.uid
   4069                     && processName.equals(hr.processName)) {
   4070                 try {
   4071                     if (mHeadless) {
   4072                         Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
   4073                     } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
   4074                         didSomething = true;
   4075                     }
   4076                 } catch (Exception e) {
   4077                     Slog.w(TAG, "Exception in new application when starting activity "
   4078                           + hr.intent.getComponent().flattenToShortString(), e);
   4079                     badApp = true;
   4080                 }
   4081             } else {
   4082                 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
   4083             }
   4084         }
   4085 
   4086         // Find any services that should be running in this process...
   4087         if (!badApp && mPendingServices.size() > 0) {
   4088             ServiceRecord sr = null;
   4089             try {
   4090                 for (int i=0; i<mPendingServices.size(); i++) {
   4091                     sr = mPendingServices.get(i);
   4092                     if (app != sr.isolatedProc && (app.uid != sr.appInfo.uid
   4093                             || !processName.equals(sr.processName))) {
   4094                         continue;
   4095                     }
   4096 
   4097                     mPendingServices.remove(i);
   4098                     i--;
   4099                     realStartServiceLocked(sr, app);
   4100                     didSomething = true;
   4101                 }
   4102             } catch (Exception e) {
   4103                 Slog.w(TAG, "Exception in new application when starting service "
   4104                       + sr.shortName, e);
   4105                 badApp = true;
   4106             }
   4107         }
   4108 
   4109         // Check if a next-broadcast receiver is in this process...
   4110         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
   4111             try {
   4112                 didSomething = sendPendingBroadcastsLocked(app);
   4113             } catch (Exception e) {
   4114                 // If the app died trying to launch the receiver we declare it 'bad'
   4115                 badApp = true;
   4116             }
   4117         }
   4118 
   4119         // Check whether the next backup agent is in this process...
   4120         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
   4121             if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
   4122             ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
   4123             try {
   4124                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
   4125                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
   4126                         mBackupTarget.backupMode);
   4127             } catch (Exception e) {
   4128                 Slog.w(TAG, "Exception scheduling backup agent creation: ");
   4129                 e.printStackTrace();
   4130             }
   4131         }
   4132 
   4133         if (badApp) {
   4134             // todo: Also need to kill application to deal with all
   4135             // kinds of exceptions.
   4136             handleAppDiedLocked(app, false, true);
   4137             return false;
   4138         }
   4139 
   4140         if (!didSomething) {
   4141             updateOomAdjLocked();
   4142         }
   4143 
   4144         return true;
   4145     }
   4146 
   4147     public final void attachApplication(IApplicationThread thread) {
   4148         synchronized (this) {
   4149             int callingPid = Binder.getCallingPid();
   4150             final long origId = Binder.clearCallingIdentity();
   4151             attachApplicationLocked(thread, callingPid);
   4152             Binder.restoreCallingIdentity(origId);
   4153         }
   4154     }
   4155 
   4156     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
   4157         final long origId = Binder.clearCallingIdentity();
   4158         ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
   4159         if (stopProfiling) {
   4160             synchronized (this) {
   4161                 if (mProfileProc == r.app) {
   4162                     if (mProfileFd != null) {
   4163                         try {
   4164                             mProfileFd.close();
   4165                         } catch (IOException e) {
   4166                         }
   4167                         clearProfilerLocked();
   4168                     }
   4169                 }
   4170             }
   4171         }
   4172         Binder.restoreCallingIdentity(origId);
   4173     }
   4174 
   4175     void enableScreenAfterBoot() {
   4176         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
   4177                 SystemClock.uptimeMillis());
   4178         mWindowManager.enableScreenAfterBoot();
   4179 
   4180         synchronized (this) {
   4181             updateEventDispatchingLocked();
   4182         }
   4183     }
   4184 
   4185     public void showBootMessage(final CharSequence msg, final boolean always) {
   4186         enforceNotIsolatedCaller("showBootMessage");
   4187         mWindowManager.showBootMessage(msg, always);
   4188     }
   4189 
   4190     public void dismissKeyguardOnNextActivity() {
   4191         enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
   4192         final long token = Binder.clearCallingIdentity();
   4193         try {
   4194             synchronized (this) {
   4195                 if (mLockScreenShown) {
   4196                     mLockScreenShown = false;
   4197                     comeOutOfSleepIfNeededLocked();
   4198                 }
   4199                 mMainStack.dismissKeyguardOnNextActivityLocked();
   4200             }
   4201         } finally {
   4202             Binder.restoreCallingIdentity(token);
   4203         }
   4204     }
   4205 
   4206     final void finishBooting() {
   4207         IntentFilter pkgFilter = new IntentFilter();
   4208         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
   4209         pkgFilter.addDataScheme("package");
   4210         mContext.registerReceiver(new BroadcastReceiver() {
   4211             @Override
   4212             public void onReceive(Context context, Intent intent) {
   4213                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
   4214                 if (pkgs != null) {
   4215                     for (String pkg : pkgs) {
   4216                         synchronized (ActivityManagerService.this) {
   4217                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
   4218                                 setResultCode(Activity.RESULT_OK);
   4219                                 return;
   4220                             }
   4221                         }
   4222                     }
   4223                 }
   4224             }
   4225         }, pkgFilter);
   4226 
   4227         IntentFilter userFilter = new IntentFilter();
   4228         userFilter.addAction(Intent.ACTION_USER_REMOVED);
   4229         mContext.registerReceiver(new BroadcastReceiver() {
   4230             @Override
   4231             public void onReceive(Context context, Intent intent) {
   4232                 onUserRemoved(intent);
   4233             }
   4234         }, userFilter);
   4235 
   4236         synchronized (this) {
   4237             // Ensure that any processes we had put on hold are now started
   4238             // up.
   4239             final int NP = mProcessesOnHold.size();
   4240             if (NP > 0) {
   4241                 ArrayList<ProcessRecord> procs =
   4242                     new ArrayList<ProcessRecord>(mProcessesOnHold);
   4243                 for (int ip=0; ip<NP; ip++) {
   4244                     if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
   4245                             + procs.get(ip));
   4246                     startProcessLocked(procs.get(ip), "on-hold", null);
   4247                 }
   4248             }
   4249 
   4250             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   4251                 // Start looking for apps that are abusing wake locks.
   4252                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   4253                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   4254                 // Tell anyone interested that we are done booting!
   4255                 SystemProperties.set("sys.boot_completed", "1");
   4256                 SystemProperties.set("dev.bootcomplete", "1");
   4257                 /* TODO: Send this to all users that are to be logged in on startup */
   4258                 broadcastIntentLocked(null, null,
   4259                         new Intent(Intent.ACTION_BOOT_COMPLETED, null),
   4260                         null, null, 0, null, null,
   4261                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
   4262                         false, false, MY_PID, Process.SYSTEM_UID, Binder.getOrigCallingUser());
   4263             }
   4264         }
   4265     }
   4266 
   4267     final void ensureBootCompleted() {
   4268         boolean booting;
   4269         boolean enableScreen;
   4270         synchronized (this) {
   4271             booting = mBooting;
   4272             mBooting = false;
   4273             enableScreen = !mBooted;
   4274             mBooted = true;
   4275         }
   4276 
   4277         if (booting) {
   4278             finishBooting();
   4279         }
   4280 
   4281         if (enableScreen) {
   4282             enableScreenAfterBoot();
   4283         }
   4284     }
   4285 
   4286     public final void activityPaused(IBinder token) {
   4287         final long origId = Binder.clearCallingIdentity();
   4288         mMainStack.activityPaused(token, false);
   4289         Binder.restoreCallingIdentity(origId);
   4290     }
   4291 
   4292     public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
   4293             CharSequence description) {
   4294         if (localLOGV) Slog.v(
   4295             TAG, "Activity stopped: token=" + token);
   4296 
   4297         // Refuse possible leaked file descriptors
   4298         if (icicle != null && icicle.hasFileDescriptors()) {
   4299             throw new IllegalArgumentException("File descriptors passed in Bundle");
   4300         }
   4301 
   4302         ActivityRecord r = null;
   4303 
   4304         final long origId = Binder.clearCallingIdentity();
   4305 
   4306         synchronized (this) {
   4307             r = mMainStack.isInStackLocked(token);
   4308             if (r != null) {
   4309                 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
   4310             }
   4311         }
   4312 
   4313         if (r != null) {
   4314             sendPendingThumbnail(r, null, null, null, false);
   4315         }
   4316 
   4317         trimApplications();
   4318 
   4319         Binder.restoreCallingIdentity(origId);
   4320     }
   4321 
   4322     public final void activityDestroyed(IBinder token) {
   4323         if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
   4324         mMainStack.activityDestroyed(token);
   4325     }
   4326 
   4327     public String getCallingPackage(IBinder token) {
   4328         synchronized (this) {
   4329             ActivityRecord r = getCallingRecordLocked(token);
   4330             return r != null && r.app != null ? r.info.packageName : null;
   4331         }
   4332     }
   4333 
   4334     public ComponentName getCallingActivity(IBinder token) {
   4335         synchronized (this) {
   4336             ActivityRecord r = getCallingRecordLocked(token);
   4337             return r != null ? r.intent.getComponent() : null;
   4338         }
   4339     }
   4340 
   4341     private ActivityRecord getCallingRecordLocked(IBinder token) {
   4342         ActivityRecord r = mMainStack.isInStackLocked(token);
   4343         if (r == null) {
   4344             return null;
   4345         }
   4346         return r.resultTo;
   4347     }
   4348 
   4349     public ComponentName getActivityClassForToken(IBinder token) {
   4350         synchronized(this) {
   4351             ActivityRecord r = mMainStack.isInStackLocked(token);
   4352             if (r == null) {
   4353                 return null;
   4354             }
   4355             return r.intent.getComponent();
   4356         }
   4357     }
   4358 
   4359     public String getPackageForToken(IBinder token) {
   4360         synchronized(this) {
   4361             ActivityRecord r = mMainStack.isInStackLocked(token);
   4362             if (r == null) {
   4363                 return null;
   4364             }
   4365             return r.packageName;
   4366         }
   4367     }
   4368 
   4369     public IIntentSender getIntentSender(int type,
   4370             String packageName, IBinder token, String resultWho,
   4371             int requestCode, Intent[] intents, String[] resolvedTypes,
   4372             int flags, Bundle options) {
   4373         enforceNotIsolatedCaller("getIntentSender");
   4374         // Refuse possible leaked file descriptors
   4375         if (intents != null) {
   4376             if (intents.length < 1) {
   4377                 throw new IllegalArgumentException("Intents array length must be >= 1");
   4378             }
   4379             for (int i=0; i<intents.length; i++) {
   4380                 Intent intent = intents[i];
   4381                 if (intent != null) {
   4382                     if (intent.hasFileDescriptors()) {
   4383                         throw new IllegalArgumentException("File descriptors passed in Intent");
   4384                     }
   4385                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
   4386                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   4387                         throw new IllegalArgumentException(
   4388                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   4389                     }
   4390                     intents[i] = new Intent(intent);
   4391                 }
   4392             }
   4393             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
   4394                 throw new IllegalArgumentException(
   4395                         "Intent array length does not match resolvedTypes length");
   4396             }
   4397         }
   4398         if (options != null) {
   4399             if (options.hasFileDescriptors()) {
   4400                 throw new IllegalArgumentException("File descriptors passed in options");
   4401             }
   4402         }
   4403 
   4404         synchronized(this) {
   4405             int callingUid = Binder.getCallingUid();
   4406             try {
   4407                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   4408                     int uid = AppGlobals.getPackageManager()
   4409                             .getPackageUid(packageName, UserId.getUserId(callingUid));
   4410                     if (!UserId.isSameApp(callingUid, uid)) {
   4411                         String msg = "Permission Denial: getIntentSender() from pid="
   4412                             + Binder.getCallingPid()
   4413                             + ", uid=" + Binder.getCallingUid()
   4414                             + ", (need uid=" + uid + ")"
   4415                             + " is not allowed to send as package " + packageName;
   4416                         Slog.w(TAG, msg);
   4417                         throw new SecurityException(msg);
   4418                     }
   4419                 }
   4420 
   4421                 if (DEBUG_MU)
   4422                     Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
   4423                             + Binder.getOrigCallingUid());
   4424                 return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
   4425                         token, resultWho, requestCode, intents, resolvedTypes, flags, options);
   4426 
   4427             } catch (RemoteException e) {
   4428                 throw new SecurityException(e);
   4429             }
   4430         }
   4431     }
   4432 
   4433     IIntentSender getIntentSenderLocked(int type,
   4434             String packageName, int callingUid, IBinder token, String resultWho,
   4435             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
   4436             Bundle options) {
   4437         if (DEBUG_MU)
   4438             Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
   4439         ActivityRecord activity = null;
   4440         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   4441             activity = mMainStack.isInStackLocked(token);
   4442             if (activity == null) {
   4443                 return null;
   4444             }
   4445             if (activity.finishing) {
   4446                 return null;
   4447             }
   4448         }
   4449 
   4450         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
   4451         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
   4452         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
   4453         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
   4454                 |PendingIntent.FLAG_UPDATE_CURRENT);
   4455 
   4456         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
   4457                 type, packageName, activity, resultWho,
   4458                 requestCode, intents, resolvedTypes, flags, options);
   4459         WeakReference<PendingIntentRecord> ref;
   4460         ref = mIntentSenderRecords.get(key);
   4461         PendingIntentRecord rec = ref != null ? ref.get() : null;
   4462         if (rec != null) {
   4463             if (!cancelCurrent) {
   4464                 if (updateCurrent) {
   4465                     if (rec.key.requestIntent != null) {
   4466                         rec.key.requestIntent.replaceExtras(intents != null ?
   4467                                 intents[intents.length - 1] : null);
   4468                     }
   4469                     if (intents != null) {
   4470                         intents[intents.length-1] = rec.key.requestIntent;
   4471                         rec.key.allIntents = intents;
   4472                         rec.key.allResolvedTypes = resolvedTypes;
   4473                     } else {
   4474                         rec.key.allIntents = null;
   4475                         rec.key.allResolvedTypes = null;
   4476                     }
   4477                 }
   4478                 return rec;
   4479             }
   4480             rec.canceled = true;
   4481             mIntentSenderRecords.remove(key);
   4482         }
   4483         if (noCreate) {
   4484             return rec;
   4485         }
   4486         rec = new PendingIntentRecord(this, key, callingUid);
   4487         mIntentSenderRecords.put(key, rec.ref);
   4488         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   4489             if (activity.pendingResults == null) {
   4490                 activity.pendingResults
   4491                         = new HashSet<WeakReference<PendingIntentRecord>>();
   4492             }
   4493             activity.pendingResults.add(rec.ref);
   4494         }
   4495         return rec;
   4496     }
   4497 
   4498     public void cancelIntentSender(IIntentSender sender) {
   4499         if (!(sender instanceof PendingIntentRecord)) {
   4500             return;
   4501         }
   4502         synchronized(this) {
   4503             PendingIntentRecord rec = (PendingIntentRecord)sender;
   4504             try {
   4505                 int uid = AppGlobals.getPackageManager()
   4506                         .getPackageUid(rec.key.packageName, UserId.getCallingUserId());
   4507                 if (!UserId.isSameApp(uid, Binder.getCallingUid())) {
   4508                     String msg = "Permission Denial: cancelIntentSender() from pid="
   4509                         + Binder.getCallingPid()
   4510                         + ", uid=" + Binder.getCallingUid()
   4511                         + " is not allowed to cancel packges "
   4512                         + rec.key.packageName;
   4513                     Slog.w(TAG, msg);
   4514                     throw new SecurityException(msg);
   4515                 }
   4516             } catch (RemoteException e) {
   4517                 throw new SecurityException(e);
   4518             }
   4519             cancelIntentSenderLocked(rec, true);
   4520         }
   4521     }
   4522 
   4523     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
   4524         rec.canceled = true;
   4525         mIntentSenderRecords.remove(rec.key);
   4526         if (cleanActivity && rec.key.activity != null) {
   4527             rec.key.activity.pendingResults.remove(rec.ref);
   4528         }
   4529     }
   4530 
   4531     public String getPackageForIntentSender(IIntentSender pendingResult) {
   4532         if (!(pendingResult instanceof PendingIntentRecord)) {
   4533             return null;
   4534         }
   4535         try {
   4536             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   4537             return res.key.packageName;
   4538         } catch (ClassCastException e) {
   4539         }
   4540         return null;
   4541     }
   4542 
   4543     public int getUidForIntentSender(IIntentSender sender) {
   4544         if (sender instanceof PendingIntentRecord) {
   4545             try {
   4546                 PendingIntentRecord res = (PendingIntentRecord)sender;
   4547                 return res.uid;
   4548             } catch (ClassCastException e) {
   4549             }
   4550         }
   4551         return -1;
   4552     }
   4553 
   4554     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
   4555         if (!(pendingResult instanceof PendingIntentRecord)) {
   4556             return false;
   4557         }
   4558         try {
   4559             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   4560             if (res.key.allIntents == null) {
   4561                 return false;
   4562             }
   4563             for (int i=0; i<res.key.allIntents.length; i++) {
   4564                 Intent intent = res.key.allIntents[i];
   4565                 if (intent.getPackage() != null && intent.getComponent() != null) {
   4566                     return false;
   4567                 }
   4568             }
   4569             return true;
   4570         } catch (ClassCastException e) {
   4571         }
   4572         return false;
   4573     }
   4574 
   4575     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
   4576         if (!(pendingResult instanceof PendingIntentRecord)) {
   4577             return false;
   4578         }
   4579         try {
   4580             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   4581             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
   4582                 return true;
   4583             }
   4584             return false;
   4585         } catch (ClassCastException e) {
   4586         }
   4587         return false;
   4588     }
   4589 
   4590     public void setProcessLimit(int max) {
   4591         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   4592                 "setProcessLimit()");
   4593         synchronized (this) {
   4594             mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
   4595             mProcessLimitOverride = max;
   4596         }
   4597         trimApplications();
   4598     }
   4599 
   4600     public int getProcessLimit() {
   4601         synchronized (this) {
   4602             return mProcessLimitOverride;
   4603         }
   4604     }
   4605 
   4606     void foregroundTokenDied(ForegroundToken token) {
   4607         synchronized (ActivityManagerService.this) {
   4608             synchronized (mPidsSelfLocked) {
   4609                 ForegroundToken cur
   4610                     = mForegroundProcesses.get(token.pid);
   4611                 if (cur != token) {
   4612                     return;
   4613                 }
   4614                 mForegroundProcesses.remove(token.pid);
   4615                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
   4616                 if (pr == null) {
   4617                     return;
   4618                 }
   4619                 pr.forcingToForeground = null;
   4620                 pr.foregroundServices = false;
   4621             }
   4622             updateOomAdjLocked();
   4623         }
   4624     }
   4625 
   4626     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
   4627         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   4628                 "setProcessForeground()");
   4629         synchronized(this) {
   4630             boolean changed = false;
   4631 
   4632             synchronized (mPidsSelfLocked) {
   4633                 ProcessRecord pr = mPidsSelfLocked.get(pid);
   4634                 if (pr == null && isForeground) {
   4635                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
   4636                     return;
   4637                 }
   4638                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
   4639                 if (oldToken != null) {
   4640                     oldToken.token.unlinkToDeath(oldToken, 0);
   4641                     mForegroundProcesses.remove(pid);
   4642                     if (pr != null) {
   4643                         pr.forcingToForeground = null;
   4644                     }
   4645                     changed = true;
   4646                 }
   4647                 if (isForeground && token != null) {
   4648                     ForegroundToken newToken = new ForegroundToken() {
   4649                         public void binderDied() {
   4650                             foregroundTokenDied(this);
   4651                         }
   4652                     };
   4653                     newToken.pid = pid;
   4654                     newToken.token = token;
   4655                     try {
   4656                         token.linkToDeath(newToken, 0);
   4657                         mForegroundProcesses.put(pid, newToken);
   4658                         pr.forcingToForeground = token;
   4659                         changed = true;
   4660                     } catch (RemoteException e) {
   4661                         // If the process died while doing this, we will later
   4662                         // do the cleanup with the process death link.
   4663                     }
   4664                 }
   4665             }
   4666 
   4667             if (changed) {
   4668                 updateOomAdjLocked();
   4669             }
   4670         }
   4671     }
   4672 
   4673     // =========================================================
   4674     // PERMISSIONS
   4675     // =========================================================
   4676 
   4677     static class PermissionController extends IPermissionController.Stub {
   4678         ActivityManagerService mActivityManagerService;
   4679         PermissionController(ActivityManagerService activityManagerService) {
   4680             mActivityManagerService = activityManagerService;
   4681         }
   4682 
   4683         public boolean checkPermission(String permission, int pid, int uid) {
   4684             return mActivityManagerService.checkPermission(permission, pid,
   4685                     uid) == PackageManager.PERMISSION_GRANTED;
   4686         }
   4687     }
   4688 
   4689     /**
   4690      * This can be called with or without the global lock held.
   4691      */
   4692     int checkComponentPermission(String permission, int pid, int uid,
   4693             int owningUid, boolean exported) {
   4694         // We might be performing an operation on behalf of an indirect binder
   4695         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
   4696         // client identity accordingly before proceeding.
   4697         Identity tlsIdentity = sCallerIdentity.get();
   4698         if (tlsIdentity != null) {
   4699             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
   4700                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
   4701             uid = tlsIdentity.uid;
   4702             pid = tlsIdentity.pid;
   4703         }
   4704 
   4705         if (pid == MY_PID) {
   4706             return PackageManager.PERMISSION_GRANTED;
   4707         }
   4708 
   4709         return ActivityManager.checkComponentPermission(permission, uid,
   4710                 owningUid, exported);
   4711     }
   4712 
   4713     /**
   4714      * As the only public entry point for permissions checking, this method
   4715      * can enforce the semantic that requesting a check on a null global
   4716      * permission is automatically denied.  (Internally a null permission
   4717      * string is used when calling {@link #checkComponentPermission} in cases
   4718      * when only uid-based security is needed.)
   4719      *
   4720      * This can be called with or without the global lock held.
   4721      */
   4722     public int checkPermission(String permission, int pid, int uid) {
   4723         if (permission == null) {
   4724             return PackageManager.PERMISSION_DENIED;
   4725         }
   4726         return checkComponentPermission(permission, pid, UserId.getAppId(uid), -1, true);
   4727     }
   4728 
   4729     /**
   4730      * Binder IPC calls go through the public entry point.
   4731      * This can be called with or without the global lock held.
   4732      */
   4733     int checkCallingPermission(String permission) {
   4734         return checkPermission(permission,
   4735                 Binder.getCallingPid(),
   4736                 UserId.getAppId(Binder.getCallingUid()));
   4737     }
   4738 
   4739     /**
   4740      * This can be called with or without the global lock held.
   4741      */
   4742     void enforceCallingPermission(String permission, String func) {
   4743         if (checkCallingPermission(permission)
   4744                 == PackageManager.PERMISSION_GRANTED) {
   4745             return;
   4746         }
   4747 
   4748         String msg = "Permission Denial: " + func + " from pid="
   4749                 + Binder.getCallingPid()
   4750                 + ", uid=" + Binder.getCallingUid()
   4751                 + " requires " + permission;
   4752         Slog.w(TAG, msg);
   4753         throw new SecurityException(msg);
   4754     }
   4755 
   4756     /**
   4757      * Determine if UID is holding permissions required to access {@link Uri} in
   4758      * the given {@link ProviderInfo}. Final permission checking is always done
   4759      * in {@link ContentProvider}.
   4760      */
   4761     private final boolean checkHoldingPermissionsLocked(
   4762             IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
   4763         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4764                 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
   4765 
   4766         if (pi.applicationInfo.uid == uid) {
   4767             return true;
   4768         } else if (!pi.exported) {
   4769             return false;
   4770         }
   4771 
   4772         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
   4773         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
   4774         try {
   4775             // check if target holds top-level <provider> permissions
   4776             if (!readMet && pi.readPermission != null
   4777                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
   4778                 readMet = true;
   4779             }
   4780             if (!writeMet && pi.writePermission != null
   4781                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
   4782                 writeMet = true;
   4783             }
   4784 
   4785             // track if unprotected read/write is allowed; any denied
   4786             // <path-permission> below removes this ability
   4787             boolean allowDefaultRead = pi.readPermission == null;
   4788             boolean allowDefaultWrite = pi.writePermission == null;
   4789 
   4790             // check if target holds any <path-permission> that match uri
   4791             final PathPermission[] pps = pi.pathPermissions;
   4792             if (pps != null) {
   4793                 final String path = uri.getPath();
   4794                 int i = pps.length;
   4795                 while (i > 0 && (!readMet || !writeMet)) {
   4796                     i--;
   4797                     PathPermission pp = pps[i];
   4798                     if (pp.match(path)) {
   4799                         if (!readMet) {
   4800                             final String pprperm = pp.getReadPermission();
   4801                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
   4802                                     + pprperm + " for " + pp.getPath()
   4803                                     + ": match=" + pp.match(path)
   4804                                     + " check=" + pm.checkUidPermission(pprperm, uid));
   4805                             if (pprperm != null) {
   4806                                 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
   4807                                     readMet = true;
   4808                                 } else {
   4809                                     allowDefaultRead = false;
   4810                                 }
   4811                             }
   4812                         }
   4813                         if (!writeMet) {
   4814                             final String ppwperm = pp.getWritePermission();
   4815                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
   4816                                     + ppwperm + " for " + pp.getPath()
   4817                                     + ": match=" + pp.match(path)
   4818                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
   4819                             if (ppwperm != null) {
   4820                                 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
   4821                                     writeMet = true;
   4822                                 } else {
   4823                                     allowDefaultWrite = false;
   4824                                 }
   4825                             }
   4826                         }
   4827                     }
   4828                 }
   4829             }
   4830 
   4831             // grant unprotected <provider> read/write, if not blocked by
   4832             // <path-permission> above
   4833             if (allowDefaultRead) readMet = true;
   4834             if (allowDefaultWrite) writeMet = true;
   4835 
   4836         } catch (RemoteException e) {
   4837             return false;
   4838         }
   4839 
   4840         return readMet && writeMet;
   4841     }
   4842 
   4843     private final boolean checkUriPermissionLocked(Uri uri, int uid,
   4844             int modeFlags) {
   4845         // Root gets to do everything.
   4846         if (uid == 0) {
   4847             return true;
   4848         }
   4849         HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   4850         if (perms == null) return false;
   4851         UriPermission perm = perms.get(uri);
   4852         if (perm == null) return false;
   4853         return (modeFlags&perm.modeFlags) == modeFlags;
   4854     }
   4855 
   4856     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
   4857         enforceNotIsolatedCaller("checkUriPermission");
   4858 
   4859         // Another redirected-binder-call permissions check as in
   4860         // {@link checkComponentPermission}.
   4861         Identity tlsIdentity = sCallerIdentity.get();
   4862         if (tlsIdentity != null) {
   4863             uid = tlsIdentity.uid;
   4864             pid = tlsIdentity.pid;
   4865         }
   4866 
   4867         uid = UserId.getAppId(uid);
   4868         // Our own process gets to do everything.
   4869         if (pid == MY_PID) {
   4870             return PackageManager.PERMISSION_GRANTED;
   4871         }
   4872         synchronized(this) {
   4873             return checkUriPermissionLocked(uri, uid, modeFlags)
   4874                     ? PackageManager.PERMISSION_GRANTED
   4875                     : PackageManager.PERMISSION_DENIED;
   4876         }
   4877     }
   4878 
   4879     /**
   4880      * Check if the targetPkg can be granted permission to access uri by
   4881      * the callingUid using the given modeFlags.  Throws a security exception
   4882      * if callingUid is not allowed to do this.  Returns the uid of the target
   4883      * if the URI permission grant should be performed; returns -1 if it is not
   4884      * needed (for example targetPkg already has permission to access the URI).
   4885      * If you already know the uid of the target, you can supply it in
   4886      * lastTargetUid else set that to -1.
   4887      */
   4888     int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
   4889             Uri uri, int modeFlags, int lastTargetUid) {
   4890         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   4891                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   4892         if (modeFlags == 0) {
   4893             return -1;
   4894         }
   4895 
   4896         if (targetPkg != null) {
   4897             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4898                     "Checking grant " + targetPkg + " permission to " + uri);
   4899         }
   4900 
   4901         final IPackageManager pm = AppGlobals.getPackageManager();
   4902 
   4903         // If this is not a content: uri, we can't do anything with it.
   4904         if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
   4905             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4906                     "Can't grant URI permission for non-content URI: " + uri);
   4907             return -1;
   4908         }
   4909 
   4910         String name = uri.getAuthority();
   4911         ProviderInfo pi = null;
   4912         ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
   4913                 UserId.getUserId(callingUid));
   4914         if (cpr != null) {
   4915             pi = cpr.info;
   4916         } else {
   4917             try {
   4918                 pi = pm.resolveContentProvider(name,
   4919                         PackageManager.GET_URI_PERMISSION_PATTERNS, UserId.getUserId(callingUid));
   4920             } catch (RemoteException ex) {
   4921             }
   4922         }
   4923         if (pi == null) {
   4924             Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
   4925             return -1;
   4926         }
   4927 
   4928         int targetUid = lastTargetUid;
   4929         if (targetUid < 0 && targetPkg != null) {
   4930             try {
   4931                 targetUid = pm.getPackageUid(targetPkg, UserId.getUserId(callingUid));
   4932                 if (targetUid < 0) {
   4933                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4934                             "Can't grant URI permission no uid for: " + targetPkg);
   4935                     return -1;
   4936                 }
   4937             } catch (RemoteException ex) {
   4938                 return -1;
   4939             }
   4940         }
   4941 
   4942         if (targetUid >= 0) {
   4943             // First...  does the target actually need this permission?
   4944             if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
   4945                 // No need to grant the target this permission.
   4946                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   4947                         "Target " + targetPkg + " already has full permission to " + uri);
   4948                 return -1;
   4949             }
   4950         } else {
   4951             // First...  there is no target package, so can anyone access it?
   4952             boolean allowed = pi.exported;
   4953             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   4954                 if (pi.readPermission != null) {
   4955                     allowed = false;
   4956                 }
   4957             }
   4958             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   4959                 if (pi.writePermission != null) {
   4960                     allowed = false;
   4961                 }
   4962             }
   4963             if (allowed) {
   4964                 return -1;
   4965             }
   4966         }
   4967 
   4968         // Second...  is the provider allowing granting of URI permissions?
   4969         if (!pi.grantUriPermissions) {
   4970             throw new SecurityException("Provider " + pi.packageName
   4971                     + "/" + pi.name
   4972                     + " does not allow granting of Uri permissions (uri "
   4973                     + uri + ")");
   4974         }
   4975         if (pi.uriPermissionPatterns != null) {
   4976             final int N = pi.uriPermissionPatterns.length;
   4977             boolean allowed = false;
   4978             for (int i=0; i<N; i++) {
   4979                 if (pi.uriPermissionPatterns[i] != null
   4980                         && pi.uriPermissionPatterns[i].match(uri.getPath())) {
   4981                     allowed = true;
   4982                     break;
   4983                 }
   4984             }
   4985             if (!allowed) {
   4986                 throw new SecurityException("Provider " + pi.packageName
   4987                         + "/" + pi.name
   4988                         + " does not allow granting of permission to path of Uri "
   4989                         + uri);
   4990             }
   4991         }
   4992 
   4993         // Third...  does the caller itself have permission to access
   4994         // this uri?
   4995         if (callingUid != Process.myUid()) {
   4996             if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
   4997                 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
   4998                     throw new SecurityException("Uid " + callingUid
   4999                             + " does not have permission to uri " + uri);
   5000                 }
   5001             }
   5002         }
   5003 
   5004         return targetUid;
   5005     }
   5006 
   5007     public int checkGrantUriPermission(int callingUid, String targetPkg,
   5008             Uri uri, int modeFlags) {
   5009         enforceNotIsolatedCaller("checkGrantUriPermission");
   5010         synchronized(this) {
   5011             return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
   5012         }
   5013     }
   5014 
   5015     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
   5016             Uri uri, int modeFlags, UriPermissionOwner owner) {
   5017         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   5018                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   5019         if (modeFlags == 0) {
   5020             return;
   5021         }
   5022 
   5023         // So here we are: the caller has the assumed permission
   5024         // to the uri, and the target doesn't.  Let's now give this to
   5025         // the target.
   5026 
   5027         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5028                 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
   5029 
   5030         HashMap<Uri, UriPermission> targetUris
   5031                 = mGrantedUriPermissions.get(targetUid);
   5032         if (targetUris == null) {
   5033             targetUris = new HashMap<Uri, UriPermission>();
   5034             mGrantedUriPermissions.put(targetUid, targetUris);
   5035         }
   5036 
   5037         UriPermission perm = targetUris.get(uri);
   5038         if (perm == null) {
   5039             perm = new UriPermission(targetUid, uri);
   5040             targetUris.put(uri, perm);
   5041         }
   5042 
   5043         perm.modeFlags |= modeFlags;
   5044         if (owner == null) {
   5045             perm.globalModeFlags |= modeFlags;
   5046         } else {
   5047             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   5048                  perm.readOwners.add(owner);
   5049                  owner.addReadPermission(perm);
   5050             }
   5051             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   5052                  perm.writeOwners.add(owner);
   5053                  owner.addWritePermission(perm);
   5054             }
   5055         }
   5056     }
   5057 
   5058     void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
   5059             int modeFlags, UriPermissionOwner owner) {
   5060         if (targetPkg == null) {
   5061             throw new NullPointerException("targetPkg");
   5062         }
   5063 
   5064         int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
   5065         if (targetUid < 0) {
   5066             return;
   5067         }
   5068 
   5069         grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
   5070     }
   5071 
   5072     static class NeededUriGrants extends ArrayList<Uri> {
   5073         final String targetPkg;
   5074         final int targetUid;
   5075         final int flags;
   5076 
   5077         NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
   5078             targetPkg = _targetPkg;
   5079             targetUid = _targetUid;
   5080             flags = _flags;
   5081         }
   5082     }
   5083 
   5084     /**
   5085      * Like checkGrantUriPermissionLocked, but takes an Intent.
   5086      */
   5087     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
   5088             String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
   5089         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5090                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
   5091                 + " clip=" + (intent != null ? intent.getClipData() : null)
   5092                 + " from " + intent + "; flags=0x"
   5093                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
   5094 
   5095         if (targetPkg == null) {
   5096             throw new NullPointerException("targetPkg");
   5097         }
   5098 
   5099         if (intent == null) {
   5100             return null;
   5101         }
   5102         Uri data = intent.getData();
   5103         ClipData clip = intent.getClipData();
   5104         if (data == null && clip == null) {
   5105             return null;
   5106         }
   5107         if (data != null) {
   5108             int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
   5109                 mode, needed != null ? needed.targetUid : -1);
   5110             if (target > 0) {
   5111                 if (needed == null) {
   5112                     needed = new NeededUriGrants(targetPkg, target, mode);
   5113                 }
   5114                 needed.add(data);
   5115             }
   5116         }
   5117         if (clip != null) {
   5118             for (int i=0; i<clip.getItemCount(); i++) {
   5119                 Uri uri = clip.getItemAt(i).getUri();
   5120                 if (uri != null) {
   5121                     int target = -1;
   5122                     target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
   5123                             mode, needed != null ? needed.targetUid : -1);
   5124                     if (target > 0) {
   5125                         if (needed == null) {
   5126                             needed = new NeededUriGrants(targetPkg, target, mode);
   5127                         }
   5128                         needed.add(uri);
   5129                     }
   5130                 } else {
   5131                     Intent clipIntent = clip.getItemAt(i).getIntent();
   5132                     if (clipIntent != null) {
   5133                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
   5134                                 callingUid, targetPkg, clipIntent, mode, needed);
   5135                         if (newNeeded != null) {
   5136                             needed = newNeeded;
   5137                         }
   5138                     }
   5139                 }
   5140             }
   5141         }
   5142 
   5143         return needed;
   5144     }
   5145 
   5146     /**
   5147      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
   5148      */
   5149     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
   5150             UriPermissionOwner owner) {
   5151         if (needed != null) {
   5152             for (int i=0; i<needed.size(); i++) {
   5153                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
   5154                         needed.get(i), needed.flags, owner);
   5155             }
   5156         }
   5157     }
   5158 
   5159     void grantUriPermissionFromIntentLocked(int callingUid,
   5160             String targetPkg, Intent intent, UriPermissionOwner owner) {
   5161         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
   5162                 intent, intent != null ? intent.getFlags() : 0, null);
   5163         if (needed == null) {
   5164             return;
   5165         }
   5166 
   5167         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
   5168     }
   5169 
   5170     public void grantUriPermission(IApplicationThread caller, String targetPkg,
   5171             Uri uri, int modeFlags) {
   5172         enforceNotIsolatedCaller("grantUriPermission");
   5173         synchronized(this) {
   5174             final ProcessRecord r = getRecordForAppLocked(caller);
   5175             if (r == null) {
   5176                 throw new SecurityException("Unable to find app for caller "
   5177                         + caller
   5178                         + " when granting permission to uri " + uri);
   5179             }
   5180             if (targetPkg == null) {
   5181                 throw new IllegalArgumentException("null target");
   5182             }
   5183             if (uri == null) {
   5184                 throw new IllegalArgumentException("null uri");
   5185             }
   5186 
   5187             grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
   5188                     null);
   5189         }
   5190     }
   5191 
   5192     void removeUriPermissionIfNeededLocked(UriPermission perm) {
   5193         if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
   5194                 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
   5195             HashMap<Uri, UriPermission> perms
   5196                     = mGrantedUriPermissions.get(perm.uid);
   5197             if (perms != null) {
   5198                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5199                         "Removing " + perm.uid + " permission to " + perm.uri);
   5200                 perms.remove(perm.uri);
   5201                 if (perms.size() == 0) {
   5202                     mGrantedUriPermissions.remove(perm.uid);
   5203                 }
   5204             }
   5205         }
   5206     }
   5207 
   5208     private void revokeUriPermissionLocked(int callingUid, Uri uri,
   5209             int modeFlags) {
   5210         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   5211                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   5212         if (modeFlags == 0) {
   5213             return;
   5214         }
   5215 
   5216         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5217                 "Revoking all granted permissions to " + uri);
   5218 
   5219         final IPackageManager pm = AppGlobals.getPackageManager();
   5220 
   5221         final String authority = uri.getAuthority();
   5222         ProviderInfo pi = null;
   5223         int userId = UserId.getUserId(callingUid);
   5224         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
   5225         if (cpr != null) {
   5226             pi = cpr.info;
   5227         } else {
   5228             try {
   5229                 pi = pm.resolveContentProvider(authority,
   5230                         PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
   5231             } catch (RemoteException ex) {
   5232             }
   5233         }
   5234         if (pi == null) {
   5235             Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
   5236             return;
   5237         }
   5238 
   5239         // Does the caller have this permission on the URI?
   5240         if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
   5241             // Right now, if you are not the original owner of the permission,
   5242             // you are not allowed to revoke it.
   5243             //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
   5244                 throw new SecurityException("Uid " + callingUid
   5245                         + " does not have permission to uri " + uri);
   5246             //}
   5247         }
   5248 
   5249         // Go through all of the permissions and remove any that match.
   5250         final List<String> SEGMENTS = uri.getPathSegments();
   5251         if (SEGMENTS != null) {
   5252             final int NS = SEGMENTS.size();
   5253             int N = mGrantedUriPermissions.size();
   5254             for (int i=0; i<N; i++) {
   5255                 HashMap<Uri, UriPermission> perms
   5256                         = mGrantedUriPermissions.valueAt(i);
   5257                 Iterator<UriPermission> it = perms.values().iterator();
   5258             toploop:
   5259                 while (it.hasNext()) {
   5260                     UriPermission perm = it.next();
   5261                     Uri targetUri = perm.uri;
   5262                     if (!authority.equals(targetUri.getAuthority())) {
   5263                         continue;
   5264                     }
   5265                     List<String> targetSegments = targetUri.getPathSegments();
   5266                     if (targetSegments == null) {
   5267                         continue;
   5268                     }
   5269                     if (targetSegments.size() < NS) {
   5270                         continue;
   5271                     }
   5272                     for (int j=0; j<NS; j++) {
   5273                         if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
   5274                             continue toploop;
   5275                         }
   5276                     }
   5277                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5278                             "Revoking " + perm.uid + " permission to " + perm.uri);
   5279                     perm.clearModes(modeFlags);
   5280                     if (perm.modeFlags == 0) {
   5281                         it.remove();
   5282                     }
   5283                 }
   5284                 if (perms.size() == 0) {
   5285                     mGrantedUriPermissions.remove(
   5286                             mGrantedUriPermissions.keyAt(i));
   5287                     N--;
   5288                     i--;
   5289                 }
   5290             }
   5291         }
   5292     }
   5293 
   5294     public void revokeUriPermission(IApplicationThread caller, Uri uri,
   5295             int modeFlags) {
   5296         enforceNotIsolatedCaller("revokeUriPermission");
   5297         synchronized(this) {
   5298             final ProcessRecord r = getRecordForAppLocked(caller);
   5299             if (r == null) {
   5300                 throw new SecurityException("Unable to find app for caller "
   5301                         + caller
   5302                         + " when revoking permission to uri " + uri);
   5303             }
   5304             if (uri == null) {
   5305                 Slog.w(TAG, "revokeUriPermission: null uri");
   5306                 return;
   5307             }
   5308 
   5309             modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   5310                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   5311             if (modeFlags == 0) {
   5312                 return;
   5313             }
   5314 
   5315             final IPackageManager pm = AppGlobals.getPackageManager();
   5316 
   5317             final String authority = uri.getAuthority();
   5318             ProviderInfo pi = null;
   5319             ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
   5320             if (cpr != null) {
   5321                 pi = cpr.info;
   5322             } else {
   5323                 try {
   5324                     pi = pm.resolveContentProvider(authority,
   5325                             PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
   5326                 } catch (RemoteException ex) {
   5327                 }
   5328             }
   5329             if (pi == null) {
   5330                 Slog.w(TAG, "No content provider found for permission revoke: "
   5331                         + uri.toSafeString());
   5332                 return;
   5333             }
   5334 
   5335             revokeUriPermissionLocked(r.uid, uri, modeFlags);
   5336         }
   5337     }
   5338 
   5339     @Override
   5340     public IBinder newUriPermissionOwner(String name) {
   5341         enforceNotIsolatedCaller("newUriPermissionOwner");
   5342         synchronized(this) {
   5343             UriPermissionOwner owner = new UriPermissionOwner(this, name);
   5344             return owner.getExternalTokenLocked();
   5345         }
   5346     }
   5347 
   5348     @Override
   5349     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
   5350             Uri uri, int modeFlags) {
   5351         synchronized(this) {
   5352             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   5353             if (owner == null) {
   5354                 throw new IllegalArgumentException("Unknown owner: " + token);
   5355             }
   5356             if (fromUid != Binder.getCallingUid()) {
   5357                 if (Binder.getCallingUid() != Process.myUid()) {
   5358                     // Only system code can grant URI permissions on behalf
   5359                     // of other users.
   5360                     throw new SecurityException("nice try");
   5361                 }
   5362             }
   5363             if (targetPkg == null) {
   5364                 throw new IllegalArgumentException("null target");
   5365             }
   5366             if (uri == null) {
   5367                 throw new IllegalArgumentException("null uri");
   5368             }
   5369 
   5370             grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
   5371         }
   5372     }
   5373 
   5374     @Override
   5375     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
   5376         synchronized(this) {
   5377             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   5378             if (owner == null) {
   5379                 throw new IllegalArgumentException("Unknown owner: " + token);
   5380             }
   5381 
   5382             if (uri == null) {
   5383                 owner.removeUriPermissionsLocked(mode);
   5384             } else {
   5385                 owner.removeUriPermissionLocked(uri, mode);
   5386             }
   5387         }
   5388     }
   5389 
   5390     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
   5391         synchronized (this) {
   5392             ProcessRecord app =
   5393                 who != null ? getRecordForAppLocked(who) : null;
   5394             if (app == null) return;
   5395 
   5396             Message msg = Message.obtain();
   5397             msg.what = WAIT_FOR_DEBUGGER_MSG;
   5398             msg.obj = app;
   5399             msg.arg1 = waiting ? 1 : 0;
   5400             mHandler.sendMessage(msg);
   5401         }
   5402     }
   5403 
   5404     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
   5405         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
   5406         final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
   5407         outInfo.availMem = Process.getFreeMemory();
   5408         outInfo.totalMem = Process.getTotalMemory();
   5409         outInfo.threshold = homeAppMem;
   5410         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
   5411         outInfo.hiddenAppThreshold = hiddenAppMem;
   5412         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
   5413                 ProcessList.SERVICE_ADJ);
   5414         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
   5415                 ProcessList.VISIBLE_APP_ADJ);
   5416         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
   5417                 ProcessList.FOREGROUND_APP_ADJ);
   5418     }
   5419 
   5420     // =========================================================
   5421     // TASK MANAGEMENT
   5422     // =========================================================
   5423 
   5424     public List getTasks(int maxNum, int flags,
   5425                          IThumbnailReceiver receiver) {
   5426         ArrayList list = new ArrayList();
   5427 
   5428         PendingThumbnailsRecord pending = null;
   5429         IApplicationThread topThumbnail = null;
   5430         ActivityRecord topRecord = null;
   5431 
   5432         synchronized(this) {
   5433             if (localLOGV) Slog.v(
   5434                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
   5435                 + ", receiver=" + receiver);
   5436 
   5437             if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
   5438                     != PackageManager.PERMISSION_GRANTED) {
   5439                 if (receiver != null) {
   5440                     // If the caller wants to wait for pending thumbnails,
   5441                     // it ain't gonna get them.
   5442                     try {
   5443                         receiver.finished();
   5444                     } catch (RemoteException ex) {
   5445                     }
   5446                 }
   5447                 String msg = "Permission Denial: getTasks() from pid="
   5448                         + Binder.getCallingPid()
   5449                         + ", uid=" + Binder.getCallingUid()
   5450                         + " requires " + android.Manifest.permission.GET_TASKS;
   5451                 Slog.w(TAG, msg);
   5452                 throw new SecurityException(msg);
   5453             }
   5454 
   5455             int pos = mMainStack.mHistory.size()-1;
   5456             ActivityRecord next =
   5457                 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
   5458             ActivityRecord top = null;
   5459             TaskRecord curTask = null;
   5460             int numActivities = 0;
   5461             int numRunning = 0;
   5462             while (pos >= 0 && maxNum > 0) {
   5463                 final ActivityRecord r = next;
   5464                 pos--;
   5465                 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
   5466 
   5467                 // Initialize state for next task if needed.
   5468                 if (top == null ||
   5469                         (top.state == ActivityState.INITIALIZING
   5470                             && top.task == r.task)) {
   5471                     top = r;
   5472                     curTask = r.task;
   5473                     numActivities = numRunning = 0;
   5474                 }
   5475 
   5476                 // Add 'r' into the current task.
   5477                 numActivities++;
   5478                 if (r.app != null && r.app.thread != null) {
   5479                     numRunning++;
   5480                 }
   5481 
   5482                 if (localLOGV) Slog.v(
   5483                     TAG, r.intent.getComponent().flattenToShortString()
   5484                     + ": task=" + r.task);
   5485 
   5486                 // If the next one is a different task, generate a new
   5487                 // TaskInfo entry for what we have.
   5488                 if (next == null || next.task != curTask) {
   5489                     ActivityManager.RunningTaskInfo ci
   5490                             = new ActivityManager.RunningTaskInfo();
   5491                     ci.id = curTask.taskId;
   5492                     ci.baseActivity = r.intent.getComponent();
   5493                     ci.topActivity = top.intent.getComponent();
   5494                     if (top.thumbHolder != null) {
   5495                         ci.description = top.thumbHolder.lastDescription;
   5496                     }
   5497                     ci.numActivities = numActivities;
   5498                     ci.numRunning = numRunning;
   5499                     //System.out.println(
   5500                     //    "#" + maxNum + ": " + " descr=" + ci.description);
   5501                     if (ci.thumbnail == null && receiver != null) {
   5502                         if (localLOGV) Slog.v(
   5503                             TAG, "State=" + top.state + "Idle=" + top.idle
   5504                             + " app=" + top.app
   5505                             + " thr=" + (top.app != null ? top.app.thread : null));
   5506                         if (top.state == ActivityState.RESUMED
   5507                                 || top.state == ActivityState.PAUSING) {
   5508                             if (top.idle && top.app != null
   5509                                 && top.app.thread != null) {
   5510                                 topRecord = top;
   5511                                 topThumbnail = top.app.thread;
   5512                             } else {
   5513                                 top.thumbnailNeeded = true;
   5514                             }
   5515                         }
   5516                         if (pending == null) {
   5517                             pending = new PendingThumbnailsRecord(receiver);
   5518                         }
   5519                         pending.pendingRecords.add(top);
   5520                     }
   5521                     list.add(ci);
   5522                     maxNum--;
   5523                     top = null;
   5524                 }
   5525             }
   5526 
   5527             if (pending != null) {
   5528                 mPendingThumbnails.add(pending);
   5529             }
   5530         }
   5531 
   5532         if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
   5533 
   5534         if (topThumbnail != null) {
   5535             if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
   5536             try {
   5537                 topThumbnail.requestThumbnail(topRecord.appToken);
   5538             } catch (Exception e) {
   5539                 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
   5540                 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
   5541             }
   5542         }
   5543 
   5544         if (pending == null && receiver != null) {
   5545             // In this case all thumbnails were available and the client
   5546             // is being asked to be told when the remaining ones come in...
   5547             // which is unusually, since the top-most currently running
   5548             // activity should never have a canned thumbnail!  Oh well.
   5549             try {
   5550                 receiver.finished();
   5551             } catch (RemoteException ex) {
   5552             }
   5553         }
   5554 
   5555         return list;
   5556     }
   5557 
   5558     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
   5559             int flags) {
   5560         final int callingUid = Binder.getCallingUid();
   5561         // If it's the system uid asking, then use the current user id.
   5562         // TODO: Make sure that there aren't any other legitimate calls from the system uid that
   5563         // require the entire list.
   5564         final int callingUserId = callingUid == Process.SYSTEM_UID
   5565                 ? mCurrentUserId : UserId.getUserId(callingUid);
   5566         synchronized (this) {
   5567             enforceCallingPermission(android.Manifest.permission.GET_TASKS,
   5568                     "getRecentTasks()");
   5569             final boolean detailed = checkCallingPermission(
   5570                     android.Manifest.permission.GET_DETAILED_TASKS)
   5571                     == PackageManager.PERMISSION_GRANTED;
   5572 
   5573             IPackageManager pm = AppGlobals.getPackageManager();
   5574 
   5575             final int N = mRecentTasks.size();
   5576             ArrayList<ActivityManager.RecentTaskInfo> res
   5577                     = new ArrayList<ActivityManager.RecentTaskInfo>(
   5578                             maxNum < N ? maxNum : N);
   5579             for (int i=0; i<N && maxNum > 0; i++) {
   5580                 TaskRecord tr = mRecentTasks.get(i);
   5581                 // Only add calling user's recent tasks
   5582                 if (tr.userId != callingUserId) continue;
   5583                 // Return the entry if desired by the caller.  We always return
   5584                 // the first entry, because callers always expect this to be the
   5585                 // foreground app.  We may filter others if the caller has
   5586                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
   5587                 // we should exclude the entry.
   5588 
   5589                 if (i == 0
   5590                         || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
   5591                         || (tr.intent == null)
   5592                         || ((tr.intent.getFlags()
   5593                                 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
   5594                     ActivityManager.RecentTaskInfo rti
   5595                             = new ActivityManager.RecentTaskInfo();
   5596                     rti.id = tr.numActivities > 0 ? tr.taskId : -1;
   5597                     rti.persistentId = tr.taskId;
   5598                     rti.baseIntent = new Intent(
   5599                             tr.intent != null ? tr.intent : tr.affinityIntent);
   5600                     if (!detailed) {
   5601                         rti.baseIntent.replaceExtras((Bundle)null);
   5602                     }
   5603                     rti.origActivity = tr.origActivity;
   5604                     rti.description = tr.lastDescription;
   5605 
   5606                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
   5607                         // Check whether this activity is currently available.
   5608                         try {
   5609                             if (rti.origActivity != null) {
   5610                                 if (pm.getActivityInfo(rti.origActivity, 0, callingUserId)
   5611                                         == null) {
   5612                                     continue;
   5613                                 }
   5614                             } else if (rti.baseIntent != null) {
   5615                                 if (pm.queryIntentActivities(rti.baseIntent,
   5616                                         null, 0, callingUserId) == null) {
   5617                                     continue;
   5618                                 }
   5619                             }
   5620                         } catch (RemoteException e) {
   5621                             // Will never happen.
   5622                         }
   5623                     }
   5624 
   5625                     res.add(rti);
   5626                     maxNum--;
   5627                 }
   5628             }
   5629             return res;
   5630         }
   5631     }
   5632 
   5633     private TaskRecord taskForIdLocked(int id) {
   5634         final int N = mRecentTasks.size();
   5635         for (int i=0; i<N; i++) {
   5636             TaskRecord tr = mRecentTasks.get(i);
   5637             if (tr.taskId == id) {
   5638                 return tr;
   5639             }
   5640         }
   5641         return null;
   5642     }
   5643 
   5644     public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
   5645         synchronized (this) {
   5646             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
   5647                     "getTaskThumbnails()");
   5648             TaskRecord tr = taskForIdLocked(id);
   5649             if (tr != null) {
   5650                 return mMainStack.getTaskThumbnailsLocked(tr);
   5651             }
   5652         }
   5653         return null;
   5654     }
   5655 
   5656     public boolean removeSubTask(int taskId, int subTaskIndex) {
   5657         synchronized (this) {
   5658             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
   5659                     "removeSubTask()");
   5660             long ident = Binder.clearCallingIdentity();
   5661             try {
   5662                 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
   5663                         true) != null;
   5664             } finally {
   5665                 Binder.restoreCallingIdentity(ident);
   5666             }
   5667         }
   5668     }
   5669 
   5670     private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
   5671         final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
   5672         Intent baseIntent = new Intent(
   5673                 tr.intent != null ? tr.intent : tr.affinityIntent);
   5674         ComponentName component = baseIntent.getComponent();
   5675         if (component == null) {
   5676             Slog.w(TAG, "Now component for base intent of task: " + tr);
   5677             return;
   5678         }
   5679 
   5680         // Find any running services associated with this app.
   5681         ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
   5682         for (ServiceRecord sr : mServiceMap.getAllServices(tr.userId)) {
   5683             if (sr.packageName.equals(component.getPackageName())) {
   5684                 services.add(sr);
   5685             }
   5686         }
   5687 
   5688         // Take care of any running services associated with the app.
   5689         for (int i=0; i<services.size(); i++) {
   5690             ServiceRecord sr = services.get(i);
   5691             if (sr.startRequested) {
   5692                 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
   5693                     Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
   5694                     stopServiceLocked(sr);
   5695                 } else {
   5696                     sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
   5697                             sr.makeNextStartId(), baseIntent, null));
   5698                     if (sr.app != null && sr.app.thread != null) {
   5699                         sendServiceArgsLocked(sr, false);
   5700                     }
   5701                 }
   5702             }
   5703         }
   5704 
   5705         if (killProcesses) {
   5706             // Find any running processes associated with this app.
   5707             final String pkg = component.getPackageName();
   5708             ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   5709             HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
   5710             for (SparseArray<ProcessRecord> uids : pmap.values()) {
   5711                 for (int i=0; i<uids.size(); i++) {
   5712                     ProcessRecord proc = uids.valueAt(i);
   5713                     if (proc.userId != tr.userId) {
   5714                         continue;
   5715                     }
   5716                     if (!proc.pkgList.contains(pkg)) {
   5717                         continue;
   5718                     }
   5719                     procs.add(proc);
   5720                 }
   5721             }
   5722 
   5723             // Kill the running processes.
   5724             for (int i=0; i<procs.size(); i++) {
   5725                 ProcessRecord pr = procs.get(i);
   5726                 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
   5727                     Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
   5728                     EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
   5729                             pr.processName, pr.setAdj, "remove task");
   5730                     pr.killedBackground = true;
   5731                     Process.killProcessQuiet(pr.pid);
   5732                 } else {
   5733                     pr.waitingToKill = "remove task";
   5734                 }
   5735             }
   5736         }
   5737     }
   5738 
   5739     public boolean removeTask(int taskId, int flags) {
   5740         synchronized (this) {
   5741             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
   5742                     "removeTask()");
   5743             long ident = Binder.clearCallingIdentity();
   5744             try {
   5745                 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
   5746                         false);
   5747                 if (r != null) {
   5748                     mRecentTasks.remove(r.task);
   5749                     cleanUpRemovedTaskLocked(r.task, flags);
   5750                     return true;
   5751                 } else {
   5752                     TaskRecord tr = null;
   5753                     int i=0;
   5754                     while (i < mRecentTasks.size()) {
   5755                         TaskRecord t = mRecentTasks.get(i);
   5756                         if (t.taskId == taskId) {
   5757                             tr = t;
   5758                             break;
   5759                         }
   5760                         i++;
   5761                     }
   5762                     if (tr != null) {
   5763                         if (tr.numActivities <= 0) {
   5764                             // Caller is just removing a recent task that is
   5765                             // not actively running.  That is easy!
   5766                             mRecentTasks.remove(i);
   5767                             cleanUpRemovedTaskLocked(tr, flags);
   5768                             return true;
   5769                         } else {
   5770                             Slog.w(TAG, "removeTask: task " + taskId
   5771                                     + " does not have activities to remove, "
   5772                                     + " but numActivities=" + tr.numActivities
   5773                                     + ": " + tr);
   5774                         }
   5775                     }
   5776                 }
   5777             } finally {
   5778                 Binder.restoreCallingIdentity(ident);
   5779             }
   5780         }
   5781         return false;
   5782     }
   5783 
   5784     private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
   5785         int j;
   5786         TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
   5787         TaskRecord jt = startTask;
   5788 
   5789         // First look backwards
   5790         for (j=startIndex-1; j>=0; j--) {
   5791             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
   5792             if (r.task != jt) {
   5793                 jt = r.task;
   5794                 if (affinity.equals(jt.affinity)) {
   5795                     return j;
   5796                 }
   5797             }
   5798         }
   5799 
   5800         // Now look forwards
   5801         final int N = mMainStack.mHistory.size();
   5802         jt = startTask;
   5803         for (j=startIndex+1; j<N; j++) {
   5804             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
   5805             if (r.task != jt) {
   5806                 if (affinity.equals(jt.affinity)) {
   5807                     return j;
   5808                 }
   5809                 jt = r.task;
   5810             }
   5811         }
   5812 
   5813         // Might it be at the top?
   5814         if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
   5815             return N-1;
   5816         }
   5817 
   5818         return -1;
   5819     }
   5820 
   5821     /**
   5822      * TODO: Add mController hook
   5823      */
   5824     public void moveTaskToFront(int task, int flags, Bundle options) {
   5825         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   5826                 "moveTaskToFront()");
   5827 
   5828         synchronized(this) {
   5829             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   5830                     Binder.getCallingUid(), "Task to front")) {
   5831                 ActivityOptions.abort(options);
   5832                 return;
   5833             }
   5834             final long origId = Binder.clearCallingIdentity();
   5835             try {
   5836                 TaskRecord tr = taskForIdLocked(task);
   5837                 if (tr != null) {
   5838                     if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
   5839                         mMainStack.mUserLeaving = true;
   5840                     }
   5841                     if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
   5842                         // Caller wants the home activity moved with it.  To accomplish this,
   5843                         // we'll just move the home task to the top first.
   5844                         mMainStack.moveHomeToFrontLocked();
   5845                     }
   5846                     mMainStack.moveTaskToFrontLocked(tr, null, options);
   5847                     return;
   5848                 }
   5849                 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
   5850                     ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
   5851                     if (hr.task.taskId == task) {
   5852                         if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
   5853                             mMainStack.mUserLeaving = true;
   5854                         }
   5855                         if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
   5856                             // Caller wants the home activity moved with it.  To accomplish this,
   5857                             // we'll just move the home task to the top first.
   5858                             mMainStack.moveHomeToFrontLocked();
   5859                         }
   5860                         mMainStack.moveTaskToFrontLocked(hr.task, null, options);
   5861                         return;
   5862                     }
   5863                 }
   5864             } finally {
   5865                 Binder.restoreCallingIdentity(origId);
   5866             }
   5867             ActivityOptions.abort(options);
   5868         }
   5869     }
   5870 
   5871     public void moveTaskToBack(int task) {
   5872         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   5873                 "moveTaskToBack()");
   5874 
   5875         synchronized(this) {
   5876             if (mMainStack.mResumedActivity != null
   5877                     && mMainStack.mResumedActivity.task.taskId == task) {
   5878                 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   5879                         Binder.getCallingUid(), "Task to back")) {
   5880                     return;
   5881                 }
   5882             }
   5883             final long origId = Binder.clearCallingIdentity();
   5884             mMainStack.moveTaskToBackLocked(task, null);
   5885             Binder.restoreCallingIdentity(origId);
   5886         }
   5887     }
   5888 
   5889     /**
   5890      * Moves an activity, and all of the other activities within the same task, to the bottom
   5891      * of the history stack.  The activity's order within the task is unchanged.
   5892      *
   5893      * @param token A reference to the activity we wish to move
   5894      * @param nonRoot If false then this only works if the activity is the root
   5895      *                of a task; if true it will work for any activity in a task.
   5896      * @return Returns true if the move completed, false if not.
   5897      */
   5898     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
   5899         enforceNotIsolatedCaller("moveActivityTaskToBack");
   5900         synchronized(this) {
   5901             final long origId = Binder.clearCallingIdentity();
   5902             int taskId = getTaskForActivityLocked(token, !nonRoot);
   5903             if (taskId >= 0) {
   5904                 return mMainStack.moveTaskToBackLocked(taskId, null);
   5905             }
   5906             Binder.restoreCallingIdentity(origId);
   5907         }
   5908         return false;
   5909     }
   5910 
   5911     public void moveTaskBackwards(int task) {
   5912         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   5913                 "moveTaskBackwards()");
   5914 
   5915         synchronized(this) {
   5916             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   5917                     Binder.getCallingUid(), "Task backwards")) {
   5918                 return;
   5919             }
   5920             final long origId = Binder.clearCallingIdentity();
   5921             moveTaskBackwardsLocked(task);
   5922             Binder.restoreCallingIdentity(origId);
   5923         }
   5924     }
   5925 
   5926     private final void moveTaskBackwardsLocked(int task) {
   5927         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
   5928     }
   5929 
   5930     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
   5931         synchronized(this) {
   5932             return getTaskForActivityLocked(token, onlyRoot);
   5933         }
   5934     }
   5935 
   5936     int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
   5937         final int N = mMainStack.mHistory.size();
   5938         TaskRecord lastTask = null;
   5939         for (int i=0; i<N; i++) {
   5940             ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   5941             if (r.appToken == token) {
   5942                 if (!onlyRoot || lastTask != r.task) {
   5943                     return r.task.taskId;
   5944                 }
   5945                 return -1;
   5946             }
   5947             lastTask = r.task;
   5948         }
   5949 
   5950         return -1;
   5951     }
   5952 
   5953     // =========================================================
   5954     // THUMBNAILS
   5955     // =========================================================
   5956 
   5957     public void reportThumbnail(IBinder token,
   5958             Bitmap thumbnail, CharSequence description) {
   5959         //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
   5960         final long origId = Binder.clearCallingIdentity();
   5961         sendPendingThumbnail(null, token, thumbnail, description, true);
   5962         Binder.restoreCallingIdentity(origId);
   5963     }
   5964 
   5965     final void sendPendingThumbnail(ActivityRecord r, IBinder token,
   5966             Bitmap thumbnail, CharSequence description, boolean always) {
   5967         TaskRecord task = null;
   5968         ArrayList receivers = null;
   5969 
   5970         //System.out.println("Send pending thumbnail: " + r);
   5971 
   5972         synchronized(this) {
   5973             if (r == null) {
   5974                 r = mMainStack.isInStackLocked(token);
   5975                 if (r == null) {
   5976                     return;
   5977                 }
   5978             }
   5979             if (thumbnail == null && r.thumbHolder != null) {
   5980                 thumbnail = r.thumbHolder.lastThumbnail;
   5981                 description = r.thumbHolder.lastDescription;
   5982             }
   5983             if (thumbnail == null && !always) {
   5984                 // If there is no thumbnail, and this entry is not actually
   5985                 // going away, then abort for now and pick up the next
   5986                 // thumbnail we get.
   5987                 return;
   5988             }
   5989             task = r.task;
   5990 
   5991             int N = mPendingThumbnails.size();
   5992             int i=0;
   5993             while (i<N) {
   5994                 PendingThumbnailsRecord pr =
   5995                     (PendingThumbnailsRecord)mPendingThumbnails.get(i);
   5996                 //System.out.println("Looking in " + pr.pendingRecords);
   5997                 if (pr.pendingRecords.remove(r)) {
   5998                     if (receivers == null) {
   5999                         receivers = new ArrayList();
   6000                     }
   6001                     receivers.add(pr);
   6002                     if (pr.pendingRecords.size() == 0) {
   6003                         pr.finished = true;
   6004                         mPendingThumbnails.remove(i);
   6005                         N--;
   6006                         continue;
   6007                     }
   6008                 }
   6009                 i++;
   6010             }
   6011         }
   6012 
   6013         if (receivers != null) {
   6014             final int N = receivers.size();
   6015             for (int i=0; i<N; i++) {
   6016                 try {
   6017                     PendingThumbnailsRecord pr =
   6018                         (PendingThumbnailsRecord)receivers.get(i);
   6019                     pr.receiver.newThumbnail(
   6020                         task != null ? task.taskId : -1, thumbnail, description);
   6021                     if (pr.finished) {
   6022                         pr.receiver.finished();
   6023                     }
   6024                 } catch (Exception e) {
   6025                     Slog.w(TAG, "Exception thrown when sending thumbnail", e);
   6026                 }
   6027             }
   6028         }
   6029     }
   6030 
   6031     // =========================================================
   6032     // CONTENT PROVIDERS
   6033     // =========================================================
   6034 
   6035     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
   6036         List<ProviderInfo> providers = null;
   6037         try {
   6038             providers = AppGlobals.getPackageManager().
   6039                 queryContentProviders(app.processName, app.uid,
   6040                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
   6041         } catch (RemoteException ex) {
   6042         }
   6043         if (DEBUG_MU)
   6044             Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
   6045         int userId = app.userId;
   6046         if (providers != null) {
   6047             final int N = providers.size();
   6048             for (int i=0; i<N; i++) {
   6049                 ProviderInfo cpi =
   6050                     (ProviderInfo)providers.get(i);
   6051 
   6052                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   6053                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
   6054                 if (cpr == null) {
   6055                     cpr = new ContentProviderRecord(this, cpi, app.info, comp);
   6056                     mProviderMap.putProviderByClass(comp, cpr);
   6057                 }
   6058                 if (DEBUG_MU)
   6059                     Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
   6060                 app.pubProviders.put(cpi.name, cpr);
   6061                 app.addPackage(cpi.applicationInfo.packageName);
   6062                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
   6063             }
   6064         }
   6065         return providers;
   6066     }
   6067 
   6068     /**
   6069      * Check if {@link ProcessRecord} has a possible chance at accessing the
   6070      * given {@link ProviderInfo}. Final permission checking is always done
   6071      * in {@link ContentProvider}.
   6072      */
   6073     private final String checkContentProviderPermissionLocked(
   6074             ProviderInfo cpi, ProcessRecord r) {
   6075         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
   6076         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
   6077         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
   6078                 cpi.applicationInfo.uid, cpi.exported)
   6079                 == PackageManager.PERMISSION_GRANTED) {
   6080             return null;
   6081         }
   6082         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
   6083                 cpi.applicationInfo.uid, cpi.exported)
   6084                 == PackageManager.PERMISSION_GRANTED) {
   6085             return null;
   6086         }
   6087 
   6088         PathPermission[] pps = cpi.pathPermissions;
   6089         if (pps != null) {
   6090             int i = pps.length;
   6091             while (i > 0) {
   6092                 i--;
   6093                 PathPermission pp = pps[i];
   6094                 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
   6095                         cpi.applicationInfo.uid, cpi.exported)
   6096                         == PackageManager.PERMISSION_GRANTED) {
   6097                     return null;
   6098                 }
   6099                 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
   6100                         cpi.applicationInfo.uid, cpi.exported)
   6101                         == PackageManager.PERMISSION_GRANTED) {
   6102                     return null;
   6103                 }
   6104             }
   6105         }
   6106 
   6107         HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   6108         if (perms != null) {
   6109             for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
   6110                 if (uri.getKey().getAuthority().equals(cpi.authority)) {
   6111                     return null;
   6112                 }
   6113             }
   6114         }
   6115 
   6116         String msg;
   6117         if (!cpi.exported) {
   6118             msg = "Permission Denial: opening provider " + cpi.name
   6119                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   6120                     + ", uid=" + callingUid + ") that is not exported from uid "
   6121                     + cpi.applicationInfo.uid;
   6122         } else {
   6123             msg = "Permission Denial: opening provider " + cpi.name
   6124                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   6125                     + ", uid=" + callingUid + ") requires "
   6126                     + cpi.readPermission + " or " + cpi.writePermission;
   6127         }
   6128         Slog.w(TAG, msg);
   6129         return msg;
   6130     }
   6131 
   6132     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
   6133             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   6134         if (r != null) {
   6135             for (int i=0; i<r.conProviders.size(); i++) {
   6136                 ContentProviderConnection conn = r.conProviders.get(i);
   6137                 if (conn.provider == cpr) {
   6138                     if (DEBUG_PROVIDER) Slog.v(TAG,
   6139                             "Adding provider requested by "
   6140                             + r.processName + " from process "
   6141                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   6142                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   6143                     if (stable) {
   6144                         conn.stableCount++;
   6145                         conn.numStableIncs++;
   6146                     } else {
   6147                         conn.unstableCount++;
   6148                         conn.numUnstableIncs++;
   6149                     }
   6150                     return conn;
   6151                 }
   6152             }
   6153             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
   6154             if (stable) {
   6155                 conn.stableCount = 1;
   6156                 conn.numStableIncs = 1;
   6157             } else {
   6158                 conn.unstableCount = 1;
   6159                 conn.numUnstableIncs = 1;
   6160             }
   6161             cpr.connections.add(conn);
   6162             r.conProviders.add(conn);
   6163             return conn;
   6164         }
   6165         cpr.addExternalProcessHandleLocked(externalProcessToken);
   6166         return null;
   6167     }
   6168 
   6169     boolean decProviderCountLocked(ContentProviderConnection conn,
   6170             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   6171         if (conn != null) {
   6172             cpr = conn.provider;
   6173             if (DEBUG_PROVIDER) Slog.v(TAG,
   6174                     "Removing provider requested by "
   6175                     + conn.client.processName + " from process "
   6176                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   6177                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   6178             if (stable) {
   6179                 conn.stableCount--;
   6180             } else {
   6181                 conn.unstableCount--;
   6182             }
   6183             if (conn.stableCount == 0 && conn.unstableCount == 0) {
   6184                 cpr.connections.remove(conn);
   6185                 conn.client.conProviders.remove(conn);
   6186                 return true;
   6187             }
   6188             return false;
   6189         }
   6190         cpr.removeExternalProcessHandleLocked(externalProcessToken);
   6191         return false;
   6192     }
   6193 
   6194     private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
   6195             String name, IBinder token, boolean stable) {
   6196         ContentProviderRecord cpr;
   6197         ContentProviderConnection conn = null;
   6198         ProviderInfo cpi = null;
   6199 
   6200         synchronized(this) {
   6201             ProcessRecord r = null;
   6202             if (caller != null) {
   6203                 r = getRecordForAppLocked(caller);
   6204                 if (r == null) {
   6205                     throw new SecurityException(
   6206                             "Unable to find app for caller " + caller
   6207                           + " (pid=" + Binder.getCallingPid()
   6208                           + ") when getting content provider " + name);
   6209                 }
   6210             }
   6211 
   6212             // First check if this content provider has been published...
   6213             int userId = UserId.getUserId(r != null ? r.uid : Binder.getCallingUid());
   6214             cpr = mProviderMap.getProviderByName(name, userId);
   6215             boolean providerRunning = cpr != null;
   6216             if (providerRunning) {
   6217                 cpi = cpr.info;
   6218                 String msg;
   6219                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
   6220                     throw new SecurityException(msg);
   6221                 }
   6222 
   6223                 if (r != null && cpr.canRunHere(r)) {
   6224                     // This provider has been published or is in the process
   6225                     // of being published...  but it is also allowed to run
   6226                     // in the caller's process, so don't make a connection
   6227                     // and just let the caller instantiate its own instance.
   6228                     ContentProviderHolder holder = cpr.newHolder(null);
   6229                     // don't give caller the provider object, it needs
   6230                     // to make its own.
   6231                     holder.provider = null;
   6232                     return holder;
   6233                 }
   6234 
   6235                 final long origId = Binder.clearCallingIdentity();
   6236 
   6237                 // In this case the provider instance already exists, so we can
   6238                 // return it right away.
   6239                 conn = incProviderCountLocked(r, cpr, token, stable);
   6240                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
   6241                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   6242                         // If this is a perceptible app accessing the provider,
   6243                         // make sure to count it as being accessed and thus
   6244                         // back up on the LRU list.  This is good because
   6245                         // content providers are often expensive to start.
   6246                         updateLruProcessLocked(cpr.proc, false, true);
   6247                     }
   6248                 }
   6249 
   6250                 if (cpr.proc != null) {
   6251                     if (false) {
   6252                         if (cpr.name.flattenToShortString().equals(
   6253                                 "com.android.providers.calendar/.CalendarProvider2")) {
   6254                             Slog.v(TAG, "****************** KILLING "
   6255                                 + cpr.name.flattenToShortString());
   6256                             Process.killProcess(cpr.proc.pid);
   6257                         }
   6258                     }
   6259                     boolean success = updateOomAdjLocked(cpr.proc);
   6260                     if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
   6261                     // NOTE: there is still a race here where a signal could be
   6262                     // pending on the process even though we managed to update its
   6263                     // adj level.  Not sure what to do about this, but at least
   6264                     // the race is now smaller.
   6265                     if (!success) {
   6266                         // Uh oh...  it looks like the provider's process
   6267                         // has been killed on us.  We need to wait for a new
   6268                         // process to be started, and make sure its death
   6269                         // doesn't kill our process.
   6270                         Slog.i(TAG,
   6271                                 "Existing provider " + cpr.name.flattenToShortString()
   6272                                 + " is crashing; detaching " + r);
   6273                         boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
   6274                         appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
   6275                         if (!lastRef) {
   6276                             // This wasn't the last ref our process had on
   6277                             // the provider...  we have now been killed, bail.
   6278                             return null;
   6279                         }
   6280                         providerRunning = false;
   6281                         conn = null;
   6282                     }
   6283                 }
   6284 
   6285                 Binder.restoreCallingIdentity(origId);
   6286             }
   6287 
   6288             if (!providerRunning) {
   6289                 try {
   6290                     cpi = AppGlobals.getPackageManager().
   6291                         resolveContentProvider(name,
   6292                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
   6293                 } catch (RemoteException ex) {
   6294                 }
   6295                 if (cpi == null) {
   6296                     return null;
   6297                 }
   6298                 if (isSingleton(cpi.processName, cpi.applicationInfo)) {
   6299                     userId = 0;
   6300                 }
   6301                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
   6302 
   6303                 String msg;
   6304                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
   6305                     throw new SecurityException(msg);
   6306                 }
   6307 
   6308                 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
   6309                         && !cpi.processName.equals("system")) {
   6310                     // If this content provider does not run in the system
   6311                     // process, and the system is not yet ready to run other
   6312                     // processes, then fail fast instead of hanging.
   6313                     throw new IllegalArgumentException(
   6314                             "Attempt to launch content provider before system ready");
   6315                 }
   6316 
   6317                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   6318                 cpr = mProviderMap.getProviderByClass(comp, userId);
   6319                 final boolean firstClass = cpr == null;
   6320                 if (firstClass) {
   6321                     try {
   6322                         ApplicationInfo ai =
   6323                             AppGlobals.getPackageManager().
   6324                                 getApplicationInfo(
   6325                                         cpi.applicationInfo.packageName,
   6326                                         STOCK_PM_FLAGS, userId);
   6327                         if (ai == null) {
   6328                             Slog.w(TAG, "No package info for content provider "
   6329                                     + cpi.name);
   6330                             return null;
   6331                         }
   6332                         ai = getAppInfoForUser(ai, userId);
   6333                         cpr = new ContentProviderRecord(this, cpi, ai, comp);
   6334                     } catch (RemoteException ex) {
   6335                         // pm is in same process, this will never happen.
   6336                     }
   6337                 }
   6338 
   6339                 if (r != null && cpr.canRunHere(r)) {
   6340                     // If this is a multiprocess provider, then just return its
   6341                     // info and allow the caller to instantiate it.  Only do
   6342                     // this if the provider is the same user as the caller's
   6343                     // process, or can run as root (so can be in any process).
   6344                     return cpr.newHolder(null);
   6345                 }
   6346 
   6347                 if (DEBUG_PROVIDER) {
   6348                     RuntimeException e = new RuntimeException("here");
   6349                     Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
   6350                           + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
   6351                 }
   6352 
   6353                 // This is single process, and our app is now connecting to it.
   6354                 // See if we are already in the process of launching this
   6355                 // provider.
   6356                 final int N = mLaunchingProviders.size();
   6357                 int i;
   6358                 for (i=0; i<N; i++) {
   6359                     if (mLaunchingProviders.get(i) == cpr) {
   6360                         break;
   6361                     }
   6362                 }
   6363 
   6364                 // If the provider is not already being launched, then get it
   6365                 // started.
   6366                 if (i >= N) {
   6367                     final long origId = Binder.clearCallingIdentity();
   6368 
   6369                     try {
   6370                         // Content provider is now in use, its package can't be stopped.
   6371                         try {
   6372                             AppGlobals.getPackageManager().setPackageStoppedState(
   6373                                     cpr.appInfo.packageName, false, userId);
   6374                         } catch (RemoteException e) {
   6375                         } catch (IllegalArgumentException e) {
   6376                             Slog.w(TAG, "Failed trying to unstop package "
   6377                                     + cpr.appInfo.packageName + ": " + e);
   6378                         }
   6379 
   6380                         ProcessRecord proc = startProcessLocked(cpi.processName,
   6381                                 cpr.appInfo, false, 0, "content provider",
   6382                                 new ComponentName(cpi.applicationInfo.packageName,
   6383                                         cpi.name), false, false);
   6384                         if (proc == null) {
   6385                             Slog.w(TAG, "Unable to launch app "
   6386                                     + cpi.applicationInfo.packageName + "/"
   6387                                     + cpi.applicationInfo.uid + " for provider "
   6388                                     + name + ": process is bad");
   6389                             return null;
   6390                         }
   6391                         cpr.launchingApp = proc;
   6392                         mLaunchingProviders.add(cpr);
   6393                     } finally {
   6394                         Binder.restoreCallingIdentity(origId);
   6395                     }
   6396                 }
   6397 
   6398                 // Make sure the provider is published (the same provider class
   6399                 // may be published under multiple names).
   6400                 if (firstClass) {
   6401                     mProviderMap.putProviderByClass(comp, cpr);
   6402                 }
   6403 
   6404                 mProviderMap.putProviderByName(name, cpr);
   6405                 conn = incProviderCountLocked(r, cpr, token, stable);
   6406                 if (conn != null) {
   6407                     conn.waiting = true;
   6408                 }
   6409             }
   6410         }
   6411 
   6412         // Wait for the provider to be published...
   6413         synchronized (cpr) {
   6414             while (cpr.provider == null) {
   6415                 if (cpr.launchingApp == null) {
   6416                     Slog.w(TAG, "Unable to launch app "
   6417                             + cpi.applicationInfo.packageName + "/"
   6418                             + cpi.applicationInfo.uid + " for provider "
   6419                             + name + ": launching app became null");
   6420                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
   6421                             cpi.applicationInfo.packageName,
   6422                             cpi.applicationInfo.uid, name);
   6423                     return null;
   6424                 }
   6425                 try {
   6426                     if (DEBUG_MU) {
   6427                         Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
   6428                                 + cpr.launchingApp);
   6429                     }
   6430                     if (conn != null) {
   6431                         conn.waiting = true;
   6432                     }
   6433                     cpr.wait();
   6434                 } catch (InterruptedException ex) {
   6435                 } finally {
   6436                     if (conn != null) {
   6437                         conn.waiting = false;
   6438                     }
   6439                 }
   6440             }
   6441         }
   6442         return cpr != null ? cpr.newHolder(conn) : null;
   6443     }
   6444 
   6445     public final ContentProviderHolder getContentProvider(
   6446             IApplicationThread caller, String name, boolean stable) {
   6447         enforceNotIsolatedCaller("getContentProvider");
   6448         if (caller == null) {
   6449             String msg = "null IApplicationThread when getting content provider "
   6450                     + name;
   6451             Slog.w(TAG, msg);
   6452             throw new SecurityException(msg);
   6453         }
   6454 
   6455         return getContentProviderImpl(caller, name, null, stable);
   6456     }
   6457 
   6458     public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
   6459         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   6460             "Do not have permission in call getContentProviderExternal()");
   6461         return getContentProviderExternalUnchecked(name, token);
   6462     }
   6463 
   6464     private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) {
   6465         return getContentProviderImpl(null, name, token, true);
   6466     }
   6467 
   6468     /**
   6469      * Drop a content provider from a ProcessRecord's bookkeeping
   6470      * @param cpr
   6471      */
   6472     public void removeContentProvider(IBinder connection, boolean stable) {
   6473         enforceNotIsolatedCaller("removeContentProvider");
   6474         synchronized (this) {
   6475             ContentProviderConnection conn;
   6476             try {
   6477                 conn = (ContentProviderConnection)connection;
   6478             } catch (ClassCastException e) {
   6479                 String msg ="removeContentProvider: " + connection
   6480                         + " not a ContentProviderConnection";
   6481                 Slog.w(TAG, msg);
   6482                 throw new IllegalArgumentException(msg);
   6483             }
   6484             if (conn == null) {
   6485                 throw new NullPointerException("connection is null");
   6486             }
   6487             if (decProviderCountLocked(conn, null, null, stable)) {
   6488                 updateOomAdjLocked();
   6489             }
   6490         }
   6491     }
   6492 
   6493     public void removeContentProviderExternal(String name, IBinder token) {
   6494         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   6495             "Do not have permission in call removeContentProviderExternal()");
   6496         removeContentProviderExternalUnchecked(name, token);
   6497     }
   6498 
   6499     private void removeContentProviderExternalUnchecked(String name, IBinder token) {
   6500         synchronized (this) {
   6501             ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
   6502                     Binder.getOrigCallingUser());
   6503             if(cpr == null) {
   6504                 //remove from mProvidersByClass
   6505                 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
   6506                 return;
   6507             }
   6508 
   6509             //update content provider record entry info
   6510             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
   6511             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
   6512                     Binder.getOrigCallingUser());
   6513             if (localCpr.hasExternalProcessHandles()) {
   6514                 if (localCpr.removeExternalProcessHandleLocked(token)) {
   6515                     updateOomAdjLocked();
   6516                 } else {
   6517                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
   6518                             + " with no external reference for token: "
   6519                             + token + ".");
   6520                 }
   6521             } else {
   6522                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
   6523                         + " with no external references.");
   6524             }
   6525         }
   6526     }
   6527 
   6528     public final void publishContentProviders(IApplicationThread caller,
   6529             List<ContentProviderHolder> providers) {
   6530         if (providers == null) {
   6531             return;
   6532         }
   6533 
   6534         enforceNotIsolatedCaller("publishContentProviders");
   6535         synchronized (this) {
   6536             final ProcessRecord r = getRecordForAppLocked(caller);
   6537             if (DEBUG_MU)
   6538                 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
   6539             if (r == null) {
   6540                 throw new SecurityException(
   6541                         "Unable to find app for caller " + caller
   6542                       + " (pid=" + Binder.getCallingPid()
   6543                       + ") when publishing content providers");
   6544             }
   6545 
   6546             final long origId = Binder.clearCallingIdentity();
   6547 
   6548             final int N = providers.size();
   6549             for (int i=0; i<N; i++) {
   6550                 ContentProviderHolder src = providers.get(i);
   6551                 if (src == null || src.info == null || src.provider == null) {
   6552                     continue;
   6553                 }
   6554                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
   6555                 if (DEBUG_MU)
   6556                     Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
   6557                 if (dst != null) {
   6558                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
   6559                     mProviderMap.putProviderByClass(comp, dst);
   6560                     String names[] = dst.info.authority.split(";");
   6561                     for (int j = 0; j < names.length; j++) {
   6562                         mProviderMap.putProviderByName(names[j], dst);
   6563                     }
   6564 
   6565                     int NL = mLaunchingProviders.size();
   6566                     int j;
   6567                     for (j=0; j<NL; j++) {
   6568                         if (mLaunchingProviders.get(j) == dst) {
   6569                             mLaunchingProviders.remove(j);
   6570                             j--;
   6571                             NL--;
   6572                         }
   6573                     }
   6574                     synchronized (dst) {
   6575                         dst.provider = src.provider;
   6576                         dst.proc = r;
   6577                         dst.notifyAll();
   6578                     }
   6579                     updateOomAdjLocked(r);
   6580                 }
   6581             }
   6582 
   6583             Binder.restoreCallingIdentity(origId);
   6584         }
   6585     }
   6586 
   6587     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
   6588         ContentProviderConnection conn;
   6589         try {
   6590             conn = (ContentProviderConnection)connection;
   6591         } catch (ClassCastException e) {
   6592             String msg ="refContentProvider: " + connection
   6593                     + " not a ContentProviderConnection";
   6594             Slog.w(TAG, msg);
   6595             throw new IllegalArgumentException(msg);
   6596         }
   6597         if (conn == null) {
   6598             throw new NullPointerException("connection is null");
   6599         }
   6600 
   6601         synchronized (this) {
   6602             if (stable > 0) {
   6603                 conn.numStableIncs += stable;
   6604             }
   6605             stable = conn.stableCount + stable;
   6606             if (stable < 0) {
   6607                 throw new IllegalStateException("stableCount < 0: " + stable);
   6608             }
   6609 
   6610             if (unstable > 0) {
   6611                 conn.numUnstableIncs += unstable;
   6612             }
   6613             unstable = conn.unstableCount + unstable;
   6614             if (unstable < 0) {
   6615                 throw new IllegalStateException("unstableCount < 0: " + unstable);
   6616             }
   6617 
   6618             if ((stable+unstable) <= 0) {
   6619                 throw new IllegalStateException("ref counts can't go to zero here: stable="
   6620                         + stable + " unstable=" + unstable);
   6621             }
   6622             conn.stableCount = stable;
   6623             conn.unstableCount = unstable;
   6624             return !conn.dead;
   6625         }
   6626     }
   6627 
   6628     public void unstableProviderDied(IBinder connection) {
   6629         ContentProviderConnection conn;
   6630         try {
   6631             conn = (ContentProviderConnection)connection;
   6632         } catch (ClassCastException e) {
   6633             String msg ="refContentProvider: " + connection
   6634                     + " not a ContentProviderConnection";
   6635             Slog.w(TAG, msg);
   6636             throw new IllegalArgumentException(msg);
   6637         }
   6638         if (conn == null) {
   6639             throw new NullPointerException("connection is null");
   6640         }
   6641 
   6642         // Safely retrieve the content provider associated with the connection.
   6643         IContentProvider provider;
   6644         synchronized (this) {
   6645             provider = conn.provider.provider;
   6646         }
   6647 
   6648         if (provider == null) {
   6649             // Um, yeah, we're way ahead of you.
   6650             return;
   6651         }
   6652 
   6653         // Make sure the caller is being honest with us.
   6654         if (provider.asBinder().pingBinder()) {
   6655             // Er, no, still looks good to us.
   6656             synchronized (this) {
   6657                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
   6658                         + " says " + conn + " died, but we don't agree");
   6659                 return;
   6660             }
   6661         }
   6662 
   6663         // Well look at that!  It's dead!
   6664         synchronized (this) {
   6665             if (conn.provider.provider != provider) {
   6666                 // But something changed...  good enough.
   6667                 return;
   6668             }
   6669 
   6670             ProcessRecord proc = conn.provider.proc;
   6671             if (proc == null || proc.thread == null) {
   6672                 // Seems like the process is already cleaned up.
   6673                 return;
   6674             }
   6675 
   6676             // As far as we're concerned, this is just like receiving a
   6677             // death notification...  just a bit prematurely.
   6678             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
   6679                     + ") early provider death");
   6680             final long ident = Binder.clearCallingIdentity();
   6681             try {
   6682                 appDiedLocked(proc, proc.pid, proc.thread);
   6683             } finally {
   6684                 Binder.restoreCallingIdentity(ident);
   6685             }
   6686         }
   6687     }
   6688 
   6689     public static final void installSystemProviders() {
   6690         List<ProviderInfo> providers;
   6691         synchronized (mSelf) {
   6692             ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
   6693             providers = mSelf.generateApplicationProvidersLocked(app);
   6694             if (providers != null) {
   6695                 for (int i=providers.size()-1; i>=0; i--) {
   6696                     ProviderInfo pi = (ProviderInfo)providers.get(i);
   6697                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   6698                         Slog.w(TAG, "Not installing system proc provider " + pi.name
   6699                                 + ": not system .apk");
   6700                         providers.remove(i);
   6701                     }
   6702                 }
   6703             }
   6704         }
   6705         if (providers != null) {
   6706             mSystemThread.installSystemProviders(providers);
   6707         }
   6708 
   6709         mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
   6710 
   6711         mSelf.mUsageStatsService.monitorPackages();
   6712     }
   6713 
   6714     /**
   6715      * Allows app to retrieve the MIME type of a URI without having permission
   6716      * to access its content provider.
   6717      *
   6718      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
   6719      *
   6720      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
   6721      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
   6722      */
   6723     public String getProviderMimeType(Uri uri) {
   6724         enforceNotIsolatedCaller("getProviderMimeType");
   6725         final String name = uri.getAuthority();
   6726         final long ident = Binder.clearCallingIdentity();
   6727         ContentProviderHolder holder = null;
   6728 
   6729         try {
   6730             holder = getContentProviderExternalUnchecked(name, null);
   6731             if (holder != null) {
   6732                 return holder.provider.getType(uri);
   6733             }
   6734         } catch (RemoteException e) {
   6735             Log.w(TAG, "Content provider dead retrieving " + uri, e);
   6736             return null;
   6737         } finally {
   6738             if (holder != null) {
   6739                 removeContentProviderExternalUnchecked(name, null);
   6740             }
   6741             Binder.restoreCallingIdentity(ident);
   6742         }
   6743 
   6744         return null;
   6745     }
   6746 
   6747     // =========================================================
   6748     // GLOBAL MANAGEMENT
   6749     // =========================================================
   6750 
   6751     final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
   6752             ApplicationInfo info, String customProcess, boolean isolated) {
   6753         String proc = customProcess != null ? customProcess : info.processName;
   6754         BatteryStatsImpl.Uid.Proc ps = null;
   6755         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   6756         int uid = info.uid;
   6757         if (isolated) {
   6758             int userId = UserId.getUserId(uid);
   6759             int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
   6760             uid = 0;
   6761             while (true) {
   6762                 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
   6763                         || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
   6764                     mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
   6765                 }
   6766                 uid = UserId.getUid(userId, mNextIsolatedProcessUid);
   6767                 mNextIsolatedProcessUid++;
   6768                 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
   6769                     // No process for this uid, use it.
   6770                     break;
   6771                 }
   6772                 stepsLeft--;
   6773                 if (stepsLeft <= 0) {
   6774                     return null;
   6775                 }
   6776             }
   6777         }
   6778         synchronized (stats) {
   6779             ps = stats.getProcessStatsLocked(info.uid, proc);
   6780         }
   6781         return new ProcessRecord(ps, thread, info, proc, uid);
   6782     }
   6783 
   6784     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
   6785         ProcessRecord app;
   6786         if (!isolated) {
   6787             app = getProcessRecordLocked(info.processName, info.uid);
   6788         } else {
   6789             app = null;
   6790         }
   6791 
   6792         if (app == null) {
   6793             app = newProcessRecordLocked(null, info, null, isolated);
   6794             mProcessNames.put(info.processName, app.uid, app);
   6795             if (isolated) {
   6796                 mIsolatedProcesses.put(app.uid, app);
   6797             }
   6798             updateLruProcessLocked(app, true, true);
   6799         }
   6800 
   6801         // This package really, really can not be stopped.
   6802         try {
   6803             AppGlobals.getPackageManager().setPackageStoppedState(
   6804                     info.packageName, false, UserId.getUserId(app.uid));
   6805         } catch (RemoteException e) {
   6806         } catch (IllegalArgumentException e) {
   6807             Slog.w(TAG, "Failed trying to unstop package "
   6808                     + info.packageName + ": " + e);
   6809         }
   6810 
   6811         if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
   6812                 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
   6813             app.persistent = true;
   6814             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
   6815         }
   6816         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
   6817             mPersistentStartingProcesses.add(app);
   6818             startProcessLocked(app, "added application", app.processName);
   6819         }
   6820 
   6821         return app;
   6822     }
   6823 
   6824     public void unhandledBack() {
   6825         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
   6826                 "unhandledBack()");
   6827 
   6828         synchronized(this) {
   6829             int count = mMainStack.mHistory.size();
   6830             if (DEBUG_SWITCH) Slog.d(
   6831                 TAG, "Performing unhandledBack(): stack size = " + count);
   6832             if (count > 1) {
   6833                 final long origId = Binder.clearCallingIdentity();
   6834                 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
   6835                         count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
   6836                 Binder.restoreCallingIdentity(origId);
   6837             }
   6838         }
   6839     }
   6840 
   6841     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
   6842         enforceNotIsolatedCaller("openContentUri");
   6843         String name = uri.getAuthority();
   6844         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null);
   6845         ParcelFileDescriptor pfd = null;
   6846         if (cph != null) {
   6847             // We record the binder invoker's uid in thread-local storage before
   6848             // going to the content provider to open the file.  Later, in the code
   6849             // that handles all permissions checks, we look for this uid and use
   6850             // that rather than the Activity Manager's own uid.  The effect is that
   6851             // we do the check against the caller's permissions even though it looks
   6852             // to the content provider like the Activity Manager itself is making
   6853             // the request.
   6854             sCallerIdentity.set(new Identity(
   6855                     Binder.getCallingPid(), Binder.getCallingUid()));
   6856             try {
   6857                 pfd = cph.provider.openFile(uri, "r");
   6858             } catch (FileNotFoundException e) {
   6859                 // do nothing; pfd will be returned null
   6860             } finally {
   6861                 // Ensure that whatever happens, we clean up the identity state
   6862                 sCallerIdentity.remove();
   6863             }
   6864 
   6865             // We've got the fd now, so we're done with the provider.
   6866             removeContentProviderExternalUnchecked(name, null);
   6867         } else {
   6868             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
   6869         }
   6870         return pfd;
   6871     }
   6872 
   6873     // Actually is sleeping or shutting down or whatever else in the future
   6874     // is an inactive state.
   6875     public boolean isSleeping() {
   6876         return mSleeping || mShuttingDown;
   6877     }
   6878 
   6879     public void goingToSleep() {
   6880         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
   6881                 != PackageManager.PERMISSION_GRANTED) {
   6882             throw new SecurityException("Requires permission "
   6883                     + android.Manifest.permission.DEVICE_POWER);
   6884         }
   6885 
   6886         synchronized(this) {
   6887             mWentToSleep = true;
   6888             updateEventDispatchingLocked();
   6889 
   6890             if (!mSleeping) {
   6891                 mSleeping = true;
   6892                 mMainStack.stopIfSleepingLocked();
   6893 
   6894                 // Initialize the wake times of all processes.
   6895                 checkExcessivePowerUsageLocked(false);
   6896                 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   6897                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   6898                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   6899             }
   6900         }
   6901     }
   6902 
   6903     public boolean shutdown(int timeout) {
   6904         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
   6905                 != PackageManager.PERMISSION_GRANTED) {
   6906             throw new SecurityException("Requires permission "
   6907                     + android.Manifest.permission.SHUTDOWN);
   6908         }
   6909 
   6910         boolean timedout = false;
   6911 
   6912         synchronized(this) {
   6913             mShuttingDown = true;
   6914             updateEventDispatchingLocked();
   6915 
   6916             if (mMainStack.mResumedActivity != null) {
   6917                 mMainStack.stopIfSleepingLocked();
   6918                 final long endTime = System.currentTimeMillis() + timeout;
   6919                 while (mMainStack.mResumedActivity != null
   6920                         || mMainStack.mPausingActivity != null) {
   6921                     long delay = endTime - System.currentTimeMillis();
   6922                     if (delay <= 0) {
   6923                         Slog.w(TAG, "Activity manager shutdown timed out");
   6924                         timedout = true;
   6925                         break;
   6926                     }
   6927                     try {
   6928                         this.wait();
   6929                     } catch (InterruptedException e) {
   6930                     }
   6931                 }
   6932             }
   6933         }
   6934 
   6935         mUsageStatsService.shutdown();
   6936         mBatteryStatsService.shutdown();
   6937 
   6938         return timedout;
   6939     }
   6940 
   6941     public final void activitySlept(IBinder token) {
   6942         if (localLOGV) Slog.v(
   6943             TAG, "Activity slept: token=" + token);
   6944 
   6945         ActivityRecord r = null;
   6946 
   6947         final long origId = Binder.clearCallingIdentity();
   6948 
   6949         synchronized (this) {
   6950             r = mMainStack.isInStackLocked(token);
   6951             if (r != null) {
   6952                 mMainStack.activitySleptLocked(r);
   6953             }
   6954         }
   6955 
   6956         Binder.restoreCallingIdentity(origId);
   6957     }
   6958 
   6959     private void comeOutOfSleepIfNeededLocked() {
   6960         if (!mWentToSleep && !mLockScreenShown) {
   6961             if (mSleeping) {
   6962                 mSleeping = false;
   6963                 mMainStack.awakeFromSleepingLocked();
   6964                 mMainStack.resumeTopActivityLocked(null);
   6965             }
   6966         }
   6967     }
   6968 
   6969     public void wakingUp() {
   6970         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
   6971                 != PackageManager.PERMISSION_GRANTED) {
   6972             throw new SecurityException("Requires permission "
   6973                     + android.Manifest.permission.DEVICE_POWER);
   6974         }
   6975 
   6976         synchronized(this) {
   6977             mWentToSleep = false;
   6978             updateEventDispatchingLocked();
   6979             comeOutOfSleepIfNeededLocked();
   6980         }
   6981     }
   6982 
   6983     private void updateEventDispatchingLocked() {
   6984         mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
   6985     }
   6986 
   6987     public void setLockScreenShown(boolean shown) {
   6988         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
   6989                 != PackageManager.PERMISSION_GRANTED) {
   6990             throw new SecurityException("Requires permission "
   6991                     + android.Manifest.permission.DEVICE_POWER);
   6992         }
   6993 
   6994         synchronized(this) {
   6995             mLockScreenShown = shown;
   6996             comeOutOfSleepIfNeededLocked();
   6997         }
   6998     }
   6999 
   7000     public void stopAppSwitches() {
   7001         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   7002                 != PackageManager.PERMISSION_GRANTED) {
   7003             throw new SecurityException("Requires permission "
   7004                     + android.Manifest.permission.STOP_APP_SWITCHES);
   7005         }
   7006 
   7007         synchronized(this) {
   7008             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
   7009                     + APP_SWITCH_DELAY_TIME;
   7010             mDidAppSwitch = false;
   7011             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   7012             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   7013             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
   7014         }
   7015     }
   7016 
   7017     public void resumeAppSwitches() {
   7018         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   7019                 != PackageManager.PERMISSION_GRANTED) {
   7020             throw new SecurityException("Requires permission "
   7021                     + android.Manifest.permission.STOP_APP_SWITCHES);
   7022         }
   7023 
   7024         synchronized(this) {
   7025             // Note that we don't execute any pending app switches... we will
   7026             // let those wait until either the timeout, or the next start
   7027             // activity request.
   7028             mAppSwitchesAllowedTime = 0;
   7029         }
   7030     }
   7031 
   7032     boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
   7033             String name) {
   7034         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
   7035             return true;
   7036         }
   7037 
   7038         final int perm = checkComponentPermission(
   7039                 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
   7040                 callingUid, -1, true);
   7041         if (perm == PackageManager.PERMISSION_GRANTED) {
   7042             return true;
   7043         }
   7044 
   7045         Slog.w(TAG, name + " request from " + callingUid + " stopped");
   7046         return false;
   7047     }
   7048 
   7049     public void setDebugApp(String packageName, boolean waitForDebugger,
   7050             boolean persistent) {
   7051         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
   7052                 "setDebugApp()");
   7053 
   7054         // Note that this is not really thread safe if there are multiple
   7055         // callers into it at the same time, but that's not a situation we
   7056         // care about.
   7057         if (persistent) {
   7058             final ContentResolver resolver = mContext.getContentResolver();
   7059             Settings.System.putString(
   7060                 resolver, Settings.System.DEBUG_APP,
   7061                 packageName);
   7062             Settings.System.putInt(
   7063                 resolver, Settings.System.WAIT_FOR_DEBUGGER,
   7064                 waitForDebugger ? 1 : 0);
   7065         }
   7066 
   7067         synchronized (this) {
   7068             if (!persistent) {
   7069                 mOrigDebugApp = mDebugApp;
   7070                 mOrigWaitForDebugger = mWaitForDebugger;
   7071             }
   7072             mDebugApp = packageName;
   7073             mWaitForDebugger = waitForDebugger;
   7074             mDebugTransient = !persistent;
   7075             if (packageName != null) {
   7076                 final long origId = Binder.clearCallingIdentity();
   7077                 forceStopPackageLocked(packageName, -1, false, false, true, true, 0);
   7078                 Binder.restoreCallingIdentity(origId);
   7079             }
   7080         }
   7081     }
   7082 
   7083     void setOpenGlTraceApp(ApplicationInfo app, String processName) {
   7084         synchronized (this) {
   7085             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   7086             if (!isDebuggable) {
   7087                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   7088                     throw new SecurityException("Process not debuggable: " + app.packageName);
   7089                 }
   7090             }
   7091 
   7092             mOpenGlTraceApp = processName;
   7093         }
   7094     }
   7095 
   7096     void setProfileApp(ApplicationInfo app, String processName, String profileFile,
   7097             ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
   7098         synchronized (this) {
   7099             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   7100             if (!isDebuggable) {
   7101                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   7102                     throw new SecurityException("Process not debuggable: " + app.packageName);
   7103                 }
   7104             }
   7105             mProfileApp = processName;
   7106             mProfileFile = profileFile;
   7107             if (mProfileFd != null) {
   7108                 try {
   7109                     mProfileFd.close();
   7110                 } catch (IOException e) {
   7111                 }
   7112                 mProfileFd = null;
   7113             }
   7114             mProfileFd = profileFd;
   7115             mProfileType = 0;
   7116             mAutoStopProfiler = autoStopProfiler;
   7117         }
   7118     }
   7119 
   7120     public void setAlwaysFinish(boolean enabled) {
   7121         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
   7122                 "setAlwaysFinish()");
   7123 
   7124         Settings.System.putInt(
   7125                 mContext.getContentResolver(),
   7126                 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
   7127 
   7128         synchronized (this) {
   7129             mAlwaysFinishActivities = enabled;
   7130         }
   7131     }
   7132 
   7133     public void setActivityController(IActivityController controller) {
   7134         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   7135                 "setActivityController()");
   7136         synchronized (this) {
   7137             mController = controller;
   7138         }
   7139     }
   7140 
   7141     public boolean isUserAMonkey() {
   7142         // For now the fact that there is a controller implies
   7143         // we have a monkey.
   7144         synchronized (this) {
   7145             return mController != null;
   7146         }
   7147     }
   7148 
   7149     public void registerProcessObserver(IProcessObserver observer) {
   7150         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   7151                 "registerProcessObserver()");
   7152         synchronized (this) {
   7153             mProcessObservers.register(observer);
   7154         }
   7155     }
   7156 
   7157     public void unregisterProcessObserver(IProcessObserver observer) {
   7158         synchronized (this) {
   7159             mProcessObservers.unregister(observer);
   7160         }
   7161     }
   7162 
   7163     public void setImmersive(IBinder token, boolean immersive) {
   7164         synchronized(this) {
   7165             ActivityRecord r = mMainStack.isInStackLocked(token);
   7166             if (r == null) {
   7167                 throw new IllegalArgumentException();
   7168             }
   7169             r.immersive = immersive;
   7170         }
   7171     }
   7172 
   7173     public boolean isImmersive(IBinder token) {
   7174         synchronized (this) {
   7175             ActivityRecord r = mMainStack.isInStackLocked(token);
   7176             if (r == null) {
   7177                 throw new IllegalArgumentException();
   7178             }
   7179             return r.immersive;
   7180         }
   7181     }
   7182 
   7183     public boolean isTopActivityImmersive() {
   7184         enforceNotIsolatedCaller("startActivity");
   7185         synchronized (this) {
   7186             ActivityRecord r = mMainStack.topRunningActivityLocked(null);
   7187             return (r != null) ? r.immersive : false;
   7188         }
   7189     }
   7190 
   7191     public final void enterSafeMode() {
   7192         synchronized(this) {
   7193             // It only makes sense to do this before the system is ready
   7194             // and started launching other packages.
   7195             if (!mSystemReady) {
   7196                 try {
   7197                     AppGlobals.getPackageManager().enterSafeMode();
   7198                 } catch (RemoteException e) {
   7199                 }
   7200             }
   7201         }
   7202     }
   7203 
   7204     public final void showSafeModeOverlay() {
   7205         View v = LayoutInflater.from(mContext).inflate(
   7206                 com.android.internal.R.layout.safe_mode, null);
   7207         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
   7208         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
   7209         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
   7210         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
   7211         lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
   7212         lp.format = v.getBackground().getOpacity();
   7213         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
   7214                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
   7215         ((WindowManager)mContext.getSystemService(
   7216                 Context.WINDOW_SERVICE)).addView(v, lp);
   7217     }
   7218 
   7219     public void noteWakeupAlarm(IIntentSender sender) {
   7220         if (!(sender instanceof PendingIntentRecord)) {
   7221             return;
   7222         }
   7223         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   7224         synchronized (stats) {
   7225             if (mBatteryStatsService.isOnBattery()) {
   7226                 mBatteryStatsService.enforceCallingPermission();
   7227                 PendingIntentRecord rec = (PendingIntentRecord)sender;
   7228                 int MY_UID = Binder.getCallingUid();
   7229                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
   7230                 BatteryStatsImpl.Uid.Pkg pkg =
   7231                     stats.getPackageStatsLocked(uid, rec.key.packageName);
   7232                 pkg.incWakeupsLocked();
   7233             }
   7234         }
   7235     }
   7236 
   7237     public boolean killPids(int[] pids, String pReason, boolean secure) {
   7238         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   7239             throw new SecurityException("killPids only available to the system");
   7240         }
   7241         String reason = (pReason == null) ? "Unknown" : pReason;
   7242         // XXX Note: don't acquire main activity lock here, because the window
   7243         // manager calls in with its locks held.
   7244 
   7245         boolean killed = false;
   7246         synchronized (mPidsSelfLocked) {
   7247             int[] types = new int[pids.length];
   7248             int worstType = 0;
   7249             for (int i=0; i<pids.length; i++) {
   7250                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   7251                 if (proc != null) {
   7252                     int type = proc.setAdj;
   7253                     types[i] = type;
   7254                     if (type > worstType) {
   7255                         worstType = type;
   7256                     }
   7257                 }
   7258             }
   7259 
   7260             // If the worst oom_adj is somewhere in the hidden proc LRU range,
   7261             // then constrain it so we will kill all hidden procs.
   7262             if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
   7263                     && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
   7264                 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
   7265             }
   7266 
   7267             // If this is not a secure call, don't let it kill processes that
   7268             // are important.
   7269             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
   7270                 worstType = ProcessList.SERVICE_ADJ;
   7271             }
   7272 
   7273             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
   7274             for (int i=0; i<pids.length; i++) {
   7275                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   7276                 if (proc == null) {
   7277                     continue;
   7278                 }
   7279                 int adj = proc.setAdj;
   7280                 if (adj >= worstType && !proc.killedBackground) {
   7281                     Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
   7282                     EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
   7283                             proc.processName, adj, reason);
   7284                     killed = true;
   7285                     proc.killedBackground = true;
   7286                     Process.killProcessQuiet(pids[i]);
   7287                 }
   7288             }
   7289         }
   7290         return killed;
   7291     }
   7292 
   7293     @Override
   7294     public boolean killProcessesBelowForeground(String reason) {
   7295         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   7296             throw new SecurityException("killProcessesBelowForeground() only available to system");
   7297         }
   7298 
   7299         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
   7300     }
   7301 
   7302     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
   7303         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   7304             throw new SecurityException("killProcessesBelowAdj() only available to system");
   7305         }
   7306 
   7307         boolean killed = false;
   7308         synchronized (mPidsSelfLocked) {
   7309             final int size = mPidsSelfLocked.size();
   7310             for (int i = 0; i < size; i++) {
   7311                 final int pid = mPidsSelfLocked.keyAt(i);
   7312                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   7313                 if (proc == null) continue;
   7314 
   7315                 final int adj = proc.setAdj;
   7316                 if (adj > belowAdj && !proc.killedBackground) {
   7317                     Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
   7318                     EventLog.writeEvent(
   7319                             EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
   7320                     killed = true;
   7321                     proc.killedBackground = true;
   7322                     Process.killProcessQuiet(pid);
   7323                 }
   7324             }
   7325         }
   7326         return killed;
   7327     }
   7328 
   7329     public final void startRunning(String pkg, String cls, String action,
   7330             String data) {
   7331         synchronized(this) {
   7332             if (mStartRunning) {
   7333                 return;
   7334             }
   7335             mStartRunning = true;
   7336             mTopComponent = pkg != null && cls != null
   7337                     ? new ComponentName(pkg, cls) : null;
   7338             mTopAction = action != null ? action : Intent.ACTION_MAIN;
   7339             mTopData = data;
   7340             if (!mSystemReady) {
   7341                 return;
   7342             }
   7343         }
   7344 
   7345         systemReady(null);
   7346     }
   7347 
   7348     private void retrieveSettings() {
   7349         final ContentResolver resolver = mContext.getContentResolver();
   7350         String debugApp = Settings.System.getString(
   7351             resolver, Settings.System.DEBUG_APP);
   7352         boolean waitForDebugger = Settings.System.getInt(
   7353             resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
   7354         boolean alwaysFinishActivities = Settings.System.getInt(
   7355             resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
   7356 
   7357         Configuration configuration = new Configuration();
   7358         Settings.System.getConfiguration(resolver, configuration);
   7359 
   7360         synchronized (this) {
   7361             mDebugApp = mOrigDebugApp = debugApp;
   7362             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
   7363             mAlwaysFinishActivities = alwaysFinishActivities;
   7364             // This happens before any activities are started, so we can
   7365             // change mConfiguration in-place.
   7366             updateConfigurationLocked(configuration, null, false, true);
   7367             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
   7368         }
   7369     }
   7370 
   7371     public boolean testIsSystemReady() {
   7372         // no need to synchronize(this) just to read & return the value
   7373         return mSystemReady;
   7374     }
   7375 
   7376     private static File getCalledPreBootReceiversFile() {
   7377         File dataDir = Environment.getDataDirectory();
   7378         File systemDir = new File(dataDir, "system");
   7379         File fname = new File(systemDir, "called_pre_boots.dat");
   7380         return fname;
   7381     }
   7382 
   7383     static final int LAST_DONE_VERSION = 10000;
   7384 
   7385     private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
   7386         ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
   7387         File file = getCalledPreBootReceiversFile();
   7388         FileInputStream fis = null;
   7389         try {
   7390             fis = new FileInputStream(file);
   7391             DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
   7392             int fvers = dis.readInt();
   7393             if (fvers == LAST_DONE_VERSION) {
   7394                 String vers = dis.readUTF();
   7395                 String codename = dis.readUTF();
   7396                 String build = dis.readUTF();
   7397                 if (android.os.Build.VERSION.RELEASE.equals(vers)
   7398                         && android.os.Build.VERSION.CODENAME.equals(codename)
   7399                         && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
   7400                     int num = dis.readInt();
   7401                     while (num > 0) {
   7402                         num--;
   7403                         String pkg = dis.readUTF();
   7404                         String cls = dis.readUTF();
   7405                         lastDoneReceivers.add(new ComponentName(pkg, cls));
   7406                     }
   7407                 }
   7408             }
   7409         } catch (FileNotFoundException e) {
   7410         } catch (IOException e) {
   7411             Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
   7412         } finally {
   7413             if (fis != null) {
   7414                 try {
   7415                     fis.close();
   7416                 } catch (IOException e) {
   7417                 }
   7418             }
   7419         }
   7420         return lastDoneReceivers;
   7421     }
   7422 
   7423     private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
   7424         File file = getCalledPreBootReceiversFile();
   7425         FileOutputStream fos = null;
   7426         DataOutputStream dos = null;
   7427         try {
   7428             Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
   7429             fos = new FileOutputStream(file);
   7430             dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
   7431             dos.writeInt(LAST_DONE_VERSION);
   7432             dos.writeUTF(android.os.Build.VERSION.RELEASE);
   7433             dos.writeUTF(android.os.Build.VERSION.CODENAME);
   7434             dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
   7435             dos.writeInt(list.size());
   7436             for (int i=0; i<list.size(); i++) {
   7437                 dos.writeUTF(list.get(i).getPackageName());
   7438                 dos.writeUTF(list.get(i).getClassName());
   7439             }
   7440         } catch (IOException e) {
   7441             Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
   7442             file.delete();
   7443         } finally {
   7444             FileUtils.sync(fos);
   7445             if (dos != null) {
   7446                 try {
   7447                     dos.close();
   7448                 } catch (IOException e) {
   7449                     // TODO Auto-generated catch block
   7450                     e.printStackTrace();
   7451                 }
   7452             }
   7453         }
   7454     }
   7455 
   7456     public void systemReady(final Runnable goingCallback) {
   7457         synchronized(this) {
   7458             if (mSystemReady) {
   7459                 if (goingCallback != null) goingCallback.run();
   7460                 return;
   7461             }
   7462 
   7463             // Check to see if there are any update receivers to run.
   7464             if (!mDidUpdate) {
   7465                 if (mWaitingUpdate) {
   7466                     return;
   7467                 }
   7468                 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
   7469                 List<ResolveInfo> ris = null;
   7470                 try {
   7471                     ris = AppGlobals.getPackageManager().queryIntentReceivers(
   7472                             intent, null, 0, 0);
   7473                 } catch (RemoteException e) {
   7474                 }
   7475                 if (ris != null) {
   7476                     for (int i=ris.size()-1; i>=0; i--) {
   7477                         if ((ris.get(i).activityInfo.applicationInfo.flags
   7478                                 &ApplicationInfo.FLAG_SYSTEM) == 0) {
   7479                             ris.remove(i);
   7480                         }
   7481                     }
   7482                     intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
   7483 
   7484                     ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
   7485 
   7486                     final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
   7487                     for (int i=0; i<ris.size(); i++) {
   7488                         ActivityInfo ai = ris.get(i).activityInfo;
   7489                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
   7490                         if (lastDoneReceivers.contains(comp)) {
   7491                             ris.remove(i);
   7492                             i--;
   7493                         }
   7494                     }
   7495 
   7496                     for (int i=0; i<ris.size(); i++) {
   7497                         ActivityInfo ai = ris.get(i).activityInfo;
   7498                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
   7499                         doneReceivers.add(comp);
   7500                         intent.setComponent(comp);
   7501                         IIntentReceiver finisher = null;
   7502                         if (i == ris.size()-1) {
   7503                             finisher = new IIntentReceiver.Stub() {
   7504                                 public void performReceive(Intent intent, int resultCode,
   7505                                         String data, Bundle extras, boolean ordered,
   7506                                         boolean sticky) {
   7507                                     // The raw IIntentReceiver interface is called
   7508                                     // with the AM lock held, so redispatch to
   7509                                     // execute our code without the lock.
   7510                                     mHandler.post(new Runnable() {
   7511                                         public void run() {
   7512                                             synchronized (ActivityManagerService.this) {
   7513                                                 mDidUpdate = true;
   7514                                             }
   7515                                             writeLastDonePreBootReceivers(doneReceivers);
   7516                                             showBootMessage(mContext.getText(
   7517                                                     R.string.android_upgrading_complete),
   7518                                                     false);
   7519                                             systemReady(goingCallback);
   7520                                         }
   7521                                     });
   7522                                 }
   7523                             };
   7524                         }
   7525                         Slog.i(TAG, "Sending system update to: " + intent.getComponent());
   7526                         /* TODO: Send this to all users */
   7527                         broadcastIntentLocked(null, null, intent, null, finisher,
   7528                                 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
   7529                                 0 /* UserId zero */);
   7530                         if (finisher != null) {
   7531                             mWaitingUpdate = true;
   7532                         }
   7533                     }
   7534                 }
   7535                 if (mWaitingUpdate) {
   7536                     return;
   7537                 }
   7538                 mDidUpdate = true;
   7539             }
   7540 
   7541             mSystemReady = true;
   7542             if (!mStartRunning) {
   7543                 return;
   7544             }
   7545         }
   7546 
   7547         ArrayList<ProcessRecord> procsToKill = null;
   7548         synchronized(mPidsSelfLocked) {
   7549             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
   7550                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   7551                 if (!isAllowedWhileBooting(proc.info)){
   7552                     if (procsToKill == null) {
   7553                         procsToKill = new ArrayList<ProcessRecord>();
   7554                     }
   7555                     procsToKill.add(proc);
   7556                 }
   7557             }
   7558         }
   7559 
   7560         synchronized(this) {
   7561             if (procsToKill != null) {
   7562                 for (int i=procsToKill.size()-1; i>=0; i--) {
   7563                     ProcessRecord proc = procsToKill.get(i);
   7564                     Slog.i(TAG, "Removing system update proc: " + proc);
   7565                     removeProcessLocked(proc, true, false, "system update done");
   7566                 }
   7567             }
   7568 
   7569             // Now that we have cleaned up any update processes, we
   7570             // are ready to start launching real processes and know that
   7571             // we won't trample on them any more.
   7572             mProcessesReady = true;
   7573         }
   7574 
   7575         Slog.i(TAG, "System now ready");
   7576         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
   7577             SystemClock.uptimeMillis());
   7578 
   7579         synchronized(this) {
   7580             // Make sure we have no pre-ready processes sitting around.
   7581 
   7582             if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
   7583                 ResolveInfo ri = mContext.getPackageManager()
   7584                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
   7585                                 STOCK_PM_FLAGS);
   7586                 CharSequence errorMsg = null;
   7587                 if (ri != null) {
   7588                     ActivityInfo ai = ri.activityInfo;
   7589                     ApplicationInfo app = ai.applicationInfo;
   7590                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   7591                         mTopAction = Intent.ACTION_FACTORY_TEST;
   7592                         mTopData = null;
   7593                         mTopComponent = new ComponentName(app.packageName,
   7594                                 ai.name);
   7595                     } else {
   7596                         errorMsg = mContext.getResources().getText(
   7597                                 com.android.internal.R.string.factorytest_not_system);
   7598                     }
   7599                 } else {
   7600                     errorMsg = mContext.getResources().getText(
   7601                             com.android.internal.R.string.factorytest_no_action);
   7602                 }
   7603                 if (errorMsg != null) {
   7604                     mTopAction = null;
   7605                     mTopData = null;
   7606                     mTopComponent = null;
   7607                     Message msg = Message.obtain();
   7608                     msg.what = SHOW_FACTORY_ERROR_MSG;
   7609                     msg.getData().putCharSequence("msg", errorMsg);
   7610                     mHandler.sendMessage(msg);
   7611                 }
   7612             }
   7613         }
   7614 
   7615         retrieveSettings();
   7616 
   7617         if (goingCallback != null) goingCallback.run();
   7618 
   7619         synchronized (this) {
   7620             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   7621                 try {
   7622                     List apps = AppGlobals.getPackageManager().
   7623                         getPersistentApplications(STOCK_PM_FLAGS);
   7624                     if (apps != null) {
   7625                         int N = apps.size();
   7626                         int i;
   7627                         for (i=0; i<N; i++) {
   7628                             ApplicationInfo info
   7629                                 = (ApplicationInfo)apps.get(i);
   7630                             if (info != null &&
   7631                                     !info.packageName.equals("android")) {
   7632                                 addAppLocked(info, false);
   7633                             }
   7634                         }
   7635                     }
   7636                 } catch (RemoteException ex) {
   7637                     // pm is in same process, this will never happen.
   7638                 }
   7639             }
   7640 
   7641             // Start up initial activity.
   7642             mBooting = true;
   7643 
   7644             try {
   7645                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
   7646                     Message msg = Message.obtain();
   7647                     msg.what = SHOW_UID_ERROR_MSG;
   7648                     mHandler.sendMessage(msg);
   7649                 }
   7650             } catch (RemoteException e) {
   7651             }
   7652 
   7653             mMainStack.resumeTopActivityLocked(null);
   7654         }
   7655     }
   7656 
   7657     private boolean makeAppCrashingLocked(ProcessRecord app,
   7658             String shortMsg, String longMsg, String stackTrace) {
   7659         app.crashing = true;
   7660         app.crashingReport = generateProcessError(app,
   7661                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
   7662         startAppProblemLocked(app);
   7663         app.stopFreezingAllLocked();
   7664         return handleAppCrashLocked(app);
   7665     }
   7666 
   7667     private void makeAppNotRespondingLocked(ProcessRecord app,
   7668             String activity, String shortMsg, String longMsg) {
   7669         app.notResponding = true;
   7670         app.notRespondingReport = generateProcessError(app,
   7671                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
   7672                 activity, shortMsg, longMsg, null);
   7673         startAppProblemLocked(app);
   7674         app.stopFreezingAllLocked();
   7675     }
   7676 
   7677     /**
   7678      * Generate a process error record, suitable for attachment to a ProcessRecord.
   7679      *
   7680      * @param app The ProcessRecord in which the error occurred.
   7681      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
   7682      *                      ActivityManager.AppErrorStateInfo
   7683      * @param activity The activity associated with the crash, if known.
   7684      * @param shortMsg Short message describing the crash.
   7685      * @param longMsg Long message describing the crash.
   7686      * @param stackTrace Full crash stack trace, may be null.
   7687      *
   7688      * @return Returns a fully-formed AppErrorStateInfo record.
   7689      */
   7690     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
   7691             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
   7692         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
   7693 
   7694         report.condition = condition;
   7695         report.processName = app.processName;
   7696         report.pid = app.pid;
   7697         report.uid = app.info.uid;
   7698         report.tag = activity;
   7699         report.shortMsg = shortMsg;
   7700         report.longMsg = longMsg;
   7701         report.stackTrace = stackTrace;
   7702 
   7703         return report;
   7704     }
   7705 
   7706     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
   7707         synchronized (this) {
   7708             app.crashing = false;
   7709             app.crashingReport = null;
   7710             app.notResponding = false;
   7711             app.notRespondingReport = null;
   7712             if (app.anrDialog == fromDialog) {
   7713                 app.anrDialog = null;
   7714             }
   7715             if (app.waitDialog == fromDialog) {
   7716                 app.waitDialog = null;
   7717             }
   7718             if (app.pid > 0 && app.pid != MY_PID) {
   7719                 handleAppCrashLocked(app);
   7720                 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
   7721                 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   7722                         app.processName, app.setAdj, "user's request after error");
   7723                 Process.killProcessQuiet(app.pid);
   7724             }
   7725         }
   7726     }
   7727 
   7728     private boolean handleAppCrashLocked(ProcessRecord app) {
   7729         if (mHeadless) {
   7730             Log.e(TAG, "handleAppCrashLocked: " + app.processName);
   7731             return false;
   7732         }
   7733         long now = SystemClock.uptimeMillis();
   7734 
   7735         Long crashTime;
   7736         if (!app.isolated) {
   7737             crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
   7738         } else {
   7739             crashTime = null;
   7740         }
   7741         if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
   7742             // This process loses!
   7743             Slog.w(TAG, "Process " + app.info.processName
   7744                     + " has crashed too many times: killing!");
   7745             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
   7746                     app.info.processName, app.uid);
   7747             for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
   7748                 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
   7749                 if (r.app == app) {
   7750                     Slog.w(TAG, "  Force finishing activity "
   7751                         + r.intent.getComponent().flattenToShortString());
   7752                     r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
   7753                 }
   7754             }
   7755             if (!app.persistent) {
   7756                 // We don't want to start this process again until the user
   7757                 // explicitly does so...  but for persistent process, we really
   7758                 // need to keep it running.  If a persistent process is actually
   7759                 // repeatedly crashing, then badness for everyone.
   7760                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
   7761                         app.info.processName);
   7762                 if (!app.isolated) {
   7763                     // XXX We don't have a way to mark isolated processes
   7764                     // as bad, since they don't have a peristent identity.
   7765                     mBadProcesses.put(app.info.processName, app.uid, now);
   7766                     mProcessCrashTimes.remove(app.info.processName, app.uid);
   7767                 }
   7768                 app.bad = true;
   7769                 app.removed = true;
   7770                 // Don't let services in this process be restarted and potentially
   7771                 // annoy the user repeatedly.  Unless it is persistent, since those
   7772                 // processes run critical code.
   7773                 removeProcessLocked(app, false, false, "crash");
   7774                 mMainStack.resumeTopActivityLocked(null);
   7775                 return false;
   7776             }
   7777             mMainStack.resumeTopActivityLocked(null);
   7778         } else {
   7779             ActivityRecord r = mMainStack.topRunningActivityLocked(null);
   7780             if (r != null && r.app == app) {
   7781                 // If the top running activity is from this crashing
   7782                 // process, then terminate it to avoid getting in a loop.
   7783                 Slog.w(TAG, "  Force finishing activity "
   7784                         + r.intent.getComponent().flattenToShortString());
   7785                 int index = mMainStack.indexOfActivityLocked(r);
   7786                 r.stack.finishActivityLocked(r, index,
   7787                         Activity.RESULT_CANCELED, null, "crashed");
   7788                 // Also terminate any activities below it that aren't yet
   7789                 // stopped, to avoid a situation where one will get
   7790                 // re-start our crashing activity once it gets resumed again.
   7791                 index--;
   7792                 if (index >= 0) {
   7793                     r = (ActivityRecord)mMainStack.mHistory.get(index);
   7794                     if (r.state == ActivityState.RESUMED
   7795                             || r.state == ActivityState.PAUSING
   7796                             || r.state == ActivityState.PAUSED) {
   7797                         if (!r.isHomeActivity || mHomeProcess != r.app) {
   7798                             Slog.w(TAG, "  Force finishing activity "
   7799                                     + r.intent.getComponent().flattenToShortString());
   7800                             r.stack.finishActivityLocked(r, index,
   7801                                     Activity.RESULT_CANCELED, null, "crashed");
   7802                         }
   7803                     }
   7804                 }
   7805             }
   7806         }
   7807 
   7808         // Bump up the crash count of any services currently running in the proc.
   7809         if (app.services.size() != 0) {
   7810             // Any services running in the application need to be placed
   7811             // back in the pending list.
   7812             Iterator<ServiceRecord> it = app.services.iterator();
   7813             while (it.hasNext()) {
   7814                 ServiceRecord sr = it.next();
   7815                 sr.crashCount++;
   7816             }
   7817         }
   7818 
   7819         // If the crashing process is what we consider to be the "home process" and it has been
   7820         // replaced by a third-party app, clear the package preferred activities from packages
   7821         // with a home activity running in the process to prevent a repeatedly crashing app
   7822         // from blocking the user to manually clear the list.
   7823         if (app == mHomeProcess && mHomeProcess.activities.size() > 0
   7824                     && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
   7825             Iterator it = mHomeProcess.activities.iterator();
   7826             while (it.hasNext()) {
   7827                 ActivityRecord r = (ActivityRecord)it.next();
   7828                 if (r.isHomeActivity) {
   7829                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
   7830                     try {
   7831                         ActivityThread.getPackageManager()
   7832                                 .clearPackagePreferredActivities(r.packageName);
   7833                     } catch (RemoteException c) {
   7834                         // pm is in same process, this will never happen.
   7835                     }
   7836                 }
   7837             }
   7838         }
   7839 
   7840         if (!app.isolated) {
   7841             // XXX Can't keep track of crash times for isolated processes,
   7842             // because they don't have a perisistent identity.
   7843             mProcessCrashTimes.put(app.info.processName, app.uid, now);
   7844         }
   7845 
   7846         return true;
   7847     }
   7848 
   7849     void startAppProblemLocked(ProcessRecord app) {
   7850         app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
   7851                 mContext, app.info.packageName, app.info.flags);
   7852         skipCurrentReceiverLocked(app);
   7853     }
   7854 
   7855     void skipCurrentReceiverLocked(ProcessRecord app) {
   7856         for (BroadcastQueue queue : mBroadcastQueues) {
   7857             queue.skipCurrentReceiverLocked(app);
   7858         }
   7859     }
   7860 
   7861     /**
   7862      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
   7863      * The application process will exit immediately after this call returns.
   7864      * @param app object of the crashing app, null for the system server
   7865      * @param crashInfo describing the exception
   7866      */
   7867     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
   7868         ProcessRecord r = findAppProcess(app, "Crash");
   7869         final String processName = app == null ? "system_server"
   7870                 : (r == null ? "unknown" : r.processName);
   7871 
   7872         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
   7873                 processName,
   7874                 r == null ? -1 : r.info.flags,
   7875                 crashInfo.exceptionClassName,
   7876                 crashInfo.exceptionMessage,
   7877                 crashInfo.throwFileName,
   7878                 crashInfo.throwLineNumber);
   7879 
   7880         addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
   7881 
   7882         crashApplication(r, crashInfo);
   7883     }
   7884 
   7885     public void handleApplicationStrictModeViolation(
   7886             IBinder app,
   7887             int violationMask,
   7888             StrictMode.ViolationInfo info) {
   7889         ProcessRecord r = findAppProcess(app, "StrictMode");
   7890         if (r == null) {
   7891             return;
   7892         }
   7893 
   7894         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
   7895             Integer stackFingerprint = info.hashCode();
   7896             boolean logIt = true;
   7897             synchronized (mAlreadyLoggedViolatedStacks) {
   7898                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
   7899                     logIt = false;
   7900                     // TODO: sub-sample into EventLog for these, with
   7901                     // the info.durationMillis?  Then we'd get
   7902                     // the relative pain numbers, without logging all
   7903                     // the stack traces repeatedly.  We'd want to do
   7904                     // likewise in the client code, which also does
   7905                     // dup suppression, before the Binder call.
   7906                 } else {
   7907                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
   7908                         mAlreadyLoggedViolatedStacks.clear();
   7909                     }
   7910                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
   7911                 }
   7912             }
   7913             if (logIt) {
   7914                 logStrictModeViolationToDropBox(r, info);
   7915             }
   7916         }
   7917 
   7918         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
   7919             AppErrorResult result = new AppErrorResult();
   7920             synchronized (this) {
   7921                 final long origId = Binder.clearCallingIdentity();
   7922 
   7923                 Message msg = Message.obtain();
   7924                 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
   7925                 HashMap<String, Object> data = new HashMap<String, Object>();
   7926                 data.put("result", result);
   7927                 data.put("app", r);
   7928                 data.put("violationMask", violationMask);
   7929                 data.put("info", info);
   7930                 msg.obj = data;
   7931                 mHandler.sendMessage(msg);
   7932 
   7933                 Binder.restoreCallingIdentity(origId);
   7934             }
   7935             int res = result.get();
   7936             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
   7937         }
   7938     }
   7939 
   7940     // Depending on the policy in effect, there could be a bunch of
   7941     // these in quick succession so we try to batch these together to
   7942     // minimize disk writes, number of dropbox entries, and maximize
   7943     // compression, by having more fewer, larger records.
   7944     private void logStrictModeViolationToDropBox(
   7945             ProcessRecord process,
   7946             StrictMode.ViolationInfo info) {
   7947         if (info == null) {
   7948             return;
   7949         }
   7950         final boolean isSystemApp = process == null ||
   7951                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
   7952                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
   7953         final String processName = process == null ? "unknown" : process.processName;
   7954         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
   7955         final DropBoxManager dbox = (DropBoxManager)
   7956                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   7957 
   7958         // Exit early if the dropbox isn't configured to accept this report type.
   7959         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   7960 
   7961         boolean bufferWasEmpty;
   7962         boolean needsFlush;
   7963         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
   7964         synchronized (sb) {
   7965             bufferWasEmpty = sb.length() == 0;
   7966             appendDropBoxProcessHeaders(process, processName, sb);
   7967             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   7968             sb.append("System-App: ").append(isSystemApp).append("\n");
   7969             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
   7970             if (info.violationNumThisLoop != 0) {
   7971                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
   7972             }
   7973             if (info.numAnimationsRunning != 0) {
   7974                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
   7975             }
   7976             if (info.broadcastIntentAction != null) {
   7977                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
   7978             }
   7979             if (info.durationMillis != -1) {
   7980                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
   7981             }
   7982             if (info.numInstances != -1) {
   7983                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
   7984             }
   7985             if (info.tags != null) {
   7986                 for (String tag : info.tags) {
   7987                     sb.append("Span-Tag: ").append(tag).append("\n");
   7988                 }
   7989             }
   7990             sb.append("\n");
   7991             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
   7992                 sb.append(info.crashInfo.stackTrace);
   7993             }
   7994             sb.append("\n");
   7995 
   7996             // Only buffer up to ~64k.  Various logging bits truncate
   7997             // things at 128k.
   7998             needsFlush = (sb.length() > 64 * 1024);
   7999         }
   8000 
   8001         // Flush immediately if the buffer's grown too large, or this
   8002         // is a non-system app.  Non-system apps are isolated with a
   8003         // different tag & policy and not batched.
   8004         //
   8005         // Batching is useful during internal testing with
   8006         // StrictMode settings turned up high.  Without batching,
   8007         // thousands of separate files could be created on boot.
   8008         if (!isSystemApp || needsFlush) {
   8009             new Thread("Error dump: " + dropboxTag) {
   8010                 @Override
   8011                 public void run() {
   8012                     String report;
   8013                     synchronized (sb) {
   8014                         report = sb.toString();
   8015                         sb.delete(0, sb.length());
   8016                         sb.trimToSize();
   8017                     }
   8018                     if (report.length() != 0) {
   8019                         dbox.addText(dropboxTag, report);
   8020                     }
   8021                 }
   8022             }.start();
   8023             return;
   8024         }
   8025 
   8026         // System app batching:
   8027         if (!bufferWasEmpty) {
   8028             // An existing dropbox-writing thread is outstanding, so
   8029             // we don't need to start it up.  The existing thread will
   8030             // catch the buffer appends we just did.
   8031             return;
   8032         }
   8033 
   8034         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
   8035         // (After this point, we shouldn't access AMS internal data structures.)
   8036         new Thread("Error dump: " + dropboxTag) {
   8037             @Override
   8038             public void run() {
   8039                 // 5 second sleep to let stacks arrive and be batched together
   8040                 try {
   8041                     Thread.sleep(5000);  // 5 seconds
   8042                 } catch (InterruptedException e) {}
   8043 
   8044                 String errorReport;
   8045                 synchronized (mStrictModeBuffer) {
   8046                     errorReport = mStrictModeBuffer.toString();
   8047                     if (errorReport.length() == 0) {
   8048                         return;
   8049                     }
   8050                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
   8051                     mStrictModeBuffer.trimToSize();
   8052                 }
   8053                 dbox.addText(dropboxTag, errorReport);
   8054             }
   8055         }.start();
   8056     }
   8057 
   8058     /**
   8059      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
   8060      * @param app object of the crashing app, null for the system server
   8061      * @param tag reported by the caller
   8062      * @param crashInfo describing the context of the error
   8063      * @return true if the process should exit immediately (WTF is fatal)
   8064      */
   8065     public boolean handleApplicationWtf(IBinder app, String tag,
   8066             ApplicationErrorReport.CrashInfo crashInfo) {
   8067         ProcessRecord r = findAppProcess(app, "WTF");
   8068         final String processName = app == null ? "system_server"
   8069                 : (r == null ? "unknown" : r.processName);
   8070 
   8071         EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
   8072                 processName,
   8073                 r == null ? -1 : r.info.flags,
   8074                 tag, crashInfo.exceptionMessage);
   8075 
   8076         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
   8077 
   8078         if (r != null && r.pid != Process.myPid() &&
   8079                 Settings.Secure.getInt(mContext.getContentResolver(),
   8080                         Settings.Secure.WTF_IS_FATAL, 0) != 0) {
   8081             crashApplication(r, crashInfo);
   8082             return true;
   8083         } else {
   8084             return false;
   8085         }
   8086     }
   8087 
   8088     /**
   8089      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
   8090      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
   8091      */
   8092     private ProcessRecord findAppProcess(IBinder app, String reason) {
   8093         if (app == null) {
   8094             return null;
   8095         }
   8096 
   8097         synchronized (this) {
   8098             for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
   8099                 final int NA = apps.size();
   8100                 for (int ia=0; ia<NA; ia++) {
   8101                     ProcessRecord p = apps.valueAt(ia);
   8102                     if (p.thread != null && p.thread.asBinder() == app) {
   8103                         return p;
   8104                     }
   8105                 }
   8106             }
   8107 
   8108             Slog.w(TAG, "Can't find mystery application for " + reason
   8109                     + " from pid=" + Binder.getCallingPid()
   8110                     + " uid=" + Binder.getCallingUid() + ": " + app);
   8111             return null;
   8112         }
   8113     }
   8114 
   8115     /**
   8116      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
   8117      * to append various headers to the dropbox log text.
   8118      */
   8119     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
   8120             StringBuilder sb) {
   8121         // Watchdog thread ends up invoking this function (with
   8122         // a null ProcessRecord) to add the stack file to dropbox.
   8123         // Do not acquire a lock on this (am) in such cases, as it
   8124         // could cause a potential deadlock, if and when watchdog
   8125         // is invoked due to unavailability of lock on am and it
   8126         // would prevent watchdog from killing system_server.
   8127         if (process == null) {
   8128             sb.append("Process: ").append(processName).append("\n");
   8129             return;
   8130         }
   8131         // Note: ProcessRecord 'process' is guarded by the service
   8132         // instance.  (notably process.pkgList, which could otherwise change
   8133         // concurrently during execution of this method)
   8134         synchronized (this) {
   8135             sb.append("Process: ").append(processName).append("\n");
   8136             int flags = process.info.flags;
   8137             IPackageManager pm = AppGlobals.getPackageManager();
   8138             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
   8139             for (String pkg : process.pkgList) {
   8140                 sb.append("Package: ").append(pkg);
   8141                 try {
   8142                     PackageInfo pi = pm.getPackageInfo(pkg, 0, 0);
   8143                     if (pi != null) {
   8144                         sb.append(" v").append(pi.versionCode);
   8145                         if (pi.versionName != null) {
   8146                             sb.append(" (").append(pi.versionName).append(")");
   8147                         }
   8148                     }
   8149                 } catch (RemoteException e) {
   8150                     Slog.e(TAG, "Error getting package info: " + pkg, e);
   8151                 }
   8152                 sb.append("\n");
   8153             }
   8154         }
   8155     }
   8156 
   8157     private static String processClass(ProcessRecord process) {
   8158         if (process == null || process.pid == MY_PID) {
   8159             return "system_server";
   8160         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   8161             return "system_app";
   8162         } else {
   8163             return "data_app";
   8164         }
   8165     }
   8166 
   8167     /**
   8168      * Write a description of an error (crash, WTF, ANR) to the drop box.
   8169      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
   8170      * @param process which caused the error, null means the system server
   8171      * @param activity which triggered the error, null if unknown
   8172      * @param parent activity related to the error, null if unknown
   8173      * @param subject line related to the error, null if absent
   8174      * @param report in long form describing the error, null if absent
   8175      * @param logFile to include in the report, null if none
   8176      * @param crashInfo giving an application stack trace, null if absent
   8177      */
   8178     public void addErrorToDropBox(String eventType,
   8179             ProcessRecord process, String processName, ActivityRecord activity,
   8180             ActivityRecord parent, String subject,
   8181             final String report, final File logFile,
   8182             final ApplicationErrorReport.CrashInfo crashInfo) {
   8183         // NOTE -- this must never acquire the ActivityManagerService lock,
   8184         // otherwise the watchdog may be prevented from resetting the system.
   8185 
   8186         final String dropboxTag = processClass(process) + "_" + eventType;
   8187         final DropBoxManager dbox = (DropBoxManager)
   8188                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   8189 
   8190         // Exit early if the dropbox isn't configured to accept this report type.
   8191         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   8192 
   8193         final StringBuilder sb = new StringBuilder(1024);
   8194         appendDropBoxProcessHeaders(process, processName, sb);
   8195         if (activity != null) {
   8196             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
   8197         }
   8198         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
   8199             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
   8200         }
   8201         if (parent != null && parent != activity) {
   8202             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
   8203         }
   8204         if (subject != null) {
   8205             sb.append("Subject: ").append(subject).append("\n");
   8206         }
   8207         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   8208         if (Debug.isDebuggerConnected()) {
   8209             sb.append("Debugger: Connected\n");
   8210         }
   8211         sb.append("\n");
   8212 
   8213         // Do the rest in a worker thread to avoid blocking the caller on I/O
   8214         // (After this point, we shouldn't access AMS internal data structures.)
   8215         Thread worker = new Thread("Error dump: " + dropboxTag) {
   8216             @Override
   8217             public void run() {
   8218                 if (report != null) {
   8219                     sb.append(report);
   8220                 }
   8221                 if (logFile != null) {
   8222                     try {
   8223                         sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
   8224                     } catch (IOException e) {
   8225                         Slog.e(TAG, "Error reading " + logFile, e);
   8226                     }
   8227                 }
   8228                 if (crashInfo != null && crashInfo.stackTrace != null) {
   8229                     sb.append(crashInfo.stackTrace);
   8230                 }
   8231 
   8232                 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
   8233                 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
   8234                 if (lines > 0) {
   8235                     sb.append("\n");
   8236 
   8237                     // Merge several logcat streams, and take the last N lines
   8238                     InputStreamReader input = null;
   8239                     try {
   8240                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
   8241                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
   8242                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
   8243 
   8244                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
   8245                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
   8246                         input = new InputStreamReader(logcat.getInputStream());
   8247 
   8248                         int num;
   8249                         char[] buf = new char[8192];
   8250                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
   8251                     } catch (IOException e) {
   8252                         Slog.e(TAG, "Error running logcat", e);
   8253                     } finally {
   8254                         if (input != null) try { input.close(); } catch (IOException e) {}
   8255                     }
   8256                 }
   8257 
   8258                 dbox.addText(dropboxTag, sb.toString());
   8259             }
   8260         };
   8261 
   8262         if (process == null) {
   8263             // If process is null, we are being called from some internal code
   8264             // and may be about to die -- run this synchronously.
   8265             worker.run();
   8266         } else {
   8267             worker.start();
   8268         }
   8269     }
   8270 
   8271     /**
   8272      * Bring up the "unexpected error" dialog box for a crashing app.
   8273      * Deal with edge cases (intercepts from instrumented applications,
   8274      * ActivityController, error intent receivers, that sort of thing).
   8275      * @param r the application crashing
   8276      * @param crashInfo describing the failure
   8277      */
   8278     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
   8279         long timeMillis = System.currentTimeMillis();
   8280         String shortMsg = crashInfo.exceptionClassName;
   8281         String longMsg = crashInfo.exceptionMessage;
   8282         String stackTrace = crashInfo.stackTrace;
   8283         if (shortMsg != null && longMsg != null) {
   8284             longMsg = shortMsg + ": " + longMsg;
   8285         } else if (shortMsg != null) {
   8286             longMsg = shortMsg;
   8287         }
   8288 
   8289         AppErrorResult result = new AppErrorResult();
   8290         synchronized (this) {
   8291             if (mController != null) {
   8292                 try {
   8293                     String name = r != null ? r.processName : null;
   8294                     int pid = r != null ? r.pid : Binder.getCallingPid();
   8295                     if (!mController.appCrashed(name, pid,
   8296                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
   8297                         Slog.w(TAG, "Force-killing crashed app " + name
   8298                                 + " at watcher's request");
   8299                         Process.killProcess(pid);
   8300                         return;
   8301                     }
   8302                 } catch (RemoteException e) {
   8303                     mController = null;
   8304                 }
   8305             }
   8306 
   8307             final long origId = Binder.clearCallingIdentity();
   8308 
   8309             // If this process is running instrumentation, finish it.
   8310             if (r != null && r.instrumentationClass != null) {
   8311                 Slog.w(TAG, "Error in app " + r.processName
   8312                       + " running instrumentation " + r.instrumentationClass + ":");
   8313                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
   8314                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
   8315                 Bundle info = new Bundle();
   8316                 info.putString("shortMsg", shortMsg);
   8317                 info.putString("longMsg", longMsg);
   8318                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
   8319                 Binder.restoreCallingIdentity(origId);
   8320                 return;
   8321             }
   8322 
   8323             // If we can't identify the process or it's already exceeded its crash quota,
   8324             // quit right away without showing a crash dialog.
   8325             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
   8326                 Binder.restoreCallingIdentity(origId);
   8327                 return;
   8328             }
   8329 
   8330             Message msg = Message.obtain();
   8331             msg.what = SHOW_ERROR_MSG;
   8332             HashMap data = new HashMap();
   8333             data.put("result", result);
   8334             data.put("app", r);
   8335             msg.obj = data;
   8336             mHandler.sendMessage(msg);
   8337 
   8338             Binder.restoreCallingIdentity(origId);
   8339         }
   8340 
   8341         int res = result.get();
   8342 
   8343         Intent appErrorIntent = null;
   8344         synchronized (this) {
   8345             if (r != null && !r.isolated) {
   8346                 // XXX Can't keep track of crash time for isolated processes,
   8347                 // since they don't have a persistent identity.
   8348                 mProcessCrashTimes.put(r.info.processName, r.uid,
   8349                         SystemClock.uptimeMillis());
   8350             }
   8351             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
   8352                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
   8353             }
   8354         }
   8355 
   8356         if (appErrorIntent != null) {
   8357             try {
   8358                 mContext.startActivity(appErrorIntent);
   8359             } catch (ActivityNotFoundException e) {
   8360                 Slog.w(TAG, "bug report receiver dissappeared", e);
   8361             }
   8362         }
   8363     }
   8364 
   8365     Intent createAppErrorIntentLocked(ProcessRecord r,
   8366             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   8367         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
   8368         if (report == null) {
   8369             return null;
   8370         }
   8371         Intent result = new Intent(Intent.ACTION_APP_ERROR);
   8372         result.setComponent(r.errorReportReceiver);
   8373         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
   8374         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   8375         return result;
   8376     }
   8377 
   8378     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
   8379             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   8380         if (r.errorReportReceiver == null) {
   8381             return null;
   8382         }
   8383 
   8384         if (!r.crashing && !r.notResponding) {
   8385             return null;
   8386         }
   8387 
   8388         ApplicationErrorReport report = new ApplicationErrorReport();
   8389         report.packageName = r.info.packageName;
   8390         report.installerPackageName = r.errorReportReceiver.getPackageName();
   8391         report.processName = r.processName;
   8392         report.time = timeMillis;
   8393         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   8394 
   8395         if (r.crashing) {
   8396             report.type = ApplicationErrorReport.TYPE_CRASH;
   8397             report.crashInfo = crashInfo;
   8398         } else if (r.notResponding) {
   8399             report.type = ApplicationErrorReport.TYPE_ANR;
   8400             report.anrInfo = new ApplicationErrorReport.AnrInfo();
   8401 
   8402             report.anrInfo.activity = r.notRespondingReport.tag;
   8403             report.anrInfo.cause = r.notRespondingReport.shortMsg;
   8404             report.anrInfo.info = r.notRespondingReport.longMsg;
   8405         }
   8406 
   8407         return report;
   8408     }
   8409 
   8410     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
   8411         enforceNotIsolatedCaller("getProcessesInErrorState");
   8412         // assume our apps are happy - lazy create the list
   8413         List<ActivityManager.ProcessErrorStateInfo> errList = null;
   8414 
   8415         synchronized (this) {
   8416 
   8417             // iterate across all processes
   8418             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   8419                 ProcessRecord app = mLruProcesses.get(i);
   8420                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
   8421                     // This one's in trouble, so we'll generate a report for it
   8422                     // crashes are higher priority (in case there's a crash *and* an anr)
   8423                     ActivityManager.ProcessErrorStateInfo report = null;
   8424                     if (app.crashing) {
   8425                         report = app.crashingReport;
   8426                     } else if (app.notResponding) {
   8427                         report = app.notRespondingReport;
   8428                     }
   8429 
   8430                     if (report != null) {
   8431                         if (errList == null) {
   8432                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
   8433                         }
   8434                         errList.add(report);
   8435                     } else {
   8436                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
   8437                                 " crashing = " + app.crashing +
   8438                                 " notResponding = " + app.notResponding);
   8439                     }
   8440                 }
   8441             }
   8442         }
   8443 
   8444         return errList;
   8445     }
   8446 
   8447     static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
   8448         if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   8449             if (currApp != null) {
   8450                 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
   8451             }
   8452             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   8453         } else if (adj >= ProcessList.SERVICE_B_ADJ) {
   8454             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   8455         } else if (adj >= ProcessList.HOME_APP_ADJ) {
   8456             if (currApp != null) {
   8457                 currApp.lru = 0;
   8458             }
   8459             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   8460         } else if (adj >= ProcessList.SERVICE_ADJ) {
   8461             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   8462         } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   8463             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
   8464         } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   8465             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
   8466         } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
   8467             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
   8468         } else {
   8469             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
   8470         }
   8471     }
   8472 
   8473     private void fillInProcMemInfo(ProcessRecord app,
   8474             ActivityManager.RunningAppProcessInfo outInfo) {
   8475         outInfo.pid = app.pid;
   8476         outInfo.uid = app.info.uid;
   8477         if (mHeavyWeightProcess == app) {
   8478             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
   8479         }
   8480         if (app.persistent) {
   8481             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
   8482         }
   8483         outInfo.lastTrimLevel = app.trimMemoryLevel;
   8484         int adj = app.curAdj;
   8485         outInfo.importance = oomAdjToImportance(adj, outInfo);
   8486         outInfo.importanceReasonCode = app.adjTypeCode;
   8487     }
   8488 
   8489     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
   8490         enforceNotIsolatedCaller("getRunningAppProcesses");
   8491         // Lazy instantiation of list
   8492         List<ActivityManager.RunningAppProcessInfo> runList = null;
   8493         synchronized (this) {
   8494             // Iterate across all processes
   8495             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   8496                 ProcessRecord app = mLruProcesses.get(i);
   8497                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
   8498                     // Generate process state info for running application
   8499                     ActivityManager.RunningAppProcessInfo currApp =
   8500                         new ActivityManager.RunningAppProcessInfo(app.processName,
   8501                                 app.pid, app.getPackageList());
   8502                     fillInProcMemInfo(app, currApp);
   8503                     if (app.adjSource instanceof ProcessRecord) {
   8504                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
   8505                         currApp.importanceReasonImportance = oomAdjToImportance(
   8506                                 app.adjSourceOom, null);
   8507                     } else if (app.adjSource instanceof ActivityRecord) {
   8508                         ActivityRecord r = (ActivityRecord)app.adjSource;
   8509                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
   8510                     }
   8511                     if (app.adjTarget instanceof ComponentName) {
   8512                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
   8513                     }
   8514                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
   8515                     //        + " lru=" + currApp.lru);
   8516                     if (runList == null) {
   8517                         runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
   8518                     }
   8519                     runList.add(currApp);
   8520                 }
   8521             }
   8522         }
   8523         return runList;
   8524     }
   8525 
   8526     public List<ApplicationInfo> getRunningExternalApplications() {
   8527         enforceNotIsolatedCaller("getRunningExternalApplications");
   8528         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
   8529         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
   8530         if (runningApps != null && runningApps.size() > 0) {
   8531             Set<String> extList = new HashSet<String>();
   8532             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
   8533                 if (app.pkgList != null) {
   8534                     for (String pkg : app.pkgList) {
   8535                         extList.add(pkg);
   8536                     }
   8537                 }
   8538             }
   8539             IPackageManager pm = AppGlobals.getPackageManager();
   8540             for (String pkg : extList) {
   8541                 try {
   8542                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserId.getCallingUserId());
   8543                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
   8544                         retList.add(info);
   8545                     }
   8546                 } catch (RemoteException e) {
   8547                 }
   8548             }
   8549         }
   8550         return retList;
   8551     }
   8552 
   8553     @Override
   8554     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
   8555         enforceNotIsolatedCaller("getMyMemoryState");
   8556         synchronized (this) {
   8557             ProcessRecord proc;
   8558             synchronized (mPidsSelfLocked) {
   8559                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
   8560             }
   8561             fillInProcMemInfo(proc, outInfo);
   8562         }
   8563     }
   8564 
   8565     @Override
   8566     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   8567         if (checkCallingPermission(android.Manifest.permission.DUMP)
   8568                 != PackageManager.PERMISSION_GRANTED) {
   8569             pw.println("Permission Denial: can't dump ActivityManager from from pid="
   8570                     + Binder.getCallingPid()
   8571                     + ", uid=" + Binder.getCallingUid()
   8572                     + " without permission "
   8573                     + android.Manifest.permission.DUMP);
   8574             return;
   8575         }
   8576 
   8577         boolean dumpAll = false;
   8578         boolean dumpClient = false;
   8579         String dumpPackage = null;
   8580 
   8581         int opti = 0;
   8582         while (opti < args.length) {
   8583             String opt = args[opti];
   8584             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   8585                 break;
   8586             }
   8587             opti++;
   8588             if ("-a".equals(opt)) {
   8589                 dumpAll = true;
   8590             } else if ("-c".equals(opt)) {
   8591                 dumpClient = true;
   8592             } else if ("-h".equals(opt)) {
   8593                 pw.println("Activity manager dump options:");
   8594                 pw.println("  [-a] [-c] [-h] [cmd] ...");
   8595                 pw.println("  cmd may be one of:");
   8596                 pw.println("    a[ctivities]: activity stack state");
   8597                 pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
   8598                 pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
   8599                 pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
   8600                 pw.println("    o[om]: out of memory management");
   8601                 pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
   8602                 pw.println("    provider [COMP_SPEC]: provider client-side state");
   8603                 pw.println("    s[ervices] [COMP_SPEC ...]: service state");
   8604                 pw.println("    service [COMP_SPEC]: service client-side state");
   8605                 pw.println("    package [PACKAGE_NAME]: all state related to given package");
   8606                 pw.println("    all: dump all activities");
   8607                 pw.println("    top: dump the top activity");
   8608                 pw.println("  cmd may also be a COMP_SPEC to dump activities.");
   8609                 pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
   8610                 pw.println("    a partial substring in a component name, a");
   8611                 pw.println("    hex object identifier.");
   8612                 pw.println("  -a: include all available server state.");
   8613                 pw.println("  -c: include client state.");
   8614                 return;
   8615             } else {
   8616                 pw.println("Unknown argument: " + opt + "; use -h for help");
   8617             }
   8618         }
   8619 
   8620         long origId = Binder.clearCallingIdentity();
   8621         boolean more = false;
   8622         // Is the caller requesting to dump a particular piece of data?
   8623         if (opti < args.length) {
   8624             String cmd = args[opti];
   8625             opti++;
   8626             if ("activities".equals(cmd) || "a".equals(cmd)) {
   8627                 synchronized (this) {
   8628                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
   8629                 }
   8630             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
   8631                 String[] newArgs;
   8632                 String name;
   8633                 if (opti >= args.length) {
   8634                     name = null;
   8635                     newArgs = EMPTY_STRING_ARRAY;
   8636                 } else {
   8637                     name = args[opti];
   8638                     opti++;
   8639                     newArgs = new String[args.length - opti];
   8640                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   8641                             args.length - opti);
   8642                 }
   8643                 synchronized (this) {
   8644                     dumpBroadcastsLocked(fd, pw, args, opti, true, name);
   8645                 }
   8646             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
   8647                 String[] newArgs;
   8648                 String name;
   8649                 if (opti >= args.length) {
   8650                     name = null;
   8651                     newArgs = EMPTY_STRING_ARRAY;
   8652                 } else {
   8653                     name = args[opti];
   8654                     opti++;
   8655                     newArgs = new String[args.length - opti];
   8656                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   8657                             args.length - opti);
   8658                 }
   8659                 synchronized (this) {
   8660                     dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
   8661                 }
   8662             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
   8663                 String[] newArgs;
   8664                 String name;
   8665                 if (opti >= args.length) {
   8666                     name = null;
   8667                     newArgs = EMPTY_STRING_ARRAY;
   8668                 } else {
   8669                     name = args[opti];
   8670                     opti++;
   8671                     newArgs = new String[args.length - opti];
   8672                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   8673                             args.length - opti);
   8674                 }
   8675                 synchronized (this) {
   8676                     dumpProcessesLocked(fd, pw, args, opti, true, name);
   8677                 }
   8678             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
   8679                 synchronized (this) {
   8680                     dumpOomLocked(fd, pw, args, opti, true);
   8681                 }
   8682             } else if ("provider".equals(cmd)) {
   8683                 String[] newArgs;
   8684                 String name;
   8685                 if (opti >= args.length) {
   8686                     name = null;
   8687                     newArgs = EMPTY_STRING_ARRAY;
   8688                 } else {
   8689                     name = args[opti];
   8690                     opti++;
   8691                     newArgs = new String[args.length - opti];
   8692                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   8693                 }
   8694                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
   8695                     pw.println("No providers match: " + name);
   8696                     pw.println("Use -h for help.");
   8697                 }
   8698             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
   8699                 synchronized (this) {
   8700                     dumpProvidersLocked(fd, pw, args, opti, true, null);
   8701                 }
   8702             } else if ("service".equals(cmd)) {
   8703                 String[] newArgs;
   8704                 String name;
   8705                 if (opti >= args.length) {
   8706                     name = null;
   8707                     newArgs = EMPTY_STRING_ARRAY;
   8708                 } else {
   8709                     name = args[opti];
   8710                     opti++;
   8711                     newArgs = new String[args.length - opti];
   8712                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   8713                             args.length - opti);
   8714                 }
   8715                 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
   8716                     pw.println("No services match: " + name);
   8717                     pw.println("Use -h for help.");
   8718                 }
   8719             } else if ("package".equals(cmd)) {
   8720                 String[] newArgs;
   8721                 if (opti >= args.length) {
   8722                     pw.println("package: no package name specified");
   8723                     pw.println("Use -h for help.");
   8724                 } else {
   8725                     dumpPackage = args[opti];
   8726                     opti++;
   8727                     newArgs = new String[args.length - opti];
   8728                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   8729                             args.length - opti);
   8730                     args = newArgs;
   8731                     opti = 0;
   8732                     more = true;
   8733                 }
   8734             } else if ("services".equals(cmd) || "s".equals(cmd)) {
   8735                 synchronized (this) {
   8736                     dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
   8737                 }
   8738             } else {
   8739                 // Dumping a single activity?
   8740                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
   8741                     pw.println("Bad activity command, or no activities match: " + cmd);
   8742                     pw.println("Use -h for help.");
   8743                 }
   8744             }
   8745             if (!more) {
   8746                 Binder.restoreCallingIdentity(origId);
   8747                 return;
   8748             }
   8749         }
   8750 
   8751         // No piece of data specified, dump everything.
   8752         synchronized (this) {
   8753             boolean needSep;
   8754             needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   8755             if (needSep) {
   8756                 pw.println(" ");
   8757             }
   8758             if (dumpAll) {
   8759                 pw.println("-------------------------------------------------------------------------------");
   8760             }
   8761             needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   8762             if (needSep) {
   8763                 pw.println(" ");
   8764             }
   8765             if (dumpAll) {
   8766                 pw.println("-------------------------------------------------------------------------------");
   8767             }
   8768             needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   8769             if (needSep) {
   8770                 pw.println(" ");
   8771             }
   8772             if (dumpAll) {
   8773                 pw.println("-------------------------------------------------------------------------------");
   8774             }
   8775             needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   8776             if (needSep) {
   8777                 pw.println(" ");
   8778             }
   8779             if (dumpAll) {
   8780                 pw.println("-------------------------------------------------------------------------------");
   8781             }
   8782             needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   8783             if (needSep) {
   8784                 pw.println(" ");
   8785             }
   8786             if (dumpAll) {
   8787                 pw.println("-------------------------------------------------------------------------------");
   8788             }
   8789             dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   8790         }
   8791         Binder.restoreCallingIdentity(origId);
   8792     }
   8793 
   8794     boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   8795             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   8796         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
   8797         pw.println("  Main stack:");
   8798         dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
   8799                 dumpPackage);
   8800         pw.println(" ");
   8801         pw.println("  Running activities (most recent first):");
   8802         dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
   8803                 dumpPackage);
   8804         if (mMainStack.mWaitingVisibleActivities.size() > 0) {
   8805             pw.println(" ");
   8806             pw.println("  Activities waiting for another to become visible:");
   8807             dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
   8808                     !dumpAll, false, dumpPackage);
   8809         }
   8810         if (mMainStack.mStoppingActivities.size() > 0) {
   8811             pw.println(" ");
   8812             pw.println("  Activities waiting to stop:");
   8813             dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
   8814                     !dumpAll, false, dumpPackage);
   8815         }
   8816         if (mMainStack.mGoingToSleepActivities.size() > 0) {
   8817             pw.println(" ");
   8818             pw.println("  Activities waiting to sleep:");
   8819             dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
   8820                     !dumpAll, false, dumpPackage);
   8821         }
   8822         if (mMainStack.mFinishingActivities.size() > 0) {
   8823             pw.println(" ");
   8824             pw.println("  Activities waiting to finish:");
   8825             dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
   8826                     !dumpAll, false, dumpPackage);
   8827         }
   8828 
   8829         pw.println(" ");
   8830         if (mMainStack.mPausingActivity != null) {
   8831             pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
   8832         }
   8833         pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
   8834         pw.println("  mFocusedActivity: " + mFocusedActivity);
   8835         if (dumpAll) {
   8836             pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
   8837             pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
   8838             pw.println("  mDismissKeyguardOnNextActivity: "
   8839                     + mMainStack.mDismissKeyguardOnNextActivity);
   8840         }
   8841 
   8842         if (mRecentTasks.size() > 0) {
   8843             pw.println();
   8844             pw.println("  Recent tasks:");
   8845 
   8846             final int N = mRecentTasks.size();
   8847             for (int i=0; i<N; i++) {
   8848                 TaskRecord tr = mRecentTasks.get(i);
   8849                 if (dumpPackage != null) {
   8850                     if (tr.realActivity == null ||
   8851                             !dumpPackage.equals(tr.realActivity)) {
   8852                         continue;
   8853                     }
   8854                 }
   8855                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
   8856                         pw.println(tr);
   8857                 if (dumpAll) {
   8858                     mRecentTasks.get(i).dump(pw, "    ");
   8859                 }
   8860             }
   8861         }
   8862 
   8863         if (dumpAll) {
   8864             pw.println(" ");
   8865             pw.println("  mCurTask: " + mCurTask);
   8866         }
   8867 
   8868         return true;
   8869     }
   8870 
   8871     boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   8872             int opti, boolean dumpAll, String dumpPackage) {
   8873         boolean needSep = false;
   8874         int numPers = 0;
   8875 
   8876         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
   8877 
   8878         if (dumpAll) {
   8879             for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
   8880                 final int NA = procs.size();
   8881                 for (int ia=0; ia<NA; ia++) {
   8882                     ProcessRecord r = procs.valueAt(ia);
   8883                     if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   8884                         continue;
   8885                     }
   8886                     if (!needSep) {
   8887                         pw.println("  All known processes:");
   8888                         needSep = true;
   8889                     }
   8890                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
   8891                         pw.print(" UID "); pw.print(procs.keyAt(ia));
   8892                         pw.print(" "); pw.println(r);
   8893                     r.dump(pw, "    ");
   8894                     if (r.persistent) {
   8895                         numPers++;
   8896                     }
   8897                 }
   8898             }
   8899         }
   8900 
   8901         if (mIsolatedProcesses.size() > 0) {
   8902             if (needSep) pw.println(" ");
   8903             needSep = true;
   8904             pw.println("  Isolated process list (sorted by uid):");
   8905             for (int i=0; i<mIsolatedProcesses.size(); i++) {
   8906                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
   8907                 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   8908                     continue;
   8909                 }
   8910                 pw.println(String.format("%sIsolated #%2d: %s",
   8911                         "    ", i, r.toString()));
   8912             }
   8913         }
   8914 
   8915         if (mLruProcesses.size() > 0) {
   8916             if (needSep) pw.println(" ");
   8917             needSep = true;
   8918             pw.println("  Process LRU list (sorted by oom_adj):");
   8919             dumpProcessOomList(pw, this, mLruProcesses, "    ",
   8920                     "Proc", "PERS", false, dumpPackage);
   8921             needSep = true;
   8922         }
   8923 
   8924         if (dumpAll) {
   8925             synchronized (mPidsSelfLocked) {
   8926                 boolean printed = false;
   8927                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   8928                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
   8929                     if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   8930                         continue;
   8931                     }
   8932                     if (!printed) {
   8933                         if (needSep) pw.println(" ");
   8934                         needSep = true;
   8935                         pw.println("  PID mappings:");
   8936                         printed = true;
   8937                     }
   8938                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
   8939                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
   8940                 }
   8941             }
   8942         }
   8943 
   8944         if (mForegroundProcesses.size() > 0) {
   8945             synchronized (mPidsSelfLocked) {
   8946                 boolean printed = false;
   8947                 for (int i=0; i<mForegroundProcesses.size(); i++) {
   8948                     ProcessRecord r = mPidsSelfLocked.get(
   8949                             mForegroundProcesses.valueAt(i).pid);
   8950                     if (dumpPackage != null && (r == null
   8951                             || !dumpPackage.equals(r.info.packageName))) {
   8952                         continue;
   8953                     }
   8954                     if (!printed) {
   8955                         if (needSep) pw.println(" ");
   8956                         needSep = true;
   8957                         pw.println("  Foreground Processes:");
   8958                         printed = true;
   8959                     }
   8960                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
   8961                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
   8962                 }
   8963             }
   8964         }
   8965 
   8966         if (mPersistentStartingProcesses.size() > 0) {
   8967             if (needSep) pw.println(" ");
   8968             needSep = true;
   8969             pw.println("  Persisent processes that are starting:");
   8970             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
   8971                     "Starting Norm", "Restarting PERS", dumpPackage);
   8972         }
   8973 
   8974         if (mRemovedProcesses.size() > 0) {
   8975             if (needSep) pw.println(" ");
   8976             needSep = true;
   8977             pw.println("  Processes that are being removed:");
   8978             dumpProcessList(pw, this, mRemovedProcesses, "    ",
   8979                     "Removed Norm", "Removed PERS", dumpPackage);
   8980         }
   8981 
   8982         if (mProcessesOnHold.size() > 0) {
   8983             if (needSep) pw.println(" ");
   8984             needSep = true;
   8985             pw.println("  Processes that are on old until the system is ready:");
   8986             dumpProcessList(pw, this, mProcessesOnHold, "    ",
   8987                     "OnHold Norm", "OnHold PERS", dumpPackage);
   8988         }
   8989 
   8990         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
   8991 
   8992         if (mProcessCrashTimes.getMap().size() > 0) {
   8993             boolean printed = false;
   8994             long now = SystemClock.uptimeMillis();
   8995             for (Map.Entry<String, SparseArray<Long>> procs
   8996                     : mProcessCrashTimes.getMap().entrySet()) {
   8997                 String pname = procs.getKey();
   8998                 SparseArray<Long> uids = procs.getValue();
   8999                 final int N = uids.size();
   9000                 for (int i=0; i<N; i++) {
   9001                     int puid = uids.keyAt(i);
   9002                     ProcessRecord r = mProcessNames.get(pname, puid);
   9003                     if (dumpPackage != null && (r == null
   9004                             || !dumpPackage.equals(r.info.packageName))) {
   9005                         continue;
   9006                     }
   9007                     if (!printed) {
   9008                         if (needSep) pw.println(" ");
   9009                         needSep = true;
   9010                         pw.println("  Time since processes crashed:");
   9011                         printed = true;
   9012                     }
   9013                     pw.print("    Process "); pw.print(pname);
   9014                             pw.print(" uid "); pw.print(puid);
   9015                             pw.print(": last crashed ");
   9016                             TimeUtils.formatDuration(now-uids.valueAt(i), pw);
   9017                             pw.println(" ago");
   9018                 }
   9019             }
   9020         }
   9021 
   9022         if (mBadProcesses.getMap().size() > 0) {
   9023             boolean printed = false;
   9024             for (Map.Entry<String, SparseArray<Long>> procs
   9025                     : mBadProcesses.getMap().entrySet()) {
   9026                 String pname = procs.getKey();
   9027                 SparseArray<Long> uids = procs.getValue();
   9028                 final int N = uids.size();
   9029                 for (int i=0; i<N; i++) {
   9030                     int puid = uids.keyAt(i);
   9031                     ProcessRecord r = mProcessNames.get(pname, puid);
   9032                     if (dumpPackage != null && (r == null
   9033                             || !dumpPackage.equals(r.info.packageName))) {
   9034                         continue;
   9035                     }
   9036                     if (!printed) {
   9037                         if (needSep) pw.println(" ");
   9038                         needSep = true;
   9039                         pw.println("  Bad processes:");
   9040                     }
   9041                     pw.print("    Bad process "); pw.print(pname);
   9042                             pw.print(" uid "); pw.print(puid);
   9043                             pw.print(": crashed at time ");
   9044                             pw.println(uids.valueAt(i));
   9045                 }
   9046             }
   9047         }
   9048 
   9049         pw.println();
   9050         pw.println("  mHomeProcess: " + mHomeProcess);
   9051         pw.println("  mPreviousProcess: " + mPreviousProcess);
   9052         if (dumpAll) {
   9053             StringBuilder sb = new StringBuilder(128);
   9054             sb.append("  mPreviousProcessVisibleTime: ");
   9055             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
   9056             pw.println(sb);
   9057         }
   9058         if (mHeavyWeightProcess != null) {
   9059             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   9060         }
   9061         pw.println("  mConfiguration: " + mConfiguration);
   9062         if (dumpAll) {
   9063             pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
   9064             if (mCompatModePackages.getPackages().size() > 0) {
   9065                 boolean printed = false;
   9066                 for (Map.Entry<String, Integer> entry
   9067                         : mCompatModePackages.getPackages().entrySet()) {
   9068                     String pkg = entry.getKey();
   9069                     int mode = entry.getValue();
   9070                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
   9071                         continue;
   9072                     }
   9073                     if (!printed) {
   9074                         pw.println("  mScreenCompatPackages:");
   9075                         printed = true;
   9076                     }
   9077                     pw.print("    "); pw.print(pkg); pw.print(": ");
   9078                             pw.print(mode); pw.println();
   9079                 }
   9080             }
   9081         }
   9082         if (mSleeping || mWentToSleep || mLockScreenShown) {
   9083             pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
   9084                     + " mLockScreenShown " + mLockScreenShown);
   9085         }
   9086         if (mShuttingDown) {
   9087             pw.println("  mShuttingDown=" + mShuttingDown);
   9088         }
   9089         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
   9090                 || mOrigWaitForDebugger) {
   9091             pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
   9092                     + " mDebugTransient=" + mDebugTransient
   9093                     + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
   9094         }
   9095         if (mOpenGlTraceApp != null) {
   9096             pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
   9097         }
   9098         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
   9099                 || mProfileFd != null) {
   9100             pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
   9101             pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
   9102             pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
   9103                     + mAutoStopProfiler);
   9104         }
   9105         if (mAlwaysFinishActivities || mController != null) {
   9106             pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
   9107                     + " mController=" + mController);
   9108         }
   9109         if (dumpAll) {
   9110             pw.println("  Total persistent processes: " + numPers);
   9111             pw.println("  mStartRunning=" + mStartRunning
   9112                     + " mProcessesReady=" + mProcessesReady
   9113                     + " mSystemReady=" + mSystemReady);
   9114             pw.println("  mBooting=" + mBooting
   9115                     + " mBooted=" + mBooted
   9116                     + " mFactoryTest=" + mFactoryTest);
   9117             pw.print("  mLastPowerCheckRealtime=");
   9118                     TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
   9119                     pw.println("");
   9120             pw.print("  mLastPowerCheckUptime=");
   9121                     TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
   9122                     pw.println("");
   9123             pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
   9124             pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
   9125             pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
   9126             pw.println("  mNumServiceProcs=" + mNumServiceProcs
   9127                     + " mNewNumServiceProcs=" + mNewNumServiceProcs);
   9128         }
   9129 
   9130         return true;
   9131     }
   9132 
   9133     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
   9134             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
   9135         if (mProcessesToGc.size() > 0) {
   9136             boolean printed = false;
   9137             long now = SystemClock.uptimeMillis();
   9138             for (int i=0; i<mProcessesToGc.size(); i++) {
   9139                 ProcessRecord proc = mProcessesToGc.get(i);
   9140                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
   9141                     continue;
   9142                 }
   9143                 if (!printed) {
   9144                     if (needSep) pw.println(" ");
   9145                     needSep = true;
   9146                     pw.println("  Processes that are waiting to GC:");
   9147                     printed = true;
   9148                 }
   9149                 pw.print("    Process "); pw.println(proc);
   9150                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
   9151                         pw.print(", last gced=");
   9152                         pw.print(now-proc.lastRequestedGc);
   9153                         pw.print(" ms ago, last lowMem=");
   9154                         pw.print(now-proc.lastLowMemory);
   9155                         pw.println(" ms ago");
   9156 
   9157             }
   9158         }
   9159         return needSep;
   9160     }
   9161 
   9162     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   9163             int opti, boolean dumpAll) {
   9164         boolean needSep = false;
   9165 
   9166         if (mLruProcesses.size() > 0) {
   9167             if (needSep) pw.println(" ");
   9168             needSep = true;
   9169             pw.println("  OOM levels:");
   9170             pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
   9171             pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
   9172             pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
   9173             pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
   9174             pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
   9175             pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
   9176             pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
   9177             pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
   9178             pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
   9179             pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
   9180             pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
   9181             pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
   9182             pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
   9183 
   9184             if (needSep) pw.println(" ");
   9185             needSep = true;
   9186             pw.println("  Process OOM control:");
   9187             dumpProcessOomList(pw, this, mLruProcesses, "    ",
   9188                     "Proc", "PERS", true, null);
   9189             needSep = true;
   9190         }
   9191 
   9192         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
   9193 
   9194         pw.println();
   9195         pw.println("  mHomeProcess: " + mHomeProcess);
   9196         pw.println("  mPreviousProcess: " + mPreviousProcess);
   9197         if (mHeavyWeightProcess != null) {
   9198             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   9199         }
   9200 
   9201         return true;
   9202     }
   9203 
   9204     /**
   9205      * There are three ways to call this:
   9206      *  - no service specified: dump all the services
   9207      *  - a flattened component name that matched an existing service was specified as the
   9208      *    first arg: dump that one service
   9209      *  - the first arg isn't the flattened component name of an existing service:
   9210      *    dump all services whose component contains the first arg as a substring
   9211      */
   9212     protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   9213             int opti, boolean dumpAll) {
   9214         ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
   9215 
   9216         if ("all".equals(name)) {
   9217             synchronized (this) {
   9218                 try {
   9219                     List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
   9220                     for (UserInfo user : users) {
   9221                         for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) {
   9222                             services.add(r1);
   9223                         }
   9224                     }
   9225                 } catch (RemoteException re) {
   9226                 }
   9227             }
   9228         } else {
   9229             ComponentName componentName = name != null
   9230                     ? ComponentName.unflattenFromString(name) : null;
   9231             int objectId = 0;
   9232             if (componentName == null) {
   9233                 // Not a '/' separated full component name; maybe an object ID?
   9234                 try {
   9235                     objectId = Integer.parseInt(name, 16);
   9236                     name = null;
   9237                     componentName = null;
   9238                 } catch (RuntimeException e) {
   9239                 }
   9240             }
   9241 
   9242             synchronized (this) {
   9243                 try {
   9244                     List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
   9245                     for (UserInfo user : users) {
   9246                         for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) {
   9247                             if (componentName != null) {
   9248                                 if (r1.name.equals(componentName)) {
   9249                                     services.add(r1);
   9250                                 }
   9251                             } else if (name != null) {
   9252                                 if (r1.name.flattenToString().contains(name)) {
   9253                                     services.add(r1);
   9254                                 }
   9255                             } else if (System.identityHashCode(r1) == objectId) {
   9256                                 services.add(r1);
   9257                             }
   9258                         }
   9259                     }
   9260                 } catch (RemoteException re) {
   9261                 }
   9262             }
   9263         }
   9264 
   9265         if (services.size() <= 0) {
   9266             return false;
   9267         }
   9268 
   9269         boolean needSep = false;
   9270         for (int i=0; i<services.size(); i++) {
   9271             if (needSep) {
   9272                 pw.println();
   9273             }
   9274             needSep = true;
   9275             dumpService("", fd, pw, services.get(i), args, dumpAll);
   9276         }
   9277         return true;
   9278     }
   9279 
   9280     /**
   9281      * Invokes IApplicationThread.dumpService() on the thread of the specified service if
   9282      * there is a thread associated with the service.
   9283      */
   9284     private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
   9285             final ServiceRecord r, String[] args, boolean dumpAll) {
   9286         String innerPrefix = prefix + "  ";
   9287         synchronized (this) {
   9288             pw.print(prefix); pw.print("SERVICE ");
   9289                     pw.print(r.shortName); pw.print(" ");
   9290                     pw.print(Integer.toHexString(System.identityHashCode(r)));
   9291                     pw.print(" pid=");
   9292                     if (r.app != null) pw.println(r.app.pid);
   9293                     else pw.println("(not running)");
   9294             if (dumpAll) {
   9295                 r.dump(pw, innerPrefix);
   9296             }
   9297         }
   9298         if (r.app != null && r.app.thread != null) {
   9299             pw.print(prefix); pw.println("  Client:");
   9300             pw.flush();
   9301             try {
   9302                 TransferPipe tp = new TransferPipe();
   9303                 try {
   9304                     r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
   9305                     tp.setBufferPrefix(prefix + "    ");
   9306                     tp.go(fd);
   9307                 } finally {
   9308                     tp.kill();
   9309                 }
   9310             } catch (IOException e) {
   9311                 pw.println(prefix + "    Failure while dumping the service: " + e);
   9312             } catch (RemoteException e) {
   9313                 pw.println(prefix + "    Got a RemoteException while dumping the service");
   9314             }
   9315         }
   9316     }
   9317 
   9318     /**
   9319      * There are three ways to call this:
   9320      *  - no provider specified: dump all the providers
   9321      *  - a flattened component name that matched an existing provider was specified as the
   9322      *    first arg: dump that one provider
   9323      *  - the first arg isn't the flattened component name of an existing provider:
   9324      *    dump all providers whose component contains the first arg as a substring
   9325      */
   9326     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   9327             int opti, boolean dumpAll) {
   9328         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
   9329     }
   9330 
   9331     static class ItemMatcher {
   9332         ArrayList<ComponentName> components;
   9333         ArrayList<String> strings;
   9334         ArrayList<Integer> objects;
   9335         boolean all;
   9336 
   9337         ItemMatcher() {
   9338             all = true;
   9339         }
   9340 
   9341         void build(String name) {
   9342             ComponentName componentName = ComponentName.unflattenFromString(name);
   9343             if (componentName != null) {
   9344                 if (components == null) {
   9345                     components = new ArrayList<ComponentName>();
   9346                 }
   9347                 components.add(componentName);
   9348                 all = false;
   9349             } else {
   9350                 int objectId = 0;
   9351                 // Not a '/' separated full component name; maybe an object ID?
   9352                 try {
   9353                     objectId = Integer.parseInt(name, 16);
   9354                     if (objects == null) {
   9355                         objects = new ArrayList<Integer>();
   9356                     }
   9357                     objects.add(objectId);
   9358                     all = false;
   9359                 } catch (RuntimeException e) {
   9360                     // Not an integer; just do string match.
   9361                     if (strings == null) {
   9362                         strings = new ArrayList<String>();
   9363                     }
   9364                     strings.add(name);
   9365                     all = false;
   9366                 }
   9367             }
   9368         }
   9369 
   9370         int build(String[] args, int opti) {
   9371             for (; opti<args.length; opti++) {
   9372                 String name = args[opti];
   9373                 if ("--".equals(name)) {
   9374                     return opti+1;
   9375                 }
   9376                 build(name);
   9377             }
   9378             return opti;
   9379         }
   9380 
   9381         boolean match(Object object, ComponentName comp) {
   9382             if (all) {
   9383                 return true;
   9384             }
   9385             if (components != null) {
   9386                 for (int i=0; i<components.size(); i++) {
   9387                     if (components.get(i).equals(comp)) {
   9388                         return true;
   9389                     }
   9390                 }
   9391             }
   9392             if (objects != null) {
   9393                 for (int i=0; i<objects.size(); i++) {
   9394                     if (System.identityHashCode(object) == objects.get(i)) {
   9395                         return true;
   9396                     }
   9397                 }
   9398             }
   9399             if (strings != null) {
   9400                 String flat = comp.flattenToString();
   9401                 for (int i=0; i<strings.size(); i++) {
   9402                     if (flat.contains(strings.get(i))) {
   9403                         return true;
   9404                     }
   9405                 }
   9406             }
   9407             return false;
   9408         }
   9409     }
   9410 
   9411     /**
   9412      * There are three things that cmd can be:
   9413      *  - a flattened component name that matches an existing activity
   9414      *  - the cmd arg isn't the flattened component name of an existing activity:
   9415      *    dump all activity whose component contains the cmd as a substring
   9416      *  - A hex number of the ActivityRecord object instance.
   9417      */
   9418     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   9419             int opti, boolean dumpAll) {
   9420         ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
   9421 
   9422         if ("all".equals(name)) {
   9423             synchronized (this) {
   9424                 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
   9425                     activities.add(r1);
   9426                 }
   9427             }
   9428         } else if ("top".equals(name)) {
   9429             synchronized (this) {
   9430                 final int N = mMainStack.mHistory.size();
   9431                 if (N > 0) {
   9432                     activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
   9433                 }
   9434             }
   9435         } else {
   9436             ItemMatcher matcher = new ItemMatcher();
   9437             matcher.build(name);
   9438 
   9439             synchronized (this) {
   9440                 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
   9441                     if (matcher.match(r1, r1.intent.getComponent())) {
   9442                         activities.add(r1);
   9443                     }
   9444                 }
   9445             }
   9446         }
   9447 
   9448         if (activities.size() <= 0) {
   9449             return false;
   9450         }
   9451 
   9452         String[] newArgs = new String[args.length - opti];
   9453         if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   9454 
   9455         TaskRecord lastTask = null;
   9456         boolean needSep = false;
   9457         for (int i=activities.size()-1; i>=0; i--) {
   9458             ActivityRecord r = (ActivityRecord)activities.get(i);
   9459             if (needSep) {
   9460                 pw.println();
   9461             }
   9462             needSep = true;
   9463             synchronized (this) {
   9464                 if (lastTask != r.task) {
   9465                     lastTask = r.task;
   9466                     pw.print("TASK "); pw.print(lastTask.affinity);
   9467                             pw.print(" id="); pw.println(lastTask.taskId);
   9468                     if (dumpAll) {
   9469                         lastTask.dump(pw, "  ");
   9470                     }
   9471                 }
   9472             }
   9473             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
   9474         }
   9475         return true;
   9476     }
   9477 
   9478     /**
   9479      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
   9480      * there is a thread associated with the activity.
   9481      */
   9482     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
   9483             final ActivityRecord r, String[] args, boolean dumpAll) {
   9484         String innerPrefix = prefix + "  ";
   9485         synchronized (this) {
   9486             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
   9487                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
   9488                     pw.print(" pid=");
   9489                     if (r.app != null) pw.println(r.app.pid);
   9490                     else pw.println("(not running)");
   9491             if (dumpAll) {
   9492                 r.dump(pw, innerPrefix);
   9493             }
   9494         }
   9495         if (r.app != null && r.app.thread != null) {
   9496             // flush anything that is already in the PrintWriter since the thread is going
   9497             // to write to the file descriptor directly
   9498             pw.flush();
   9499             try {
   9500                 TransferPipe tp = new TransferPipe();
   9501                 try {
   9502                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
   9503                             r.appToken, innerPrefix, args);
   9504                     tp.go(fd);
   9505                 } finally {
   9506                     tp.kill();
   9507                 }
   9508             } catch (IOException e) {
   9509                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   9510             } catch (RemoteException e) {
   9511                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   9512             }
   9513         }
   9514     }
   9515 
   9516     boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   9517             int opti, boolean dumpAll, String dumpPackage) {
   9518         boolean needSep = false;
   9519 
   9520         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
   9521         if (dumpAll) {
   9522             if (mRegisteredReceivers.size() > 0) {
   9523                 boolean printed = false;
   9524                 Iterator it = mRegisteredReceivers.values().iterator();
   9525                 while (it.hasNext()) {
   9526                     ReceiverList r = (ReceiverList)it.next();
   9527                     if (dumpPackage != null && (r.app == null ||
   9528                             !dumpPackage.equals(r.app.info.packageName))) {
   9529                         continue;
   9530                     }
   9531                     if (!printed) {
   9532                         pw.println("  Registered Receivers:");
   9533                         needSep = true;
   9534                         printed = true;
   9535                     }
   9536                     pw.print("  * "); pw.println(r);
   9537                     r.dump(pw, "    ");
   9538                 }
   9539             }
   9540 
   9541             if (mReceiverResolver.dump(pw, needSep ?
   9542                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
   9543                     "    ", dumpPackage, false)) {
   9544                 needSep = true;
   9545             }
   9546         }
   9547 
   9548         for (BroadcastQueue q : mBroadcastQueues) {
   9549             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
   9550         }
   9551 
   9552         needSep = true;
   9553 
   9554         if (mStickyBroadcasts != null && dumpPackage == null) {
   9555             if (needSep) {
   9556                 pw.println();
   9557             }
   9558             needSep = true;
   9559             pw.println("  Sticky broadcasts:");
   9560             StringBuilder sb = new StringBuilder(128);
   9561             for (Map.Entry<String, ArrayList<Intent>> ent
   9562                     : mStickyBroadcasts.entrySet()) {
   9563                 pw.print("  * Sticky action "); pw.print(ent.getKey());
   9564                 if (dumpAll) {
   9565                     pw.println(":");
   9566                     ArrayList<Intent> intents = ent.getValue();
   9567                     final int N = intents.size();
   9568                     for (int i=0; i<N; i++) {
   9569                         sb.setLength(0);
   9570                         sb.append("    Intent: ");
   9571                         intents.get(i).toShortString(sb, false, true, false, false);
   9572                         pw.println(sb.toString());
   9573                         Bundle bundle = intents.get(i).getExtras();
   9574                         if (bundle != null) {
   9575                             pw.print("      ");
   9576                             pw.println(bundle.toString());
   9577                         }
   9578                     }
   9579                 } else {
   9580                     pw.println("");
   9581                 }
   9582             }
   9583             needSep = true;
   9584         }
   9585 
   9586         if (dumpAll) {
   9587             pw.println();
   9588             for (BroadcastQueue queue : mBroadcastQueues) {
   9589                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
   9590                         + queue.mBroadcastsScheduled);
   9591             }
   9592             pw.println("  mHandler:");
   9593             mHandler.dump(new PrintWriterPrinter(pw), "    ");
   9594             needSep = true;
   9595         }
   9596 
   9597         return needSep;
   9598     }
   9599 
   9600     /**
   9601      * Prints a list of ServiceRecords (dumpsys activity services)
   9602      */
   9603     boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   9604             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   9605         boolean needSep = false;
   9606 
   9607         ItemMatcher matcher = new ItemMatcher();
   9608         matcher.build(args, opti);
   9609 
   9610         pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
   9611         try {
   9612             List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
   9613             for (UserInfo user : users) {
   9614                 if (mServiceMap.getAllServices(user.id).size() > 0) {
   9615                     boolean printed = false;
   9616                     long nowReal = SystemClock.elapsedRealtime();
   9617                     Iterator<ServiceRecord> it = mServiceMap.getAllServices(
   9618                             user.id).iterator();
   9619                     needSep = false;
   9620                     while (it.hasNext()) {
   9621                         ServiceRecord r = it.next();
   9622                         if (!matcher.match(r, r.name)) {
   9623                             continue;
   9624                         }
   9625                         if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
   9626                             continue;
   9627                         }
   9628                         if (!printed) {
   9629                             pw.println("  Active services:");
   9630                             printed = true;
   9631                         }
   9632                         if (needSep) {
   9633                             pw.println();
   9634                         }
   9635                         pw.print("  * ");
   9636                         pw.println(r);
   9637                         if (dumpAll) {
   9638                             r.dump(pw, "    ");
   9639                             needSep = true;
   9640                         } else {
   9641                             pw.print("    app=");
   9642                             pw.println(r.app);
   9643                             pw.print("    created=");
   9644                             TimeUtils.formatDuration(r.createTime, nowReal, pw);
   9645                             pw.print(" started=");
   9646                             pw.print(r.startRequested);
   9647                             pw.print(" connections=");
   9648                             pw.println(r.connections.size());
   9649                             if (r.connections.size() > 0) {
   9650                                 pw.println("    Connections:");
   9651                                 for (ArrayList<ConnectionRecord> clist : r.connections.values()) {
   9652                                     for (int i = 0; i < clist.size(); i++) {
   9653                                         ConnectionRecord conn = clist.get(i);
   9654                                         pw.print("      ");
   9655                                         pw.print(conn.binding.intent.intent.getIntent()
   9656                                                 .toShortString(false, false, false, false));
   9657                                         pw.print(" -> ");
   9658                                         ProcessRecord proc = conn.binding.client;
   9659                                         pw.println(proc != null ? proc.toShortString() : "null");
   9660                                     }
   9661                                 }
   9662                             }
   9663                         }
   9664                         if (dumpClient && r.app != null && r.app.thread != null) {
   9665                             pw.println("    Client:");
   9666                             pw.flush();
   9667                             try {
   9668                                 TransferPipe tp = new TransferPipe();
   9669                                 try {
   9670                                     r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(),
   9671                                             r, args);
   9672                                     tp.setBufferPrefix("      ");
   9673                                     // Short timeout, since blocking here can
   9674                                     // deadlock with the application.
   9675                                     tp.go(fd, 2000);
   9676                                 } finally {
   9677                                     tp.kill();
   9678                                 }
   9679                             } catch (IOException e) {
   9680                                 pw.println("      Failure while dumping the service: " + e);
   9681                             } catch (RemoteException e) {
   9682                                 pw.println("      Got a RemoteException while dumping the service");
   9683                             }
   9684                             needSep = true;
   9685                         }
   9686                     }
   9687                     needSep = printed;
   9688                 }
   9689             }
   9690         } catch (RemoteException re) {
   9691 
   9692         }
   9693 
   9694         if (mPendingServices.size() > 0) {
   9695             boolean printed = false;
   9696             for (int i=0; i<mPendingServices.size(); i++) {
   9697                 ServiceRecord r = mPendingServices.get(i);
   9698                 if (!matcher.match(r, r.name)) {
   9699                     continue;
   9700                 }
   9701                 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
   9702                     continue;
   9703                 }
   9704                 if (!printed) {
   9705                     if (needSep) pw.println(" ");
   9706                     needSep = true;
   9707                     pw.println("  Pending services:");
   9708                     printed = true;
   9709                 }
   9710                 pw.print("  * Pending "); pw.println(r);
   9711                 r.dump(pw, "    ");
   9712             }
   9713             needSep = true;
   9714         }
   9715 
   9716         if (mRestartingServices.size() > 0) {
   9717             boolean printed = false;
   9718             for (int i=0; i<mRestartingServices.size(); i++) {
   9719                 ServiceRecord r = mRestartingServices.get(i);
   9720                 if (!matcher.match(r, r.name)) {
   9721                     continue;
   9722                 }
   9723                 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
   9724                     continue;
   9725                 }
   9726                 if (!printed) {
   9727                     if (needSep) pw.println(" ");
   9728                     needSep = true;
   9729                     pw.println("  Restarting services:");
   9730                     printed = true;
   9731                 }
   9732                 pw.print("  * Restarting "); pw.println(r);
   9733                 r.dump(pw, "    ");
   9734             }
   9735             needSep = true;
   9736         }
   9737 
   9738         if (mStoppingServices.size() > 0) {
   9739             boolean printed = false;
   9740             for (int i=0; i<mStoppingServices.size(); i++) {
   9741                 ServiceRecord r = mStoppingServices.get(i);
   9742                 if (!matcher.match(r, r.name)) {
   9743                     continue;
   9744                 }
   9745                 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
   9746                     continue;
   9747                 }
   9748                 if (!printed) {
   9749                     if (needSep) pw.println(" ");
   9750                     needSep = true;
   9751                     pw.println("  Stopping services:");
   9752                     printed = true;
   9753                 }
   9754                 pw.print("  * Stopping "); pw.println(r);
   9755                 r.dump(pw, "    ");
   9756             }
   9757             needSep = true;
   9758         }
   9759 
   9760         if (dumpAll) {
   9761             if (mServiceConnections.size() > 0) {
   9762                 boolean printed = false;
   9763                 Iterator<ArrayList<ConnectionRecord>> it
   9764                         = mServiceConnections.values().iterator();
   9765                 while (it.hasNext()) {
   9766                     ArrayList<ConnectionRecord> r = it.next();
   9767                     for (int i=0; i<r.size(); i++) {
   9768                         ConnectionRecord cr = r.get(i);
   9769                         if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
   9770                             continue;
   9771                         }
   9772                         if (dumpPackage != null && (cr.binding.client == null
   9773                                 || !dumpPackage.equals(cr.binding.client.info.packageName))) {
   9774                             continue;
   9775                         }
   9776                         if (!printed) {
   9777                             if (needSep) pw.println(" ");
   9778                             needSep = true;
   9779                             pw.println("  Connection bindings to services:");
   9780                             printed = true;
   9781                         }
   9782                         pw.print("  * "); pw.println(cr);
   9783                         cr.dump(pw, "    ");
   9784                     }
   9785                 }
   9786                 needSep = true;
   9787             }
   9788         }
   9789 
   9790         return needSep;
   9791     }
   9792 
   9793     boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   9794             int opti, boolean dumpAll, String dumpPackage) {
   9795         boolean needSep = true;
   9796 
   9797         ItemMatcher matcher = new ItemMatcher();
   9798         matcher.build(args, opti);
   9799 
   9800         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
   9801 
   9802         mProviderMap.dumpProvidersLocked(pw, dumpAll);
   9803 
   9804         if (mLaunchingProviders.size() > 0) {
   9805             boolean printed = false;
   9806             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
   9807                 ContentProviderRecord r = mLaunchingProviders.get(i);
   9808                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
   9809                     continue;
   9810                 }
   9811                 if (!printed) {
   9812                     if (needSep) pw.println(" ");
   9813                     needSep = true;
   9814                     pw.println("  Launching content providers:");
   9815                     printed = true;
   9816                 }
   9817                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
   9818                         pw.println(r);
   9819             }
   9820         }
   9821 
   9822         if (mGrantedUriPermissions.size() > 0) {
   9823             if (needSep) pw.println();
   9824             needSep = true;
   9825             pw.println("Granted Uri Permissions:");
   9826             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
   9827                 int uid = mGrantedUriPermissions.keyAt(i);
   9828                 HashMap<Uri, UriPermission> perms
   9829                         = mGrantedUriPermissions.valueAt(i);
   9830                 pw.print("  * UID "); pw.print(uid);
   9831                         pw.println(" holds:");
   9832                 for (UriPermission perm : perms.values()) {
   9833                     pw.print("    "); pw.println(perm);
   9834                     if (dumpAll) {
   9835                         perm.dump(pw, "      ");
   9836                     }
   9837                 }
   9838             }
   9839             needSep = true;
   9840         }
   9841 
   9842         return needSep;
   9843     }
   9844 
   9845     boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   9846             int opti, boolean dumpAll, String dumpPackage) {
   9847         boolean needSep = false;
   9848 
   9849         if (mIntentSenderRecords.size() > 0) {
   9850             boolean printed = false;
   9851             Iterator<WeakReference<PendingIntentRecord>> it
   9852                     = mIntentSenderRecords.values().iterator();
   9853             while (it.hasNext()) {
   9854                 WeakReference<PendingIntentRecord> ref = it.next();
   9855                 PendingIntentRecord rec = ref != null ? ref.get(): null;
   9856                 if (dumpPackage != null && (rec == null
   9857                         || !dumpPackage.equals(rec.key.packageName))) {
   9858                     continue;
   9859                 }
   9860                 if (!printed) {
   9861                     pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
   9862                     printed = true;
   9863                 }
   9864                 needSep = true;
   9865                 if (rec != null) {
   9866                     pw.print("  * "); pw.println(rec);
   9867                     if (dumpAll) {
   9868                         rec.dump(pw, "    ");
   9869                     }
   9870                 } else {
   9871                     pw.print("  * "); pw.println(ref);
   9872                 }
   9873             }
   9874         }
   9875 
   9876         return needSep;
   9877     }
   9878 
   9879     private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
   9880             String prefix, String label, boolean complete, boolean brief, boolean client,
   9881             String dumpPackage) {
   9882         TaskRecord lastTask = null;
   9883         boolean needNL = false;
   9884         final String innerPrefix = prefix + "      ";
   9885         final String[] args = new String[0];
   9886         for (int i=list.size()-1; i>=0; i--) {
   9887             final ActivityRecord r = (ActivityRecord)list.get(i);
   9888             if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
   9889                 continue;
   9890             }
   9891             final boolean full = !brief && (complete || !r.isInHistory());
   9892             if (needNL) {
   9893                 pw.println(" ");
   9894                 needNL = false;
   9895             }
   9896             if (lastTask != r.task) {
   9897                 lastTask = r.task;
   9898                 pw.print(prefix);
   9899                 pw.print(full ? "* " : "  ");
   9900                 pw.println(lastTask);
   9901                 if (full) {
   9902                     lastTask.dump(pw, prefix + "  ");
   9903                 } else if (complete) {
   9904                     // Complete + brief == give a summary.  Isn't that obvious?!?
   9905                     if (lastTask.intent != null) {
   9906                         pw.print(prefix); pw.print("  ");
   9907                                 pw.println(lastTask.intent.toInsecureStringWithClip());
   9908                     }
   9909                 }
   9910             }
   9911             pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
   9912             pw.print(" #"); pw.print(i); pw.print(": ");
   9913             pw.println(r);
   9914             if (full) {
   9915                 r.dump(pw, innerPrefix);
   9916             } else if (complete) {
   9917                 // Complete + brief == give a summary.  Isn't that obvious?!?
   9918                 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
   9919                 if (r.app != null) {
   9920                     pw.print(innerPrefix); pw.println(r.app);
   9921                 }
   9922             }
   9923             if (client && r.app != null && r.app.thread != null) {
   9924                 // flush anything that is already in the PrintWriter since the thread is going
   9925                 // to write to the file descriptor directly
   9926                 pw.flush();
   9927                 try {
   9928                     TransferPipe tp = new TransferPipe();
   9929                     try {
   9930                         r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
   9931                                 r.appToken, innerPrefix, args);
   9932                         // Short timeout, since blocking here can
   9933                         // deadlock with the application.
   9934                         tp.go(fd, 2000);
   9935                     } finally {
   9936                         tp.kill();
   9937                     }
   9938                 } catch (IOException e) {
   9939                     pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   9940                 } catch (RemoteException e) {
   9941                     pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   9942                 }
   9943                 needNL = true;
   9944             }
   9945         }
   9946     }
   9947 
   9948     private static String buildOomTag(String prefix, String space, int val, int base) {
   9949         if (val == base) {
   9950             if (space == null) return prefix;
   9951             return prefix + "  ";
   9952         }
   9953         return prefix + "+" + Integer.toString(val-base);
   9954     }
   9955 
   9956     private static final int dumpProcessList(PrintWriter pw,
   9957             ActivityManagerService service, List list,
   9958             String prefix, String normalLabel, String persistentLabel,
   9959             String dumpPackage) {
   9960         int numPers = 0;
   9961         final int N = list.size()-1;
   9962         for (int i=N; i>=0; i--) {
   9963             ProcessRecord r = (ProcessRecord)list.get(i);
   9964             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   9965                 continue;
   9966             }
   9967             pw.println(String.format("%s%s #%2d: %s",
   9968                     prefix, (r.persistent ? persistentLabel : normalLabel),
   9969                     i, r.toString()));
   9970             if (r.persistent) {
   9971                 numPers++;
   9972             }
   9973         }
   9974         return numPers;
   9975     }
   9976 
   9977     private static final boolean dumpProcessOomList(PrintWriter pw,
   9978             ActivityManagerService service, List<ProcessRecord> origList,
   9979             String prefix, String normalLabel, String persistentLabel,
   9980             boolean inclDetails, String dumpPackage) {
   9981 
   9982         ArrayList<Pair<ProcessRecord, Integer>> list
   9983                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
   9984         for (int i=0; i<origList.size(); i++) {
   9985             ProcessRecord r = origList.get(i);
   9986             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   9987                 continue;
   9988             }
   9989             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
   9990         }
   9991 
   9992         if (list.size() <= 0) {
   9993             return false;
   9994         }
   9995 
   9996         Comparator<Pair<ProcessRecord, Integer>> comparator
   9997                 = new Comparator<Pair<ProcessRecord, Integer>>() {
   9998             @Override
   9999             public int compare(Pair<ProcessRecord, Integer> object1,
   10000                     Pair<ProcessRecord, Integer> object2) {
   10001                 if (object1.first.setAdj != object2.first.setAdj) {
   10002                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
   10003                 }
   10004                 if (object1.second.intValue() != object2.second.intValue()) {
   10005                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
   10006                 }
   10007                 return 0;
   10008             }
   10009         };
   10010 
   10011         Collections.sort(list, comparator);
   10012 
   10013         final long curRealtime = SystemClock.elapsedRealtime();
   10014         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
   10015         final long curUptime = SystemClock.uptimeMillis();
   10016         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
   10017 
   10018         for (int i=list.size()-1; i>=0; i--) {
   10019             ProcessRecord r = list.get(i).first;
   10020             String oomAdj;
   10021             if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   10022                 oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
   10023             } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
   10024                 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
   10025             } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
   10026                 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
   10027             } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
   10028                 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
   10029             } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
   10030                 oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
   10031             } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
   10032                 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
   10033             } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   10034                 oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
   10035             } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   10036                 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
   10037             } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
   10038                 oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
   10039             } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
   10040                 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
   10041             } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
   10042                 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
   10043             } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
   10044                 oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
   10045             } else {
   10046                 oomAdj = Integer.toString(r.setAdj);
   10047             }
   10048             String schedGroup;
   10049             switch (r.setSchedGroup) {
   10050                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
   10051                     schedGroup = "B";
   10052                     break;
   10053                 case Process.THREAD_GROUP_DEFAULT:
   10054                     schedGroup = "F";
   10055                     break;
   10056                 default:
   10057                     schedGroup = Integer.toString(r.setSchedGroup);
   10058                     break;
   10059             }
   10060             String foreground;
   10061             if (r.foregroundActivities) {
   10062                 foreground = "A";
   10063             } else if (r.foregroundServices) {
   10064                 foreground = "S";
   10065             } else {
   10066                 foreground = " ";
   10067             }
   10068             pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
   10069                     prefix, (r.persistent ? persistentLabel : normalLabel),
   10070                     (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
   10071                     foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
   10072             if (r.adjSource != null || r.adjTarget != null) {
   10073                 pw.print(prefix);
   10074                 pw.print("    ");
   10075                 if (r.adjTarget instanceof ComponentName) {
   10076                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
   10077                 } else if (r.adjTarget != null) {
   10078                     pw.print(r.adjTarget.toString());
   10079                 } else {
   10080                     pw.print("{null}");
   10081                 }
   10082                 pw.print("<=");
   10083                 if (r.adjSource instanceof ProcessRecord) {
   10084                     pw.print("Proc{");
   10085                     pw.print(((ProcessRecord)r.adjSource).toShortString());
   10086                     pw.println("}");
   10087                 } else if (r.adjSource != null) {
   10088                     pw.println(r.adjSource.toString());
   10089                 } else {
   10090                     pw.println("{null}");
   10091                 }
   10092             }
   10093             if (inclDetails) {
   10094                 pw.print(prefix);
   10095                 pw.print("    ");
   10096                 pw.print("oom: max="); pw.print(r.maxAdj);
   10097                 pw.print(" hidden="); pw.print(r.hiddenAdj);
   10098                 pw.print(" curRaw="); pw.print(r.curRawAdj);
   10099                 pw.print(" setRaw="); pw.print(r.setRawAdj);
   10100                 pw.print(" cur="); pw.print(r.curAdj);
   10101                 pw.print(" set="); pw.println(r.setAdj);
   10102                 pw.print(prefix);
   10103                 pw.print("    ");
   10104                 pw.print("keeping="); pw.print(r.keeping);
   10105                 pw.print(" hidden="); pw.print(r.hidden);
   10106                 pw.print(" empty="); pw.print(r.empty);
   10107                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
   10108 
   10109                 if (!r.keeping) {
   10110                     if (r.lastWakeTime != 0) {
   10111                         long wtime;
   10112                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
   10113                         synchronized (stats) {
   10114                             wtime = stats.getProcessWakeTime(r.info.uid,
   10115                                     r.pid, curRealtime);
   10116                         }
   10117                         long timeUsed = wtime - r.lastWakeTime;
   10118                         pw.print(prefix);
   10119                         pw.print("    ");
   10120                         pw.print("keep awake over ");
   10121                         TimeUtils.formatDuration(realtimeSince, pw);
   10122                         pw.print(" used ");
   10123                         TimeUtils.formatDuration(timeUsed, pw);
   10124                         pw.print(" (");
   10125                         pw.print((timeUsed*100)/realtimeSince);
   10126                         pw.println("%)");
   10127                     }
   10128                     if (r.lastCpuTime != 0) {
   10129                         long timeUsed = r.curCpuTime - r.lastCpuTime;
   10130                         pw.print(prefix);
   10131                         pw.print("    ");
   10132                         pw.print("run cpu over ");
   10133                         TimeUtils.formatDuration(uptimeSince, pw);
   10134                         pw.print(" used ");
   10135                         TimeUtils.formatDuration(timeUsed, pw);
   10136                         pw.print(" (");
   10137                         pw.print((timeUsed*100)/uptimeSince);
   10138                         pw.println("%)");
   10139                     }
   10140                 }
   10141             }
   10142         }
   10143         return true;
   10144     }
   10145 
   10146     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
   10147         ArrayList<ProcessRecord> procs;
   10148         synchronized (this) {
   10149             if (args != null && args.length > start
   10150                     && args[start].charAt(0) != '-') {
   10151                 procs = new ArrayList<ProcessRecord>();
   10152                 int pid = -1;
   10153                 try {
   10154                     pid = Integer.parseInt(args[start]);
   10155                 } catch (NumberFormatException e) {
   10156 
   10157                 }
   10158                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   10159                     ProcessRecord proc = mLruProcesses.get(i);
   10160                     if (proc.pid == pid) {
   10161                         procs.add(proc);
   10162                     } else if (proc.processName.equals(args[start])) {
   10163                         procs.add(proc);
   10164                     }
   10165                 }
   10166                 if (procs.size() <= 0) {
   10167                     pw.println("No process found for: " + args[start]);
   10168                     return null;
   10169                 }
   10170             } else {
   10171                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
   10172             }
   10173         }
   10174         return procs;
   10175     }
   10176 
   10177     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
   10178             PrintWriter pw, String[] args) {
   10179         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
   10180         if (procs == null) {
   10181             return;
   10182         }
   10183 
   10184         long uptime = SystemClock.uptimeMillis();
   10185         long realtime = SystemClock.elapsedRealtime();
   10186         pw.println("Applications Graphics Acceleration Info:");
   10187         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   10188 
   10189         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   10190             ProcessRecord r = procs.get(i);
   10191             if (r.thread != null) {
   10192                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
   10193                 pw.flush();
   10194                 try {
   10195                     TransferPipe tp = new TransferPipe();
   10196                     try {
   10197                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
   10198                         tp.go(fd);
   10199                     } finally {
   10200                         tp.kill();
   10201                     }
   10202                 } catch (IOException e) {
   10203                     pw.println("Failure while dumping the app: " + r);
   10204                     pw.flush();
   10205                 } catch (RemoteException e) {
   10206                     pw.println("Got a RemoteException while dumping the app " + r);
   10207                     pw.flush();
   10208                 }
   10209             }
   10210         }
   10211     }
   10212 
   10213     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
   10214         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
   10215         if (procs == null) {
   10216             return;
   10217         }
   10218 
   10219         pw.println("Applications Database Info:");
   10220 
   10221         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   10222             ProcessRecord r = procs.get(i);
   10223             if (r.thread != null) {
   10224                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
   10225                 pw.flush();
   10226                 try {
   10227                     TransferPipe tp = new TransferPipe();
   10228                     try {
   10229                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
   10230                         tp.go(fd);
   10231                     } finally {
   10232                         tp.kill();
   10233                     }
   10234                 } catch (IOException e) {
   10235                     pw.println("Failure while dumping the app: " + r);
   10236                     pw.flush();
   10237                 } catch (RemoteException e) {
   10238                     pw.println("Got a RemoteException while dumping the app " + r);
   10239                     pw.flush();
   10240                 }
   10241             }
   10242         }
   10243     }
   10244 
   10245     final static class MemItem {
   10246         final String label;
   10247         final String shortLabel;
   10248         final long pss;
   10249         final int id;
   10250         ArrayList<MemItem> subitems;
   10251 
   10252         public MemItem(String _label, String _shortLabel, long _pss, int _id) {
   10253             label = _label;
   10254             shortLabel = _shortLabel;
   10255             pss = _pss;
   10256             id = _id;
   10257         }
   10258     }
   10259 
   10260     static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
   10261             boolean sort) {
   10262         if (sort) {
   10263             Collections.sort(items, new Comparator<MemItem>() {
   10264                 @Override
   10265                 public int compare(MemItem lhs, MemItem rhs) {
   10266                     if (lhs.pss < rhs.pss) {
   10267                         return 1;
   10268                     } else if (lhs.pss > rhs.pss) {
   10269                         return -1;
   10270                     }
   10271                     return 0;
   10272                 }
   10273             });
   10274         }
   10275 
   10276         for (int i=0; i<items.size(); i++) {
   10277             MemItem mi = items.get(i);
   10278             pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
   10279             if (mi.subitems != null) {
   10280                 dumpMemItems(pw, prefix + "           ", mi.subitems, true);
   10281             }
   10282         }
   10283     }
   10284 
   10285     // These are in KB.
   10286     static final long[] DUMP_MEM_BUCKETS = new long[] {
   10287         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
   10288         120*1024, 160*1024, 200*1024,
   10289         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
   10290         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
   10291     };
   10292 
   10293     static final void appendMemBucket(StringBuilder out, long memKB, String label,
   10294             boolean stackLike) {
   10295         int start = label.lastIndexOf('.');
   10296         if (start >= 0) start++;
   10297         else start = 0;
   10298         int end = label.length();
   10299         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
   10300             if (DUMP_MEM_BUCKETS[i] >= memKB) {
   10301                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
   10302                 out.append(bucket);
   10303                 out.append(stackLike ? "MB." : "MB ");
   10304                 out.append(label, start, end);
   10305                 return;
   10306             }
   10307         }
   10308         out.append(memKB/1024);
   10309         out.append(stackLike ? "MB." : "MB ");
   10310         out.append(label, start, end);
   10311     }
   10312 
   10313     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
   10314             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
   10315             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
   10316             ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
   10317             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
   10318     };
   10319     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
   10320             "System", "Persistent", "Foreground",
   10321             "Visible", "Perceptible", "Heavy Weight",
   10322             "Backup", "A Services", "Home", "Previous",
   10323             "B Services", "Background"
   10324     };
   10325 
   10326     final void dumpApplicationMemoryUsage(FileDescriptor fd,
   10327             PrintWriter pw, String prefix, String[] args, boolean brief,
   10328             PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
   10329         boolean dumpAll = false;
   10330         boolean oomOnly = false;
   10331 
   10332         int opti = 0;
   10333         while (opti < args.length) {
   10334             String opt = args[opti];
   10335             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   10336                 break;
   10337             }
   10338             opti++;
   10339             if ("-a".equals(opt)) {
   10340                 dumpAll = true;
   10341             } else if ("--oom".equals(opt)) {
   10342                 oomOnly = true;
   10343             } else if ("-h".equals(opt)) {
   10344                 pw.println("meminfo dump options: [-a] [--oom] [process]");
   10345                 pw.println("  -a: include all available information for each process.");
   10346                 pw.println("  --oom: only show processes organized by oom adj.");
   10347                 pw.println("If [process] is specified it can be the name or ");
   10348                 pw.println("pid of a specific process to dump.");
   10349                 return;
   10350             } else {
   10351                 pw.println("Unknown argument: " + opt + "; use -h for help");
   10352             }
   10353         }
   10354 
   10355         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
   10356         if (procs == null) {
   10357             return;
   10358         }
   10359 
   10360         final boolean isCheckinRequest = scanArgs(args, "--checkin");
   10361         long uptime = SystemClock.uptimeMillis();
   10362         long realtime = SystemClock.elapsedRealtime();
   10363 
   10364         if (procs.size() == 1 || isCheckinRequest) {
   10365             dumpAll = true;
   10366         }
   10367 
   10368         if (isCheckinRequest) {
   10369             // short checkin version
   10370             pw.println(uptime + "," + realtime);
   10371             pw.flush();
   10372         } else {
   10373             pw.println("Applications Memory Usage (kB):");
   10374             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   10375         }
   10376 
   10377         String[] innerArgs = new String[args.length-opti];
   10378         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
   10379 
   10380         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
   10381         long nativePss=0, dalvikPss=0, otherPss=0;
   10382         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
   10383 
   10384         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
   10385         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
   10386                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
   10387 
   10388         long totalPss = 0;
   10389 
   10390         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   10391             ProcessRecord r = procs.get(i);
   10392             if (r.thread != null) {
   10393                 if (!isCheckinRequest && dumpAll) {
   10394                     pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
   10395                     pw.flush();
   10396                 }
   10397                 Debug.MemoryInfo mi = null;
   10398                 if (dumpAll) {
   10399                     try {
   10400                         mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
   10401                     } catch (RemoteException e) {
   10402                         if (!isCheckinRequest) {
   10403                             pw.println("Got RemoteException!");
   10404                             pw.flush();
   10405                         }
   10406                     }
   10407                 } else {
   10408                     mi = new Debug.MemoryInfo();
   10409                     Debug.getMemoryInfo(r.pid, mi);
   10410                 }
   10411 
   10412                 if (!isCheckinRequest && mi != null) {
   10413                     long myTotalPss = mi.getTotalPss();
   10414                     totalPss += myTotalPss;
   10415                     MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
   10416                             r.processName, myTotalPss, 0);
   10417                     procMems.add(pssItem);
   10418 
   10419                     nativePss += mi.nativePss;
   10420                     dalvikPss += mi.dalvikPss;
   10421                     otherPss += mi.otherPss;
   10422                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   10423                         long mem = mi.getOtherPss(j);
   10424                         miscPss[j] += mem;
   10425                         otherPss -= mem;
   10426                     }
   10427 
   10428                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
   10429                         if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
   10430                                 || oomIndex == (oomPss.length-1)) {
   10431                             oomPss[oomIndex] += myTotalPss;
   10432                             if (oomProcs[oomIndex] == null) {
   10433                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
   10434                             }
   10435                             oomProcs[oomIndex].add(pssItem);
   10436                             break;
   10437                         }
   10438                     }
   10439                 }
   10440             }
   10441         }
   10442 
   10443         if (!isCheckinRequest && procs.size() > 1) {
   10444             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
   10445 
   10446             catMems.add(new MemItem("Native", "Native", nativePss, -1));
   10447             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
   10448             catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
   10449             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   10450                 String label = Debug.MemoryInfo.getOtherLabel(j);
   10451                 catMems.add(new MemItem(label, label, miscPss[j], j));
   10452             }
   10453 
   10454             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
   10455             for (int j=0; j<oomPss.length; j++) {
   10456                 if (oomPss[j] != 0) {
   10457                     String label = DUMP_MEM_OOM_LABEL[j];
   10458                     MemItem item = new MemItem(label, label, oomPss[j],
   10459                             DUMP_MEM_OOM_ADJ[j]);
   10460                     item.subitems = oomProcs[j];
   10461                     oomMems.add(item);
   10462                 }
   10463             }
   10464 
   10465             if (outTag != null || outStack != null) {
   10466                 if (outTag != null) {
   10467                     appendMemBucket(outTag, totalPss, "total", false);
   10468                 }
   10469                 if (outStack != null) {
   10470                     appendMemBucket(outStack, totalPss, "total", true);
   10471                 }
   10472                 boolean firstLine = true;
   10473                 for (int i=0; i<oomMems.size(); i++) {
   10474                     MemItem miCat = oomMems.get(i);
   10475                     if (miCat.subitems == null || miCat.subitems.size() < 1) {
   10476                         continue;
   10477                     }
   10478                     if (miCat.id < ProcessList.SERVICE_ADJ
   10479                             || miCat.id == ProcessList.HOME_APP_ADJ
   10480                             || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
   10481                         if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
   10482                             outTag.append(" / ");
   10483                         }
   10484                         if (outStack != null) {
   10485                             if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
   10486                                 if (firstLine) {
   10487                                     outStack.append(":");
   10488                                     firstLine = false;
   10489                                 }
   10490                                 outStack.append("\n\t at ");
   10491                             } else {
   10492                                 outStack.append("$");
   10493                             }
   10494                         }
   10495                         for (int j=0; j<miCat.subitems.size(); j++) {
   10496                             MemItem mi = miCat.subitems.get(j);
   10497                             if (j > 0) {
   10498                                 if (outTag != null) {
   10499                                     outTag.append(" ");
   10500                                 }
   10501                                 if (outStack != null) {
   10502                                     outStack.append("$");
   10503                                 }
   10504                             }
   10505                             if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
   10506                                 appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
   10507                             }
   10508                             if (outStack != null) {
   10509                                 appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
   10510                             }
   10511                         }
   10512                         if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
   10513                             outStack.append("(");
   10514                             for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
   10515                                 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
   10516                                     outStack.append(DUMP_MEM_OOM_LABEL[k]);
   10517                                     outStack.append(":");
   10518                                     outStack.append(DUMP_MEM_OOM_ADJ[k]);
   10519                                 }
   10520                             }
   10521                             outStack.append(")");
   10522                         }
   10523                     }
   10524                 }
   10525             }
   10526 
   10527             if (!brief && !oomOnly) {
   10528                 pw.println();
   10529                 pw.println("Total PSS by process:");
   10530                 dumpMemItems(pw, "  ", procMems, true);
   10531                 pw.println();
   10532             }
   10533             pw.println("Total PSS by OOM adjustment:");
   10534             dumpMemItems(pw, "  ", oomMems, false);
   10535             if (!oomOnly) {
   10536                 PrintWriter out = categoryPw != null ? categoryPw : pw;
   10537                 out.println();
   10538                 out.println("Total PSS by category:");
   10539                 dumpMemItems(out, "  ", catMems, true);
   10540             }
   10541             pw.println();
   10542             pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
   10543             final int[] SINGLE_LONG_FORMAT = new int[] {
   10544                 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
   10545             };
   10546             long[] longOut = new long[1];
   10547             Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
   10548                     SINGLE_LONG_FORMAT, null, longOut, null);
   10549             long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   10550             longOut[0] = 0;
   10551             Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
   10552                     SINGLE_LONG_FORMAT, null, longOut, null);
   10553             long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   10554             longOut[0] = 0;
   10555             Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
   10556                     SINGLE_LONG_FORMAT, null, longOut, null);
   10557             long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   10558             longOut[0] = 0;
   10559             Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
   10560                     SINGLE_LONG_FORMAT, null, longOut, null);
   10561             long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   10562             pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
   10563                     pw.print(shared); pw.println(" kB");
   10564             pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
   10565                     pw.print(voltile); pw.println(" kB volatile");
   10566         }
   10567     }
   10568 
   10569     /**
   10570      * Searches array of arguments for the specified string
   10571      * @param args array of argument strings
   10572      * @param value value to search for
   10573      * @return true if the value is contained in the array
   10574      */
   10575     private static boolean scanArgs(String[] args, String value) {
   10576         if (args != null) {
   10577             for (String arg : args) {
   10578                 if (value.equals(arg)) {
   10579                     return true;
   10580                 }
   10581             }
   10582         }
   10583         return false;
   10584     }
   10585 
   10586     private final void killServicesLocked(ProcessRecord app,
   10587             boolean allowRestart) {
   10588         // Report disconnected services.
   10589         if (false) {
   10590             // XXX we are letting the client link to the service for
   10591             // death notifications.
   10592             if (app.services.size() > 0) {
   10593                 Iterator<ServiceRecord> it = app.services.iterator();
   10594                 while (it.hasNext()) {
   10595                     ServiceRecord r = it.next();
   10596                     if (r.connections.size() > 0) {
   10597                         Iterator<ArrayList<ConnectionRecord>> jt
   10598                                 = r.connections.values().iterator();
   10599                         while (jt.hasNext()) {
   10600                             ArrayList<ConnectionRecord> cl = jt.next();
   10601                             for (int i=0; i<cl.size(); i++) {
   10602                                 ConnectionRecord c = cl.get(i);
   10603                                 if (c.binding.client != app) {
   10604                                     try {
   10605                                         //c.conn.connected(r.className, null);
   10606                                     } catch (Exception e) {
   10607                                         // todo: this should be asynchronous!
   10608                                         Slog.w(TAG, "Exception thrown disconnected servce "
   10609                                               + r.shortName
   10610                                               + " from app " + app.processName, e);
   10611                                     }
   10612                                 }
   10613                             }
   10614                         }
   10615                     }
   10616                 }
   10617             }
   10618         }
   10619 
   10620         // Clean up any connections this application has to other services.
   10621         if (app.connections.size() > 0) {
   10622             Iterator<ConnectionRecord> it = app.connections.iterator();
   10623             while (it.hasNext()) {
   10624                 ConnectionRecord r = it.next();
   10625                 removeConnectionLocked(r, app, null);
   10626             }
   10627         }
   10628         app.connections.clear();
   10629 
   10630         if (app.services.size() != 0) {
   10631             // Any services running in the application need to be placed
   10632             // back in the pending list.
   10633             Iterator<ServiceRecord> it = app.services.iterator();
   10634             while (it.hasNext()) {
   10635                 ServiceRecord sr = it.next();
   10636                 synchronized (sr.stats.getBatteryStats()) {
   10637                     sr.stats.stopLaunchedLocked();
   10638                 }
   10639                 sr.app = null;
   10640                 sr.isolatedProc = null;
   10641                 sr.executeNesting = 0;
   10642                 if (mStoppingServices.remove(sr)) {
   10643                     if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
   10644                 }
   10645 
   10646                 boolean hasClients = sr.bindings.size() > 0;
   10647                 if (hasClients) {
   10648                     Iterator<IntentBindRecord> bindings
   10649                             = sr.bindings.values().iterator();
   10650                     while (bindings.hasNext()) {
   10651                         IntentBindRecord b = bindings.next();
   10652                         if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
   10653                                 + ": shouldUnbind=" + b.hasBound);
   10654                         b.binder = null;
   10655                         b.requested = b.received = b.hasBound = false;
   10656                     }
   10657                 }
   10658 
   10659                 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
   10660                         &ApplicationInfo.FLAG_PERSISTENT) == 0) {
   10661                     Slog.w(TAG, "Service crashed " + sr.crashCount
   10662                             + " times, stopping: " + sr);
   10663                     EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
   10664                             sr.crashCount, sr.shortName, app.pid);
   10665                     bringDownServiceLocked(sr, true);
   10666                 } else if (!allowRestart) {
   10667                     bringDownServiceLocked(sr, true);
   10668                 } else {
   10669                     boolean canceled = scheduleServiceRestartLocked(sr, true);
   10670 
   10671                     // Should the service remain running?  Note that in the
   10672                     // extreme case of so many attempts to deliver a command
   10673                     // that it failed we also will stop it here.
   10674                     if (sr.startRequested && (sr.stopIfKilled || canceled)) {
   10675                         if (sr.pendingStarts.size() == 0) {
   10676                             sr.startRequested = false;
   10677                             if (!hasClients) {
   10678                                 // Whoops, no reason to restart!
   10679                                 bringDownServiceLocked(sr, true);
   10680                             }
   10681                         }
   10682                     }
   10683                 }
   10684             }
   10685 
   10686             if (!allowRestart) {
   10687                 app.services.clear();
   10688             }
   10689         }
   10690 
   10691         // Make sure we have no more records on the stopping list.
   10692         int i = mStoppingServices.size();
   10693         while (i > 0) {
   10694             i--;
   10695             ServiceRecord sr = mStoppingServices.get(i);
   10696             if (sr.app == app) {
   10697                 mStoppingServices.remove(i);
   10698                 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
   10699             }
   10700         }
   10701 
   10702         app.executingServices.clear();
   10703     }
   10704 
   10705     private final boolean removeDyingProviderLocked(ProcessRecord proc,
   10706             ContentProviderRecord cpr, boolean always) {
   10707         final boolean inLaunching = mLaunchingProviders.contains(cpr);
   10708 
   10709         if (!inLaunching || always) {
   10710             synchronized (cpr) {
   10711                 cpr.launchingApp = null;
   10712                 cpr.notifyAll();
   10713             }
   10714             mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid));
   10715             String names[] = cpr.info.authority.split(";");
   10716             for (int j = 0; j < names.length; j++) {
   10717                 mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid));
   10718             }
   10719         }
   10720 
   10721         for (int i=0; i<cpr.connections.size(); i++) {
   10722             ContentProviderConnection conn = cpr.connections.get(i);
   10723             if (conn.waiting) {
   10724                 // If this connection is waiting for the provider, then we don't
   10725                 // need to mess with its process unless we are always removing
   10726                 // or for some reason the provider is not currently launching.
   10727                 if (inLaunching && !always) {
   10728                     continue;
   10729                 }
   10730             }
   10731             ProcessRecord capp = conn.client;
   10732             conn.dead = true;
   10733             if (conn.stableCount > 0) {
   10734                 if (!capp.persistent && capp.thread != null
   10735                         && capp.pid != 0
   10736                         && capp.pid != MY_PID) {
   10737                     Slog.i(TAG, "Kill " + capp.processName
   10738                             + " (pid " + capp.pid + "): provider " + cpr.info.name
   10739                             + " in dying process " + (proc != null ? proc.processName : "??"));
   10740                     EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
   10741                             capp.processName, capp.setAdj, "dying provider "
   10742                                     + cpr.name.toShortString());
   10743                     Process.killProcessQuiet(capp.pid);
   10744                 }
   10745             } else if (capp.thread != null && conn.provider.provider != null) {
   10746                 try {
   10747                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
   10748                 } catch (RemoteException e) {
   10749                 }
   10750                 // In the protocol here, we don't expect the client to correctly
   10751                 // clean up this connection, we'll just remove it.
   10752                 cpr.connections.remove(i);
   10753                 conn.client.conProviders.remove(conn);
   10754             }
   10755         }
   10756 
   10757         if (inLaunching && always) {
   10758             mLaunchingProviders.remove(cpr);
   10759         }
   10760         return inLaunching;
   10761     }
   10762 
   10763     /**
   10764      * Main code for cleaning up a process when it has gone away.  This is
   10765      * called both as a result of the process dying, or directly when stopping
   10766      * a process when running in single process mode.
   10767      */
   10768     private final void cleanUpApplicationRecordLocked(ProcessRecord app,
   10769             boolean restarting, boolean allowRestart, int index) {
   10770         if (index >= 0) {
   10771             mLruProcesses.remove(index);
   10772         }
   10773 
   10774         mProcessesToGc.remove(app);
   10775 
   10776         // Dismiss any open dialogs.
   10777         if (app.crashDialog != null) {
   10778             app.crashDialog.dismiss();
   10779             app.crashDialog = null;
   10780         }
   10781         if (app.anrDialog != null) {
   10782             app.anrDialog.dismiss();
   10783             app.anrDialog = null;
   10784         }
   10785         if (app.waitDialog != null) {
   10786             app.waitDialog.dismiss();
   10787             app.waitDialog = null;
   10788         }
   10789 
   10790         app.crashing = false;
   10791         app.notResponding = false;
   10792 
   10793         app.resetPackageList();
   10794         app.unlinkDeathRecipient();
   10795         app.thread = null;
   10796         app.forcingToForeground = null;
   10797         app.foregroundServices = false;
   10798         app.foregroundActivities = false;
   10799         app.hasShownUi = false;
   10800         app.hasAboveClient = false;
   10801 
   10802         killServicesLocked(app, allowRestart);
   10803 
   10804         boolean restart = false;
   10805 
   10806         // Remove published content providers.
   10807         if (!app.pubProviders.isEmpty()) {
   10808             Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
   10809             while (it.hasNext()) {
   10810                 ContentProviderRecord cpr = it.next();
   10811 
   10812                 final boolean always = app.bad || !allowRestart;
   10813                 if (removeDyingProviderLocked(app, cpr, always) || always) {
   10814                     // We left the provider in the launching list, need to
   10815                     // restart it.
   10816                     restart = true;
   10817                 }
   10818 
   10819                 cpr.provider = null;
   10820                 cpr.proc = null;
   10821             }
   10822             app.pubProviders.clear();
   10823         }
   10824 
   10825         // Take care of any launching providers waiting for this process.
   10826         if (checkAppInLaunchingProvidersLocked(app, false)) {
   10827             restart = true;
   10828         }
   10829 
   10830         // Unregister from connected content providers.
   10831         if (!app.conProviders.isEmpty()) {
   10832             for (int i=0; i<app.conProviders.size(); i++) {
   10833                 ContentProviderConnection conn = app.conProviders.get(i);
   10834                 conn.provider.connections.remove(conn);
   10835             }
   10836             app.conProviders.clear();
   10837         }
   10838 
   10839         // At this point there may be remaining entries in mLaunchingProviders
   10840         // where we were the only one waiting, so they are no longer of use.
   10841         // Look for these and clean up if found.
   10842         // XXX Commented out for now.  Trying to figure out a way to reproduce
   10843         // the actual situation to identify what is actually going on.
   10844         if (false) {
   10845             for (int i=0; i<mLaunchingProviders.size(); i++) {
   10846                 ContentProviderRecord cpr = (ContentProviderRecord)
   10847                         mLaunchingProviders.get(i);
   10848                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
   10849                     synchronized (cpr) {
   10850                         cpr.launchingApp = null;
   10851                         cpr.notifyAll();
   10852                     }
   10853                 }
   10854             }
   10855         }
   10856 
   10857         skipCurrentReceiverLocked(app);
   10858 
   10859         // Unregister any receivers.
   10860         if (app.receivers.size() > 0) {
   10861             Iterator<ReceiverList> it = app.receivers.iterator();
   10862             while (it.hasNext()) {
   10863                 removeReceiverLocked(it.next());
   10864             }
   10865             app.receivers.clear();
   10866         }
   10867 
   10868         // If the app is undergoing backup, tell the backup manager about it
   10869         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
   10870             if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
   10871             try {
   10872                 IBackupManager bm = IBackupManager.Stub.asInterface(
   10873                         ServiceManager.getService(Context.BACKUP_SERVICE));
   10874                 bm.agentDisconnected(app.info.packageName);
   10875             } catch (RemoteException e) {
   10876                 // can't happen; backup manager is local
   10877             }
   10878         }
   10879 
   10880         for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
   10881             ProcessChangeItem item = mPendingProcessChanges.get(i);
   10882             if (item.pid == app.pid) {
   10883                 mPendingProcessChanges.remove(i);
   10884                 mAvailProcessChanges.add(item);
   10885             }
   10886         }
   10887         mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
   10888 
   10889         // If the caller is restarting this app, then leave it in its
   10890         // current lists and let the caller take care of it.
   10891         if (restarting) {
   10892             return;
   10893         }
   10894 
   10895         if (!app.persistent || app.isolated) {
   10896             if (DEBUG_PROCESSES) Slog.v(TAG,
   10897                     "Removing non-persistent process during cleanup: " + app);
   10898             mProcessNames.remove(app.processName, app.uid);
   10899             mIsolatedProcesses.remove(app.uid);
   10900             if (mHeavyWeightProcess == app) {
   10901                 mHeavyWeightProcess = null;
   10902                 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
   10903             }
   10904         } else if (!app.removed) {
   10905             // This app is persistent, so we need to keep its record around.
   10906             // If it is not already on the pending app list, add it there
   10907             // and start a new process for it.
   10908             if (mPersistentStartingProcesses.indexOf(app) < 0) {
   10909                 mPersistentStartingProcesses.add(app);
   10910                 restart = true;
   10911             }
   10912         }
   10913         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   10914                 "Clean-up removing on hold: " + app);
   10915         mProcessesOnHold.remove(app);
   10916 
   10917         if (app == mHomeProcess) {
   10918             mHomeProcess = null;
   10919         }
   10920         if (app == mPreviousProcess) {
   10921             mPreviousProcess = null;
   10922         }
   10923 
   10924         if (restart && !app.isolated) {
   10925             // We have components that still need to be running in the
   10926             // process, so re-launch it.
   10927             mProcessNames.put(app.processName, app.uid, app);
   10928             startProcessLocked(app, "restart", app.processName);
   10929         } else if (app.pid > 0 && app.pid != MY_PID) {
   10930             // Goodbye!
   10931             synchronized (mPidsSelfLocked) {
   10932                 mPidsSelfLocked.remove(app.pid);
   10933                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   10934             }
   10935             app.setPid(0);
   10936         }
   10937     }
   10938 
   10939     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
   10940         // Look through the content providers we are waiting to have launched,
   10941         // and if any run in this process then either schedule a restart of
   10942         // the process or kill the client waiting for it if this process has
   10943         // gone bad.
   10944         int NL = mLaunchingProviders.size();
   10945         boolean restart = false;
   10946         for (int i=0; i<NL; i++) {
   10947             ContentProviderRecord cpr = mLaunchingProviders.get(i);
   10948             if (cpr.launchingApp == app) {
   10949                 if (!alwaysBad && !app.bad) {
   10950                     restart = true;
   10951                 } else {
   10952                     removeDyingProviderLocked(app, cpr, true);
   10953                     NL = mLaunchingProviders.size();
   10954                 }
   10955             }
   10956         }
   10957         return restart;
   10958     }
   10959 
   10960     // =========================================================
   10961     // SERVICES
   10962     // =========================================================
   10963 
   10964     ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
   10965         ActivityManager.RunningServiceInfo info =
   10966             new ActivityManager.RunningServiceInfo();
   10967         info.service = r.name;
   10968         if (r.app != null) {
   10969             info.pid = r.app.pid;
   10970         }
   10971         info.uid = r.appInfo.uid;
   10972         info.process = r.processName;
   10973         info.foreground = r.isForeground;
   10974         info.activeSince = r.createTime;
   10975         info.started = r.startRequested;
   10976         info.clientCount = r.connections.size();
   10977         info.crashCount = r.crashCount;
   10978         info.lastActivityTime = r.lastActivity;
   10979         if (r.isForeground) {
   10980             info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
   10981         }
   10982         if (r.startRequested) {
   10983             info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
   10984         }
   10985         if (r.app != null && r.app.pid == MY_PID) {
   10986             info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
   10987         }
   10988         if (r.app != null && r.app.persistent) {
   10989             info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
   10990         }
   10991 
   10992         for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
   10993             for (int i=0; i<connl.size(); i++) {
   10994                 ConnectionRecord conn = connl.get(i);
   10995                 if (conn.clientLabel != 0) {
   10996                     info.clientPackage = conn.binding.client.info.packageName;
   10997                     info.clientLabel = conn.clientLabel;
   10998                     return info;
   10999                 }
   11000             }
   11001         }
   11002         return info;
   11003     }
   11004 
   11005     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
   11006             int flags) {
   11007         enforceNotIsolatedCaller("getServices");
   11008         synchronized (this) {
   11009             ArrayList<ActivityManager.RunningServiceInfo> res
   11010                     = new ArrayList<ActivityManager.RunningServiceInfo>();
   11011 
   11012             int userId = UserId.getUserId(Binder.getCallingUid());
   11013             if (mServiceMap.getAllServices(userId).size() > 0) {
   11014                 Iterator<ServiceRecord> it
   11015                         = mServiceMap.getAllServices(userId).iterator();
   11016                 while (it.hasNext() && res.size() < maxNum) {
   11017                     res.add(makeRunningServiceInfoLocked(it.next()));
   11018                 }
   11019             }
   11020 
   11021             for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
   11022                 ServiceRecord r = mRestartingServices.get(i);
   11023                 ActivityManager.RunningServiceInfo info =
   11024                         makeRunningServiceInfoLocked(r);
   11025                 info.restarting = r.nextRestartTime;
   11026                 res.add(info);
   11027             }
   11028 
   11029             return res;
   11030         }
   11031     }
   11032 
   11033     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
   11034         enforceNotIsolatedCaller("getRunningServiceControlPanel");
   11035         synchronized (this) {
   11036             int userId = UserId.getUserId(Binder.getCallingUid());
   11037             ServiceRecord r = mServiceMap.getServiceByName(name, userId);
   11038             if (r != null) {
   11039                 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
   11040                     for (int i=0; i<conn.size(); i++) {
   11041                         if (conn.get(i).clientIntent != null) {
   11042                             return conn.get(i).clientIntent;
   11043                         }
   11044                     }
   11045                 }
   11046             }
   11047         }
   11048         return null;
   11049     }
   11050 
   11051     private final ServiceRecord findServiceLocked(ComponentName name,
   11052             IBinder token) {
   11053         ServiceRecord r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
   11054         return r == token ? r : null;
   11055     }
   11056 
   11057     private final class ServiceLookupResult {
   11058         final ServiceRecord record;
   11059         final String permission;
   11060 
   11061         ServiceLookupResult(ServiceRecord _record, String _permission) {
   11062             record = _record;
   11063             permission = _permission;
   11064         }
   11065     };
   11066 
   11067     private ServiceLookupResult findServiceLocked(Intent service,
   11068             String resolvedType, int userId) {
   11069         ServiceRecord r = null;
   11070         if (service.getComponent() != null) {
   11071             r = mServiceMap.getServiceByName(service.getComponent(), userId);
   11072         }
   11073         if (r == null) {
   11074             Intent.FilterComparison filter = new Intent.FilterComparison(service);
   11075             r = mServiceMap.getServiceByIntent(filter, userId);
   11076         }
   11077 
   11078         if (r == null) {
   11079             try {
   11080                 ResolveInfo rInfo =
   11081                     AppGlobals.getPackageManager().resolveService(
   11082                                 service, resolvedType, 0, userId);
   11083                 ServiceInfo sInfo =
   11084                     rInfo != null ? rInfo.serviceInfo : null;
   11085                 if (sInfo == null) {
   11086                     return null;
   11087                 }
   11088 
   11089                 ComponentName name = new ComponentName(
   11090                         sInfo.applicationInfo.packageName, sInfo.name);
   11091                 r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
   11092             } catch (RemoteException ex) {
   11093                 // pm is in same process, this will never happen.
   11094             }
   11095         }
   11096         if (r != null) {
   11097             int callingPid = Binder.getCallingPid();
   11098             int callingUid = Binder.getCallingUid();
   11099             if (checkComponentPermission(r.permission,
   11100                     callingPid, callingUid, r.appInfo.uid, r.exported)
   11101                     != PackageManager.PERMISSION_GRANTED) {
   11102                 if (!r.exported) {
   11103                     Slog.w(TAG, "Permission Denial: Accessing service " + r.name
   11104                             + " from pid=" + callingPid
   11105                             + ", uid=" + callingUid
   11106                             + " that is not exported from uid " + r.appInfo.uid);
   11107                     return new ServiceLookupResult(null, "not exported from uid "
   11108                             + r.appInfo.uid);
   11109                 }
   11110                 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
   11111                         + " from pid=" + callingPid
   11112                         + ", uid=" + callingUid
   11113                         + " requires " + r.permission);
   11114                 return new ServiceLookupResult(null, r.permission);
   11115             }
   11116             return new ServiceLookupResult(r, null);
   11117         }
   11118         return null;
   11119     }
   11120 
   11121     private class ServiceRestarter implements Runnable {
   11122         private ServiceRecord mService;
   11123 
   11124         void setService(ServiceRecord service) {
   11125             mService = service;
   11126         }
   11127 
   11128         public void run() {
   11129             synchronized(ActivityManagerService.this) {
   11130                 performServiceRestartLocked(mService);
   11131             }
   11132         }
   11133     }
   11134 
   11135     private ServiceLookupResult retrieveServiceLocked(Intent service,
   11136             String resolvedType, int callingPid, int callingUid, int userId) {
   11137         ServiceRecord r = null;
   11138         if (DEBUG_SERVICE)
   11139             Slog.v(TAG, "retrieveServiceLocked: " + service + " type=" + resolvedType
   11140                     + " callingUid=" + callingUid);
   11141 
   11142         if (service.getComponent() != null) {
   11143             r = mServiceMap.getServiceByName(service.getComponent(), userId);
   11144         }
   11145         if (r == null) {
   11146             Intent.FilterComparison filter = new Intent.FilterComparison(service);
   11147             r = mServiceMap.getServiceByIntent(filter, userId);
   11148         }
   11149         if (r == null) {
   11150             try {
   11151                 ResolveInfo rInfo =
   11152                     AppGlobals.getPackageManager().resolveService(
   11153                                 service, resolvedType, STOCK_PM_FLAGS, userId);
   11154                 ServiceInfo sInfo =
   11155                     rInfo != null ? rInfo.serviceInfo : null;
   11156                 if (sInfo == null) {
   11157                     Slog.w(TAG, "Unable to start service " + service +
   11158                           ": not found");
   11159                     return null;
   11160                 }
   11161                 if (userId > 0) {
   11162                     if (isSingleton(sInfo.processName, sInfo.applicationInfo)) {
   11163                         userId = 0;
   11164                     }
   11165                     sInfo.applicationInfo = getAppInfoForUser(sInfo.applicationInfo, userId);
   11166                 }
   11167                 ComponentName name = new ComponentName(
   11168                         sInfo.applicationInfo.packageName, sInfo.name);
   11169                 r = mServiceMap.getServiceByName(name, userId);
   11170                 if (r == null) {
   11171                     Intent.FilterComparison filter = new Intent.FilterComparison(
   11172                             service.cloneFilter());
   11173                     ServiceRestarter res = new ServiceRestarter();
   11174                     BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   11175                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   11176                     synchronized (stats) {
   11177                         ss = stats.getServiceStatsLocked(
   11178                                 sInfo.applicationInfo.uid, sInfo.packageName,
   11179                                 sInfo.name);
   11180                     }
   11181                     r = new ServiceRecord(this, ss, name, filter, sInfo, res);
   11182                     res.setService(r);
   11183                     mServiceMap.putServiceByName(name, UserId.getUserId(r.appInfo.uid), r);
   11184                     mServiceMap.putServiceByIntent(filter, UserId.getUserId(r.appInfo.uid), r);
   11185 
   11186                     // Make sure this component isn't in the pending list.
   11187                     int N = mPendingServices.size();
   11188                     for (int i=0; i<N; i++) {
   11189                         ServiceRecord pr = mPendingServices.get(i);
   11190                         if (pr.name.equals(name)) {
   11191                             mPendingServices.remove(i);
   11192                             i--;
   11193                             N--;
   11194                         }
   11195                     }
   11196                 }
   11197             } catch (RemoteException ex) {
   11198                 // pm is in same process, this will never happen.
   11199             }
   11200         }
   11201         if (r != null) {
   11202             if (checkComponentPermission(r.permission,
   11203                     callingPid, callingUid, r.appInfo.uid, r.exported)
   11204                     != PackageManager.PERMISSION_GRANTED) {
   11205                 if (!r.exported) {
   11206                     Slog.w(TAG, "Permission Denial: Accessing service " + r.name
   11207                             + " from pid=" + callingPid
   11208                             + ", uid=" + callingUid
   11209                             + " that is not exported from uid " + r.appInfo.uid);
   11210                     return new ServiceLookupResult(null, "not exported from uid "
   11211                             + r.appInfo.uid);
   11212                 }
   11213                 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
   11214                         + " from pid=" + callingPid
   11215                         + ", uid=" + callingUid
   11216                         + " requires " + r.permission);
   11217                 return new ServiceLookupResult(null, r.permission);
   11218             }
   11219             return new ServiceLookupResult(r, null);
   11220         }
   11221         return null;
   11222     }
   11223 
   11224     private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
   11225         if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
   11226                 + why + " of " + r + " in app " + r.app);
   11227         else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
   11228                 + why + " of " + r.shortName);
   11229         long now = SystemClock.uptimeMillis();
   11230         if (r.executeNesting == 0 && r.app != null) {
   11231             if (r.app.executingServices.size() == 0) {
   11232                 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   11233                 msg.obj = r.app;
   11234                 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
   11235             }
   11236             r.app.executingServices.add(r);
   11237         }
   11238         r.executeNesting++;
   11239         r.executingStart = now;
   11240     }
   11241 
   11242     private final void sendServiceArgsLocked(ServiceRecord r,
   11243             boolean oomAdjusted) {
   11244         final int N = r.pendingStarts.size();
   11245         if (N == 0) {
   11246             return;
   11247         }
   11248 
   11249         while (r.pendingStarts.size() > 0) {
   11250             try {
   11251                 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
   11252                 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
   11253                         + r + " " + r.intent + " args=" + si.intent);
   11254                 if (si.intent == null && N > 1) {
   11255                     // If somehow we got a dummy null intent in the middle,
   11256                     // then skip it.  DO NOT skip a null intent when it is
   11257                     // the only one in the list -- this is to support the
   11258                     // onStartCommand(null) case.
   11259                     continue;
   11260                 }
   11261                 si.deliveredTime = SystemClock.uptimeMillis();
   11262                 r.deliveredStarts.add(si);
   11263                 si.deliveryCount++;
   11264                 if (si.neededGrants != null) {
   11265                     grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
   11266                             si.getUriPermissionsLocked());
   11267                 }
   11268                 bumpServiceExecutingLocked(r, "start");
   11269                 if (!oomAdjusted) {
   11270                     oomAdjusted = true;
   11271                     updateOomAdjLocked(r.app);
   11272                 }
   11273                 int flags = 0;
   11274                 if (si.deliveryCount > 1) {
   11275                     flags |= Service.START_FLAG_RETRY;
   11276                 }
   11277                 if (si.doneExecutingCount > 0) {
   11278                     flags |= Service.START_FLAG_REDELIVERY;
   11279                 }
   11280                 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
   11281             } catch (RemoteException e) {
   11282                 // Remote process gone...  we'll let the normal cleanup take
   11283                 // care of this.
   11284                 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
   11285                 break;
   11286             } catch (Exception e) {
   11287                 Slog.w(TAG, "Unexpected exception", e);
   11288                 break;
   11289             }
   11290         }
   11291     }
   11292 
   11293     private final boolean requestServiceBindingLocked(ServiceRecord r,
   11294             IntentBindRecord i, boolean rebind) {
   11295         if (r.app == null || r.app.thread == null) {
   11296             // If service is not currently running, can't yet bind.
   11297             return false;
   11298         }
   11299         if ((!i.requested || rebind) && i.apps.size() > 0) {
   11300             try {
   11301                 bumpServiceExecutingLocked(r, "bind");
   11302                 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
   11303                 if (!rebind) {
   11304                     i.requested = true;
   11305                 }
   11306                 i.hasBound = true;
   11307                 i.doRebind = false;
   11308             } catch (RemoteException e) {
   11309                 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
   11310                 return false;
   11311             }
   11312         }
   11313         return true;
   11314     }
   11315 
   11316     private final void requestServiceBindingsLocked(ServiceRecord r) {
   11317         Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
   11318         while (bindings.hasNext()) {
   11319             IntentBindRecord i = bindings.next();
   11320             if (!requestServiceBindingLocked(r, i, false)) {
   11321                 break;
   11322             }
   11323         }
   11324     }
   11325 
   11326     private final void realStartServiceLocked(ServiceRecord r,
   11327             ProcessRecord app) throws RemoteException {
   11328         if (app.thread == null) {
   11329             throw new RemoteException();
   11330         }
   11331         if (DEBUG_MU)
   11332             Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
   11333                     + ", ProcessRecord.uid = " + app.uid);
   11334         r.app = app;
   11335         r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
   11336 
   11337         app.services.add(r);
   11338         bumpServiceExecutingLocked(r, "create");
   11339         updateLruProcessLocked(app, true, true);
   11340 
   11341         boolean created = false;
   11342         try {
   11343             mStringBuilder.setLength(0);
   11344             r.intent.getIntent().toShortString(mStringBuilder, true, false, true, false);
   11345             EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
   11346                     System.identityHashCode(r), r.shortName,
   11347                     mStringBuilder.toString(), r.app.pid);
   11348             synchronized (r.stats.getBatteryStats()) {
   11349                 r.stats.startLaunchedLocked();
   11350             }
   11351             ensurePackageDexOpt(r.serviceInfo.packageName);
   11352             app.thread.scheduleCreateService(r, r.serviceInfo,
   11353                     compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
   11354             r.postNotification();
   11355             created = true;
   11356         } finally {
   11357             if (!created) {
   11358                 app.services.remove(r);
   11359                 scheduleServiceRestartLocked(r, false);
   11360             }
   11361         }
   11362 
   11363         requestServiceBindingsLocked(r);
   11364 
   11365         // If the service is in the started state, and there are no
   11366         // pending arguments, then fake up one so its onStartCommand() will
   11367         // be called.
   11368         if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
   11369             r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
   11370                     null, null));
   11371         }
   11372 
   11373         sendServiceArgsLocked(r, true);
   11374     }
   11375 
   11376     private final boolean scheduleServiceRestartLocked(ServiceRecord r,
   11377             boolean allowCancel) {
   11378         boolean canceled = false;
   11379 
   11380         final long now = SystemClock.uptimeMillis();
   11381         long minDuration = SERVICE_RESTART_DURATION;
   11382         long resetTime = SERVICE_RESET_RUN_DURATION;
   11383 
   11384         if ((r.serviceInfo.applicationInfo.flags
   11385                 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
   11386             minDuration /= 4;
   11387         }
   11388 
   11389         // Any delivered but not yet finished starts should be put back
   11390         // on the pending list.
   11391         final int N = r.deliveredStarts.size();
   11392         if (N > 0) {
   11393             for (int i=N-1; i>=0; i--) {
   11394                 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
   11395                 si.removeUriPermissionsLocked();
   11396                 if (si.intent == null) {
   11397                     // We'll generate this again if needed.
   11398                 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
   11399                         && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
   11400                     r.pendingStarts.add(0, si);
   11401                     long dur = SystemClock.uptimeMillis() - si.deliveredTime;
   11402                     dur *= 2;
   11403                     if (minDuration < dur) minDuration = dur;
   11404                     if (resetTime < dur) resetTime = dur;
   11405                 } else {
   11406                     Slog.w(TAG, "Canceling start item " + si.intent + " in service "
   11407                             + r.name);
   11408                     canceled = true;
   11409                 }
   11410             }
   11411             r.deliveredStarts.clear();
   11412         }
   11413 
   11414         r.totalRestartCount++;
   11415         if (r.restartDelay == 0) {
   11416             r.restartCount++;
   11417             r.restartDelay = minDuration;
   11418         } else {
   11419             // If it has been a "reasonably long time" since the service
   11420             // was started, then reset our restart duration back to
   11421             // the beginning, so we don't infinitely increase the duration
   11422             // on a service that just occasionally gets killed (which is
   11423             // a normal case, due to process being killed to reclaim memory).
   11424             if (now > (r.restartTime+resetTime)) {
   11425                 r.restartCount = 1;
   11426                 r.restartDelay = minDuration;
   11427             } else {
   11428                 if ((r.serviceInfo.applicationInfo.flags
   11429                         &ApplicationInfo.FLAG_PERSISTENT) != 0) {
   11430                     // Services in peristent processes will restart much more
   11431                     // quickly, since they are pretty important.  (Think SystemUI).
   11432                     r.restartDelay += minDuration/2;
   11433                 } else {
   11434                     r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
   11435                     if (r.restartDelay < minDuration) {
   11436                         r.restartDelay = minDuration;
   11437                     }
   11438                 }
   11439             }
   11440         }
   11441 
   11442         r.nextRestartTime = now + r.restartDelay;
   11443 
   11444         // Make sure that we don't end up restarting a bunch of services
   11445         // all at the same time.
   11446         boolean repeat;
   11447         do {
   11448             repeat = false;
   11449             for (int i=mRestartingServices.size()-1; i>=0; i--) {
   11450                 ServiceRecord r2 = mRestartingServices.get(i);
   11451                 if (r2 != r && r.nextRestartTime
   11452                         >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
   11453                         && r.nextRestartTime
   11454                         < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
   11455                     r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
   11456                     r.restartDelay = r.nextRestartTime - now;
   11457                     repeat = true;
   11458                     break;
   11459                 }
   11460             }
   11461         } while (repeat);
   11462 
   11463         if (!mRestartingServices.contains(r)) {
   11464             mRestartingServices.add(r);
   11465         }
   11466 
   11467         r.cancelNotification();
   11468 
   11469         mHandler.removeCallbacks(r.restarter);
   11470         mHandler.postAtTime(r.restarter, r.nextRestartTime);
   11471         r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
   11472         Slog.w(TAG, "Scheduling restart of crashed service "
   11473                 + r.shortName + " in " + r.restartDelay + "ms");
   11474         EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
   11475                 r.shortName, r.restartDelay);
   11476 
   11477         return canceled;
   11478     }
   11479 
   11480     final void performServiceRestartLocked(ServiceRecord r) {
   11481         if (!mRestartingServices.contains(r)) {
   11482             return;
   11483         }
   11484         bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
   11485     }
   11486 
   11487     private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
   11488         if (r.restartDelay == 0) {
   11489             return false;
   11490         }
   11491         r.resetRestartCounter();
   11492         mRestartingServices.remove(r);
   11493         mHandler.removeCallbacks(r.restarter);
   11494         return true;
   11495     }
   11496 
   11497     private final boolean bringUpServiceLocked(ServiceRecord r,
   11498             int intentFlags, boolean whileRestarting) {
   11499         //Slog.i(TAG, "Bring up service:");
   11500         //r.dump("  ");
   11501 
   11502         if (r.app != null && r.app.thread != null) {
   11503             sendServiceArgsLocked(r, false);
   11504             return true;
   11505         }
   11506 
   11507         if (!whileRestarting && r.restartDelay > 0) {
   11508             // If waiting for a restart, then do nothing.
   11509             return true;
   11510         }
   11511 
   11512         if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
   11513 
   11514         // We are now bringing the service up, so no longer in the
   11515         // restarting state.
   11516         mRestartingServices.remove(r);
   11517 
   11518         // Service is now being launched, its package can't be stopped.
   11519         try {
   11520             AppGlobals.getPackageManager().setPackageStoppedState(
   11521                     r.packageName, false, r.userId);
   11522         } catch (RemoteException e) {
   11523         } catch (IllegalArgumentException e) {
   11524             Slog.w(TAG, "Failed trying to unstop package "
   11525                     + r.packageName + ": " + e);
   11526         }
   11527 
   11528         final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
   11529         final String appName = r.processName;
   11530         ProcessRecord app;
   11531 
   11532         if (!isolated) {
   11533             app = getProcessRecordLocked(appName, r.appInfo.uid);
   11534             if (DEBUG_MU)
   11535                 Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app);
   11536             if (app != null && app.thread != null) {
   11537                 try {
   11538                     app.addPackage(r.appInfo.packageName);
   11539                     realStartServiceLocked(r, app);
   11540                     return true;
   11541                 } catch (RemoteException e) {
   11542                     Slog.w(TAG, "Exception when starting service " + r.shortName, e);
   11543                 }
   11544 
   11545                 // If a dead object exception was thrown -- fall through to
   11546                 // restart the application.
   11547             }
   11548         } else {
   11549             // If this service runs in an isolated process, then each time
   11550             // we call startProcessLocked() we will get a new isolated
   11551             // process, starting another process if we are currently waiting
   11552             // for a previous process to come up.  To deal with this, we store
   11553             // in the service any current isolated process it is running in or
   11554             // waiting to have come up.
   11555             app = r.isolatedProc;
   11556         }
   11557 
   11558         // Not running -- get it started, and enqueue this service record
   11559         // to be executed when the app comes up.
   11560         if (app == null) {
   11561             if ((app=startProcessLocked(appName, r.appInfo, true, intentFlags,
   11562                     "service", r.name, false, isolated)) == null) {
   11563                 Slog.w(TAG, "Unable to launch app "
   11564                         + r.appInfo.packageName + "/"
   11565                         + r.appInfo.uid + " for service "
   11566                         + r.intent.getIntent() + ": process is bad");
   11567                 bringDownServiceLocked(r, true);
   11568                 return false;
   11569             }
   11570             if (isolated) {
   11571                 r.isolatedProc = app;
   11572             }
   11573         }
   11574 
   11575         if (!mPendingServices.contains(r)) {
   11576             mPendingServices.add(r);
   11577         }
   11578 
   11579         return true;
   11580     }
   11581 
   11582     private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
   11583         //Slog.i(TAG, "Bring down service:");
   11584         //r.dump("  ");
   11585 
   11586         // Does it still need to run?
   11587         if (!force && r.startRequested) {
   11588             return;
   11589         }
   11590         if (r.connections.size() > 0) {
   11591             if (!force) {
   11592                 // XXX should probably keep a count of the number of auto-create
   11593                 // connections directly in the service.
   11594                 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
   11595                 while (it.hasNext()) {
   11596                     ArrayList<ConnectionRecord> cr = it.next();
   11597                     for (int i=0; i<cr.size(); i++) {
   11598                         if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
   11599                             return;
   11600                         }
   11601                     }
   11602                 }
   11603             }
   11604 
   11605             // Report to all of the connections that the service is no longer
   11606             // available.
   11607             Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
   11608             while (it.hasNext()) {
   11609                 ArrayList<ConnectionRecord> c = it.next();
   11610                 for (int i=0; i<c.size(); i++) {
   11611                     ConnectionRecord cr = c.get(i);
   11612                     // There is still a connection to the service that is
   11613                     // being brought down.  Mark it as dead.
   11614                     cr.serviceDead = true;
   11615                     try {
   11616                         cr.conn.connected(r.name, null);
   11617                     } catch (Exception e) {
   11618                         Slog.w(TAG, "Failure disconnecting service " + r.name +
   11619                               " to connection " + c.get(i).conn.asBinder() +
   11620                               " (in " + c.get(i).binding.client.processName + ")", e);
   11621                     }
   11622                 }
   11623             }
   11624         }
   11625 
   11626         // Tell the service that it has been unbound.
   11627         if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
   11628             Iterator<IntentBindRecord> it = r.bindings.values().iterator();
   11629             while (it.hasNext()) {
   11630                 IntentBindRecord ibr = it.next();
   11631                 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
   11632                         + ": hasBound=" + ibr.hasBound);
   11633                 if (r.app != null && r.app.thread != null && ibr.hasBound) {
   11634                     try {
   11635                         bumpServiceExecutingLocked(r, "bring down unbind");
   11636                         updateOomAdjLocked(r.app);
   11637                         ibr.hasBound = false;
   11638                         r.app.thread.scheduleUnbindService(r,
   11639                                 ibr.intent.getIntent());
   11640                     } catch (Exception e) {
   11641                         Slog.w(TAG, "Exception when unbinding service "
   11642                                 + r.shortName, e);
   11643                         serviceDoneExecutingLocked(r, true);
   11644                     }
   11645                 }
   11646             }
   11647         }
   11648 
   11649         if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
   11650         EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
   11651                 System.identityHashCode(r), r.shortName,
   11652                 (r.app != null) ? r.app.pid : -1);
   11653 
   11654         mServiceMap.removeServiceByName(r.name, r.userId);
   11655         mServiceMap.removeServiceByIntent(r.intent, r.userId);
   11656         r.totalRestartCount = 0;
   11657         unscheduleServiceRestartLocked(r);
   11658 
   11659         // Also make sure it is not on the pending list.
   11660         int N = mPendingServices.size();
   11661         for (int i=0; i<N; i++) {
   11662             if (mPendingServices.get(i) == r) {
   11663                 mPendingServices.remove(i);
   11664                 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
   11665                 i--;
   11666                 N--;
   11667             }
   11668         }
   11669 
   11670         r.cancelNotification();
   11671         r.isForeground = false;
   11672         r.foregroundId = 0;
   11673         r.foregroundNoti = null;
   11674 
   11675         // Clear start entries.
   11676         r.clearDeliveredStartsLocked();
   11677         r.pendingStarts.clear();
   11678 
   11679         if (r.app != null) {
   11680             synchronized (r.stats.getBatteryStats()) {
   11681                 r.stats.stopLaunchedLocked();
   11682             }
   11683             r.app.services.remove(r);
   11684             if (r.app.thread != null) {
   11685                 try {
   11686                     bumpServiceExecutingLocked(r, "stop");
   11687                     mStoppingServices.add(r);
   11688                     updateOomAdjLocked(r.app);
   11689                     r.app.thread.scheduleStopService(r);
   11690                 } catch (Exception e) {
   11691                     Slog.w(TAG, "Exception when stopping service "
   11692                             + r.shortName, e);
   11693                     serviceDoneExecutingLocked(r, true);
   11694                 }
   11695                 updateServiceForegroundLocked(r.app, false);
   11696             } else {
   11697                 if (DEBUG_SERVICE) Slog.v(
   11698                     TAG, "Removed service that has no process: " + r);
   11699             }
   11700         } else {
   11701             if (DEBUG_SERVICE) Slog.v(
   11702                 TAG, "Removed service that is not running: " + r);
   11703         }
   11704 
   11705         if (r.bindings.size() > 0) {
   11706             r.bindings.clear();
   11707         }
   11708 
   11709         if (r.restarter instanceof ServiceRestarter) {
   11710            ((ServiceRestarter)r.restarter).setService(null);
   11711         }
   11712     }
   11713 
   11714     ComponentName startServiceLocked(IApplicationThread caller,
   11715             Intent service, String resolvedType,
   11716             int callingPid, int callingUid) {
   11717         synchronized(this) {
   11718             if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
   11719                     + " type=" + resolvedType + " args=" + service.getExtras());
   11720 
   11721             if (caller != null) {
   11722                 final ProcessRecord callerApp = getRecordForAppLocked(caller);
   11723                 if (callerApp == null) {
   11724                     throw new SecurityException(
   11725                             "Unable to find app for caller " + caller
   11726                             + " (pid=" + Binder.getCallingPid()
   11727                             + ") when starting service " + service);
   11728                 }
   11729             }
   11730 
   11731             ServiceLookupResult res =
   11732                 retrieveServiceLocked(service, resolvedType,
   11733                         callingPid, callingUid, UserId.getUserId(callingUid));
   11734             if (res == null) {
   11735                 return null;
   11736             }
   11737             if (res.record == null) {
   11738                 return new ComponentName("!", res.permission != null
   11739                         ? res.permission : "private to package");
   11740             }
   11741             ServiceRecord r = res.record;
   11742             NeededUriGrants neededGrants = checkGrantUriPermissionFromIntentLocked(
   11743                     callingUid, r.packageName, service, service.getFlags(), null);
   11744             if (unscheduleServiceRestartLocked(r)) {
   11745                 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
   11746             }
   11747             r.startRequested = true;
   11748             r.callStart = false;
   11749             r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
   11750                     service, neededGrants));
   11751             r.lastActivity = SystemClock.uptimeMillis();
   11752             synchronized (r.stats.getBatteryStats()) {
   11753                 r.stats.startRunningLocked();
   11754             }
   11755             if (!bringUpServiceLocked(r, service.getFlags(), false)) {
   11756                 return new ComponentName("!", "Service process is bad");
   11757             }
   11758             return r.name;
   11759         }
   11760     }
   11761 
   11762     public ComponentName startService(IApplicationThread caller, Intent service,
   11763             String resolvedType) {
   11764         enforceNotIsolatedCaller("startService");
   11765         // Refuse possible leaked file descriptors
   11766         if (service != null && service.hasFileDescriptors() == true) {
   11767             throw new IllegalArgumentException("File descriptors passed in Intent");
   11768         }
   11769 
   11770         if (DEBUG_SERVICE)
   11771             Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
   11772         synchronized(this) {
   11773             final int callingPid = Binder.getCallingPid();
   11774             final int callingUid = Binder.getCallingUid();
   11775             final long origId = Binder.clearCallingIdentity();
   11776             ComponentName res = startServiceLocked(caller, service,
   11777                     resolvedType, callingPid, callingUid);
   11778             Binder.restoreCallingIdentity(origId);
   11779             return res;
   11780         }
   11781     }
   11782 
   11783     ComponentName startServiceInPackage(int uid,
   11784             Intent service, String resolvedType) {
   11785         synchronized(this) {
   11786             if (DEBUG_SERVICE)
   11787                 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
   11788             final long origId = Binder.clearCallingIdentity();
   11789             ComponentName res = startServiceLocked(null, service,
   11790                     resolvedType, -1, uid);
   11791             Binder.restoreCallingIdentity(origId);
   11792             return res;
   11793         }
   11794     }
   11795 
   11796     private void stopServiceLocked(ServiceRecord service) {
   11797         synchronized (service.stats.getBatteryStats()) {
   11798             service.stats.stopRunningLocked();
   11799         }
   11800         service.startRequested = false;
   11801         service.callStart = false;
   11802         bringDownServiceLocked(service, false);
   11803     }
   11804 
   11805     public int stopService(IApplicationThread caller, Intent service,
   11806             String resolvedType) {
   11807         enforceNotIsolatedCaller("stopService");
   11808         // Refuse possible leaked file descriptors
   11809         if (service != null && service.hasFileDescriptors() == true) {
   11810             throw new IllegalArgumentException("File descriptors passed in Intent");
   11811         }
   11812 
   11813         synchronized(this) {
   11814             if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
   11815                     + " type=" + resolvedType);
   11816 
   11817             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   11818             if (caller != null && callerApp == null) {
   11819                 throw new SecurityException(
   11820                         "Unable to find app for caller " + caller
   11821                         + " (pid=" + Binder.getCallingPid()
   11822                         + ") when stopping service " + service);
   11823             }
   11824 
   11825             // If this service is active, make sure it is stopped.
   11826             ServiceLookupResult r = findServiceLocked(service, resolvedType,
   11827                     callerApp == null ? UserId.getCallingUserId() : callerApp.userId);
   11828             if (r != null) {
   11829                 if (r.record != null) {
   11830                     final long origId = Binder.clearCallingIdentity();
   11831                     try {
   11832                         stopServiceLocked(r.record);
   11833                     } finally {
   11834                         Binder.restoreCallingIdentity(origId);
   11835                     }
   11836                     return 1;
   11837                 }
   11838                 return -1;
   11839             }
   11840         }
   11841 
   11842         return 0;
   11843     }
   11844 
   11845     public IBinder peekService(Intent service, String resolvedType) {
   11846         enforceNotIsolatedCaller("peekService");
   11847         // Refuse possible leaked file descriptors
   11848         if (service != null && service.hasFileDescriptors() == true) {
   11849             throw new IllegalArgumentException("File descriptors passed in Intent");
   11850         }
   11851 
   11852         IBinder ret = null;
   11853 
   11854         synchronized(this) {
   11855             ServiceLookupResult r = findServiceLocked(service, resolvedType,
   11856                     UserId.getCallingUserId());
   11857 
   11858             if (r != null) {
   11859                 // r.record is null if findServiceLocked() failed the caller permission check
   11860                 if (r.record == null) {
   11861                     throw new SecurityException(
   11862                             "Permission Denial: Accessing service " + r.record.name
   11863                             + " from pid=" + Binder.getCallingPid()
   11864                             + ", uid=" + Binder.getCallingUid()
   11865                             + " requires " + r.permission);
   11866                 }
   11867                 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
   11868                 if (ib != null) {
   11869                     ret = ib.binder;
   11870                 }
   11871             }
   11872         }
   11873 
   11874         return ret;
   11875     }
   11876 
   11877     public boolean stopServiceToken(ComponentName className, IBinder token,
   11878             int startId) {
   11879         synchronized(this) {
   11880             if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
   11881                     + " " + token + " startId=" + startId);
   11882             ServiceRecord r = findServiceLocked(className, token);
   11883             if (r != null) {
   11884                 if (startId >= 0) {
   11885                     // Asked to only stop if done with all work.  Note that
   11886                     // to avoid leaks, we will take this as dropping all
   11887                     // start items up to and including this one.
   11888                     ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
   11889                     if (si != null) {
   11890                         while (r.deliveredStarts.size() > 0) {
   11891                             ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
   11892                             cur.removeUriPermissionsLocked();
   11893                             if (cur == si) {
   11894                                 break;
   11895                             }
   11896                         }
   11897                     }
   11898 
   11899                     if (r.getLastStartId() != startId) {
   11900                         return false;
   11901                     }
   11902 
   11903                     if (r.deliveredStarts.size() > 0) {
   11904                         Slog.w(TAG, "stopServiceToken startId " + startId
   11905                                 + " is last, but have " + r.deliveredStarts.size()
   11906                                 + " remaining args");
   11907                     }
   11908                 }
   11909 
   11910                 synchronized (r.stats.getBatteryStats()) {
   11911                     r.stats.stopRunningLocked();
   11912                     r.startRequested = false;
   11913                     r.callStart = false;
   11914                 }
   11915                 final long origId = Binder.clearCallingIdentity();
   11916                 bringDownServiceLocked(r, false);
   11917                 Binder.restoreCallingIdentity(origId);
   11918                 return true;
   11919             }
   11920         }
   11921         return false;
   11922     }
   11923 
   11924     public void setServiceForeground(ComponentName className, IBinder token,
   11925             int id, Notification notification, boolean removeNotification) {
   11926         final long origId = Binder.clearCallingIdentity();
   11927         try {
   11928         synchronized(this) {
   11929             ServiceRecord r = findServiceLocked(className, token);
   11930             if (r != null) {
   11931                 if (id != 0) {
   11932                     if (notification == null) {
   11933                         throw new IllegalArgumentException("null notification");
   11934                     }
   11935                     if (r.foregroundId != id) {
   11936                         r.cancelNotification();
   11937                         r.foregroundId = id;
   11938                     }
   11939                     notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
   11940                     r.foregroundNoti = notification;
   11941                     r.isForeground = true;
   11942                     r.postNotification();
   11943                     if (r.app != null) {
   11944                         updateServiceForegroundLocked(r.app, true);
   11945                     }
   11946                 } else {
   11947                     if (r.isForeground) {
   11948                         r.isForeground = false;
   11949                         if (r.app != null) {
   11950                             updateLruProcessLocked(r.app, false, true);
   11951                             updateServiceForegroundLocked(r.app, true);
   11952                         }
   11953                     }
   11954                     if (removeNotification) {
   11955                         r.cancelNotification();
   11956                         r.foregroundId = 0;
   11957                         r.foregroundNoti = null;
   11958                     }
   11959                 }
   11960             }
   11961         }
   11962         } finally {
   11963             Binder.restoreCallingIdentity(origId);
   11964         }
   11965     }
   11966 
   11967     public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
   11968         boolean anyForeground = false;
   11969         for (ServiceRecord sr : proc.services) {
   11970             if (sr.isForeground) {
   11971                 anyForeground = true;
   11972                 break;
   11973             }
   11974         }
   11975         if (anyForeground != proc.foregroundServices) {
   11976             proc.foregroundServices = anyForeground;
   11977             if (oomAdj) {
   11978                 updateOomAdjLocked();
   11979             }
   11980         }
   11981     }
   11982 
   11983     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo) {
   11984         boolean result = false;
   11985         if (UserId.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
   11986             result = false;
   11987         } else if (componentProcessName == aInfo.packageName) {
   11988             result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
   11989         } else if ("system".equals(componentProcessName)) {
   11990             result = true;
   11991         }
   11992         if (DEBUG_MU) {
   11993             Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo + ") = " + result);
   11994         }
   11995         return result;
   11996     }
   11997 
   11998     public int bindService(IApplicationThread caller, IBinder token,
   11999             Intent service, String resolvedType,
   12000             IServiceConnection connection, int flags, int userId) {
   12001         enforceNotIsolatedCaller("bindService");
   12002         // Refuse possible leaked file descriptors
   12003         if (service != null && service.hasFileDescriptors() == true) {
   12004             throw new IllegalArgumentException("File descriptors passed in Intent");
   12005         }
   12006 
   12007         checkValidCaller(Binder.getCallingUid(), userId);
   12008 
   12009         synchronized(this) {
   12010             if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
   12011                     + " type=" + resolvedType + " conn=" + connection.asBinder()
   12012                     + " flags=0x" + Integer.toHexString(flags));
   12013             if (DEBUG_MU)
   12014                 Slog.i(TAG_MU, "bindService uid=" + Binder.getCallingUid() + " origUid="
   12015                         + Binder.getOrigCallingUid());
   12016             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   12017             if (callerApp == null) {
   12018                 throw new SecurityException(
   12019                         "Unable to find app for caller " + caller
   12020                         + " (pid=" + Binder.getCallingPid()
   12021                         + ") when binding service " + service);
   12022             }
   12023 
   12024             ActivityRecord activity = null;
   12025             if (token != null) {
   12026                 activity = mMainStack.isInStackLocked(token);
   12027                 if (activity == null) {
   12028                     Slog.w(TAG, "Binding with unknown activity: " + token);
   12029                     return 0;
   12030                 }
   12031             }
   12032 
   12033             int clientLabel = 0;
   12034             PendingIntent clientIntent = null;
   12035 
   12036             if (callerApp.info.uid == Process.SYSTEM_UID) {
   12037                 // Hacky kind of thing -- allow system stuff to tell us
   12038                 // what they are, so we can report this elsewhere for
   12039                 // others to know why certain services are running.
   12040                 try {
   12041                     clientIntent = (PendingIntent)service.getParcelableExtra(
   12042                             Intent.EXTRA_CLIENT_INTENT);
   12043                 } catch (RuntimeException e) {
   12044                 }
   12045                 if (clientIntent != null) {
   12046                     clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
   12047                     if (clientLabel != 0) {
   12048                         // There are no useful extras in the intent, trash them.
   12049                         // System code calling with this stuff just needs to know
   12050                         // this will happen.
   12051                         service = service.cloneFilter();
   12052                     }
   12053                 }
   12054             }
   12055 
   12056             ServiceLookupResult res =
   12057                 retrieveServiceLocked(service, resolvedType,
   12058                         Binder.getCallingPid(), Binder.getCallingUid(), userId);
   12059             if (res == null) {
   12060                 return 0;
   12061             }
   12062             if (res.record == null) {
   12063                 return -1;
   12064             }
   12065             if (isSingleton(res.record.processName, res.record.appInfo)) {
   12066                 userId = 0;
   12067                 res = retrieveServiceLocked(service, resolvedType, Binder.getCallingPid(),
   12068                         Binder.getCallingUid(), 0);
   12069             }
   12070             ServiceRecord s = res.record;
   12071 
   12072             final long origId = Binder.clearCallingIdentity();
   12073 
   12074             if (unscheduleServiceRestartLocked(s)) {
   12075                 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
   12076                         + s);
   12077             }
   12078 
   12079             AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
   12080             ConnectionRecord c = new ConnectionRecord(b, activity,
   12081                     connection, flags, clientLabel, clientIntent);
   12082 
   12083             IBinder binder = connection.asBinder();
   12084             ArrayList<ConnectionRecord> clist = s.connections.get(binder);
   12085             if (clist == null) {
   12086                 clist = new ArrayList<ConnectionRecord>();
   12087                 s.connections.put(binder, clist);
   12088             }
   12089             clist.add(c);
   12090             b.connections.add(c);
   12091             if (activity != null) {
   12092                 if (activity.connections == null) {
   12093                     activity.connections = new HashSet<ConnectionRecord>();
   12094                 }
   12095                 activity.connections.add(c);
   12096             }
   12097             b.client.connections.add(c);
   12098             if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
   12099                 b.client.hasAboveClient = true;
   12100             }
   12101             clist = mServiceConnections.get(binder);
   12102             if (clist == null) {
   12103                 clist = new ArrayList<ConnectionRecord>();
   12104                 mServiceConnections.put(binder, clist);
   12105             }
   12106             clist.add(c);
   12107 
   12108             if ((flags&Context.BIND_AUTO_CREATE) != 0) {
   12109                 s.lastActivity = SystemClock.uptimeMillis();
   12110                 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
   12111                     return 0;
   12112                 }
   12113             }
   12114 
   12115             if (s.app != null) {
   12116                 // This could have made the service more important.
   12117                 updateOomAdjLocked(s.app);
   12118             }
   12119 
   12120             if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
   12121                     + ": received=" + b.intent.received
   12122                     + " apps=" + b.intent.apps.size()
   12123                     + " doRebind=" + b.intent.doRebind);
   12124 
   12125             if (s.app != null && b.intent.received) {
   12126                 // Service is already running, so we can immediately
   12127                 // publish the connection.
   12128                 try {
   12129                     c.conn.connected(s.name, b.intent.binder);
   12130                 } catch (Exception e) {
   12131                     Slog.w(TAG, "Failure sending service " + s.shortName
   12132                             + " to connection " + c.conn.asBinder()
   12133                             + " (in " + c.binding.client.processName + ")", e);
   12134                 }
   12135 
   12136                 // If this is the first app connected back to this binding,
   12137                 // and the service had previously asked to be told when
   12138                 // rebound, then do so.
   12139                 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
   12140                     requestServiceBindingLocked(s, b.intent, true);
   12141                 }
   12142             } else if (!b.intent.requested) {
   12143                 requestServiceBindingLocked(s, b.intent, false);
   12144             }
   12145 
   12146             Binder.restoreCallingIdentity(origId);
   12147         }
   12148 
   12149         return 1;
   12150     }
   12151 
   12152     void removeConnectionLocked(
   12153         ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
   12154         IBinder binder = c.conn.asBinder();
   12155         AppBindRecord b = c.binding;
   12156         ServiceRecord s = b.service;
   12157         ArrayList<ConnectionRecord> clist = s.connections.get(binder);
   12158         if (clist != null) {
   12159             clist.remove(c);
   12160             if (clist.size() == 0) {
   12161                 s.connections.remove(binder);
   12162             }
   12163         }
   12164         b.connections.remove(c);
   12165         if (c.activity != null && c.activity != skipAct) {
   12166             if (c.activity.connections != null) {
   12167                 c.activity.connections.remove(c);
   12168             }
   12169         }
   12170         if (b.client != skipApp) {
   12171             b.client.connections.remove(c);
   12172             if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
   12173                 b.client.updateHasAboveClientLocked();
   12174             }
   12175         }
   12176         clist = mServiceConnections.get(binder);
   12177         if (clist != null) {
   12178             clist.remove(c);
   12179             if (clist.size() == 0) {
   12180                 mServiceConnections.remove(binder);
   12181             }
   12182         }
   12183 
   12184         if (b.connections.size() == 0) {
   12185             b.intent.apps.remove(b.client);
   12186         }
   12187 
   12188         if (!c.serviceDead) {
   12189             if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
   12190                     + ": shouldUnbind=" + b.intent.hasBound);
   12191             if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
   12192                     && b.intent.hasBound) {
   12193                 try {
   12194                     bumpServiceExecutingLocked(s, "unbind");
   12195                     updateOomAdjLocked(s.app);
   12196                     b.intent.hasBound = false;
   12197                     // Assume the client doesn't want to know about a rebind;
   12198                     // we will deal with that later if it asks for one.
   12199                     b.intent.doRebind = false;
   12200                     s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
   12201                 } catch (Exception e) {
   12202                     Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
   12203                     serviceDoneExecutingLocked(s, true);
   12204                 }
   12205             }
   12206 
   12207             if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
   12208                 bringDownServiceLocked(s, false);
   12209             }
   12210         }
   12211     }
   12212 
   12213     public boolean unbindService(IServiceConnection connection) {
   12214         synchronized (this) {
   12215             IBinder binder = connection.asBinder();
   12216             if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
   12217             ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
   12218             if (clist == null) {
   12219                 Slog.w(TAG, "Unbind failed: could not find connection for "
   12220                       + connection.asBinder());
   12221                 return false;
   12222             }
   12223 
   12224             final long origId = Binder.clearCallingIdentity();
   12225 
   12226             while (clist.size() > 0) {
   12227                 ConnectionRecord r = clist.get(0);
   12228                 removeConnectionLocked(r, null, null);
   12229 
   12230                 if (r.binding.service.app != null) {
   12231                     // This could have made the service less important.
   12232                     updateOomAdjLocked(r.binding.service.app);
   12233                 }
   12234             }
   12235 
   12236             Binder.restoreCallingIdentity(origId);
   12237         }
   12238 
   12239         return true;
   12240     }
   12241 
   12242     public void publishService(IBinder token, Intent intent, IBinder service) {
   12243         // Refuse possible leaked file descriptors
   12244         if (intent != null && intent.hasFileDescriptors() == true) {
   12245             throw new IllegalArgumentException("File descriptors passed in Intent");
   12246         }
   12247 
   12248         synchronized(this) {
   12249             if (!(token instanceof ServiceRecord)) {
   12250                 throw new IllegalArgumentException("Invalid service token");
   12251             }
   12252             ServiceRecord r = (ServiceRecord)token;
   12253 
   12254             final long origId = Binder.clearCallingIdentity();
   12255 
   12256             if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
   12257                     + " " + intent + ": " + service);
   12258             if (r != null) {
   12259                 Intent.FilterComparison filter
   12260                         = new Intent.FilterComparison(intent);
   12261                 IntentBindRecord b = r.bindings.get(filter);
   12262                 if (b != null && !b.received) {
   12263                     b.binder = service;
   12264                     b.requested = true;
   12265                     b.received = true;
   12266                     if (r.connections.size() > 0) {
   12267                         Iterator<ArrayList<ConnectionRecord>> it
   12268                                 = r.connections.values().iterator();
   12269                         while (it.hasNext()) {
   12270                             ArrayList<ConnectionRecord> clist = it.next();
   12271                             for (int i=0; i<clist.size(); i++) {
   12272                                 ConnectionRecord c = clist.get(i);
   12273                                 if (!filter.equals(c.binding.intent.intent)) {
   12274                                     if (DEBUG_SERVICE) Slog.v(
   12275                                             TAG, "Not publishing to: " + c);
   12276                                     if (DEBUG_SERVICE) Slog.v(
   12277                                             TAG, "Bound intent: " + c.binding.intent.intent);
   12278                                     if (DEBUG_SERVICE) Slog.v(
   12279                                             TAG, "Published intent: " + intent);
   12280                                     continue;
   12281                                 }
   12282                                 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
   12283                                 try {
   12284                                     c.conn.connected(r.name, service);
   12285                                 } catch (Exception e) {
   12286                                     Slog.w(TAG, "Failure sending service " + r.name +
   12287                                           " to connection " + c.conn.asBinder() +
   12288                                           " (in " + c.binding.client.processName + ")", e);
   12289                                 }
   12290                             }
   12291                         }
   12292                     }
   12293                 }
   12294 
   12295                 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
   12296 
   12297                 Binder.restoreCallingIdentity(origId);
   12298             }
   12299         }
   12300     }
   12301 
   12302     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
   12303         // Refuse possible leaked file descriptors
   12304         if (intent != null && intent.hasFileDescriptors() == true) {
   12305             throw new IllegalArgumentException("File descriptors passed in Intent");
   12306         }
   12307 
   12308         synchronized(this) {
   12309             if (!(token instanceof ServiceRecord)) {
   12310                 throw new IllegalArgumentException("Invalid service token");
   12311             }
   12312             ServiceRecord r = (ServiceRecord)token;
   12313 
   12314             final long origId = Binder.clearCallingIdentity();
   12315 
   12316             if (r != null) {
   12317                 Intent.FilterComparison filter
   12318                         = new Intent.FilterComparison(intent);
   12319                 IntentBindRecord b = r.bindings.get(filter);
   12320                 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
   12321                         + " at " + b + ": apps="
   12322                         + (b != null ? b.apps.size() : 0));
   12323 
   12324                 boolean inStopping = mStoppingServices.contains(r);
   12325                 if (b != null) {
   12326                     if (b.apps.size() > 0 && !inStopping) {
   12327                         // Applications have already bound since the last
   12328                         // unbind, so just rebind right here.
   12329                         requestServiceBindingLocked(r, b, true);
   12330                     } else {
   12331                         // Note to tell the service the next time there is
   12332                         // a new client.
   12333                         b.doRebind = true;
   12334                     }
   12335                 }
   12336 
   12337                 serviceDoneExecutingLocked(r, inStopping);
   12338 
   12339                 Binder.restoreCallingIdentity(origId);
   12340             }
   12341         }
   12342     }
   12343 
   12344     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
   12345         synchronized(this) {
   12346             if (!(token instanceof ServiceRecord)) {
   12347                 throw new IllegalArgumentException("Invalid service token");
   12348             }
   12349             ServiceRecord r = (ServiceRecord)token;
   12350             boolean inStopping = mStoppingServices.contains(token);
   12351             if (r != null) {
   12352                 if (r != token) {
   12353                     Slog.w(TAG, "Done executing service " + r.name
   12354                           + " with incorrect token: given " + token
   12355                           + ", expected " + r);
   12356                     return;
   12357                 }
   12358 
   12359                 if (type == 1) {
   12360                     // This is a call from a service start...  take care of
   12361                     // book-keeping.
   12362                     r.callStart = true;
   12363                     switch (res) {
   12364                         case Service.START_STICKY_COMPATIBILITY:
   12365                         case Service.START_STICKY: {
   12366                             // We are done with the associated start arguments.
   12367                             r.findDeliveredStart(startId, true);
   12368                             // Don't stop if killed.
   12369                             r.stopIfKilled = false;
   12370                             break;
   12371                         }
   12372                         case Service.START_NOT_STICKY: {
   12373                             // We are done with the associated start arguments.
   12374                             r.findDeliveredStart(startId, true);
   12375                             if (r.getLastStartId() == startId) {
   12376                                 // There is no more work, and this service
   12377                                 // doesn't want to hang around if killed.
   12378                                 r.stopIfKilled = true;
   12379                             }
   12380                             break;
   12381                         }
   12382                         case Service.START_REDELIVER_INTENT: {
   12383                             // We'll keep this item until they explicitly
   12384                             // call stop for it, but keep track of the fact
   12385                             // that it was delivered.
   12386                             ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
   12387                             if (si != null) {
   12388                                 si.deliveryCount = 0;
   12389                                 si.doneExecutingCount++;
   12390                                 // Don't stop if killed.
   12391                                 r.stopIfKilled = true;
   12392                             }
   12393                             break;
   12394                         }
   12395                         case Service.START_TASK_REMOVED_COMPLETE: {
   12396                             // Special processing for onTaskRemoved().  Don't
   12397                             // impact normal onStartCommand() processing.
   12398                             r.findDeliveredStart(startId, true);
   12399                             break;
   12400                         }
   12401                         default:
   12402                             throw new IllegalArgumentException(
   12403                                     "Unknown service start result: " + res);
   12404                     }
   12405                     if (res == Service.START_STICKY_COMPATIBILITY) {
   12406                         r.callStart = false;
   12407                     }
   12408                 }
   12409                 if (DEBUG_MU)
   12410                     Slog.v(TAG_MU, "before serviceDontExecutingLocked, uid="
   12411                             + Binder.getOrigCallingUid());
   12412                 final long origId = Binder.clearCallingIdentity();
   12413                 serviceDoneExecutingLocked(r, inStopping);
   12414                 Binder.restoreCallingIdentity(origId);
   12415             } else {
   12416                 Slog.w(TAG, "Done executing unknown service from pid "
   12417                         + Binder.getCallingPid());
   12418             }
   12419         }
   12420     }
   12421 
   12422     public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
   12423         if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
   12424                 + ": nesting=" + r.executeNesting
   12425                 + ", inStopping=" + inStopping + ", app=" + r.app);
   12426         else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
   12427         r.executeNesting--;
   12428         if (r.executeNesting <= 0 && r.app != null) {
   12429             if (DEBUG_SERVICE) Slog.v(TAG,
   12430                     "Nesting at 0 of " + r.shortName);
   12431             r.app.executingServices.remove(r);
   12432             if (r.app.executingServices.size() == 0) {
   12433                 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
   12434                         "No more executingServices of " + r.shortName);
   12435                 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
   12436             }
   12437             if (inStopping) {
   12438                 if (DEBUG_SERVICE) Slog.v(TAG,
   12439                         "doneExecuting remove stopping " + r);
   12440                 mStoppingServices.remove(r);
   12441                 r.bindings.clear();
   12442             }
   12443             updateOomAdjLocked(r.app);
   12444         }
   12445     }
   12446 
   12447     void serviceTimeout(ProcessRecord proc) {
   12448         String anrMessage = null;
   12449 
   12450         synchronized(this) {
   12451             if (proc.executingServices.size() == 0 || proc.thread == null) {
   12452                 return;
   12453             }
   12454             long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
   12455             Iterator<ServiceRecord> it = proc.executingServices.iterator();
   12456             ServiceRecord timeout = null;
   12457             long nextTime = 0;
   12458             while (it.hasNext()) {
   12459                 ServiceRecord sr = it.next();
   12460                 if (sr.executingStart < maxTime) {
   12461                     timeout = sr;
   12462                     break;
   12463                 }
   12464                 if (sr.executingStart > nextTime) {
   12465                     nextTime = sr.executingStart;
   12466                 }
   12467             }
   12468             if (timeout != null && mLruProcesses.contains(proc)) {
   12469                 Slog.w(TAG, "Timeout executing service: " + timeout);
   12470                 anrMessage = "Executing service " + timeout.shortName;
   12471             } else {
   12472                 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   12473                 msg.obj = proc;
   12474                 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
   12475             }
   12476         }
   12477 
   12478         if (anrMessage != null) {
   12479             appNotResponding(proc, null, null, anrMessage);
   12480         }
   12481     }
   12482 
   12483     // =========================================================
   12484     // BACKUP AND RESTORE
   12485     // =========================================================
   12486 
   12487     // Cause the target app to be launched if necessary and its backup agent
   12488     // instantiated.  The backup agent will invoke backupAgentCreated() on the
   12489     // activity manager to announce its creation.
   12490     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
   12491         if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
   12492         enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
   12493 
   12494         synchronized(this) {
   12495             // !!! TODO: currently no check here that we're already bound
   12496             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   12497             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   12498             synchronized (stats) {
   12499                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
   12500             }
   12501 
   12502             // Backup agent is now in use, its package can't be stopped.
   12503             try {
   12504                 AppGlobals.getPackageManager().setPackageStoppedState(
   12505                         app.packageName, false, UserId.getUserId(app.uid));
   12506             } catch (RemoteException e) {
   12507             } catch (IllegalArgumentException e) {
   12508                 Slog.w(TAG, "Failed trying to unstop package "
   12509                         + app.packageName + ": " + e);
   12510             }
   12511 
   12512             BackupRecord r = new BackupRecord(ss, app, backupMode);
   12513             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
   12514                     ? new ComponentName(app.packageName, app.backupAgentName)
   12515                     : new ComponentName("android", "FullBackupAgent");
   12516             // startProcessLocked() returns existing proc's record if it's already running
   12517             ProcessRecord proc = startProcessLocked(app.processName, app,
   12518                     false, 0, "backup", hostingName, false, false);
   12519             if (proc == null) {
   12520                 Slog.e(TAG, "Unable to start backup agent process " + r);
   12521                 return false;
   12522             }
   12523 
   12524             r.app = proc;
   12525             mBackupTarget = r;
   12526             mBackupAppName = app.packageName;
   12527 
   12528             // Try not to kill the process during backup
   12529             updateOomAdjLocked(proc);
   12530 
   12531             // If the process is already attached, schedule the creation of the backup agent now.
   12532             // If it is not yet live, this will be done when it attaches to the framework.
   12533             if (proc.thread != null) {
   12534                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
   12535                 try {
   12536                     proc.thread.scheduleCreateBackupAgent(app,
   12537                             compatibilityInfoForPackageLocked(app), backupMode);
   12538                 } catch (RemoteException e) {
   12539                     // Will time out on the backup manager side
   12540                 }
   12541             } else {
   12542                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
   12543             }
   12544             // Invariants: at this point, the target app process exists and the application
   12545             // is either already running or in the process of coming up.  mBackupTarget and
   12546             // mBackupAppName describe the app, so that when it binds back to the AM we
   12547             // know that it's scheduled for a backup-agent operation.
   12548         }
   12549 
   12550         return true;
   12551     }
   12552 
   12553     // A backup agent has just come up
   12554     public void backupAgentCreated(String agentPackageName, IBinder agent) {
   12555         if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
   12556                 + " = " + agent);
   12557 
   12558         synchronized(this) {
   12559             if (!agentPackageName.equals(mBackupAppName)) {
   12560                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
   12561                 return;
   12562             }
   12563         }
   12564 
   12565         long oldIdent = Binder.clearCallingIdentity();
   12566         try {
   12567             IBackupManager bm = IBackupManager.Stub.asInterface(
   12568                     ServiceManager.getService(Context.BACKUP_SERVICE));
   12569             bm.agentConnected(agentPackageName, agent);
   12570         } catch (RemoteException e) {
   12571             // can't happen; the backup manager service is local
   12572         } catch (Exception e) {
   12573             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
   12574             e.printStackTrace();
   12575         } finally {
   12576             Binder.restoreCallingIdentity(oldIdent);
   12577         }
   12578     }
   12579 
   12580     // done with this agent
   12581     public void unbindBackupAgent(ApplicationInfo appInfo) {
   12582         if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
   12583         if (appInfo == null) {
   12584             Slog.w(TAG, "unbind backup agent for null app");
   12585             return;
   12586         }
   12587 
   12588         synchronized(this) {
   12589             if (mBackupAppName == null) {
   12590                 Slog.w(TAG, "Unbinding backup agent with no active backup");
   12591                 return;
   12592             }
   12593 
   12594             if (!mBackupAppName.equals(appInfo.packageName)) {
   12595                 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
   12596                 return;
   12597             }
   12598 
   12599             ProcessRecord proc = mBackupTarget.app;
   12600             mBackupTarget = null;
   12601             mBackupAppName = null;
   12602 
   12603             // Not backing this app up any more; reset its OOM adjustment
   12604             updateOomAdjLocked(proc);
   12605 
   12606             // If the app crashed during backup, 'thread' will be null here
   12607             if (proc.thread != null) {
   12608                 try {
   12609                     proc.thread.scheduleDestroyBackupAgent(appInfo,
   12610                             compatibilityInfoForPackageLocked(appInfo));
   12611                 } catch (Exception e) {
   12612                     Slog.e(TAG, "Exception when unbinding backup agent:");
   12613                     e.printStackTrace();
   12614                 }
   12615             }
   12616         }
   12617     }
   12618     // =========================================================
   12619     // BROADCASTS
   12620     // =========================================================
   12621 
   12622     private final List getStickiesLocked(String action, IntentFilter filter,
   12623             List cur) {
   12624         final ContentResolver resolver = mContext.getContentResolver();
   12625         final ArrayList<Intent> list = mStickyBroadcasts.get(action);
   12626         if (list == null) {
   12627             return cur;
   12628         }
   12629         int N = list.size();
   12630         for (int i=0; i<N; i++) {
   12631             Intent intent = list.get(i);
   12632             if (filter.match(resolver, intent, true, TAG) >= 0) {
   12633                 if (cur == null) {
   12634                     cur = new ArrayList<Intent>();
   12635                 }
   12636                 cur.add(intent);
   12637             }
   12638         }
   12639         return cur;
   12640     }
   12641 
   12642     boolean isPendingBroadcastProcessLocked(int pid) {
   12643         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
   12644                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
   12645     }
   12646 
   12647     void skipPendingBroadcastLocked(int pid) {
   12648             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   12649             for (BroadcastQueue queue : mBroadcastQueues) {
   12650                 queue.skipPendingBroadcastLocked(pid);
   12651             }
   12652     }
   12653 
   12654     // The app just attached; send any pending broadcasts that it should receive
   12655     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
   12656         boolean didSomething = false;
   12657         for (BroadcastQueue queue : mBroadcastQueues) {
   12658             didSomething |= queue.sendPendingBroadcastsLocked(app);
   12659         }
   12660         return didSomething;
   12661     }
   12662 
   12663     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
   12664             IIntentReceiver receiver, IntentFilter filter, String permission) {
   12665         enforceNotIsolatedCaller("registerReceiver");
   12666         synchronized(this) {
   12667             ProcessRecord callerApp = null;
   12668             if (caller != null) {
   12669                 callerApp = getRecordForAppLocked(caller);
   12670                 if (callerApp == null) {
   12671                     throw new SecurityException(
   12672                             "Unable to find app for caller " + caller
   12673                             + " (pid=" + Binder.getCallingPid()
   12674                             + ") when registering receiver " + receiver);
   12675                 }
   12676                 if (callerApp.info.uid != Process.SYSTEM_UID &&
   12677                         !callerApp.pkgList.contains(callerPackage)) {
   12678                     throw new SecurityException("Given caller package " + callerPackage
   12679                             + " is not running in process " + callerApp);
   12680                 }
   12681             } else {
   12682                 callerPackage = null;
   12683             }
   12684 
   12685             List allSticky = null;
   12686 
   12687             // Look for any matching sticky broadcasts...
   12688             Iterator actions = filter.actionsIterator();
   12689             if (actions != null) {
   12690                 while (actions.hasNext()) {
   12691                     String action = (String)actions.next();
   12692                     allSticky = getStickiesLocked(action, filter, allSticky);
   12693                 }
   12694             } else {
   12695                 allSticky = getStickiesLocked(null, filter, allSticky);
   12696             }
   12697 
   12698             // The first sticky in the list is returned directly back to
   12699             // the client.
   12700             Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
   12701 
   12702             if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
   12703                     + ": " + sticky);
   12704 
   12705             if (receiver == null) {
   12706                 return sticky;
   12707             }
   12708 
   12709             ReceiverList rl
   12710                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   12711             if (rl == null) {
   12712                 rl = new ReceiverList(this, callerApp,
   12713                         Binder.getCallingPid(),
   12714                         Binder.getCallingUid(), receiver);
   12715                 if (rl.app != null) {
   12716                     rl.app.receivers.add(rl);
   12717                 } else {
   12718                     try {
   12719                         receiver.asBinder().linkToDeath(rl, 0);
   12720                     } catch (RemoteException e) {
   12721                         return sticky;
   12722                     }
   12723                     rl.linkedToDeath = true;
   12724                 }
   12725                 mRegisteredReceivers.put(receiver.asBinder(), rl);
   12726             }
   12727             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
   12728             rl.add(bf);
   12729             if (!bf.debugCheck()) {
   12730                 Slog.w(TAG, "==> For Dynamic broadast");
   12731             }
   12732             mReceiverResolver.addFilter(bf);
   12733 
   12734             // Enqueue broadcasts for all existing stickies that match
   12735             // this filter.
   12736             if (allSticky != null) {
   12737                 ArrayList receivers = new ArrayList();
   12738                 receivers.add(bf);
   12739 
   12740                 int N = allSticky.size();
   12741                 for (int i=0; i<N; i++) {
   12742                     Intent intent = (Intent)allSticky.get(i);
   12743                     BroadcastQueue queue = broadcastQueueForIntent(intent);
   12744                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
   12745                             null, -1, -1, null, receivers, null, 0, null, null,
   12746                             false, true, true);
   12747                     queue.enqueueParallelBroadcastLocked(r);
   12748                     queue.scheduleBroadcastsLocked();
   12749                 }
   12750             }
   12751 
   12752             return sticky;
   12753         }
   12754     }
   12755 
   12756     public void unregisterReceiver(IIntentReceiver receiver) {
   12757         if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
   12758 
   12759         final long origId = Binder.clearCallingIdentity();
   12760         try {
   12761             boolean doTrim = false;
   12762 
   12763             synchronized(this) {
   12764                 ReceiverList rl
   12765                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   12766                 if (rl != null) {
   12767                     if (rl.curBroadcast != null) {
   12768                         BroadcastRecord r = rl.curBroadcast;
   12769                         final boolean doNext = finishReceiverLocked(
   12770                                 receiver.asBinder(), r.resultCode, r.resultData,
   12771                                 r.resultExtras, r.resultAbort, true);
   12772                         if (doNext) {
   12773                             doTrim = true;
   12774                             r.queue.processNextBroadcast(false);
   12775                         }
   12776                     }
   12777 
   12778                     if (rl.app != null) {
   12779                         rl.app.receivers.remove(rl);
   12780                     }
   12781                     removeReceiverLocked(rl);
   12782                     if (rl.linkedToDeath) {
   12783                         rl.linkedToDeath = false;
   12784                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
   12785                     }
   12786                 }
   12787             }
   12788 
   12789             // If we actually concluded any broadcasts, we might now be able
   12790             // to trim the recipients' apps from our working set
   12791             if (doTrim) {
   12792                 trimApplications();
   12793                 return;
   12794             }
   12795 
   12796         } finally {
   12797             Binder.restoreCallingIdentity(origId);
   12798         }
   12799     }
   12800 
   12801     void removeReceiverLocked(ReceiverList rl) {
   12802         mRegisteredReceivers.remove(rl.receiver.asBinder());
   12803         int N = rl.size();
   12804         for (int i=0; i<N; i++) {
   12805             mReceiverResolver.removeFilter(rl.get(i));
   12806         }
   12807     }
   12808 
   12809     private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
   12810         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   12811             ProcessRecord r = mLruProcesses.get(i);
   12812             if (r.thread != null) {
   12813                 try {
   12814                     r.thread.dispatchPackageBroadcast(cmd, packages);
   12815                 } catch (RemoteException ex) {
   12816                 }
   12817             }
   12818         }
   12819     }
   12820 
   12821     private final int broadcastIntentLocked(ProcessRecord callerApp,
   12822             String callerPackage, Intent intent, String resolvedType,
   12823             IIntentReceiver resultTo, int resultCode, String resultData,
   12824             Bundle map, String requiredPermission,
   12825             boolean ordered, boolean sticky, int callingPid, int callingUid,
   12826             int userId) {
   12827         intent = new Intent(intent);
   12828 
   12829         // By default broadcasts do not go to stopped apps.
   12830         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
   12831 
   12832         if (DEBUG_BROADCAST_LIGHT) Slog.v(
   12833             TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
   12834             + " ordered=" + ordered + " userid=" + userId);
   12835         if ((resultTo != null) && !ordered) {
   12836             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
   12837         }
   12838 
   12839         // Handle special intents: if this broadcast is from the package
   12840         // manager about a package being removed, we need to remove all of
   12841         // its activities from the history stack.
   12842         final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
   12843                 intent.getAction());
   12844         if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
   12845                 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
   12846                 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
   12847                 || uidRemoved) {
   12848             if (checkComponentPermission(
   12849                     android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
   12850                     callingPid, callingUid, -1, true)
   12851                     == PackageManager.PERMISSION_GRANTED) {
   12852                 if (uidRemoved) {
   12853                     final Bundle intentExtras = intent.getExtras();
   12854                     final int uid = intentExtras != null
   12855                             ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
   12856                     if (uid >= 0) {
   12857                         BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
   12858                         synchronized (bs) {
   12859                             bs.removeUidStatsLocked(uid);
   12860                         }
   12861                     }
   12862                 } else {
   12863                     // If resources are unvailble just force stop all
   12864                     // those packages and flush the attribute cache as well.
   12865                     if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
   12866                         String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   12867                         if (list != null && (list.length > 0)) {
   12868                             for (String pkg : list) {
   12869                                 forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
   12870                             }
   12871                             sendPackageBroadcastLocked(
   12872                                     IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
   12873                         }
   12874                     } else {
   12875                         Uri data = intent.getData();
   12876                         String ssp;
   12877                         if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   12878                             if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
   12879                                 forceStopPackageLocked(ssp,
   12880                                         intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
   12881                                         false, userId);
   12882                             }
   12883                             if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
   12884                                 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
   12885                                         new String[] {ssp});
   12886                             }
   12887                         }
   12888                     }
   12889                 }
   12890             } else {
   12891                 String msg = "Permission Denial: " + intent.getAction()
   12892                         + " broadcast from " + callerPackage + " (pid=" + callingPid
   12893                         + ", uid=" + callingUid + ")"
   12894                         + " requires "
   12895                         + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
   12896                 Slog.w(TAG, msg);
   12897                 throw new SecurityException(msg);
   12898             }
   12899 
   12900         // Special case for adding a package: by default turn on compatibility
   12901         // mode.
   12902         } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
   12903             Uri data = intent.getData();
   12904             String ssp;
   12905             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   12906                 mCompatModePackages.handlePackageAddedLocked(ssp,
   12907                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
   12908             }
   12909         }
   12910 
   12911         /*
   12912          * If this is the time zone changed action, queue up a message that will reset the timezone
   12913          * of all currently running processes. This message will get queued up before the broadcast
   12914          * happens.
   12915          */
   12916         if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
   12917             mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
   12918         }
   12919 
   12920         if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
   12921             mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
   12922         }
   12923 
   12924         if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
   12925             ProxyProperties proxy = intent.getParcelableExtra("proxy");
   12926             mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
   12927         }
   12928 
   12929         /*
   12930          * Prevent non-system code (defined here to be non-persistent
   12931          * processes) from sending protected broadcasts.
   12932          */
   12933         if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
   12934                 || callingUid == Process.SHELL_UID || callingUid == 0) {
   12935             // Always okay.
   12936         } else if (callerApp == null || !callerApp.persistent) {
   12937             try {
   12938                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
   12939                         intent.getAction())) {
   12940                     String msg = "Permission Denial: not allowed to send broadcast "
   12941                             + intent.getAction() + " from pid="
   12942                             + callingPid + ", uid=" + callingUid;
   12943                     Slog.w(TAG, msg);
   12944                     throw new SecurityException(msg);
   12945                 }
   12946             } catch (RemoteException e) {
   12947                 Slog.w(TAG, "Remote exception", e);
   12948                 return ActivityManager.BROADCAST_SUCCESS;
   12949             }
   12950         }
   12951 
   12952         // Add to the sticky list if requested.
   12953         if (sticky) {
   12954             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
   12955                     callingPid, callingUid)
   12956                     != PackageManager.PERMISSION_GRANTED) {
   12957                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
   12958                         + callingPid + ", uid=" + callingUid
   12959                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   12960                 Slog.w(TAG, msg);
   12961                 throw new SecurityException(msg);
   12962             }
   12963             if (requiredPermission != null) {
   12964                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
   12965                         + " and enforce permission " + requiredPermission);
   12966                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
   12967             }
   12968             if (intent.getComponent() != null) {
   12969                 throw new SecurityException(
   12970                         "Sticky broadcasts can't target a specific component");
   12971             }
   12972             ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
   12973             if (list == null) {
   12974                 list = new ArrayList<Intent>();
   12975                 mStickyBroadcasts.put(intent.getAction(), list);
   12976             }
   12977             int N = list.size();
   12978             int i;
   12979             for (i=0; i<N; i++) {
   12980                 if (intent.filterEquals(list.get(i))) {
   12981                     // This sticky already exists, replace it.
   12982                     list.set(i, new Intent(intent));
   12983                     break;
   12984                 }
   12985             }
   12986             if (i >= N) {
   12987                 list.add(new Intent(intent));
   12988             }
   12989         }
   12990 
   12991         // Figure out who all will receive this broadcast.
   12992         List receivers = null;
   12993         List<BroadcastFilter> registeredReceivers = null;
   12994         try {
   12995             if (intent.getComponent() != null) {
   12996                 // Broadcast is going to one specific receiver class...
   12997                 ActivityInfo ai = AppGlobals.getPackageManager().
   12998                         getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS, userId);
   12999                 if (ai != null) {
   13000                     receivers = new ArrayList();
   13001                     ResolveInfo ri = new ResolveInfo();
   13002                     if (isSingleton(ai.processName, ai.applicationInfo)) {
   13003                         ri.activityInfo = getActivityInfoForUser(ai, 0);
   13004                     } else {
   13005                         ri.activityInfo = getActivityInfoForUser(ai, userId);
   13006                     }
   13007                     receivers.add(ri);
   13008                 }
   13009             } else {
   13010                 // Need to resolve the intent to interested receivers...
   13011                 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
   13012                          == 0) {
   13013                     receivers =
   13014                         AppGlobals.getPackageManager().queryIntentReceivers(
   13015                                     intent, resolvedType, STOCK_PM_FLAGS, userId);
   13016                 }
   13017                 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false,
   13018                         userId);
   13019             }
   13020         } catch (RemoteException ex) {
   13021             // pm is in same process, this will never happen.
   13022         }
   13023 
   13024         final boolean replacePending =
   13025                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
   13026 
   13027         if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
   13028                 + " replacePending=" + replacePending);
   13029 
   13030         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
   13031         if (!ordered && NR > 0) {
   13032             // If we are not serializing this broadcast, then send the
   13033             // registered receivers separately so they don't wait for the
   13034             // components to be launched.
   13035             final BroadcastQueue queue = broadcastQueueForIntent(intent);
   13036             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   13037                     callerPackage, callingPid, callingUid, requiredPermission,
   13038                     registeredReceivers, resultTo, resultCode, resultData, map,
   13039                     ordered, sticky, false);
   13040             if (DEBUG_BROADCAST) Slog.v(
   13041                     TAG, "Enqueueing parallel broadcast " + r);
   13042             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
   13043             if (!replaced) {
   13044                 queue.enqueueParallelBroadcastLocked(r);
   13045                 queue.scheduleBroadcastsLocked();
   13046             }
   13047             registeredReceivers = null;
   13048             NR = 0;
   13049         }
   13050 
   13051         // Merge into one list.
   13052         int ir = 0;
   13053         if (receivers != null) {
   13054             // A special case for PACKAGE_ADDED: do not allow the package
   13055             // being added to see this broadcast.  This prevents them from
   13056             // using this as a back door to get run as soon as they are
   13057             // installed.  Maybe in the future we want to have a special install
   13058             // broadcast or such for apps, but we'd like to deliberately make
   13059             // this decision.
   13060             String skipPackages[] = null;
   13061             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
   13062                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
   13063                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
   13064                 Uri data = intent.getData();
   13065                 if (data != null) {
   13066                     String pkgName = data.getSchemeSpecificPart();
   13067                     if (pkgName != null) {
   13068                         skipPackages = new String[] { pkgName };
   13069                     }
   13070                 }
   13071             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
   13072                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   13073             }
   13074             if (skipPackages != null && (skipPackages.length > 0)) {
   13075                 for (String skipPackage : skipPackages) {
   13076                     if (skipPackage != null) {
   13077                         int NT = receivers.size();
   13078                         for (int it=0; it<NT; it++) {
   13079                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
   13080                             if (curt.activityInfo.packageName.equals(skipPackage)) {
   13081                                 receivers.remove(it);
   13082                                 it--;
   13083                                 NT--;
   13084                             }
   13085                         }
   13086                     }
   13087                 }
   13088             }
   13089 
   13090             int NT = receivers != null ? receivers.size() : 0;
   13091             int it = 0;
   13092             ResolveInfo curt = null;
   13093             BroadcastFilter curr = null;
   13094             while (it < NT && ir < NR) {
   13095                 if (curt == null) {
   13096                     curt = (ResolveInfo)receivers.get(it);
   13097                 }
   13098                 if (curr == null) {
   13099                     curr = registeredReceivers.get(ir);
   13100                 }
   13101                 if (curr.getPriority() >= curt.priority) {
   13102                     // Insert this broadcast record into the final list.
   13103                     receivers.add(it, curr);
   13104                     ir++;
   13105                     curr = null;
   13106                     it++;
   13107                     NT++;
   13108                 } else {
   13109                     // Skip to the next ResolveInfo in the final list.
   13110                     it++;
   13111                     curt = null;
   13112                 }
   13113             }
   13114         }
   13115         while (ir < NR) {
   13116             if (receivers == null) {
   13117                 receivers = new ArrayList();
   13118             }
   13119             receivers.add(registeredReceivers.get(ir));
   13120             ir++;
   13121         }
   13122 
   13123         if ((receivers != null && receivers.size() > 0)
   13124                 || resultTo != null) {
   13125             BroadcastQueue queue = broadcastQueueForIntent(intent);
   13126             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   13127                     callerPackage, callingPid, callingUid, requiredPermission,
   13128                     receivers, resultTo, resultCode, resultData, map, ordered,
   13129                     sticky, false);
   13130             if (DEBUG_BROADCAST) Slog.v(
   13131                     TAG, "Enqueueing ordered broadcast " + r
   13132                     + ": prev had " + queue.mOrderedBroadcasts.size());
   13133             if (DEBUG_BROADCAST) {
   13134                 int seq = r.intent.getIntExtra("seq", -1);
   13135                 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
   13136             }
   13137             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
   13138             if (!replaced) {
   13139                 queue.enqueueOrderedBroadcastLocked(r);
   13140                 queue.scheduleBroadcastsLocked();
   13141             }
   13142         }
   13143 
   13144         return ActivityManager.BROADCAST_SUCCESS;
   13145     }
   13146 
   13147     final Intent verifyBroadcastLocked(Intent intent) {
   13148         // Refuse possible leaked file descriptors
   13149         if (intent != null && intent.hasFileDescriptors() == true) {
   13150             throw new IllegalArgumentException("File descriptors passed in Intent");
   13151         }
   13152 
   13153         int flags = intent.getFlags();
   13154 
   13155         if (!mProcessesReady) {
   13156             // if the caller really truly claims to know what they're doing, go
   13157             // ahead and allow the broadcast without launching any receivers
   13158             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
   13159                 intent = new Intent(intent);
   13160                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   13161             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
   13162                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
   13163                         + " before boot completion");
   13164                 throw new IllegalStateException("Cannot broadcast before boot completed");
   13165             }
   13166         }
   13167 
   13168         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   13169             throw new IllegalArgumentException(
   13170                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   13171         }
   13172 
   13173         return intent;
   13174     }
   13175 
   13176     public final int broadcastIntent(IApplicationThread caller,
   13177             Intent intent, String resolvedType, IIntentReceiver resultTo,
   13178             int resultCode, String resultData, Bundle map,
   13179             String requiredPermission, boolean serialized, boolean sticky, int userId) {
   13180         enforceNotIsolatedCaller("broadcastIntent");
   13181         synchronized(this) {
   13182             intent = verifyBroadcastLocked(intent);
   13183 
   13184             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   13185             final int callingPid = Binder.getCallingPid();
   13186             final int callingUid = Binder.getCallingUid();
   13187             final long origId = Binder.clearCallingIdentity();
   13188             int res = broadcastIntentLocked(callerApp,
   13189                     callerApp != null ? callerApp.info.packageName : null,
   13190                     intent, resolvedType, resultTo,
   13191                     resultCode, resultData, map, requiredPermission, serialized, sticky,
   13192                     callingPid, callingUid, userId);
   13193             Binder.restoreCallingIdentity(origId);
   13194             return res;
   13195         }
   13196     }
   13197 
   13198     int broadcastIntentInPackage(String packageName, int uid,
   13199             Intent intent, String resolvedType, IIntentReceiver resultTo,
   13200             int resultCode, String resultData, Bundle map,
   13201             String requiredPermission, boolean serialized, boolean sticky, int userId) {
   13202         synchronized(this) {
   13203             intent = verifyBroadcastLocked(intent);
   13204 
   13205             final long origId = Binder.clearCallingIdentity();
   13206             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
   13207                     resultTo, resultCode, resultData, map, requiredPermission,
   13208                     serialized, sticky, -1, uid, userId);
   13209             Binder.restoreCallingIdentity(origId);
   13210             return res;
   13211         }
   13212     }
   13213 
   13214     // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user.
   13215     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
   13216         // Refuse possible leaked file descriptors
   13217         if (intent != null && intent.hasFileDescriptors() == true) {
   13218             throw new IllegalArgumentException("File descriptors passed in Intent");
   13219         }
   13220 
   13221         synchronized(this) {
   13222             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
   13223                     != PackageManager.PERMISSION_GRANTED) {
   13224                 String msg = "Permission Denial: unbroadcastIntent() from pid="
   13225                         + Binder.getCallingPid()
   13226                         + ", uid=" + Binder.getCallingUid()
   13227                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   13228                 Slog.w(TAG, msg);
   13229                 throw new SecurityException(msg);
   13230             }
   13231             ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
   13232             if (list != null) {
   13233                 int N = list.size();
   13234                 int i;
   13235                 for (i=0; i<N; i++) {
   13236                     if (intent.filterEquals(list.get(i))) {
   13237                         list.remove(i);
   13238                         break;
   13239                     }
   13240                 }
   13241             }
   13242         }
   13243     }
   13244 
   13245     private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
   13246             String resultData, Bundle resultExtras, boolean resultAbort,
   13247             boolean explicit) {
   13248         final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
   13249         if (r == null) {
   13250             Slog.w(TAG, "finishReceiver called but not found on queue");
   13251             return false;
   13252         }
   13253 
   13254         return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
   13255                 explicit);
   13256     }
   13257 
   13258     public void finishReceiver(IBinder who, int resultCode, String resultData,
   13259             Bundle resultExtras, boolean resultAbort) {
   13260         if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
   13261 
   13262         // Refuse possible leaked file descriptors
   13263         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
   13264             throw new IllegalArgumentException("File descriptors passed in Bundle");
   13265         }
   13266 
   13267         final long origId = Binder.clearCallingIdentity();
   13268         try {
   13269             boolean doNext = false;
   13270             BroadcastRecord r = null;
   13271 
   13272             synchronized(this) {
   13273                 r = broadcastRecordForReceiverLocked(who);
   13274                 if (r != null) {
   13275                     doNext = r.queue.finishReceiverLocked(r, resultCode,
   13276                         resultData, resultExtras, resultAbort, true);
   13277                 }
   13278             }
   13279 
   13280             if (doNext) {
   13281                 r.queue.processNextBroadcast(false);
   13282             }
   13283             trimApplications();
   13284         } finally {
   13285             Binder.restoreCallingIdentity(origId);
   13286         }
   13287     }
   13288 
   13289     // =========================================================
   13290     // INSTRUMENTATION
   13291     // =========================================================
   13292 
   13293     public boolean startInstrumentation(ComponentName className,
   13294             String profileFile, int flags, Bundle arguments,
   13295             IInstrumentationWatcher watcher) {
   13296         enforceNotIsolatedCaller("startInstrumentation");
   13297         // Refuse possible leaked file descriptors
   13298         if (arguments != null && arguments.hasFileDescriptors()) {
   13299             throw new IllegalArgumentException("File descriptors passed in Bundle");
   13300         }
   13301 
   13302         synchronized(this) {
   13303             InstrumentationInfo ii = null;
   13304             ApplicationInfo ai = null;
   13305             try {
   13306                 ii = mContext.getPackageManager().getInstrumentationInfo(
   13307                     className, STOCK_PM_FLAGS);
   13308                 ai = mContext.getPackageManager().getApplicationInfo(
   13309                         ii.targetPackage, STOCK_PM_FLAGS);
   13310             } catch (PackageManager.NameNotFoundException e) {
   13311             }
   13312             if (ii == null) {
   13313                 reportStartInstrumentationFailure(watcher, className,
   13314                         "Unable to find instrumentation info for: " + className);
   13315                 return false;
   13316             }
   13317             if (ai == null) {
   13318                 reportStartInstrumentationFailure(watcher, className,
   13319                         "Unable to find instrumentation target package: " + ii.targetPackage);
   13320                 return false;
   13321             }
   13322 
   13323             int match = mContext.getPackageManager().checkSignatures(
   13324                     ii.targetPackage, ii.packageName);
   13325             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
   13326                 String msg = "Permission Denial: starting instrumentation "
   13327                         + className + " from pid="
   13328                         + Binder.getCallingPid()
   13329                         + ", uid=" + Binder.getCallingPid()
   13330                         + " not allowed because package " + ii.packageName
   13331                         + " does not have a signature matching the target "
   13332                         + ii.targetPackage;
   13333                 reportStartInstrumentationFailure(watcher, className, msg);
   13334                 throw new SecurityException(msg);
   13335             }
   13336 
   13337             int userId = UserId.getCallingUserId();
   13338             final long origId = Binder.clearCallingIdentity();
   13339             // Instrumentation can kill and relaunch even persistent processes
   13340             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
   13341             ProcessRecord app = addAppLocked(ai, false);
   13342             app.instrumentationClass = className;
   13343             app.instrumentationInfo = ai;
   13344             app.instrumentationProfileFile = profileFile;
   13345             app.instrumentationArguments = arguments;
   13346             app.instrumentationWatcher = watcher;
   13347             app.instrumentationResultClass = className;
   13348             Binder.restoreCallingIdentity(origId);
   13349         }
   13350 
   13351         return true;
   13352     }
   13353 
   13354     /**
   13355      * Report errors that occur while attempting to start Instrumentation.  Always writes the
   13356      * error to the logs, but if somebody is watching, send the report there too.  This enables
   13357      * the "am" command to report errors with more information.
   13358      *
   13359      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
   13360      * @param cn The component name of the instrumentation.
   13361      * @param report The error report.
   13362      */
   13363     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
   13364             ComponentName cn, String report) {
   13365         Slog.w(TAG, report);
   13366         try {
   13367             if (watcher != null) {
   13368                 Bundle results = new Bundle();
   13369                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
   13370                 results.putString("Error", report);
   13371                 watcher.instrumentationStatus(cn, -1, results);
   13372             }
   13373         } catch (RemoteException e) {
   13374             Slog.w(TAG, e);
   13375         }
   13376     }
   13377 
   13378     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
   13379         if (app.instrumentationWatcher != null) {
   13380             try {
   13381                 // NOTE:  IInstrumentationWatcher *must* be oneway here
   13382                 app.instrumentationWatcher.instrumentationFinished(
   13383                     app.instrumentationClass,
   13384                     resultCode,
   13385                     results);
   13386             } catch (RemoteException e) {
   13387             }
   13388         }
   13389         app.instrumentationWatcher = null;
   13390         app.instrumentationClass = null;
   13391         app.instrumentationInfo = null;
   13392         app.instrumentationProfileFile = null;
   13393         app.instrumentationArguments = null;
   13394 
   13395         forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId);
   13396     }
   13397 
   13398     public void finishInstrumentation(IApplicationThread target,
   13399             int resultCode, Bundle results) {
   13400         int userId = UserId.getCallingUserId();
   13401         // Refuse possible leaked file descriptors
   13402         if (results != null && results.hasFileDescriptors()) {
   13403             throw new IllegalArgumentException("File descriptors passed in Intent");
   13404         }
   13405 
   13406         synchronized(this) {
   13407             ProcessRecord app = getRecordForAppLocked(target);
   13408             if (app == null) {
   13409                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
   13410                 return;
   13411             }
   13412             final long origId = Binder.clearCallingIdentity();
   13413             finishInstrumentationLocked(app, resultCode, results);
   13414             Binder.restoreCallingIdentity(origId);
   13415         }
   13416     }
   13417 
   13418     // =========================================================
   13419     // CONFIGURATION
   13420     // =========================================================
   13421 
   13422     public ConfigurationInfo getDeviceConfigurationInfo() {
   13423         ConfigurationInfo config = new ConfigurationInfo();
   13424         synchronized (this) {
   13425             config.reqTouchScreen = mConfiguration.touchscreen;
   13426             config.reqKeyboardType = mConfiguration.keyboard;
   13427             config.reqNavigation = mConfiguration.navigation;
   13428             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
   13429                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
   13430                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
   13431             }
   13432             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
   13433                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
   13434                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
   13435             }
   13436             config.reqGlEsVersion = GL_ES_VERSION;
   13437         }
   13438         return config;
   13439     }
   13440 
   13441     public Configuration getConfiguration() {
   13442         Configuration ci;
   13443         synchronized(this) {
   13444             ci = new Configuration(mConfiguration);
   13445         }
   13446         return ci;
   13447     }
   13448 
   13449     public void updatePersistentConfiguration(Configuration values) {
   13450         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   13451                 "updateConfiguration()");
   13452         enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
   13453                 "updateConfiguration()");
   13454         if (values == null) {
   13455             throw new NullPointerException("Configuration must not be null");
   13456         }
   13457 
   13458         synchronized(this) {
   13459             final long origId = Binder.clearCallingIdentity();
   13460             updateConfigurationLocked(values, null, true, false);
   13461             Binder.restoreCallingIdentity(origId);
   13462         }
   13463     }
   13464 
   13465     public void updateConfiguration(Configuration values) {
   13466         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   13467                 "updateConfiguration()");
   13468 
   13469         synchronized(this) {
   13470             if (values == null && mWindowManager != null) {
   13471                 // sentinel: fetch the current configuration from the window manager
   13472                 values = mWindowManager.computeNewConfiguration();
   13473             }
   13474 
   13475             if (mWindowManager != null) {
   13476                 mProcessList.applyDisplaySize(mWindowManager);
   13477             }
   13478 
   13479             final long origId = Binder.clearCallingIdentity();
   13480             if (values != null) {
   13481                 Settings.System.clearConfiguration(values);
   13482             }
   13483             updateConfigurationLocked(values, null, false, false);
   13484             Binder.restoreCallingIdentity(origId);
   13485         }
   13486     }
   13487 
   13488     /**
   13489      * Do either or both things: (1) change the current configuration, and (2)
   13490      * make sure the given activity is running with the (now) current
   13491      * configuration.  Returns true if the activity has been left running, or
   13492      * false if <var>starting</var> is being destroyed to match the new
   13493      * configuration.
   13494      * @param persistent TODO
   13495      */
   13496     boolean updateConfigurationLocked(Configuration values,
   13497             ActivityRecord starting, boolean persistent, boolean initLocale) {
   13498         // do nothing if we are headless
   13499         if (mHeadless) return true;
   13500 
   13501         int changes = 0;
   13502 
   13503         boolean kept = true;
   13504 
   13505         if (values != null) {
   13506             Configuration newConfig = new Configuration(mConfiguration);
   13507             changes = newConfig.updateFrom(values);
   13508             if (changes != 0) {
   13509                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
   13510                     Slog.i(TAG, "Updating configuration to: " + values);
   13511                 }
   13512 
   13513                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
   13514 
   13515                 if (values.locale != null && !initLocale) {
   13516                     saveLocaleLocked(values.locale,
   13517                                      !values.locale.equals(mConfiguration.locale),
   13518                                      values.userSetLocale);
   13519                 }
   13520 
   13521                 mConfigurationSeq++;
   13522                 if (mConfigurationSeq <= 0) {
   13523                     mConfigurationSeq = 1;
   13524                 }
   13525                 newConfig.seq = mConfigurationSeq;
   13526                 mConfiguration = newConfig;
   13527                 Slog.i(TAG, "Config changed: " + newConfig);
   13528 
   13529                 final Configuration configCopy = new Configuration(mConfiguration);
   13530 
   13531                 // TODO: If our config changes, should we auto dismiss any currently
   13532                 // showing dialogs?
   13533                 mShowDialogs = shouldShowDialogs(newConfig);
   13534 
   13535                 AttributeCache ac = AttributeCache.instance();
   13536                 if (ac != null) {
   13537                     ac.updateConfiguration(configCopy);
   13538                 }
   13539 
   13540                 // Make sure all resources in our process are updated
   13541                 // right now, so that anyone who is going to retrieve
   13542                 // resource values after we return will be sure to get
   13543                 // the new ones.  This is especially important during
   13544                 // boot, where the first config change needs to guarantee
   13545                 // all resources have that config before following boot
   13546                 // code is executed.
   13547                 mSystemThread.applyConfigurationToResources(configCopy);
   13548 
   13549                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
   13550                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
   13551                     msg.obj = new Configuration(configCopy);
   13552                     mHandler.sendMessage(msg);
   13553                 }
   13554 
   13555                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   13556                     ProcessRecord app = mLruProcesses.get(i);
   13557                     try {
   13558                         if (app.thread != null) {
   13559                             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
   13560                                     + app.processName + " new config " + mConfiguration);
   13561                             app.thread.scheduleConfigurationChanged(configCopy);
   13562                         }
   13563                     } catch (Exception e) {
   13564                     }
   13565                 }
   13566                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
   13567                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   13568                         | Intent.FLAG_RECEIVER_REPLACE_PENDING);
   13569                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
   13570                         null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
   13571                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
   13572                     broadcastIntentLocked(null, null,
   13573                             new Intent(Intent.ACTION_LOCALE_CHANGED),
   13574                             null, null, 0, null, null,
   13575                             null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
   13576                 }
   13577             }
   13578         }
   13579 
   13580         if (changes != 0 && starting == null) {
   13581             // If the configuration changed, and the caller is not already
   13582             // in the process of starting an activity, then find the top
   13583             // activity to check if its configuration needs to change.
   13584             starting = mMainStack.topRunningActivityLocked(null);
   13585         }
   13586 
   13587         if (starting != null) {
   13588             kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
   13589             // And we need to make sure at this point that all other activities
   13590             // are made visible with the correct configuration.
   13591             mMainStack.ensureActivitiesVisibleLocked(starting, changes);
   13592         }
   13593 
   13594         if (values != null && mWindowManager != null) {
   13595             mWindowManager.setNewConfiguration(mConfiguration);
   13596         }
   13597 
   13598         return kept;
   13599     }
   13600 
   13601     /**
   13602      * Decide based on the configuration whether we should shouw the ANR,
   13603      * crash, etc dialogs.  The idea is that if there is no affordnace to
   13604      * press the on-screen buttons, we shouldn't show the dialog.
   13605      *
   13606      * A thought: SystemUI might also want to get told about this, the Power
   13607      * dialog / global actions also might want different behaviors.
   13608      */
   13609     private static final boolean shouldShowDialogs(Configuration config) {
   13610         return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
   13611                 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
   13612     }
   13613 
   13614     /**
   13615      * Save the locale.  You must be inside a synchronized (this) block.
   13616      */
   13617     private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
   13618         if(isDiff) {
   13619             SystemProperties.set("user.language", l.getLanguage());
   13620             SystemProperties.set("user.region", l.getCountry());
   13621         }
   13622 
   13623         if(isPersist) {
   13624             SystemProperties.set("persist.sys.language", l.getLanguage());
   13625             SystemProperties.set("persist.sys.country", l.getCountry());
   13626             SystemProperties.set("persist.sys.localevar", l.getVariant());
   13627         }
   13628     }
   13629 
   13630     @Override
   13631     public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
   13632         ActivityRecord srec = ActivityRecord.forToken(token);
   13633         return srec != null && srec.task.affinity != null &&
   13634                 srec.task.affinity.equals(destAffinity);
   13635     }
   13636 
   13637     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
   13638             Intent resultData) {
   13639         ComponentName dest = destIntent.getComponent();
   13640 
   13641         synchronized (this) {
   13642             ActivityRecord srec = ActivityRecord.forToken(token);
   13643             if (srec == null) {
   13644                 return false;
   13645             }
   13646             ArrayList<ActivityRecord> history = srec.stack.mHistory;
   13647             final int start = history.indexOf(srec);
   13648             if (start < 0) {
   13649                 // Current activity is not in history stack; do nothing.
   13650                 return false;
   13651             }
   13652             int finishTo = start - 1;
   13653             ActivityRecord parent = null;
   13654             boolean foundParentInTask = false;
   13655             if (dest != null) {
   13656                 TaskRecord tr = srec.task;
   13657                 for (int i = start - 1; i >= 0; i--) {
   13658                     ActivityRecord r = history.get(i);
   13659                     if (tr != r.task) {
   13660                         // Couldn't find parent in the same task; stop at the one above this.
   13661                         // (Root of current task; in-app "home" behavior)
   13662                         // Always at least finish the current activity.
   13663                         finishTo = Math.min(start - 1, i + 1);
   13664                         parent = history.get(finishTo);
   13665                         break;
   13666                     } else if (r.info.packageName.equals(dest.getPackageName()) &&
   13667                             r.info.name.equals(dest.getClassName())) {
   13668                         finishTo = i;
   13669                         parent = r;
   13670                         foundParentInTask = true;
   13671                         break;
   13672                     }
   13673                 }
   13674             }
   13675 
   13676             if (mController != null) {
   13677                 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
   13678                 if (next != null) {
   13679                     // ask watcher if this is allowed
   13680                     boolean resumeOK = true;
   13681                     try {
   13682                         resumeOK = mController.activityResuming(next.packageName);
   13683                     } catch (RemoteException e) {
   13684                         mController = null;
   13685                     }
   13686 
   13687                     if (!resumeOK) {
   13688                         return false;
   13689                     }
   13690                 }
   13691             }
   13692             final long origId = Binder.clearCallingIdentity();
   13693             for (int i = start; i > finishTo; i--) {
   13694                 ActivityRecord r = history.get(i);
   13695                 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
   13696                         "navigate-up");
   13697                 // Only return the supplied result for the first activity finished
   13698                 resultCode = Activity.RESULT_CANCELED;
   13699                 resultData = null;
   13700             }
   13701 
   13702             if (parent != null && foundParentInTask) {
   13703                 final int parentLaunchMode = parent.info.launchMode;
   13704                 final int destIntentFlags = destIntent.getFlags();
   13705                 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
   13706                         parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
   13707                         parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
   13708                         (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
   13709                     parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
   13710                 } else {
   13711                     try {
   13712                         ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
   13713                                 destIntent.getComponent(), 0, UserId.getCallingUserId());
   13714                         int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
   13715                                 null, aInfo, parent.appToken, null,
   13716                                 0, -1, parent.launchedFromUid, 0, null, true, null);
   13717                         foundParentInTask = res == ActivityManager.START_SUCCESS;
   13718                     } catch (RemoteException e) {
   13719                         foundParentInTask = false;
   13720                     }
   13721                     mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
   13722                             resultData, "navigate-up");
   13723                 }
   13724             }
   13725             Binder.restoreCallingIdentity(origId);
   13726             return foundParentInTask;
   13727         }
   13728     }
   13729 
   13730     public int getLaunchedFromUid(IBinder activityToken) {
   13731         ActivityRecord srec = ActivityRecord.forToken(activityToken);
   13732         if (srec == null) {
   13733             return -1;
   13734         }
   13735         return srec.launchedFromUid;
   13736     }
   13737 
   13738     // =========================================================
   13739     // LIFETIME MANAGEMENT
   13740     // =========================================================
   13741 
   13742     // Returns which broadcast queue the app is the current [or imminent] receiver
   13743     // on, or 'null' if the app is not an active broadcast recipient.
   13744     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
   13745         BroadcastRecord r = app.curReceiver;
   13746         if (r != null) {
   13747             return r.queue;
   13748         }
   13749 
   13750         // It's not the current receiver, but it might be starting up to become one
   13751         synchronized (this) {
   13752             for (BroadcastQueue queue : mBroadcastQueues) {
   13753                 r = queue.mPendingBroadcast;
   13754                 if (r != null && r.curApp == app) {
   13755                     // found it; report which queue it's in
   13756                     return queue;
   13757                 }
   13758             }
   13759         }
   13760 
   13761         return null;
   13762     }
   13763 
   13764     private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
   13765             ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
   13766         if (mAdjSeq == app.adjSeq) {
   13767             // This adjustment has already been computed.  If we are calling
   13768             // from the top, we may have already computed our adjustment with
   13769             // an earlier hidden adjustment that isn't really for us... if
   13770             // so, use the new hidden adjustment.
   13771             if (!recursed && app.hidden) {
   13772                 app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
   13773             }
   13774             return app.curRawAdj;
   13775         }
   13776 
   13777         if (app.thread == null) {
   13778             app.adjSeq = mAdjSeq;
   13779             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13780             return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
   13781         }
   13782 
   13783         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
   13784         app.adjSource = null;
   13785         app.adjTarget = null;
   13786         app.empty = false;
   13787         app.hidden = false;
   13788 
   13789         final int activitiesSize = app.activities.size();
   13790 
   13791         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   13792             // The max adjustment doesn't allow this app to be anything
   13793             // below foreground, so it is not worth doing work for it.
   13794             app.adjType = "fixed";
   13795             app.adjSeq = mAdjSeq;
   13796             app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
   13797             app.foregroundActivities = false;
   13798             app.keeping = true;
   13799             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
   13800             // System process can do UI, and when they do we want to have
   13801             // them trim their memory after the user leaves the UI.  To
   13802             // facilitate this, here we need to determine whether or not it
   13803             // is currently showing UI.
   13804             app.systemNoUi = true;
   13805             if (app == TOP_APP) {
   13806                 app.systemNoUi = false;
   13807             } else if (activitiesSize > 0) {
   13808                 for (int j = 0; j < activitiesSize; j++) {
   13809                     final ActivityRecord r = app.activities.get(j);
   13810                     if (r.visible) {
   13811                         app.systemNoUi = false;
   13812                         break;
   13813                     }
   13814                 }
   13815             }
   13816             return (app.curAdj=app.maxAdj);
   13817         }
   13818 
   13819         app.keeping = false;
   13820         app.systemNoUi = false;
   13821 
   13822         // Determine the importance of the process, starting with most
   13823         // important to least, and assign an appropriate OOM adjustment.
   13824         int adj;
   13825         int schedGroup;
   13826         boolean foregroundActivities = false;
   13827         boolean interesting = false;
   13828         BroadcastQueue queue;
   13829         if (app == TOP_APP) {
   13830             // The last app on the list is the foreground app.
   13831             adj = ProcessList.FOREGROUND_APP_ADJ;
   13832             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13833             app.adjType = "top-activity";
   13834             foregroundActivities = true;
   13835             interesting = true;
   13836         } else if (app.instrumentationClass != null) {
   13837             // Don't want to kill running instrumentation.
   13838             adj = ProcessList.FOREGROUND_APP_ADJ;
   13839             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13840             app.adjType = "instrumentation";
   13841             interesting = true;
   13842         } else if ((queue = isReceivingBroadcast(app)) != null) {
   13843             // An app that is currently receiving a broadcast also
   13844             // counts as being in the foreground for OOM killer purposes.
   13845             // It's placed in a sched group based on the nature of the
   13846             // broadcast as reflected by which queue it's active in.
   13847             adj = ProcessList.FOREGROUND_APP_ADJ;
   13848             schedGroup = (queue == mFgBroadcastQueue)
   13849                     ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13850             app.adjType = "broadcast";
   13851         } else if (app.executingServices.size() > 0) {
   13852             // An app that is currently executing a service callback also
   13853             // counts as being in the foreground.
   13854             adj = ProcessList.FOREGROUND_APP_ADJ;
   13855             schedGroup = Process.THREAD_GROUP_DEFAULT;
   13856             app.adjType = "exec-service";
   13857         } else if (activitiesSize > 0) {
   13858             // This app is in the background with paused activities.
   13859             // We inspect activities to potentially upgrade adjustment further below.
   13860             adj = hiddenAdj;
   13861             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13862             app.hidden = true;
   13863             app.adjType = "bg-activities";
   13864         } else {
   13865             // A very not-needed process.  If this is lower in the lru list,
   13866             // we will push it in to the empty bucket.
   13867             adj = hiddenAdj;
   13868             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13869             app.hidden = true;
   13870             app.empty = true;
   13871             app.adjType = "bg-empty";
   13872         }
   13873 
   13874         boolean hasStoppingActivities = false;
   13875 
   13876         // Examine all activities if not already foreground.
   13877         if (!foregroundActivities && activitiesSize > 0) {
   13878             for (int j = 0; j < activitiesSize; j++) {
   13879                 final ActivityRecord r = app.activities.get(j);
   13880                 if (r.visible) {
   13881                     // App has a visible activity; only upgrade adjustment.
   13882                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   13883                         adj = ProcessList.VISIBLE_APP_ADJ;
   13884                         app.adjType = "visible";
   13885                     }
   13886                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   13887                     app.hidden = false;
   13888                     foregroundActivities = true;
   13889                     break;
   13890                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
   13891                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   13892                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   13893                         app.adjType = "pausing";
   13894                     }
   13895                     app.hidden = false;
   13896                     foregroundActivities = true;
   13897                 } else if (r.state == ActivityState.STOPPING) {
   13898                     // We will apply the actual adjustment later, because
   13899                     // we want to allow this process to immediately go through
   13900                     // any memory trimming that is in effect.
   13901                     app.hidden = false;
   13902                     foregroundActivities = true;
   13903                     hasStoppingActivities = true;
   13904                 }
   13905             }
   13906         }
   13907 
   13908         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   13909             if (app.foregroundServices) {
   13910                 // The user is aware of this app, so make it visible.
   13911                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   13912                 app.hidden = false;
   13913                 app.adjType = "foreground-service";
   13914                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   13915             } else if (app.forcingToForeground != null) {
   13916                 // The user is aware of this app, so make it visible.
   13917                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   13918                 app.hidden = false;
   13919                 app.adjType = "force-foreground";
   13920                 app.adjSource = app.forcingToForeground;
   13921                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   13922             }
   13923         }
   13924 
   13925         if (app.foregroundServices) {
   13926             interesting = true;
   13927         }
   13928 
   13929         if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
   13930             // We don't want to kill the current heavy-weight process.
   13931             adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
   13932             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13933             app.hidden = false;
   13934             app.adjType = "heavy";
   13935         }
   13936 
   13937         if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
   13938             // This process is hosting what we currently consider to be the
   13939             // home app, so we don't want to let it go into the background.
   13940             adj = ProcessList.HOME_APP_ADJ;
   13941             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13942             app.hidden = false;
   13943             app.adjType = "home";
   13944         }
   13945 
   13946         if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
   13947                 && app.activities.size() > 0) {
   13948             // This was the previous process that showed UI to the user.
   13949             // We want to try to keep it around more aggressively, to give
   13950             // a good experience around switching between two apps.
   13951             adj = ProcessList.PREVIOUS_APP_ADJ;
   13952             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   13953             app.hidden = false;
   13954             app.adjType = "previous";
   13955         }
   13956 
   13957         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
   13958                 + " reason=" + app.adjType);
   13959 
   13960         // By default, we use the computed adjustment.  It may be changed if
   13961         // there are applications dependent on our services or providers, but
   13962         // this gives us a baseline and makes sure we don't get into an
   13963         // infinite recursion.
   13964         app.adjSeq = mAdjSeq;
   13965         app.curRawAdj = app.nonStoppingAdj = adj;
   13966 
   13967         if (mBackupTarget != null && app == mBackupTarget.app) {
   13968             // If possible we want to avoid killing apps while they're being backed up
   13969             if (adj > ProcessList.BACKUP_APP_ADJ) {
   13970                 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
   13971                 adj = ProcessList.BACKUP_APP_ADJ;
   13972                 app.adjType = "backup";
   13973                 app.hidden = false;
   13974             }
   13975         }
   13976 
   13977         if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   13978                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   13979             final long now = SystemClock.uptimeMillis();
   13980             // This process is more important if the top activity is
   13981             // bound to the service.
   13982             Iterator<ServiceRecord> jt = app.services.iterator();
   13983             while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
   13984                 ServiceRecord s = jt.next();
   13985                 if (s.startRequested) {
   13986                     if (app.hasShownUi && app != mHomeProcess) {
   13987                         // If this process has shown some UI, let it immediately
   13988                         // go to the LRU list because it may be pretty heavy with
   13989                         // UI stuff.  We'll tag it with a label just to help
   13990                         // debug and understand what is going on.
   13991                         if (adj > ProcessList.SERVICE_ADJ) {
   13992                             app.adjType = "started-bg-ui-services";
   13993                         }
   13994                     } else {
   13995                         if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
   13996                             // This service has seen some activity within
   13997                             // recent memory, so we will keep its process ahead
   13998                             // of the background processes.
   13999                             if (adj > ProcessList.SERVICE_ADJ) {
   14000                                 adj = ProcessList.SERVICE_ADJ;
   14001                                 app.adjType = "started-services";
   14002                                 app.hidden = false;
   14003                             }
   14004                         }
   14005                         // If we have let the service slide into the background
   14006                         // state, still have some text describing what it is doing
   14007                         // even though the service no longer has an impact.
   14008                         if (adj > ProcessList.SERVICE_ADJ) {
   14009                             app.adjType = "started-bg-services";
   14010                         }
   14011                     }
   14012                     // Don't kill this process because it is doing work; it
   14013                     // has said it is doing work.
   14014                     app.keeping = true;
   14015                 }
   14016                 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   14017                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   14018                     Iterator<ArrayList<ConnectionRecord>> kt
   14019                             = s.connections.values().iterator();
   14020                     while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
   14021                         ArrayList<ConnectionRecord> clist = kt.next();
   14022                         for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
   14023                             // XXX should compute this based on the max of
   14024                             // all connected clients.
   14025                             ConnectionRecord cr = clist.get(i);
   14026                             if (cr.binding.client == app) {
   14027                                 // Binding to ourself is not interesting.
   14028                                 continue;
   14029                             }
   14030                             if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
   14031                                 ProcessRecord client = cr.binding.client;
   14032                                 int clientAdj = adj;
   14033                                 int myHiddenAdj = hiddenAdj;
   14034                                 if (myHiddenAdj > client.hiddenAdj) {
   14035                                     if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
   14036                                         myHiddenAdj = client.hiddenAdj;
   14037                                     } else {
   14038                                         myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
   14039                                     }
   14040                                 }
   14041                                 clientAdj = computeOomAdjLocked(
   14042                                     client, myHiddenAdj, TOP_APP, true, doingAll);
   14043                                 String adjType = null;
   14044                                 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
   14045                                     // Not doing bind OOM management, so treat
   14046                                     // this guy more like a started service.
   14047                                     if (app.hasShownUi && app != mHomeProcess) {
   14048                                         // If this process has shown some UI, let it immediately
   14049                                         // go to the LRU list because it may be pretty heavy with
   14050                                         // UI stuff.  We'll tag it with a label just to help
   14051                                         // debug and understand what is going on.
   14052                                         if (adj > clientAdj) {
   14053                                             adjType = "bound-bg-ui-services";
   14054                                         }
   14055                                         app.hidden = false;
   14056                                         clientAdj = adj;
   14057                                     } else {
   14058                                         if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
   14059                                             // This service has not seen activity within
   14060                                             // recent memory, so allow it to drop to the
   14061                                             // LRU list if there is no other reason to keep
   14062                                             // it around.  We'll also tag it with a label just
   14063                                             // to help debug and undertand what is going on.
   14064                                             if (adj > clientAdj) {
   14065                                                 adjType = "bound-bg-services";
   14066                                             }
   14067                                             clientAdj = adj;
   14068                                         }
   14069                                     }
   14070                                 }
   14071                                 if (adj > clientAdj) {
   14072                                     // If this process has recently shown UI, and
   14073                                     // the process that is binding to it is less
   14074                                     // important than being visible, then we don't
   14075                                     // care about the binding as much as we care
   14076                                     // about letting this process get into the LRU
   14077                                     // list to be killed and restarted if needed for
   14078                                     // memory.
   14079                                     if (app.hasShownUi && app != mHomeProcess
   14080                                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   14081                                         adjType = "bound-bg-ui-services";
   14082                                     } else {
   14083                                         if ((cr.flags&(Context.BIND_ABOVE_CLIENT
   14084                                                 |Context.BIND_IMPORTANT)) != 0) {
   14085                                             adj = clientAdj;
   14086                                         } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
   14087                                                 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
   14088                                                 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   14089                                             adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   14090                                         } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
   14091                                             adj = clientAdj;
   14092                                         } else {
   14093                                             app.pendingUiClean = true;
   14094                                             if (adj > ProcessList.VISIBLE_APP_ADJ) {
   14095                                                 adj = ProcessList.VISIBLE_APP_ADJ;
   14096                                             }
   14097                                         }
   14098                                         if (!client.hidden) {
   14099                                             app.hidden = false;
   14100                                         }
   14101                                         if (client.keeping) {
   14102                                             app.keeping = true;
   14103                                         }
   14104                                         adjType = "service";
   14105                                     }
   14106                                 }
   14107                                 if (adjType != null) {
   14108                                     app.adjType = adjType;
   14109                                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   14110                                             .REASON_SERVICE_IN_USE;
   14111                                     app.adjSource = cr.binding.client;
   14112                                     app.adjSourceOom = clientAdj;
   14113                                     app.adjTarget = s.name;
   14114                                 }
   14115                                 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   14116                                     if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   14117                                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   14118                                     }
   14119                                 }
   14120                             }
   14121                             if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
   14122                                 ActivityRecord a = cr.activity;
   14123                                 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
   14124                                         (a.visible || a.state == ActivityState.RESUMED
   14125                                          || a.state == ActivityState.PAUSING)) {
   14126                                     adj = ProcessList.FOREGROUND_APP_ADJ;
   14127                                     if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   14128                                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   14129                                     }
   14130                                     app.hidden = false;
   14131                                     app.adjType = "service";
   14132                                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   14133                                             .REASON_SERVICE_IN_USE;
   14134                                     app.adjSource = a;
   14135                                     app.adjSourceOom = adj;
   14136                                     app.adjTarget = s.name;
   14137                                 }
   14138                             }
   14139                         }
   14140                     }
   14141                 }
   14142             }
   14143 
   14144             // Finally, if this process has active services running in it, we
   14145             // would like to avoid killing it unless it would prevent the current
   14146             // application from running.  By default we put the process in
   14147             // with the rest of the background processes; as we scan through
   14148             // its services we may bump it up from there.
   14149             if (adj > hiddenAdj) {
   14150                 adj = hiddenAdj;
   14151                 app.hidden = false;
   14152                 app.adjType = "bg-services";
   14153             }
   14154         }
   14155 
   14156         if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   14157                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   14158             Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
   14159             while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
   14160                     || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
   14161                 ContentProviderRecord cpr = jt.next();
   14162                 for (int i = cpr.connections.size()-1;
   14163                         i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   14164                                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
   14165                         i--) {
   14166                     ContentProviderConnection conn = cpr.connections.get(i);
   14167                     ProcessRecord client = conn.client;
   14168                     if (client == app) {
   14169                         // Being our own client is not interesting.
   14170                         continue;
   14171                     }
   14172                     int myHiddenAdj = hiddenAdj;
   14173                     if (myHiddenAdj > client.hiddenAdj) {
   14174                         if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
   14175                             myHiddenAdj = client.hiddenAdj;
   14176                         } else {
   14177                             myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
   14178                         }
   14179                     }
   14180                     int clientAdj = computeOomAdjLocked(
   14181                         client, myHiddenAdj, TOP_APP, true, doingAll);
   14182                     if (adj > clientAdj) {
   14183                         if (app.hasShownUi && app != mHomeProcess
   14184                                 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   14185                             app.adjType = "bg-ui-provider";
   14186                         } else {
   14187                             adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
   14188                                     ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
   14189                             app.adjType = "provider";
   14190                         }
   14191                         if (!client.hidden) {
   14192                             app.hidden = false;
   14193                         }
   14194                         if (client.keeping) {
   14195                             app.keeping = true;
   14196                         }
   14197                         app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   14198                                 .REASON_PROVIDER_IN_USE;
   14199                         app.adjSource = client;
   14200                         app.adjSourceOom = clientAdj;
   14201                         app.adjTarget = cpr.name;
   14202                     }
   14203                     if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   14204                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   14205                     }
   14206                 }
   14207                 // If the provider has external (non-framework) process
   14208                 // dependencies, ensure that its adjustment is at least
   14209                 // FOREGROUND_APP_ADJ.
   14210                 if (cpr.hasExternalProcessHandles()) {
   14211                     if (adj > ProcessList.FOREGROUND_APP_ADJ) {
   14212                         adj = ProcessList.FOREGROUND_APP_ADJ;
   14213                         schedGroup = Process.THREAD_GROUP_DEFAULT;
   14214                         app.hidden = false;
   14215                         app.keeping = true;
   14216                         app.adjType = "provider";
   14217                         app.adjTarget = cpr.name;
   14218                     }
   14219                 }
   14220             }
   14221         }
   14222 
   14223         if (adj == ProcessList.SERVICE_ADJ) {
   14224             if (doingAll) {
   14225                 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
   14226                 mNewNumServiceProcs++;
   14227             }
   14228             if (app.serviceb) {
   14229                 adj = ProcessList.SERVICE_B_ADJ;
   14230             }
   14231         } else {
   14232             app.serviceb = false;
   14233         }
   14234 
   14235         app.nonStoppingAdj = adj;
   14236 
   14237         if (hasStoppingActivities) {
   14238             // Only upgrade adjustment.
   14239             if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   14240                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   14241                 app.adjType = "stopping";
   14242             }
   14243         }
   14244 
   14245         app.curRawAdj = adj;
   14246 
   14247         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
   14248         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
   14249         if (adj > app.maxAdj) {
   14250             adj = app.maxAdj;
   14251             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   14252                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   14253             }
   14254         }
   14255         if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
   14256             app.keeping = true;
   14257         }
   14258 
   14259         if (app.hasAboveClient) {
   14260             // If this process has bound to any services with BIND_ABOVE_CLIENT,
   14261             // then we need to drop its adjustment to be lower than the service's
   14262             // in order to honor the request.  We want to drop it by one adjustment
   14263             // level...  but there is special meaning applied to various levels so
   14264             // we will skip some of them.
   14265             if (adj < ProcessList.FOREGROUND_APP_ADJ) {
   14266                 // System process will not get dropped, ever
   14267             } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
   14268                 adj = ProcessList.VISIBLE_APP_ADJ;
   14269             } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
   14270                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   14271             } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
   14272                 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
   14273             } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
   14274                 adj++;
   14275             }
   14276         }
   14277 
   14278         int importance = app.memImportance;
   14279         if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
   14280             app.curAdj = adj;
   14281             app.curSchedGroup = schedGroup;
   14282             if (!interesting) {
   14283                 // For this reporting, if there is not something explicitly
   14284                 // interesting in this process then we will push it to the
   14285                 // background importance.
   14286                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   14287             } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   14288                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   14289             } else if (adj >= ProcessList.SERVICE_B_ADJ) {
   14290                 importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   14291             } else if (adj >= ProcessList.HOME_APP_ADJ) {
   14292                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   14293             } else if (adj >= ProcessList.SERVICE_ADJ) {
   14294                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   14295             } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   14296                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
   14297             } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   14298                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
   14299             } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
   14300                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
   14301             } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
   14302                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
   14303             } else {
   14304                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
   14305             }
   14306         }
   14307 
   14308         int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
   14309         if (foregroundActivities != app.foregroundActivities) {
   14310             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
   14311         }
   14312         if (changes != 0) {
   14313             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
   14314             app.memImportance = importance;
   14315             app.foregroundActivities = foregroundActivities;
   14316             int i = mPendingProcessChanges.size()-1;
   14317             ProcessChangeItem item = null;
   14318             while (i >= 0) {
   14319                 item = mPendingProcessChanges.get(i);
   14320                 if (item.pid == app.pid) {
   14321                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
   14322                     break;
   14323                 }
   14324                 i--;
   14325             }
   14326             if (i < 0) {
   14327                 // No existing item in pending changes; need a new one.
   14328                 final int NA = mAvailProcessChanges.size();
   14329                 if (NA > 0) {
   14330                     item = mAvailProcessChanges.remove(NA-1);
   14331                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
   14332                 } else {
   14333                     item = new ProcessChangeItem();
   14334                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
   14335                 }
   14336                 item.changes = 0;
   14337                 item.pid = app.pid;
   14338                 item.uid = app.info.uid;
   14339                 if (mPendingProcessChanges.size() == 0) {
   14340                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
   14341                             "*** Enqueueing dispatch processes changed!");
   14342                     mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
   14343                 }
   14344                 mPendingProcessChanges.add(item);
   14345             }
   14346             item.changes |= changes;
   14347             item.importance = importance;
   14348             item.foregroundActivities = foregroundActivities;
   14349             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
   14350                     + Integer.toHexString(System.identityHashCode(item))
   14351                     + " " + app.toShortString() + ": changes=" + item.changes
   14352                     + " importance=" + item.importance
   14353                     + " foreground=" + item.foregroundActivities
   14354                     + " type=" + app.adjType + " source=" + app.adjSource
   14355                     + " target=" + app.adjTarget);
   14356         }
   14357 
   14358         return app.curRawAdj;
   14359     }
   14360 
   14361     /**
   14362      * Ask a given process to GC right now.
   14363      */
   14364     final void performAppGcLocked(ProcessRecord app) {
   14365         try {
   14366             app.lastRequestedGc = SystemClock.uptimeMillis();
   14367             if (app.thread != null) {
   14368                 if (app.reportLowMemory) {
   14369                     app.reportLowMemory = false;
   14370                     app.thread.scheduleLowMemory();
   14371                 } else {
   14372                     app.thread.processInBackground();
   14373                 }
   14374             }
   14375         } catch (Exception e) {
   14376             // whatever.
   14377         }
   14378     }
   14379 
   14380     /**
   14381      * Returns true if things are idle enough to perform GCs.
   14382      */
   14383     private final boolean canGcNowLocked() {
   14384         boolean processingBroadcasts = false;
   14385         for (BroadcastQueue q : mBroadcastQueues) {
   14386             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
   14387                 processingBroadcasts = true;
   14388             }
   14389         }
   14390         return !processingBroadcasts
   14391                 && (mSleeping || (mMainStack.mResumedActivity != null &&
   14392                         mMainStack.mResumedActivity.idle));
   14393     }
   14394 
   14395     /**
   14396      * Perform GCs on all processes that are waiting for it, but only
   14397      * if things are idle.
   14398      */
   14399     final void performAppGcsLocked() {
   14400         final int N = mProcessesToGc.size();
   14401         if (N <= 0) {
   14402             return;
   14403         }
   14404         if (canGcNowLocked()) {
   14405             while (mProcessesToGc.size() > 0) {
   14406                 ProcessRecord proc = mProcessesToGc.remove(0);
   14407                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
   14408                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
   14409                             <= SystemClock.uptimeMillis()) {
   14410                         // To avoid spamming the system, we will GC processes one
   14411                         // at a time, waiting a few seconds between each.
   14412                         performAppGcLocked(proc);
   14413                         scheduleAppGcsLocked();
   14414                         return;
   14415                     } else {
   14416                         // It hasn't been long enough since we last GCed this
   14417                         // process...  put it in the list to wait for its time.
   14418                         addProcessToGcListLocked(proc);
   14419                         break;
   14420                     }
   14421                 }
   14422             }
   14423 
   14424             scheduleAppGcsLocked();
   14425         }
   14426     }
   14427 
   14428     /**
   14429      * If all looks good, perform GCs on all processes waiting for them.
   14430      */
   14431     final void performAppGcsIfAppropriateLocked() {
   14432         if (canGcNowLocked()) {
   14433             performAppGcsLocked();
   14434             return;
   14435         }
   14436         // Still not idle, wait some more.
   14437         scheduleAppGcsLocked();
   14438     }
   14439 
   14440     /**
   14441      * Schedule the execution of all pending app GCs.
   14442      */
   14443     final void scheduleAppGcsLocked() {
   14444         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
   14445 
   14446         if (mProcessesToGc.size() > 0) {
   14447             // Schedule a GC for the time to the next process.
   14448             ProcessRecord proc = mProcessesToGc.get(0);
   14449             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
   14450 
   14451             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
   14452             long now = SystemClock.uptimeMillis();
   14453             if (when < (now+GC_TIMEOUT)) {
   14454                 when = now + GC_TIMEOUT;
   14455             }
   14456             mHandler.sendMessageAtTime(msg, when);
   14457         }
   14458     }
   14459 
   14460     /**
   14461      * Add a process to the array of processes waiting to be GCed.  Keeps the
   14462      * list in sorted order by the last GC time.  The process can't already be
   14463      * on the list.
   14464      */
   14465     final void addProcessToGcListLocked(ProcessRecord proc) {
   14466         boolean added = false;
   14467         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
   14468             if (mProcessesToGc.get(i).lastRequestedGc <
   14469                     proc.lastRequestedGc) {
   14470                 added = true;
   14471                 mProcessesToGc.add(i+1, proc);
   14472                 break;
   14473             }
   14474         }
   14475         if (!added) {
   14476             mProcessesToGc.add(0, proc);
   14477         }
   14478     }
   14479 
   14480     /**
   14481      * Set up to ask a process to GC itself.  This will either do it
   14482      * immediately, or put it on the list of processes to gc the next
   14483      * time things are idle.
   14484      */
   14485     final void scheduleAppGcLocked(ProcessRecord app) {
   14486         long now = SystemClock.uptimeMillis();
   14487         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
   14488             return;
   14489         }
   14490         if (!mProcessesToGc.contains(app)) {
   14491             addProcessToGcListLocked(app);
   14492             scheduleAppGcsLocked();
   14493         }
   14494     }
   14495 
   14496     final void checkExcessivePowerUsageLocked(boolean doKills) {
   14497         updateCpuStatsNow();
   14498 
   14499         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   14500         boolean doWakeKills = doKills;
   14501         boolean doCpuKills = doKills;
   14502         if (mLastPowerCheckRealtime == 0) {
   14503             doWakeKills = false;
   14504         }
   14505         if (mLastPowerCheckUptime == 0) {
   14506             doCpuKills = false;
   14507         }
   14508         if (stats.isScreenOn()) {
   14509             doWakeKills = false;
   14510         }
   14511         final long curRealtime = SystemClock.elapsedRealtime();
   14512         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
   14513         final long curUptime = SystemClock.uptimeMillis();
   14514         final long uptimeSince = curUptime - mLastPowerCheckUptime;
   14515         mLastPowerCheckRealtime = curRealtime;
   14516         mLastPowerCheckUptime = curUptime;
   14517         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
   14518             doWakeKills = false;
   14519         }
   14520         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
   14521             doCpuKills = false;
   14522         }
   14523         int i = mLruProcesses.size();
   14524         while (i > 0) {
   14525             i--;
   14526             ProcessRecord app = mLruProcesses.get(i);
   14527             if (!app.keeping) {
   14528                 long wtime;
   14529                 synchronized (stats) {
   14530                     wtime = stats.getProcessWakeTime(app.info.uid,
   14531                             app.pid, curRealtime);
   14532                 }
   14533                 long wtimeUsed = wtime - app.lastWakeTime;
   14534                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
   14535                 if (DEBUG_POWER) {
   14536                     StringBuilder sb = new StringBuilder(128);
   14537                     sb.append("Wake for ");
   14538                     app.toShortString(sb);
   14539                     sb.append(": over ");
   14540                     TimeUtils.formatDuration(realtimeSince, sb);
   14541                     sb.append(" used ");
   14542                     TimeUtils.formatDuration(wtimeUsed, sb);
   14543                     sb.append(" (");
   14544                     sb.append((wtimeUsed*100)/realtimeSince);
   14545                     sb.append("%)");
   14546                     Slog.i(TAG, sb.toString());
   14547                     sb.setLength(0);
   14548                     sb.append("CPU for ");
   14549                     app.toShortString(sb);
   14550                     sb.append(": over ");
   14551                     TimeUtils.formatDuration(uptimeSince, sb);
   14552                     sb.append(" used ");
   14553                     TimeUtils.formatDuration(cputimeUsed, sb);
   14554                     sb.append(" (");
   14555                     sb.append((cputimeUsed*100)/uptimeSince);
   14556                     sb.append("%)");
   14557                     Slog.i(TAG, sb.toString());
   14558                 }
   14559                 // If a process has held a wake lock for more
   14560                 // than 50% of the time during this period,
   14561                 // that sounds bad.  Kill!
   14562                 if (doWakeKills && realtimeSince > 0
   14563                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
   14564                     synchronized (stats) {
   14565                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
   14566                                 realtimeSince, wtimeUsed);
   14567                     }
   14568                     Slog.w(TAG, "Excessive wake lock in " + app.processName
   14569                             + " (pid " + app.pid + "): held " + wtimeUsed
   14570                             + " during " + realtimeSince);
   14571                     EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   14572                             app.processName, app.setAdj, "excessive wake lock");
   14573                     Process.killProcessQuiet(app.pid);
   14574                 } else if (doCpuKills && uptimeSince > 0
   14575                         && ((cputimeUsed*100)/uptimeSince) >= 50) {
   14576                     synchronized (stats) {
   14577                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
   14578                                 uptimeSince, cputimeUsed);
   14579                     }
   14580                     Slog.w(TAG, "Excessive CPU in " + app.processName
   14581                             + " (pid " + app.pid + "): used " + cputimeUsed
   14582                             + " during " + uptimeSince);
   14583                     EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   14584                             app.processName, app.setAdj, "excessive cpu");
   14585                     Process.killProcessQuiet(app.pid);
   14586                 } else {
   14587                     app.lastWakeTime = wtime;
   14588                     app.lastCpuTime = app.curCpuTime;
   14589                 }
   14590             }
   14591         }
   14592     }
   14593 
   14594     private final boolean updateOomAdjLocked(
   14595             ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
   14596         app.hiddenAdj = hiddenAdj;
   14597 
   14598         if (app.thread == null) {
   14599             return false;
   14600         }
   14601 
   14602         final boolean wasKeeping = app.keeping;
   14603 
   14604         boolean success = true;
   14605 
   14606         computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
   14607 
   14608         if (app.curRawAdj != app.setRawAdj) {
   14609             if (wasKeeping && !app.keeping) {
   14610                 // This app is no longer something we want to keep.  Note
   14611                 // its current wake lock time to later know to kill it if
   14612                 // it is not behaving well.
   14613                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   14614                 synchronized (stats) {
   14615                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
   14616                             app.pid, SystemClock.elapsedRealtime());
   14617                 }
   14618                 app.lastCpuTime = app.curCpuTime;
   14619             }
   14620 
   14621             app.setRawAdj = app.curRawAdj;
   14622         }
   14623 
   14624         if (app.curAdj != app.setAdj) {
   14625             if (Process.setOomAdj(app.pid, app.curAdj)) {
   14626                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
   14627                     TAG, "Set " + app.pid + " " + app.processName +
   14628                     " adj " + app.curAdj + ": " + app.adjType);
   14629                 app.setAdj = app.curAdj;
   14630             } else {
   14631                 success = false;
   14632                 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
   14633             }
   14634         }
   14635         if (app.setSchedGroup != app.curSchedGroup) {
   14636             app.setSchedGroup = app.curSchedGroup;
   14637             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   14638                     "Setting process group of " + app.processName
   14639                     + " to " + app.curSchedGroup);
   14640             if (app.waitingToKill != null &&
   14641                     app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
   14642                 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
   14643                 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   14644                         app.processName, app.setAdj, app.waitingToKill);
   14645                 app.killedBackground = true;
   14646                 Process.killProcessQuiet(app.pid);
   14647                 success = false;
   14648             } else {
   14649                 if (true) {
   14650                     long oldId = Binder.clearCallingIdentity();
   14651                     try {
   14652                         Process.setProcessGroup(app.pid, app.curSchedGroup);
   14653                     } catch (Exception e) {
   14654                         Slog.w(TAG, "Failed setting process group of " + app.pid
   14655                                 + " to " + app.curSchedGroup);
   14656                         e.printStackTrace();
   14657                     } finally {
   14658                         Binder.restoreCallingIdentity(oldId);
   14659                     }
   14660                 } else {
   14661                     if (app.thread != null) {
   14662                         try {
   14663                             app.thread.setSchedulingGroup(app.curSchedGroup);
   14664                         } catch (RemoteException e) {
   14665                         }
   14666                     }
   14667                 }
   14668             }
   14669         }
   14670         return success;
   14671     }
   14672 
   14673     private final ActivityRecord resumedAppLocked() {
   14674         ActivityRecord resumedActivity = mMainStack.mResumedActivity;
   14675         if (resumedActivity == null || resumedActivity.app == null) {
   14676             resumedActivity = mMainStack.mPausingActivity;
   14677             if (resumedActivity == null || resumedActivity.app == null) {
   14678                 resumedActivity = mMainStack.topRunningActivityLocked(null);
   14679             }
   14680         }
   14681         return resumedActivity;
   14682     }
   14683 
   14684     private final boolean updateOomAdjLocked(ProcessRecord app) {
   14685         final ActivityRecord TOP_ACT = resumedAppLocked();
   14686         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   14687         int curAdj = app.curAdj;
   14688         final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
   14689             && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
   14690 
   14691         mAdjSeq++;
   14692 
   14693         boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
   14694         final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
   14695             && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
   14696         if (nowHidden != wasHidden) {
   14697             // Changed to/from hidden state, so apps after it in the LRU
   14698             // list may also be changed.
   14699             updateOomAdjLocked();
   14700         }
   14701         return success;
   14702     }
   14703 
   14704     final void updateOomAdjLocked() {
   14705         final ActivityRecord TOP_ACT = resumedAppLocked();
   14706         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   14707 
   14708         if (false) {
   14709             RuntimeException e = new RuntimeException();
   14710             e.fillInStackTrace();
   14711             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
   14712         }
   14713 
   14714         mAdjSeq++;
   14715         mNewNumServiceProcs = 0;
   14716 
   14717         // Let's determine how many processes we have running vs.
   14718         // how many slots we have for background processes; we may want
   14719         // to put multiple processes in a slot of there are enough of
   14720         // them.
   14721         int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
   14722         int factor = (mLruProcesses.size()-4)/numSlots;
   14723         if (factor < 1) factor = 1;
   14724         int step = 0;
   14725         int numHidden = 0;
   14726         int numTrimming = 0;
   14727 
   14728         // First update the OOM adjustment for each of the
   14729         // application processes based on their current state.
   14730         int i = mLruProcesses.size();
   14731         int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
   14732         while (i > 0) {
   14733             i--;
   14734             ProcessRecord app = mLruProcesses.get(i);
   14735             //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
   14736             updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
   14737             if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
   14738                 && app.curAdj == curHiddenAdj) {
   14739                 step++;
   14740                 if (step >= factor) {
   14741                     step = 0;
   14742                     curHiddenAdj++;
   14743                 }
   14744             }
   14745             if (!app.killedBackground) {
   14746                 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
   14747                     numHidden++;
   14748                     if (numHidden > mProcessLimit) {
   14749                         Slog.i(TAG, "No longer want " + app.processName
   14750                                 + " (pid " + app.pid + "): hidden #" + numHidden);
   14751                         EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   14752                                 app.processName, app.setAdj, "too many background");
   14753                         app.killedBackground = true;
   14754                         Process.killProcessQuiet(app.pid);
   14755                     }
   14756                 }
   14757                 if (!app.killedBackground && app.isolated && app.services.size() <= 0) {
   14758                     // If this is an isolated process, and there are no
   14759                     // services running in it, then the process is no longer
   14760                     // needed.  We agressively kill these because we can by
   14761                     // definition not re-use the same process again, and it is
   14762                     // good to avoid having whatever code was running in them
   14763                     // left sitting around after no longer needed.
   14764                     Slog.i(TAG, "Isolated process " + app.processName
   14765                             + " (pid " + app.pid + ") no longer needed");
   14766                     EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   14767                             app.processName, app.setAdj, "isolated not needed");
   14768                     app.killedBackground = true;
   14769                     Process.killProcessQuiet(app.pid);
   14770                 }
   14771                 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
   14772                         && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
   14773                         && !app.killedBackground) {
   14774                     numTrimming++;
   14775                 }
   14776             }
   14777         }
   14778 
   14779         mNumServiceProcs = mNewNumServiceProcs;
   14780 
   14781         // Now determine the memory trimming level of background processes.
   14782         // Unfortunately we need to start at the back of the list to do this
   14783         // properly.  We only do this if the number of background apps we
   14784         // are managing to keep around is less than half the maximum we desire;
   14785         // if we are keeping a good number around, we'll let them use whatever
   14786         // memory they want.
   14787         if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
   14788             final int N = mLruProcesses.size();
   14789             factor = numTrimming/3;
   14790             int minFactor = 2;
   14791             if (mHomeProcess != null) minFactor++;
   14792             if (mPreviousProcess != null) minFactor++;
   14793             if (factor < minFactor) factor = minFactor;
   14794             step = 0;
   14795             int fgTrimLevel;
   14796             if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/5)) {
   14797                 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
   14798             } else if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/3)) {
   14799                 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
   14800             } else {
   14801                 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
   14802             }
   14803             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
   14804             for (i=0; i<N; i++) {
   14805                 ProcessRecord app = mLruProcesses.get(i);
   14806                 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
   14807                         && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
   14808                         && !app.killedBackground) {
   14809                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
   14810                         try {
   14811                             app.thread.scheduleTrimMemory(curLevel);
   14812                         } catch (RemoteException e) {
   14813                         }
   14814                         if (false) {
   14815                             // For now we won't do this; our memory trimming seems
   14816                             // to be good enough at this point that destroying
   14817                             // activities causes more harm than good.
   14818                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
   14819                                     && app != mHomeProcess && app != mPreviousProcess) {
   14820                                 // Need to do this on its own message because the stack may not
   14821                                 // be in a consistent state at this point.
   14822                                 // For these apps we will also finish their activities
   14823                                 // to help them free memory.
   14824                                 mMainStack.scheduleDestroyActivities(app, false, "trim");
   14825                             }
   14826                         }
   14827                     }
   14828                     app.trimMemoryLevel = curLevel;
   14829                     step++;
   14830                     if (step >= factor) {
   14831                         step = 0;
   14832                         switch (curLevel) {
   14833                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
   14834                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
   14835                                 break;
   14836                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
   14837                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   14838                                 break;
   14839                         }
   14840                     }
   14841                 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   14842                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
   14843                             && app.thread != null) {
   14844                         try {
   14845                             app.thread.scheduleTrimMemory(
   14846                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   14847                         } catch (RemoteException e) {
   14848                         }
   14849                     }
   14850                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   14851                 } else {
   14852                     if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
   14853                             && app.pendingUiClean) {
   14854                         // If this application is now in the background and it
   14855                         // had done UI, then give it the special trim level to
   14856                         // have it free UI resources.
   14857                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
   14858                         if (app.trimMemoryLevel < level && app.thread != null) {
   14859                             try {
   14860                                 app.thread.scheduleTrimMemory(level);
   14861                             } catch (RemoteException e) {
   14862                             }
   14863                         }
   14864                         app.pendingUiClean = false;
   14865                     }
   14866                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
   14867                         try {
   14868                             app.thread.scheduleTrimMemory(fgTrimLevel);
   14869                         } catch (RemoteException e) {
   14870                         }
   14871                     }
   14872                     app.trimMemoryLevel = fgTrimLevel;
   14873                 }
   14874             }
   14875         } else {
   14876             final int N = mLruProcesses.size();
   14877             for (i=0; i<N; i++) {
   14878                 ProcessRecord app = mLruProcesses.get(i);
   14879                 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
   14880                         && app.pendingUiClean) {
   14881                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
   14882                             && app.thread != null) {
   14883                         try {
   14884                             app.thread.scheduleTrimMemory(
   14885                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   14886                         } catch (RemoteException e) {
   14887                         }
   14888                     }
   14889                     app.pendingUiClean = false;
   14890                 }
   14891                 app.trimMemoryLevel = 0;
   14892             }
   14893         }
   14894 
   14895         if (mAlwaysFinishActivities) {
   14896             // Need to do this on its own message because the stack may not
   14897             // be in a consistent state at this point.
   14898             mMainStack.scheduleDestroyActivities(null, false, "always-finish");
   14899         }
   14900     }
   14901 
   14902     final void trimApplications() {
   14903         synchronized (this) {
   14904             int i;
   14905 
   14906             // First remove any unused application processes whose package
   14907             // has been removed.
   14908             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
   14909                 final ProcessRecord app = mRemovedProcesses.get(i);
   14910                 if (app.activities.size() == 0
   14911                         && app.curReceiver == null && app.services.size() == 0) {
   14912                     Slog.i(
   14913                         TAG, "Exiting empty application process "
   14914                         + app.processName + " ("
   14915                         + (app.thread != null ? app.thread.asBinder() : null)
   14916                         + ")\n");
   14917                     if (app.pid > 0 && app.pid != MY_PID) {
   14918                         EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
   14919                                 app.processName, app.setAdj, "empty");
   14920                         Process.killProcessQuiet(app.pid);
   14921                     } else {
   14922                         try {
   14923                             app.thread.scheduleExit();
   14924                         } catch (Exception e) {
   14925                             // Ignore exceptions.
   14926                         }
   14927                     }
   14928                     cleanUpApplicationRecordLocked(app, false, true, -1);
   14929                     mRemovedProcesses.remove(i);
   14930 
   14931                     if (app.persistent) {
   14932                         if (app.persistent) {
   14933                             addAppLocked(app.info, false);
   14934                         }
   14935                     }
   14936                 }
   14937             }
   14938 
   14939             // Now update the oom adj for all processes.
   14940             updateOomAdjLocked();
   14941         }
   14942     }
   14943 
   14944     /** This method sends the specified signal to each of the persistent apps */
   14945     public void signalPersistentProcesses(int sig) throws RemoteException {
   14946         if (sig != Process.SIGNAL_USR1) {
   14947             throw new SecurityException("Only SIGNAL_USR1 is allowed");
   14948         }
   14949 
   14950         synchronized (this) {
   14951             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
   14952                     != PackageManager.PERMISSION_GRANTED) {
   14953                 throw new SecurityException("Requires permission "
   14954                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
   14955             }
   14956 
   14957             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   14958                 ProcessRecord r = mLruProcesses.get(i);
   14959                 if (r.thread != null && r.persistent) {
   14960                     Process.sendSignal(r.pid, sig);
   14961                 }
   14962             }
   14963         }
   14964     }
   14965 
   14966     private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
   14967         if (proc == null || proc == mProfileProc) {
   14968             proc = mProfileProc;
   14969             path = mProfileFile;
   14970             profileType = mProfileType;
   14971             clearProfilerLocked();
   14972         }
   14973         if (proc == null) {
   14974             return;
   14975         }
   14976         try {
   14977             proc.thread.profilerControl(false, path, null, profileType);
   14978         } catch (RemoteException e) {
   14979             throw new IllegalStateException("Process disappeared");
   14980         }
   14981     }
   14982 
   14983     private void clearProfilerLocked() {
   14984         if (mProfileFd != null) {
   14985             try {
   14986                 mProfileFd.close();
   14987             } catch (IOException e) {
   14988             }
   14989         }
   14990         mProfileApp = null;
   14991         mProfileProc = null;
   14992         mProfileFile = null;
   14993         mProfileType = 0;
   14994         mAutoStopProfiler = false;
   14995     }
   14996 
   14997     public boolean profileControl(String process, boolean start,
   14998             String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
   14999 
   15000         try {
   15001             synchronized (this) {
   15002                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   15003                 // its own permission.
   15004                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   15005                         != PackageManager.PERMISSION_GRANTED) {
   15006                     throw new SecurityException("Requires permission "
   15007                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   15008                 }
   15009 
   15010                 if (start && fd == null) {
   15011                     throw new IllegalArgumentException("null fd");
   15012                 }
   15013 
   15014                 ProcessRecord proc = null;
   15015                 if (process != null) {
   15016                     try {
   15017                         int pid = Integer.parseInt(process);
   15018                         synchronized (mPidsSelfLocked) {
   15019                             proc = mPidsSelfLocked.get(pid);
   15020                         }
   15021                     } catch (NumberFormatException e) {
   15022                     }
   15023 
   15024                     if (proc == null) {
   15025                         HashMap<String, SparseArray<ProcessRecord>> all
   15026                                 = mProcessNames.getMap();
   15027                         SparseArray<ProcessRecord> procs = all.get(process);
   15028                         if (procs != null && procs.size() > 0) {
   15029                             proc = procs.valueAt(0);
   15030                         }
   15031                     }
   15032                 }
   15033 
   15034                 if (start && (proc == null || proc.thread == null)) {
   15035                     throw new IllegalArgumentException("Unknown process: " + process);
   15036                 }
   15037 
   15038                 if (start) {
   15039                     stopProfilerLocked(null, null, 0);
   15040                     setProfileApp(proc.info, proc.processName, path, fd, false);
   15041                     mProfileProc = proc;
   15042                     mProfileType = profileType;
   15043                     try {
   15044                         fd = fd.dup();
   15045                     } catch (IOException e) {
   15046                         fd = null;
   15047                     }
   15048                     proc.thread.profilerControl(start, path, fd, profileType);
   15049                     fd = null;
   15050                     mProfileFd = null;
   15051                 } else {
   15052                     stopProfilerLocked(proc, path, profileType);
   15053                     if (fd != null) {
   15054                         try {
   15055                             fd.close();
   15056                         } catch (IOException e) {
   15057                         }
   15058                     }
   15059                 }
   15060 
   15061                 return true;
   15062             }
   15063         } catch (RemoteException e) {
   15064             throw new IllegalStateException("Process disappeared");
   15065         } finally {
   15066             if (fd != null) {
   15067                 try {
   15068                     fd.close();
   15069                 } catch (IOException e) {
   15070                 }
   15071             }
   15072         }
   15073     }
   15074 
   15075     public boolean dumpHeap(String process, boolean managed,
   15076             String path, ParcelFileDescriptor fd) throws RemoteException {
   15077 
   15078         try {
   15079             synchronized (this) {
   15080                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   15081                 // its own permission (same as profileControl).
   15082                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   15083                         != PackageManager.PERMISSION_GRANTED) {
   15084                     throw new SecurityException("Requires permission "
   15085                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   15086                 }
   15087 
   15088                 if (fd == null) {
   15089                     throw new IllegalArgumentException("null fd");
   15090                 }
   15091 
   15092                 ProcessRecord proc = null;
   15093                 try {
   15094                     int pid = Integer.parseInt(process);
   15095                     synchronized (mPidsSelfLocked) {
   15096                         proc = mPidsSelfLocked.get(pid);
   15097                     }
   15098                 } catch (NumberFormatException e) {
   15099                 }
   15100 
   15101                 if (proc == null) {
   15102                     HashMap<String, SparseArray<ProcessRecord>> all
   15103                             = mProcessNames.getMap();
   15104                     SparseArray<ProcessRecord> procs = all.get(process);
   15105                     if (procs != null && procs.size() > 0) {
   15106                         proc = procs.valueAt(0);
   15107                     }
   15108                 }
   15109 
   15110                 if (proc == null || proc.thread == null) {
   15111                     throw new IllegalArgumentException("Unknown process: " + process);
   15112                 }
   15113 
   15114                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   15115                 if (!isDebuggable) {
   15116                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   15117                         throw new SecurityException("Process not debuggable: " + proc);
   15118                     }
   15119                 }
   15120 
   15121                 proc.thread.dumpHeap(managed, path, fd);
   15122                 fd = null;
   15123                 return true;
   15124             }
   15125         } catch (RemoteException e) {
   15126             throw new IllegalStateException("Process disappeared");
   15127         } finally {
   15128             if (fd != null) {
   15129                 try {
   15130                     fd.close();
   15131                 } catch (IOException e) {
   15132                 }
   15133             }
   15134         }
   15135     }
   15136 
   15137     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
   15138     public void monitor() {
   15139         synchronized (this) { }
   15140     }
   15141 
   15142     void onCoreSettingsChange(Bundle settings) {
   15143         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   15144             ProcessRecord processRecord = mLruProcesses.get(i);
   15145             try {
   15146                 if (processRecord.thread != null) {
   15147                     processRecord.thread.setCoreSettings(settings);
   15148                 }
   15149             } catch (RemoteException re) {
   15150                 /* ignore */
   15151             }
   15152         }
   15153     }
   15154 
   15155     // Multi-user methods
   15156 
   15157     private int mCurrentUserId;
   15158     private SparseIntArray mLoggedInUsers = new SparseIntArray(5);
   15159 
   15160     public boolean switchUser(int userId) {
   15161         final int callingUid = Binder.getCallingUid();
   15162         if (callingUid != 0 && callingUid != Process.myUid()) {
   15163             Slog.e(TAG, "Trying to switch user from unauthorized app");
   15164             return false;
   15165         }
   15166         if (mCurrentUserId == userId)
   15167             return true;
   15168 
   15169         synchronized (this) {
   15170             // Check if user is already logged in, otherwise check if user exists first before
   15171             // adding to the list of logged in users.
   15172             if (mLoggedInUsers.indexOfKey(userId) < 0) {
   15173                 if (!userExists(userId)) {
   15174                     return false;
   15175                 }
   15176                 mLoggedInUsers.append(userId, userId);
   15177             }
   15178 
   15179             mCurrentUserId = userId;
   15180             boolean haveActivities = mMainStack.switchUser(userId);
   15181             if (!haveActivities) {
   15182                 startHomeActivityLocked(userId);
   15183             }
   15184 
   15185         }
   15186 
   15187         // Inform of user switch
   15188         Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
   15189         addedIntent.putExtra(Intent.EXTRA_USERID, userId);
   15190         mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS);
   15191 
   15192         return true;
   15193     }
   15194 
   15195     @Override
   15196     public UserInfo getCurrentUser() throws RemoteException {
   15197         final int callingUid = Binder.getCallingUid();
   15198         if (callingUid != 0 && callingUid != Process.myUid()) {
   15199             Slog.e(TAG, "Trying to get user from unauthorized app");
   15200             return null;
   15201         }
   15202         return AppGlobals.getPackageManager().getUser(mCurrentUserId);
   15203     }
   15204 
   15205     private void onUserRemoved(Intent intent) {
   15206         int extraUserId = intent.getIntExtra(Intent.EXTRA_USERID, -1);
   15207         if (extraUserId < 1) return;
   15208 
   15209         // Kill all the processes for the user
   15210         ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>();
   15211         synchronized (this) {
   15212             HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap();
   15213             for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) {
   15214                 SparseArray<ProcessRecord> uids = uidMap.getValue();
   15215                 for (int i = 0; i < uids.size(); i++) {
   15216                     if (UserId.getUserId(uids.keyAt(i)) == extraUserId) {
   15217                         pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i)));
   15218                     }
   15219                 }
   15220             }
   15221 
   15222             for (Pair<String,Integer> pkgAndUid : pkgAndUids) {
   15223                 forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second,
   15224                         false, false, true, true, extraUserId);
   15225             }
   15226         }
   15227     }
   15228 
   15229     private boolean userExists(int userId) {
   15230         try {
   15231             UserInfo user = AppGlobals.getPackageManager().getUser(userId);
   15232             return user != null;
   15233         } catch (RemoteException re) {
   15234             // Won't happen, in same process
   15235         }
   15236 
   15237         return false;
   15238     }
   15239 
   15240     private void checkValidCaller(int uid, int userId) {
   15241         if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
   15242 
   15243         throw new SecurityException("Caller uid=" + uid
   15244                 + " is not privileged to communicate with user=" + userId);
   15245     }
   15246 
   15247     private int applyUserId(int uid, int userId) {
   15248         return UserId.getUid(userId, uid);
   15249     }
   15250 
   15251     private ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
   15252         if (info == null) return null;
   15253         ApplicationInfo newInfo = new ApplicationInfo(info);
   15254         newInfo.uid = applyUserId(info.uid, userId);
   15255         newInfo.dataDir = USER_DATA_DIR + userId + "/"
   15256                 + info.packageName;
   15257         return newInfo;
   15258     }
   15259 
   15260     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
   15261         if (aInfo == null
   15262                 || (userId < 1 && aInfo.applicationInfo.uid < UserId.PER_USER_RANGE)) {
   15263             return aInfo;
   15264         }
   15265 
   15266         ActivityInfo info = new ActivityInfo(aInfo);
   15267         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
   15268         return info;
   15269     }
   15270 
   15271     static class ServiceMap {
   15272 
   15273         private final SparseArray<HashMap<ComponentName, ServiceRecord>> mServicesByNamePerUser
   15274                 = new SparseArray<HashMap<ComponentName, ServiceRecord>>();
   15275         private final SparseArray<HashMap<Intent.FilterComparison, ServiceRecord>>
   15276                 mServicesByIntentPerUser = new SparseArray<
   15277                     HashMap<Intent.FilterComparison, ServiceRecord>>();
   15278 
   15279         ServiceRecord getServiceByName(ComponentName name, int callingUser) {
   15280             // TODO: Deal with global services
   15281             if (DEBUG_MU)
   15282                 Slog.v(TAG_MU, "getServiceByName(" + name + "), callingUser = " + callingUser);
   15283             return getServices(callingUser).get(name);
   15284         }
   15285 
   15286         ServiceRecord getServiceByName(ComponentName name) {
   15287             return getServiceByName(name, -1);
   15288         }
   15289 
   15290         ServiceRecord getServiceByIntent(Intent.FilterComparison filter, int callingUser) {
   15291             // TODO: Deal with global services
   15292             if (DEBUG_MU)
   15293                 Slog.v(TAG_MU, "getServiceByIntent(" + filter + "), callingUser = " + callingUser);
   15294             return getServicesByIntent(callingUser).get(filter);
   15295         }
   15296 
   15297         ServiceRecord getServiceByIntent(Intent.FilterComparison filter) {
   15298             return getServiceByIntent(filter, -1);
   15299         }
   15300 
   15301         void putServiceByName(ComponentName name, int callingUser, ServiceRecord value) {
   15302             // TODO: Deal with global services
   15303             getServices(callingUser).put(name, value);
   15304         }
   15305 
   15306         void putServiceByIntent(Intent.FilterComparison filter, int callingUser,
   15307                 ServiceRecord value) {
   15308             // TODO: Deal with global services
   15309             getServicesByIntent(callingUser).put(filter, value);
   15310         }
   15311 
   15312         void removeServiceByName(ComponentName name, int callingUser) {
   15313             // TODO: Deal with global services
   15314             ServiceRecord removed = getServices(callingUser).remove(name);
   15315             if (DEBUG_MU)
   15316                 Slog.v(TAG, "removeServiceByName user=" + callingUser + " name=" + name
   15317                         + " removed=" + removed);
   15318         }
   15319 
   15320         void removeServiceByIntent(Intent.FilterComparison filter, int callingUser) {
   15321             // TODO: Deal with global services
   15322             ServiceRecord removed = getServicesByIntent(callingUser).remove(filter);
   15323             if (DEBUG_MU)
   15324                 Slog.v(TAG_MU, "removeServiceByIntent user=" + callingUser + " intent=" + filter
   15325                         + " removed=" + removed);
   15326         }
   15327 
   15328         Collection<ServiceRecord> getAllServices(int callingUser) {
   15329             // TODO: Deal with global services
   15330             return getServices(callingUser).values();
   15331         }
   15332 
   15333         private HashMap<ComponentName, ServiceRecord> getServices(int callingUser) {
   15334             HashMap map = mServicesByNamePerUser.get(callingUser);
   15335             if (map == null) {
   15336                 map = new HashMap<ComponentName, ServiceRecord>();
   15337                 mServicesByNamePerUser.put(callingUser, map);
   15338             }
   15339             return map;
   15340         }
   15341 
   15342         private HashMap<Intent.FilterComparison, ServiceRecord> getServicesByIntent(
   15343                 int callingUser) {
   15344             HashMap map = mServicesByIntentPerUser.get(callingUser);
   15345             if (map == null) {
   15346                 map = new HashMap<Intent.FilterComparison, ServiceRecord>();
   15347                 mServicesByIntentPerUser.put(callingUser, map);
   15348             }
   15349             return map;
   15350         }
   15351     }
   15352 }
   15353