Home | History | Annotate | Download | only in app
      1 /*
      2  * Copyright (C) 2006 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 android.app;
     18 
     19 import android.annotation.IntDef;
     20 import android.annotation.NonNull;
     21 import android.annotation.Nullable;
     22 import android.content.ActivityNotFoundException;
     23 import android.content.ComponentName;
     24 import android.content.Context;
     25 import android.content.Intent;
     26 import android.content.IntentFilter;
     27 import android.content.pm.ActivityInfo;
     28 import android.content.res.Configuration;
     29 import android.hardware.input.InputManager;
     30 import android.net.Uri;
     31 import android.os.Bundle;
     32 import android.os.Debug;
     33 import android.os.IBinder;
     34 import android.os.Looper;
     35 import android.os.MessageQueue;
     36 import android.os.PerformanceCollector;
     37 import android.os.PersistableBundle;
     38 import android.os.Process;
     39 import android.os.RemoteException;
     40 import android.os.ServiceManager;
     41 import android.os.SystemClock;
     42 import android.os.TestLooperManager;
     43 import android.os.UserHandle;
     44 import android.util.AndroidRuntimeException;
     45 import android.util.Log;
     46 import android.view.IWindowManager;
     47 import android.view.InputDevice;
     48 import android.view.KeyCharacterMap;
     49 import android.view.KeyEvent;
     50 import android.view.MotionEvent;
     51 import android.view.ViewConfiguration;
     52 import android.view.Window;
     53 
     54 import com.android.internal.content.ReferrerIntent;
     55 
     56 import java.io.File;
     57 import java.lang.annotation.Retention;
     58 import java.lang.annotation.RetentionPolicy;
     59 import java.util.ArrayList;
     60 import java.util.List;
     61 
     62 /**
     63  * Base class for implementing application instrumentation code.  When running
     64  * with instrumentation turned on, this class will be instantiated for you
     65  * before any of the application code, allowing you to monitor all of the
     66  * interaction the system has with the application.  An Instrumentation
     67  * implementation is described to the system through an AndroidManifest.xml's
     68  * <instrumentation> tag.
     69  */
     70 public class Instrumentation {
     71 
     72     /**
     73      * If included in the status or final bundle sent to an IInstrumentationWatcher, this key
     74      * identifies the class that is writing the report.  This can be used to provide more structured
     75      * logging or reporting capabilities in the IInstrumentationWatcher.
     76      */
     77     public static final String REPORT_KEY_IDENTIFIER = "id";
     78     /**
     79      * If included in the status or final bundle sent to an IInstrumentationWatcher, this key
     80      * identifies a string which can simply be printed to the output stream.  Using these streams
     81      * provides a "pretty printer" version of the status & final packets.  Any bundles including
     82      * this key should also include the complete set of raw key/value pairs, so that the
     83      * instrumentation can also be launched, and results collected, by an automated system.
     84      */
     85     public static final String REPORT_KEY_STREAMRESULT = "stream";
     86 
     87     private static final String TAG = "Instrumentation";
     88 
     89     /**
     90      * @hide
     91      */
     92     @Retention(RetentionPolicy.SOURCE)
     93     @IntDef({0, UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES})
     94     public @interface UiAutomationFlags {};
     95 
     96 
     97     private final Object mSync = new Object();
     98     private ActivityThread mThread = null;
     99     private MessageQueue mMessageQueue = null;
    100     private Context mInstrContext;
    101     private Context mAppContext;
    102     private ComponentName mComponent;
    103     private Thread mRunner;
    104     private List<ActivityWaiter> mWaitingActivities;
    105     private List<ActivityMonitor> mActivityMonitors;
    106     private IInstrumentationWatcher mWatcher;
    107     private IUiAutomationConnection mUiAutomationConnection;
    108     private boolean mAutomaticPerformanceSnapshots = false;
    109     private PerformanceCollector mPerformanceCollector;
    110     private Bundle mPerfMetrics = new Bundle();
    111     private UiAutomation mUiAutomation;
    112 
    113     public Instrumentation() {
    114     }
    115 
    116     /**
    117      * Called for methods that shouldn't be called by standard apps and
    118      * should only be used in instrumentation environments. This is not
    119      * security feature as these classes will still be accessible through
    120      * reflection, but it will serve as noticeable discouragement from
    121      * doing such a thing.
    122      */
    123     private void checkInstrumenting(String method) {
    124         // Check if we have an instrumentation context, as init should only get called by
    125         // the system in startup processes that are being instrumented.
    126         if (mInstrContext == null) {
    127             throw new RuntimeException(method +
    128                     " cannot be called outside of instrumented processes");
    129         }
    130     }
    131 
    132     /**
    133      * Called when the instrumentation is starting, before any application code
    134      * has been loaded.  Usually this will be implemented to simply call
    135      * {@link #start} to begin the instrumentation thread, which will then
    136      * continue execution in {@link #onStart}.
    137      *
    138      * <p>If you do not need your own thread -- that is you are writing your
    139      * instrumentation to be completely asynchronous (returning to the event
    140      * loop so that the application can run), you can simply begin your
    141      * instrumentation here, for example call {@link Context#startActivity} to
    142      * begin the appropriate first activity of the application.
    143      *
    144      * @param arguments Any additional arguments that were supplied when the
    145      *                  instrumentation was started.
    146      */
    147     public void onCreate(Bundle arguments) {
    148     }
    149 
    150     /**
    151      * Create and start a new thread in which to run instrumentation.  This new
    152      * thread will call to {@link #onStart} where you can implement the
    153      * instrumentation.
    154      */
    155     public void start() {
    156         if (mRunner != null) {
    157             throw new RuntimeException("Instrumentation already started");
    158         }
    159         mRunner = new InstrumentationThread("Instr: " + getClass().getName());
    160         mRunner.start();
    161     }
    162 
    163     /**
    164      * Method where the instrumentation thread enters execution.  This allows
    165      * you to run your instrumentation code in a separate thread than the
    166      * application, so that it can perform blocking operation such as
    167      * {@link #sendKeySync} or {@link #startActivitySync}.
    168      *
    169      * <p>You will typically want to call finish() when this function is done,
    170      * to end your instrumentation.
    171      */
    172     public void onStart() {
    173     }
    174 
    175     /**
    176      * This is called whenever the system captures an unhandled exception that
    177      * was thrown by the application.  The default implementation simply
    178      * returns false, allowing normal system handling of the exception to take
    179      * place.
    180      *
    181      * @param obj The client object that generated the exception.  May be an
    182      *            Application, Activity, BroadcastReceiver, Service, or null.
    183      * @param e The exception that was thrown.
    184      *
    185      * @return To allow normal system exception process to occur, return false.
    186      *         If true is returned, the system will proceed as if the exception
    187      *         didn't happen.
    188      */
    189     public boolean onException(Object obj, Throwable e) {
    190         return false;
    191     }
    192 
    193     /**
    194      * Provide a status report about the application.
    195      *
    196      * @param resultCode Current success/failure of instrumentation.
    197      * @param results Any results to send back to the code that started the instrumentation.
    198      */
    199     public void sendStatus(int resultCode, Bundle results) {
    200         if (mWatcher != null) {
    201             try {
    202                 mWatcher.instrumentationStatus(mComponent, resultCode, results);
    203             }
    204             catch (RemoteException e) {
    205                 mWatcher = null;
    206             }
    207         }
    208     }
    209 
    210     /**
    211      * Report some results in the middle of instrumentation execution.  Later results (including
    212      * those provided by {@link #finish}) will be combined with {@link Bundle#putAll}.
    213      */
    214     public void addResults(Bundle results) {
    215         IActivityManager am = ActivityManager.getService();
    216         try {
    217             am.addInstrumentationResults(mThread.getApplicationThread(), results);
    218         } catch (RemoteException ex) {
    219             throw ex.rethrowFromSystemServer();
    220         }
    221     }
    222 
    223     /**
    224      * Terminate instrumentation of the application.  This will cause the
    225      * application process to exit, removing this instrumentation from the next
    226      * time the application is started.  If multiple processes are currently running
    227      * for this instrumentation, all of those processes will be killed.
    228      *
    229      * @param resultCode Overall success/failure of instrumentation.
    230      * @param results Any results to send back to the code that started the
    231      *                instrumentation.
    232      */
    233     public void finish(int resultCode, Bundle results) {
    234         if (mAutomaticPerformanceSnapshots) {
    235             endPerformanceSnapshot();
    236         }
    237         if (mPerfMetrics != null) {
    238             if (results == null) {
    239                 results = new Bundle();
    240             }
    241             results.putAll(mPerfMetrics);
    242         }
    243         if ((mUiAutomation != null) && !mUiAutomation.isDestroyed()) {
    244             mUiAutomation.disconnect();
    245             mUiAutomation = null;
    246         }
    247         mThread.finishInstrumentation(resultCode, results);
    248     }
    249 
    250     public void setAutomaticPerformanceSnapshots() {
    251         mAutomaticPerformanceSnapshots = true;
    252         mPerformanceCollector = new PerformanceCollector();
    253     }
    254 
    255     public void startPerformanceSnapshot() {
    256         if (!isProfiling()) {
    257             mPerformanceCollector.beginSnapshot(null);
    258         }
    259     }
    260 
    261     public void endPerformanceSnapshot() {
    262         if (!isProfiling()) {
    263             mPerfMetrics = mPerformanceCollector.endSnapshot();
    264         }
    265     }
    266 
    267     /**
    268      * Called when the instrumented application is stopping, after all of the
    269      * normal application cleanup has occurred.
    270      */
    271     public void onDestroy() {
    272     }
    273 
    274     /**
    275      * Return the Context of this instrumentation's package.  Note that this is
    276      * often different than the Context of the application being
    277      * instrumentated, since the instrumentation code often lives is a
    278      * different package than that of the application it is running against.
    279      * See {@link #getTargetContext} to retrieve a Context for the target
    280      * application.
    281      *
    282      * @return The instrumentation's package context.
    283      *
    284      * @see #getTargetContext
    285      */
    286     public Context getContext() {
    287         return mInstrContext;
    288     }
    289 
    290     /**
    291      * Returns complete component name of this instrumentation.
    292      *
    293      * @return Returns the complete component name for this instrumentation.
    294      */
    295     public ComponentName getComponentName() {
    296         return mComponent;
    297     }
    298 
    299     /**
    300      * Return a Context for the target application being instrumented.  Note
    301      * that this is often different than the Context of the instrumentation
    302      * code, since the instrumentation code often lives is a different package
    303      * than that of the application it is running against. See
    304      * {@link #getContext} to retrieve a Context for the instrumentation code.
    305      *
    306      * @return A Context in the target application.
    307      *
    308      * @see #getContext
    309      */
    310     public Context getTargetContext() {
    311         return mAppContext;
    312     }
    313 
    314     /**
    315      * Return the name of the process this instrumentation is running in.  Note this should
    316      * only be used for testing and debugging.  If you are thinking about using this to,
    317      * for example, conditionalize what is initialized in an Application class, it is strongly
    318      * recommended to instead use lazy initialization (such as a getter for the state that
    319      * only creates it when requested).  This can greatly reduce the work your process does
    320      * when created for secondary things, such as to receive a broadcast.
    321      */
    322     public String getProcessName() {
    323         return mThread.getProcessName();
    324     }
    325 
    326     /**
    327      * Check whether this instrumentation was started with profiling enabled.
    328      *
    329      * @return Returns true if profiling was enabled when starting, else false.
    330      */
    331     public boolean isProfiling() {
    332         return mThread.isProfiling();
    333     }
    334 
    335     /**
    336      * This method will start profiling if isProfiling() returns true. You should
    337      * only call this method if you set the handleProfiling attribute in the
    338      * manifest file for this Instrumentation to true.
    339      */
    340     public void startProfiling() {
    341         if (mThread.isProfiling()) {
    342             File file = new File(mThread.getProfileFilePath());
    343             file.getParentFile().mkdirs();
    344             Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
    345         }
    346     }
    347 
    348     /**
    349      * Stops profiling if isProfiling() returns true.
    350      */
    351     public void stopProfiling() {
    352         if (mThread.isProfiling()) {
    353             Debug.stopMethodTracing();
    354         }
    355     }
    356 
    357     /**
    358      * Force the global system in or out of touch mode.  This can be used if
    359      * your instrumentation relies on the UI being in one more or the other
    360      * when it starts.
    361      *
    362      * @param inTouch Set to true to be in touch mode, false to be in
    363      * focus mode.
    364      */
    365     public void setInTouchMode(boolean inTouch) {
    366         try {
    367             IWindowManager.Stub.asInterface(
    368                     ServiceManager.getService("window")).setInTouchMode(inTouch);
    369         } catch (RemoteException e) {
    370             // Shouldn't happen!
    371         }
    372     }
    373 
    374     /**
    375      * Schedule a callback for when the application's main thread goes idle
    376      * (has no more events to process).
    377      *
    378      * @param recipient Called the next time the thread's message queue is
    379      *                  idle.
    380      */
    381     public void waitForIdle(Runnable recipient) {
    382         mMessageQueue.addIdleHandler(new Idler(recipient));
    383         mThread.getHandler().post(new EmptyRunnable());
    384     }
    385 
    386     /**
    387      * Synchronously wait for the application to be idle.  Can not be called
    388      * from the main application thread -- use {@link #start} to execute
    389      * instrumentation in its own thread.
    390      */
    391     public void waitForIdleSync() {
    392         validateNotAppThread();
    393         Idler idler = new Idler(null);
    394         mMessageQueue.addIdleHandler(idler);
    395         mThread.getHandler().post(new EmptyRunnable());
    396         idler.waitForIdle();
    397     }
    398 
    399     /**
    400      * Execute a call on the application's main thread, blocking until it is
    401      * complete.  Useful for doing things that are not thread-safe, such as
    402      * looking at or modifying the view hierarchy.
    403      *
    404      * @param runner The code to run on the main thread.
    405      */
    406     public void runOnMainSync(Runnable runner) {
    407         validateNotAppThread();
    408         SyncRunnable sr = new SyncRunnable(runner);
    409         mThread.getHandler().post(sr);
    410         sr.waitForComplete();
    411     }
    412 
    413     /**
    414      * Start a new activity and wait for it to begin running before returning.
    415      * In addition to being synchronous, this method as some semantic
    416      * differences from the standard {@link Context#startActivity} call: the
    417      * activity component is resolved before talking with the activity manager
    418      * (its class name is specified in the Intent that this method ultimately
    419      * starts), and it does not allow you to start activities that run in a
    420      * different process.  In addition, if the given Intent resolves to
    421      * multiple activities, instead of displaying a dialog for the user to
    422      * select an activity, an exception will be thrown.
    423      *
    424      * <p>The function returns as soon as the activity goes idle following the
    425      * call to its {@link Activity#onCreate}.  Generally this means it has gone
    426      * through the full initialization including {@link Activity#onResume} and
    427      * drawn and displayed its initial window.
    428      *
    429      * @param intent Description of the activity to start.
    430      *
    431      * @see Context#startActivity
    432      * @see #startActivitySync(Intent, Bundle)
    433      */
    434     public Activity startActivitySync(Intent intent) {
    435         return startActivitySync(intent, null /* options */);
    436     }
    437 
    438     /**
    439      * Start a new activity and wait for it to begin running before returning.
    440      * In addition to being synchronous, this method as some semantic
    441      * differences from the standard {@link Context#startActivity} call: the
    442      * activity component is resolved before talking with the activity manager
    443      * (its class name is specified in the Intent that this method ultimately
    444      * starts), and it does not allow you to start activities that run in a
    445      * different process.  In addition, if the given Intent resolves to
    446      * multiple activities, instead of displaying a dialog for the user to
    447      * select an activity, an exception will be thrown.
    448      *
    449      * <p>The function returns as soon as the activity goes idle following the
    450      * call to its {@link Activity#onCreate}.  Generally this means it has gone
    451      * through the full initialization including {@link Activity#onResume} and
    452      * drawn and displayed its initial window.
    453      *
    454      * @param intent Description of the activity to start.
    455      * @param options Additional options for how the Activity should be started.
    456      * May be null if there are no options.  See {@link android.app.ActivityOptions}
    457      * for how to build the Bundle supplied here; there are no supported definitions
    458      * for building it manually.
    459      *
    460      * @see Context#startActivity(Intent, Bundle)
    461      */
    462     @NonNull
    463     public Activity startActivitySync(@NonNull Intent intent, @Nullable Bundle options) {
    464         validateNotAppThread();
    465 
    466         synchronized (mSync) {
    467             intent = new Intent(intent);
    468 
    469             ActivityInfo ai = intent.resolveActivityInfo(
    470                 getTargetContext().getPackageManager(), 0);
    471             if (ai == null) {
    472                 throw new RuntimeException("Unable to resolve activity for: " + intent);
    473             }
    474             String myProc = mThread.getProcessName();
    475             if (!ai.processName.equals(myProc)) {
    476                 // todo: if this intent is ambiguous, look here to see if
    477                 // there is a single match that is in our package.
    478                 throw new RuntimeException("Intent in process "
    479                         + myProc + " resolved to different process "
    480                         + ai.processName + ": " + intent);
    481             }
    482 
    483             intent.setComponent(new ComponentName(
    484                     ai.applicationInfo.packageName, ai.name));
    485             final ActivityWaiter aw = new ActivityWaiter(intent);
    486 
    487             if (mWaitingActivities == null) {
    488                 mWaitingActivities = new ArrayList();
    489             }
    490             mWaitingActivities.add(aw);
    491 
    492             getTargetContext().startActivity(intent, options);
    493 
    494             do {
    495                 try {
    496                     mSync.wait();
    497                 } catch (InterruptedException e) {
    498                 }
    499             } while (mWaitingActivities.contains(aw));
    500 
    501             return aw.activity;
    502         }
    503     }
    504 
    505     /**
    506      * Information about a particular kind of Intent that is being monitored.
    507      * An instance of this class is added to the
    508      * current instrumentation through {@link #addMonitor}; after being added,
    509      * when a new activity is being started the monitor will be checked and, if
    510      * matching, its hit count updated and (optionally) the call stopped and a
    511      * canned result returned.
    512      *
    513      * <p>An ActivityMonitor can also be used to look for the creation of an
    514      * activity, through the {@link #waitForActivity} method.  This will return
    515      * after a matching activity has been created with that activity object.
    516      */
    517     public static class ActivityMonitor {
    518         private final IntentFilter mWhich;
    519         private final String mClass;
    520         private final ActivityResult mResult;
    521         private final boolean mBlock;
    522         private final boolean mIgnoreMatchingSpecificIntents;
    523 
    524 
    525         // This is protected by 'Instrumentation.this.mSync'.
    526         /*package*/ int mHits = 0;
    527 
    528         // This is protected by 'this'.
    529         /*package*/ Activity mLastActivity = null;
    530 
    531         /**
    532          * Create a new ActivityMonitor that looks for a particular kind of
    533          * intent to be started.
    534          *
    535          * @param which The set of intents this monitor is responsible for.
    536          * @param result A canned result to return if the monitor is hit; can
    537          *               be null.
    538          * @param block Controls whether the monitor should block the activity
    539          *              start (returning its canned result) or let the call
    540          *              proceed.
    541          *
    542          * @see Instrumentation#addMonitor
    543          */
    544         public ActivityMonitor(
    545             IntentFilter which, ActivityResult result, boolean block) {
    546             mWhich = which;
    547             mClass = null;
    548             mResult = result;
    549             mBlock = block;
    550             mIgnoreMatchingSpecificIntents = false;
    551         }
    552 
    553         /**
    554          * Create a new ActivityMonitor that looks for a specific activity
    555          * class to be started.
    556          *
    557          * @param cls The activity class this monitor is responsible for.
    558          * @param result A canned result to return if the monitor is hit; can
    559          *               be null.
    560          * @param block Controls whether the monitor should block the activity
    561          *              start (returning its canned result) or let the call
    562          *              proceed.
    563          *
    564          * @see Instrumentation#addMonitor
    565          */
    566         public ActivityMonitor(
    567             String cls, ActivityResult result, boolean block) {
    568             mWhich = null;
    569             mClass = cls;
    570             mResult = result;
    571             mBlock = block;
    572             mIgnoreMatchingSpecificIntents = false;
    573         }
    574 
    575         /**
    576          * Create a new ActivityMonitor that can be used for intercepting any activity to be
    577          * started.
    578          *
    579          * <p> When an activity is started, {@link #onStartActivity(Intent)} will be called on
    580          * instances created using this constructor to see if it is a hit.
    581          *
    582          * @see #onStartActivity(Intent)
    583          */
    584         public ActivityMonitor() {
    585             mWhich = null;
    586             mClass = null;
    587             mResult = null;
    588             mBlock = false;
    589             mIgnoreMatchingSpecificIntents = true;
    590         }
    591 
    592         /**
    593          * @return true if this monitor is used for intercepting any started activity by calling
    594          *         into {@link #onStartActivity(Intent)}, false if this monitor is only used
    595          *         for specific intents corresponding to the intent filter or activity class
    596          *         passed in the constructor.
    597          */
    598         final boolean ignoreMatchingSpecificIntents() {
    599             return mIgnoreMatchingSpecificIntents;
    600         }
    601 
    602         /**
    603          * Retrieve the filter associated with this ActivityMonitor.
    604          */
    605         public final IntentFilter getFilter() {
    606             return mWhich;
    607         }
    608 
    609         /**
    610          * Retrieve the result associated with this ActivityMonitor, or null if
    611          * none.
    612          */
    613         public final ActivityResult getResult() {
    614             return mResult;
    615         }
    616 
    617         /**
    618          * Check whether this monitor blocks activity starts (not allowing the
    619          * actual activity to run) or allows them to execute normally.
    620          */
    621         public final boolean isBlocking() {
    622             return mBlock;
    623         }
    624 
    625         /**
    626          * Retrieve the number of times the monitor has been hit so far.
    627          */
    628         public final int getHits() {
    629             return mHits;
    630         }
    631 
    632         /**
    633          * Retrieve the most recent activity class that was seen by this
    634          * monitor.
    635          */
    636         public final Activity getLastActivity() {
    637             return mLastActivity;
    638         }
    639 
    640         /**
    641          * Block until an Activity is created that matches this monitor,
    642          * returning the resulting activity.
    643          *
    644          * @return Activity
    645          */
    646         public final Activity waitForActivity() {
    647             synchronized (this) {
    648                 while (mLastActivity == null) {
    649                     try {
    650                         wait();
    651                     } catch (InterruptedException e) {
    652                     }
    653                 }
    654                 Activity res = mLastActivity;
    655                 mLastActivity = null;
    656                 return res;
    657             }
    658         }
    659 
    660         /**
    661          * Block until an Activity is created that matches this monitor,
    662          * returning the resulting activity or till the timeOut period expires.
    663          * If the timeOut expires before the activity is started, return null.
    664          *
    665          * @param timeOut Time to wait in milliseconds before the activity is created.
    666          *
    667          * @return Activity
    668          */
    669         public final Activity waitForActivityWithTimeout(long timeOut) {
    670             synchronized (this) {
    671                 if (mLastActivity == null) {
    672                     try {
    673                         wait(timeOut);
    674                     } catch (InterruptedException e) {
    675                     }
    676                 }
    677                 if (mLastActivity == null) {
    678                     return null;
    679                 } else {
    680                     Activity res = mLastActivity;
    681                     mLastActivity = null;
    682                     return res;
    683                 }
    684             }
    685         }
    686 
    687         /**
    688          * Used for intercepting any started activity.
    689          *
    690          * <p> A non-null return value here will be considered a hit for this monitor.
    691          * By default this will return {@code null} and subclasses can override this to return
    692          * a non-null value if the intent needs to be intercepted.
    693          *
    694          * <p> Whenever a new activity is started, this method will be called on instances created
    695          * using {@link #Instrumentation.ActivityMonitor()} to check if there is a match. In case
    696          * of a match, the activity start will be blocked and the returned result will be used.
    697          *
    698          * @param intent The intent used for starting the activity.
    699          * @return The {@link ActivityResult} that needs to be used in case of a match.
    700          */
    701         public ActivityResult onStartActivity(Intent intent) {
    702             return null;
    703         }
    704 
    705         final boolean match(Context who,
    706                             Activity activity,
    707                             Intent intent) {
    708             if (mIgnoreMatchingSpecificIntents) {
    709                 return false;
    710             }
    711             synchronized (this) {
    712                 if (mWhich != null
    713                     && mWhich.match(who.getContentResolver(), intent,
    714                                     true, "Instrumentation") < 0) {
    715                     return false;
    716                 }
    717                 if (mClass != null) {
    718                     String cls = null;
    719                     if (activity != null) {
    720                         cls = activity.getClass().getName();
    721                     } else if (intent.getComponent() != null) {
    722                         cls = intent.getComponent().getClassName();
    723                     }
    724                     if (cls == null || !mClass.equals(cls)) {
    725                         return false;
    726                     }
    727                 }
    728                 if (activity != null) {
    729                     mLastActivity = activity;
    730                     notifyAll();
    731                 }
    732                 return true;
    733             }
    734         }
    735     }
    736 
    737     /**
    738      * Add a new {@link ActivityMonitor} that will be checked whenever an
    739      * activity is started.  The monitor is added
    740      * after any existing ones; the monitor will be hit only if none of the
    741      * existing monitors can themselves handle the Intent.
    742      *
    743      * @param monitor The new ActivityMonitor to see.
    744      *
    745      * @see #addMonitor(IntentFilter, ActivityResult, boolean)
    746      * @see #checkMonitorHit
    747      */
    748     public void addMonitor(ActivityMonitor monitor) {
    749         synchronized (mSync) {
    750             if (mActivityMonitors == null) {
    751                 mActivityMonitors = new ArrayList();
    752             }
    753             mActivityMonitors.add(monitor);
    754         }
    755     }
    756 
    757     /**
    758      * A convenience wrapper for {@link #addMonitor(ActivityMonitor)} that
    759      * creates an intent filter matching {@link ActivityMonitor} for you and
    760      * returns it.
    761      *
    762      * @param filter The set of intents this monitor is responsible for.
    763      * @param result A canned result to return if the monitor is hit; can
    764      *               be null.
    765      * @param block Controls whether the monitor should block the activity
    766      *              start (returning its canned result) or let the call
    767      *              proceed.
    768      *
    769      * @return The newly created and added activity monitor.
    770      *
    771      * @see #addMonitor(ActivityMonitor)
    772      * @see #checkMonitorHit
    773      */
    774     public ActivityMonitor addMonitor(
    775         IntentFilter filter, ActivityResult result, boolean block) {
    776         ActivityMonitor am = new ActivityMonitor(filter, result, block);
    777         addMonitor(am);
    778         return am;
    779     }
    780 
    781     /**
    782      * A convenience wrapper for {@link #addMonitor(ActivityMonitor)} that
    783      * creates a class matching {@link ActivityMonitor} for you and returns it.
    784      *
    785      * @param cls The activity class this monitor is responsible for.
    786      * @param result A canned result to return if the monitor is hit; can
    787      *               be null.
    788      * @param block Controls whether the monitor should block the activity
    789      *              start (returning its canned result) or let the call
    790      *              proceed.
    791      *
    792      * @return The newly created and added activity monitor.
    793      *
    794      * @see #addMonitor(ActivityMonitor)
    795      * @see #checkMonitorHit
    796      */
    797     public ActivityMonitor addMonitor(
    798         String cls, ActivityResult result, boolean block) {
    799         ActivityMonitor am = new ActivityMonitor(cls, result, block);
    800         addMonitor(am);
    801         return am;
    802     }
    803 
    804     /**
    805      * Test whether an existing {@link ActivityMonitor} has been hit.  If the
    806      * monitor has been hit at least <var>minHits</var> times, then it will be
    807      * removed from the activity monitor list and true returned.  Otherwise it
    808      * is left as-is and false is returned.
    809      *
    810      * @param monitor The ActivityMonitor to check.
    811      * @param minHits The minimum number of hits required.
    812      *
    813      * @return True if the hit count has been reached, else false.
    814      *
    815      * @see #addMonitor
    816      */
    817     public boolean checkMonitorHit(ActivityMonitor monitor, int minHits) {
    818         waitForIdleSync();
    819         synchronized (mSync) {
    820             if (monitor.getHits() < minHits) {
    821                 return false;
    822             }
    823             mActivityMonitors.remove(monitor);
    824         }
    825         return true;
    826     }
    827 
    828     /**
    829      * Wait for an existing {@link ActivityMonitor} to be hit.  Once the
    830      * monitor has been hit, it is removed from the activity monitor list and
    831      * the first created Activity object that matched it is returned.
    832      *
    833      * @param monitor The ActivityMonitor to wait for.
    834      *
    835      * @return The Activity object that matched the monitor.
    836      */
    837     public Activity waitForMonitor(ActivityMonitor monitor) {
    838         Activity activity = monitor.waitForActivity();
    839         synchronized (mSync) {
    840             mActivityMonitors.remove(monitor);
    841         }
    842         return activity;
    843     }
    844 
    845     /**
    846      * Wait for an existing {@link ActivityMonitor} to be hit till the timeout
    847      * expires.  Once the monitor has been hit, it is removed from the activity
    848      * monitor list and the first created Activity object that matched it is
    849      * returned.  If the timeout expires, a null object is returned.
    850      *
    851      * @param monitor The ActivityMonitor to wait for.
    852      * @param timeOut The timeout value in milliseconds.
    853      *
    854      * @return The Activity object that matched the monitor.
    855      */
    856     public Activity waitForMonitorWithTimeout(ActivityMonitor monitor, long timeOut) {
    857         Activity activity = monitor.waitForActivityWithTimeout(timeOut);
    858         synchronized (mSync) {
    859             mActivityMonitors.remove(monitor);
    860         }
    861         return activity;
    862     }
    863 
    864     /**
    865      * Remove an {@link ActivityMonitor} that was previously added with
    866      * {@link #addMonitor}.
    867      *
    868      * @param monitor The monitor to remove.
    869      *
    870      * @see #addMonitor
    871      */
    872     public void removeMonitor(ActivityMonitor monitor) {
    873         synchronized (mSync) {
    874             mActivityMonitors.remove(monitor);
    875         }
    876     }
    877 
    878     /**
    879      * Execute a particular menu item.
    880      *
    881      * @param targetActivity The activity in question.
    882      * @param id The identifier associated with the menu item.
    883      * @param flag Additional flags, if any.
    884      * @return Whether the invocation was successful (for example, it could be
    885      *         false if item is disabled).
    886      */
    887     public boolean invokeMenuActionSync(Activity targetActivity,
    888                                     int id, int flag) {
    889         class MenuRunnable implements Runnable {
    890             private final Activity activity;
    891             private final int identifier;
    892             private final int flags;
    893             boolean returnValue;
    894 
    895             public MenuRunnable(Activity _activity, int _identifier,
    896                                     int _flags) {
    897                 activity = _activity;
    898                 identifier = _identifier;
    899                 flags = _flags;
    900             }
    901 
    902             public void run() {
    903                 Window win = activity.getWindow();
    904 
    905                 returnValue = win.performPanelIdentifierAction(
    906                             Window.FEATURE_OPTIONS_PANEL,
    907                             identifier,
    908                             flags);
    909             }
    910 
    911         }
    912         MenuRunnable mr = new MenuRunnable(targetActivity, id, flag);
    913         runOnMainSync(mr);
    914         return mr.returnValue;
    915     }
    916 
    917     /**
    918      * Show the context menu for the currently focused view and executes a
    919      * particular context menu item.
    920      *
    921      * @param targetActivity The activity in question.
    922      * @param id The identifier associated with the context menu item.
    923      * @param flag Additional flags, if any.
    924      * @return Whether the invocation was successful (for example, it could be
    925      *         false if item is disabled).
    926      */
    927     public boolean invokeContextMenuAction(Activity targetActivity, int id, int flag) {
    928         validateNotAppThread();
    929 
    930         // Bring up context menu for current focus.
    931         // It'd be nice to do this through code, but currently ListView depends on
    932         //   long press to set metadata for its selected child
    933 
    934         final KeyEvent downEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER);
    935         sendKeySync(downEvent);
    936 
    937         // Need to wait for long press
    938         waitForIdleSync();
    939         try {
    940             Thread.sleep(ViewConfiguration.getLongPressTimeout());
    941         } catch (InterruptedException e) {
    942             Log.e(TAG, "Could not sleep for long press timeout", e);
    943             return false;
    944         }
    945 
    946         final KeyEvent upEvent = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER);
    947         sendKeySync(upEvent);
    948 
    949         // Wait for context menu to appear
    950         waitForIdleSync();
    951 
    952         class ContextMenuRunnable implements Runnable {
    953             private final Activity activity;
    954             private final int identifier;
    955             private final int flags;
    956             boolean returnValue;
    957 
    958             public ContextMenuRunnable(Activity _activity, int _identifier,
    959                                     int _flags) {
    960                 activity = _activity;
    961                 identifier = _identifier;
    962                 flags = _flags;
    963             }
    964 
    965             public void run() {
    966                 Window win = activity.getWindow();
    967                 returnValue = win.performContextMenuIdentifierAction(
    968                             identifier,
    969                             flags);
    970             }
    971 
    972         }
    973 
    974         ContextMenuRunnable cmr = new ContextMenuRunnable(targetActivity, id, flag);
    975         runOnMainSync(cmr);
    976         return cmr.returnValue;
    977     }
    978 
    979     /**
    980      * Sends the key events corresponding to the text to the app being
    981      * instrumented.
    982      *
    983      * @param text The text to be sent.
    984      */
    985     public void sendStringSync(String text) {
    986         if (text == null) {
    987             return;
    988         }
    989         KeyCharacterMap keyCharacterMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
    990 
    991         KeyEvent[] events = keyCharacterMap.getEvents(text.toCharArray());
    992 
    993         if (events != null) {
    994             for (int i = 0; i < events.length; i++) {
    995                 // We have to change the time of an event before injecting it because
    996                 // all KeyEvents returned by KeyCharacterMap.getEvents() have the same
    997                 // time stamp and the system rejects too old events. Hence, it is
    998                 // possible for an event to become stale before it is injected if it
    999                 // takes too long to inject the preceding ones.
   1000                 sendKeySync(KeyEvent.changeTimeRepeat(events[i], SystemClock.uptimeMillis(), 0));
   1001             }
   1002         }
   1003     }
   1004 
   1005     /**
   1006      * Send a key event to the currently focused window/view and wait for it to
   1007      * be processed.  Finished at some point after the recipient has returned
   1008      * from its event processing, though it may <em>not</em> have completely
   1009      * finished reacting from the event -- for example, if it needs to update
   1010      * its display as a result, it may still be in the process of doing that.
   1011      *
   1012      * @param event The event to send to the current focus.
   1013      */
   1014     public void sendKeySync(KeyEvent event) {
   1015         validateNotAppThread();
   1016 
   1017         long downTime = event.getDownTime();
   1018         long eventTime = event.getEventTime();
   1019         int action = event.getAction();
   1020         int code = event.getKeyCode();
   1021         int repeatCount = event.getRepeatCount();
   1022         int metaState = event.getMetaState();
   1023         int deviceId = event.getDeviceId();
   1024         int scancode = event.getScanCode();
   1025         int source = event.getSource();
   1026         int flags = event.getFlags();
   1027         if (source == InputDevice.SOURCE_UNKNOWN) {
   1028             source = InputDevice.SOURCE_KEYBOARD;
   1029         }
   1030         if (eventTime == 0) {
   1031             eventTime = SystemClock.uptimeMillis();
   1032         }
   1033         if (downTime == 0) {
   1034             downTime = eventTime;
   1035         }
   1036         KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
   1037                 deviceId, scancode, flags | KeyEvent.FLAG_FROM_SYSTEM, source);
   1038         InputManager.getInstance().injectInputEvent(newEvent,
   1039                 InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
   1040     }
   1041 
   1042     /**
   1043      * Sends an up and down key event sync to the currently focused window.
   1044      *
   1045      * @param key The integer keycode for the event.
   1046      */
   1047     public void sendKeyDownUpSync(int key) {
   1048         sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, key));
   1049         sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, key));
   1050     }
   1051 
   1052     /**
   1053      * Higher-level method for sending both the down and up key events for a
   1054      * particular character key code.  Equivalent to creating both KeyEvent
   1055      * objects by hand and calling {@link #sendKeySync}.  The event appears
   1056      * as if it came from keyboard 0, the built in one.
   1057      *
   1058      * @param keyCode The key code of the character to send.
   1059      */
   1060     public void sendCharacterSync(int keyCode) {
   1061         sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, keyCode));
   1062         sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, keyCode));
   1063     }
   1064 
   1065     /**
   1066      * Dispatch a pointer event. Finished at some point after the recipient has
   1067      * returned from its event processing, though it may <em>not</em> have
   1068      * completely finished reacting from the event -- for example, if it needs
   1069      * to update its display as a result, it may still be in the process of
   1070      * doing that.
   1071      *
   1072      * @param event A motion event describing the pointer action.  (As noted in
   1073      * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
   1074      * {@link SystemClock#uptimeMillis()} as the timebase.
   1075      */
   1076     public void sendPointerSync(MotionEvent event) {
   1077         validateNotAppThread();
   1078         if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
   1079             event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
   1080         }
   1081         InputManager.getInstance().injectInputEvent(event,
   1082                 InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
   1083     }
   1084 
   1085     /**
   1086      * Dispatch a trackball event. Finished at some point after the recipient has
   1087      * returned from its event processing, though it may <em>not</em> have
   1088      * completely finished reacting from the event -- for example, if it needs
   1089      * to update its display as a result, it may still be in the process of
   1090      * doing that.
   1091      *
   1092      * @param event A motion event describing the trackball action.  (As noted in
   1093      * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
   1094      * {@link SystemClock#uptimeMillis()} as the timebase.
   1095      */
   1096     public void sendTrackballEventSync(MotionEvent event) {
   1097         validateNotAppThread();
   1098         if ((event.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) {
   1099             event.setSource(InputDevice.SOURCE_TRACKBALL);
   1100         }
   1101         InputManager.getInstance().injectInputEvent(event,
   1102                 InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
   1103     }
   1104 
   1105     /**
   1106      * Perform instantiation of the process's {@link Application} object.  The
   1107      * default implementation provides the normal system behavior.
   1108      *
   1109      * @param cl The ClassLoader with which to instantiate the object.
   1110      * @param className The name of the class implementing the Application
   1111      *                  object.
   1112      * @param context The context to initialize the application with
   1113      *
   1114      * @return The newly instantiated Application object.
   1115      */
   1116     public Application newApplication(ClassLoader cl, String className, Context context)
   1117             throws InstantiationException, IllegalAccessException,
   1118             ClassNotFoundException {
   1119         Application app = getFactory(context.getPackageName())
   1120                 .instantiateApplication(cl, className);
   1121         app.attach(context);
   1122         return app;
   1123     }
   1124 
   1125     /**
   1126      * Perform instantiation of the process's {@link Application} object.  The
   1127      * default implementation provides the normal system behavior.
   1128      *
   1129      * @param clazz The class used to create an Application object from.
   1130      * @param context The context to initialize the application with
   1131      *
   1132      * @return The newly instantiated Application object.
   1133      */
   1134     static public Application newApplication(Class<?> clazz, Context context)
   1135             throws InstantiationException, IllegalAccessException,
   1136             ClassNotFoundException {
   1137         Application app = (Application)clazz.newInstance();
   1138         app.attach(context);
   1139         return app;
   1140     }
   1141 
   1142     /**
   1143      * Perform calling of the application's {@link Application#onCreate}
   1144      * method.  The default implementation simply calls through to that method.
   1145      *
   1146      * <p>Note: This method will be called immediately after {@link #onCreate(Bundle)}.
   1147      * Often instrumentation tests start their test thread in onCreate(); you
   1148      * need to be careful of races between these.  (Well between it and
   1149      * everything else, but let's start here.)
   1150      *
   1151      * @param app The application being created.
   1152      */
   1153     public void callApplicationOnCreate(Application app) {
   1154         app.onCreate();
   1155     }
   1156 
   1157     /**
   1158      * Perform instantiation of an {@link Activity} object.  This method is intended for use with
   1159      * unit tests, such as android.test.ActivityUnitTestCase.  The activity will be useable
   1160      * locally but will be missing some of the linkages necessary for use within the system.
   1161      *
   1162      * @param clazz The Class of the desired Activity
   1163      * @param context The base context for the activity to use
   1164      * @param token The token for this activity to communicate with
   1165      * @param application The application object (if any)
   1166      * @param intent The intent that started this Activity
   1167      * @param info ActivityInfo from the manifest
   1168      * @param title The title, typically retrieved from the ActivityInfo record
   1169      * @param parent The parent Activity (if any)
   1170      * @param id The embedded Id (if any)
   1171      * @param lastNonConfigurationInstance Arbitrary object that will be
   1172      * available via {@link Activity#getLastNonConfigurationInstance()
   1173      * Activity.getLastNonConfigurationInstance()}.
   1174      * @return Returns the instantiated activity
   1175      * @throws InstantiationException
   1176      * @throws IllegalAccessException
   1177      */
   1178     public Activity newActivity(Class<?> clazz, Context context,
   1179             IBinder token, Application application, Intent intent, ActivityInfo info,
   1180             CharSequence title, Activity parent, String id,
   1181             Object lastNonConfigurationInstance) throws InstantiationException,
   1182             IllegalAccessException {
   1183         Activity activity = (Activity)clazz.newInstance();
   1184         ActivityThread aThread = null;
   1185         // Activity.attach expects a non-null Application Object.
   1186         if (application == null) {
   1187             application = new Application();
   1188         }
   1189         activity.attach(context, aThread, this, token, 0 /* ident */, application, intent,
   1190                 info, title, parent, id,
   1191                 (Activity.NonConfigurationInstances)lastNonConfigurationInstance,
   1192                 new Configuration(), null /* referrer */, null /* voiceInteractor */,
   1193                 null /* window */, null /* activityConfigCallback */);
   1194         return activity;
   1195     }
   1196 
   1197     /**
   1198      * Perform instantiation of the process's {@link Activity} object.  The
   1199      * default implementation provides the normal system behavior.
   1200      *
   1201      * @param cl The ClassLoader with which to instantiate the object.
   1202      * @param className The name of the class implementing the Activity
   1203      *                  object.
   1204      * @param intent The Intent object that specified the activity class being
   1205      *               instantiated.
   1206      *
   1207      * @return The newly instantiated Activity object.
   1208      */
   1209     public Activity newActivity(ClassLoader cl, String className,
   1210             Intent intent)
   1211             throws InstantiationException, IllegalAccessException,
   1212             ClassNotFoundException {
   1213         String pkg = intent != null && intent.getComponent() != null
   1214                 ? intent.getComponent().getPackageName() : null;
   1215         return getFactory(pkg).instantiateActivity(cl, className, intent);
   1216     }
   1217 
   1218     private AppComponentFactory getFactory(String pkg) {
   1219         if (pkg == null) {
   1220             Log.e(TAG, "No pkg specified, disabling AppComponentFactory");
   1221             return AppComponentFactory.DEFAULT;
   1222         }
   1223         if (mThread == null) {
   1224             Log.e(TAG, "Uninitialized ActivityThread, likely app-created Instrumentation,"
   1225                     + " disabling AppComponentFactory", new Throwable());
   1226             return AppComponentFactory.DEFAULT;
   1227         }
   1228         LoadedApk apk = mThread.peekPackageInfo(pkg, true);
   1229         // This is in the case of starting up "android".
   1230         if (apk == null) apk = mThread.getSystemContext().mPackageInfo;
   1231         return apk.getAppFactory();
   1232     }
   1233 
   1234     private void prePerformCreate(Activity activity) {
   1235         if (mWaitingActivities != null) {
   1236             synchronized (mSync) {
   1237                 final int N = mWaitingActivities.size();
   1238                 for (int i=0; i<N; i++) {
   1239                     final ActivityWaiter aw = mWaitingActivities.get(i);
   1240                     final Intent intent = aw.intent;
   1241                     if (intent.filterEquals(activity.getIntent())) {
   1242                         aw.activity = activity;
   1243                         mMessageQueue.addIdleHandler(new ActivityGoing(aw));
   1244                     }
   1245                 }
   1246             }
   1247         }
   1248     }
   1249 
   1250     private void postPerformCreate(Activity activity) {
   1251         if (mActivityMonitors != null) {
   1252             synchronized (mSync) {
   1253                 final int N = mActivityMonitors.size();
   1254                 for (int i=0; i<N; i++) {
   1255                     final ActivityMonitor am = mActivityMonitors.get(i);
   1256                     am.match(activity, activity, activity.getIntent());
   1257                 }
   1258             }
   1259         }
   1260     }
   1261 
   1262     /**
   1263      * Perform calling of an activity's {@link Activity#onCreate}
   1264      * method.  The default implementation simply calls through to that method.
   1265      *
   1266      * @param activity The activity being created.
   1267      * @param icicle The previously frozen state (or null) to pass through to onCreate().
   1268      */
   1269     public void callActivityOnCreate(Activity activity, Bundle icicle) {
   1270         prePerformCreate(activity);
   1271         activity.performCreate(icicle);
   1272         postPerformCreate(activity);
   1273     }
   1274 
   1275     /**
   1276      * Perform calling of an activity's {@link Activity#onCreate}
   1277      * method.  The default implementation simply calls through to that method.
   1278      *  @param activity The activity being created.
   1279      * @param icicle The previously frozen state (or null) to pass through to
   1280      * @param persistentState The previously persisted state (or null)
   1281      */
   1282     public void callActivityOnCreate(Activity activity, Bundle icicle,
   1283             PersistableBundle persistentState) {
   1284         prePerformCreate(activity);
   1285         activity.performCreate(icicle, persistentState);
   1286         postPerformCreate(activity);
   1287     }
   1288 
   1289     public void callActivityOnDestroy(Activity activity) {
   1290       // TODO: the following block causes intermittent hangs when using startActivity
   1291       // temporarily comment out until root cause is fixed (bug 2630683)
   1292 //      if (mWaitingActivities != null) {
   1293 //          synchronized (mSync) {
   1294 //              final int N = mWaitingActivities.size();
   1295 //              for (int i=0; i<N; i++) {
   1296 //                  final ActivityWaiter aw = mWaitingActivities.get(i);
   1297 //                  final Intent intent = aw.intent;
   1298 //                  if (intent.filterEquals(activity.getIntent())) {
   1299 //                      aw.activity = activity;
   1300 //                      mMessageQueue.addIdleHandler(new ActivityGoing(aw));
   1301 //                  }
   1302 //              }
   1303 //          }
   1304 //      }
   1305 
   1306       activity.performDestroy();
   1307   }
   1308 
   1309     /**
   1310      * Perform calling of an activity's {@link Activity#onRestoreInstanceState}
   1311      * method.  The default implementation simply calls through to that method.
   1312      *
   1313      * @param activity The activity being restored.
   1314      * @param savedInstanceState The previously saved state being restored.
   1315      */
   1316     public void callActivityOnRestoreInstanceState(Activity activity, Bundle savedInstanceState) {
   1317         activity.performRestoreInstanceState(savedInstanceState);
   1318     }
   1319 
   1320     /**
   1321      * Perform calling of an activity's {@link Activity#onRestoreInstanceState}
   1322      * method.  The default implementation simply calls through to that method.
   1323      *
   1324      * @param activity The activity being restored.
   1325      * @param savedInstanceState The previously saved state being restored.
   1326      * @param persistentState The previously persisted state (or null)
   1327      */
   1328     public void callActivityOnRestoreInstanceState(Activity activity, Bundle savedInstanceState,
   1329             PersistableBundle persistentState) {
   1330         activity.performRestoreInstanceState(savedInstanceState, persistentState);
   1331     }
   1332 
   1333     /**
   1334      * Perform calling of an activity's {@link Activity#onPostCreate} method.
   1335      * The default implementation simply calls through to that method.
   1336      *
   1337      * @param activity The activity being created.
   1338      * @param icicle The previously frozen state (or null) to pass through to
   1339      *               onPostCreate().
   1340      */
   1341     public void callActivityOnPostCreate(Activity activity, Bundle icicle) {
   1342         activity.onPostCreate(icicle);
   1343     }
   1344 
   1345     /**
   1346      * Perform calling of an activity's {@link Activity#onPostCreate} method.
   1347      * The default implementation simply calls through to that method.
   1348      *
   1349      * @param activity The activity being created.
   1350      * @param icicle The previously frozen state (or null) to pass through to
   1351      *               onPostCreate().
   1352      */
   1353     public void callActivityOnPostCreate(Activity activity, Bundle icicle,
   1354             PersistableBundle persistentState) {
   1355         activity.onPostCreate(icicle, persistentState);
   1356     }
   1357 
   1358     /**
   1359      * Perform calling of an activity's {@link Activity#onNewIntent}
   1360      * method.  The default implementation simply calls through to that method.
   1361      *
   1362      * @param activity The activity receiving a new Intent.
   1363      * @param intent The new intent being received.
   1364      */
   1365     public void callActivityOnNewIntent(Activity activity, Intent intent) {
   1366         activity.performNewIntent(intent);
   1367     }
   1368 
   1369     /**
   1370      * @hide
   1371      */
   1372     public void callActivityOnNewIntent(Activity activity, ReferrerIntent intent) {
   1373         final String oldReferrer = activity.mReferrer;
   1374         try {
   1375             if (intent != null) {
   1376                 activity.mReferrer = intent.mReferrer;
   1377             }
   1378             callActivityOnNewIntent(activity, intent != null ? new Intent(intent) : null);
   1379         } finally {
   1380             activity.mReferrer = oldReferrer;
   1381         }
   1382     }
   1383 
   1384     /**
   1385      * Perform calling of an activity's {@link Activity#onStart}
   1386      * method.  The default implementation simply calls through to that method.
   1387      *
   1388      * @param activity The activity being started.
   1389      */
   1390     public void callActivityOnStart(Activity activity) {
   1391         activity.onStart();
   1392     }
   1393 
   1394     /**
   1395      * Perform calling of an activity's {@link Activity#onRestart}
   1396      * method.  The default implementation simply calls through to that method.
   1397      *
   1398      * @param activity The activity being restarted.
   1399      */
   1400     public void callActivityOnRestart(Activity activity) {
   1401         activity.onRestart();
   1402     }
   1403 
   1404     /**
   1405      * Perform calling of an activity's {@link Activity#onResume} method.  The
   1406      * default implementation simply calls through to that method.
   1407      *
   1408      * @param activity The activity being resumed.
   1409      */
   1410     public void callActivityOnResume(Activity activity) {
   1411         activity.mResumed = true;
   1412         activity.onResume();
   1413 
   1414         if (mActivityMonitors != null) {
   1415             synchronized (mSync) {
   1416                 final int N = mActivityMonitors.size();
   1417                 for (int i=0; i<N; i++) {
   1418                     final ActivityMonitor am = mActivityMonitors.get(i);
   1419                     am.match(activity, activity, activity.getIntent());
   1420                 }
   1421             }
   1422         }
   1423     }
   1424 
   1425     /**
   1426      * Perform calling of an activity's {@link Activity#onStop}
   1427      * method.  The default implementation simply calls through to that method.
   1428      *
   1429      * @param activity The activity being stopped.
   1430      */
   1431     public void callActivityOnStop(Activity activity) {
   1432         activity.onStop();
   1433     }
   1434 
   1435     /**
   1436      * Perform calling of an activity's {@link Activity#onSaveInstanceState}
   1437      * method.  The default implementation simply calls through to that method.
   1438      *
   1439      * @param activity The activity being saved.
   1440      * @param outState The bundle to pass to the call.
   1441      */
   1442     public void callActivityOnSaveInstanceState(Activity activity, Bundle outState) {
   1443         activity.performSaveInstanceState(outState);
   1444     }
   1445 
   1446     /**
   1447      * Perform calling of an activity's {@link Activity#onSaveInstanceState}
   1448      * method.  The default implementation simply calls through to that method.
   1449      *  @param activity The activity being saved.
   1450      * @param outState The bundle to pass to the call.
   1451      * @param outPersistentState The persistent bundle to pass to the call.
   1452      */
   1453     public void callActivityOnSaveInstanceState(Activity activity, Bundle outState,
   1454             PersistableBundle outPersistentState) {
   1455         activity.performSaveInstanceState(outState, outPersistentState);
   1456     }
   1457 
   1458     /**
   1459      * Perform calling of an activity's {@link Activity#onPause} method.  The
   1460      * default implementation simply calls through to that method.
   1461      *
   1462      * @param activity The activity being paused.
   1463      */
   1464     public void callActivityOnPause(Activity activity) {
   1465         activity.performPause();
   1466     }
   1467 
   1468     /**
   1469      * Perform calling of an activity's {@link Activity#onUserLeaveHint} method.
   1470      * The default implementation simply calls through to that method.
   1471      *
   1472      * @param activity The activity being notified that the user has navigated away
   1473      */
   1474     public void callActivityOnUserLeaving(Activity activity) {
   1475         activity.performUserLeaving();
   1476     }
   1477 
   1478     /*
   1479      * Starts allocation counting. This triggers a gc and resets the counts.
   1480      *
   1481      * @deprecated Accurate counting is a burden on the runtime and may be removed.
   1482      */
   1483     @Deprecated
   1484     public void startAllocCounting() {
   1485         // Before we start trigger a GC and reset the debug counts. Run the
   1486         // finalizers and another GC before starting and stopping the alloc
   1487         // counts. This will free up any objects that were just sitting around
   1488         // waiting for their finalizers to be run.
   1489         Runtime.getRuntime().gc();
   1490         Runtime.getRuntime().runFinalization();
   1491         Runtime.getRuntime().gc();
   1492 
   1493         Debug.resetAllCounts();
   1494 
   1495         // start the counts
   1496         Debug.startAllocCounting();
   1497     }
   1498 
   1499     /*
   1500      * Stops allocation counting.
   1501      *
   1502      * @deprecated Accurate counting is a burden on the runtime and may be removed.
   1503      */
   1504     @Deprecated
   1505     public void stopAllocCounting() {
   1506         Runtime.getRuntime().gc();
   1507         Runtime.getRuntime().runFinalization();
   1508         Runtime.getRuntime().gc();
   1509         Debug.stopAllocCounting();
   1510     }
   1511 
   1512     /**
   1513      * If Results already contains Key, it appends Value to the key's ArrayList
   1514      * associated with the key. If the key doesn't already exist in results, it
   1515      * adds the key/value pair to results.
   1516      */
   1517     private void addValue(String key, int value, Bundle results) {
   1518         if (results.containsKey(key)) {
   1519             List<Integer> list = results.getIntegerArrayList(key);
   1520             if (list != null) {
   1521                 list.add(value);
   1522             }
   1523         } else {
   1524             ArrayList<Integer> list = new ArrayList<Integer>();
   1525             list.add(value);
   1526             results.putIntegerArrayList(key, list);
   1527         }
   1528     }
   1529 
   1530     /**
   1531      * Returns a bundle with the current results from the allocation counting.
   1532      */
   1533     public Bundle getAllocCounts() {
   1534         Bundle results = new Bundle();
   1535         results.putLong("global_alloc_count", Debug.getGlobalAllocCount());
   1536         results.putLong("global_alloc_size", Debug.getGlobalAllocSize());
   1537         results.putLong("global_freed_count", Debug.getGlobalFreedCount());
   1538         results.putLong("global_freed_size", Debug.getGlobalFreedSize());
   1539         results.putLong("gc_invocation_count", Debug.getGlobalGcInvocationCount());
   1540         return results;
   1541     }
   1542 
   1543     /**
   1544      * Returns a bundle with the counts for various binder counts for this process. Currently the only two that are
   1545      * reported are the number of send and the number of received transactions.
   1546      */
   1547     public Bundle getBinderCounts() {
   1548         Bundle results = new Bundle();
   1549         results.putLong("sent_transactions", Debug.getBinderSentTransactions());
   1550         results.putLong("received_transactions", Debug.getBinderReceivedTransactions());
   1551         return results;
   1552     }
   1553 
   1554     /**
   1555      * Description of a Activity execution result to return to the original
   1556      * activity.
   1557      */
   1558     public static final class ActivityResult {
   1559         /**
   1560          * Create a new activity result.  See {@link Activity#setResult} for
   1561          * more information.
   1562          *
   1563          * @param resultCode The result code to propagate back to the
   1564          * originating activity, often RESULT_CANCELED or RESULT_OK
   1565          * @param resultData The data to propagate back to the originating
   1566          * activity.
   1567          */
   1568         public ActivityResult(int resultCode, Intent resultData) {
   1569             mResultCode = resultCode;
   1570             mResultData = resultData;
   1571         }
   1572 
   1573         /**
   1574          * Retrieve the result code contained in this result.
   1575          */
   1576         public int getResultCode() {
   1577             return mResultCode;
   1578         }
   1579 
   1580         /**
   1581          * Retrieve the data contained in this result.
   1582          */
   1583         public Intent getResultData() {
   1584             return mResultData;
   1585         }
   1586 
   1587         private final int mResultCode;
   1588         private final Intent mResultData;
   1589     }
   1590 
   1591     /**
   1592      * Execute a startActivity call made by the application.  The default
   1593      * implementation takes care of updating any active {@link ActivityMonitor}
   1594      * objects and dispatches this call to the system activity manager; you can
   1595      * override this to watch for the application to start an activity, and
   1596      * modify what happens when it does.
   1597      *
   1598      * <p>This method returns an {@link ActivityResult} object, which you can
   1599      * use when intercepting application calls to avoid performing the start
   1600      * activity action but still return the result the application is
   1601      * expecting.  To do this, override this method to catch the call to start
   1602      * activity so that it returns a new ActivityResult containing the results
   1603      * you would like the application to see, and don't call up to the super
   1604      * class.  Note that an application is only expecting a result if
   1605      * <var>requestCode</var> is &gt;= 0.
   1606      *
   1607      * <p>This method throws {@link android.content.ActivityNotFoundException}
   1608      * if there was no Activity found to run the given Intent.
   1609      *
   1610      * @param who The Context from which the activity is being started.
   1611      * @param contextThread The main thread of the Context from which the activity
   1612      *                      is being started.
   1613      * @param token Internal token identifying to the system who is starting
   1614      *              the activity; may be null.
   1615      * @param target Which activity is performing the start (and thus receiving
   1616      *               any result); may be null if this call is not being made
   1617      *               from an activity.
   1618      * @param intent The actual Intent to start.
   1619      * @param requestCode Identifier for this request's result; less than zero
   1620      *                    if the caller is not expecting a result.
   1621      * @param options Addition options.
   1622      *
   1623      * @return To force the return of a particular result, return an
   1624      *         ActivityResult object containing the desired data; otherwise
   1625      *         return null.  The default implementation always returns null.
   1626      *
   1627      * @throws android.content.ActivityNotFoundException
   1628      *
   1629      * @see Activity#startActivity(Intent)
   1630      * @see Activity#startActivityForResult(Intent, int)
   1631      * @see Activity#startActivityFromChild
   1632      *
   1633      * {@hide}
   1634      */
   1635     public ActivityResult execStartActivity(
   1636             Context who, IBinder contextThread, IBinder token, Activity target,
   1637             Intent intent, int requestCode, Bundle options) {
   1638         IApplicationThread whoThread = (IApplicationThread) contextThread;
   1639         Uri referrer = target != null ? target.onProvideReferrer() : null;
   1640         if (referrer != null) {
   1641             intent.putExtra(Intent.EXTRA_REFERRER, referrer);
   1642         }
   1643         if (mActivityMonitors != null) {
   1644             synchronized (mSync) {
   1645                 final int N = mActivityMonitors.size();
   1646                 for (int i=0; i<N; i++) {
   1647                     final ActivityMonitor am = mActivityMonitors.get(i);
   1648                     ActivityResult result = null;
   1649                     if (am.ignoreMatchingSpecificIntents()) {
   1650                         result = am.onStartActivity(intent);
   1651                     }
   1652                     if (result != null) {
   1653                         am.mHits++;
   1654                         return result;
   1655                     } else if (am.match(who, null, intent)) {
   1656                         am.mHits++;
   1657                         if (am.isBlocking()) {
   1658                             return requestCode >= 0 ? am.getResult() : null;
   1659                         }
   1660                         break;
   1661                     }
   1662                 }
   1663             }
   1664         }
   1665         try {
   1666             intent.migrateExtraStreamToClipData();
   1667             intent.prepareToLeaveProcess(who);
   1668             int result = ActivityManager.getService()
   1669                 .startActivity(whoThread, who.getBasePackageName(), intent,
   1670                         intent.resolveTypeIfNeeded(who.getContentResolver()),
   1671                         token, target != null ? target.mEmbeddedID : null,
   1672                         requestCode, 0, null, options);
   1673             checkStartActivityResult(result, intent);
   1674         } catch (RemoteException e) {
   1675             throw new RuntimeException("Failure from system", e);
   1676         }
   1677         return null;
   1678     }
   1679 
   1680     /**
   1681      * Like {@link #execStartActivity(Context, IBinder, IBinder, Activity, Intent, int, Bundle)},
   1682      * but accepts an array of activities to be started.  Note that active
   1683      * {@link ActivityMonitor} objects only match against the first activity in
   1684      * the array.
   1685      *
   1686      * {@hide}
   1687      */
   1688     public void execStartActivities(Context who, IBinder contextThread,
   1689             IBinder token, Activity target, Intent[] intents, Bundle options) {
   1690         execStartActivitiesAsUser(who, contextThread, token, target, intents, options,
   1691                 who.getUserId());
   1692     }
   1693 
   1694     /**
   1695      * Like {@link #execStartActivity(Context, IBinder, IBinder, Activity, Intent, int, Bundle)},
   1696      * but accepts an array of activities to be started.  Note that active
   1697      * {@link ActivityMonitor} objects only match against the first activity in
   1698      * the array.
   1699      *
   1700      * @return The corresponding flag {@link ActivityManager#START_CANCELED},
   1701      *         {@link ActivityManager#START_SUCCESS} etc. indicating whether the launch was
   1702      *         successful.
   1703      *
   1704      * {@hide}
   1705      */
   1706     public int execStartActivitiesAsUser(Context who, IBinder contextThread,
   1707             IBinder token, Activity target, Intent[] intents, Bundle options,
   1708             int userId) {
   1709         IApplicationThread whoThread = (IApplicationThread) contextThread;
   1710         if (mActivityMonitors != null) {
   1711             synchronized (mSync) {
   1712                 final int N = mActivityMonitors.size();
   1713                 for (int i=0; i<N; i++) {
   1714                     final ActivityMonitor am = mActivityMonitors.get(i);
   1715                     ActivityResult result = null;
   1716                     if (am.ignoreMatchingSpecificIntents()) {
   1717                         result = am.onStartActivity(intents[0]);
   1718                     }
   1719                     if (result != null) {
   1720                         am.mHits++;
   1721                         return ActivityManager.START_CANCELED;
   1722                     } else if (am.match(who, null, intents[0])) {
   1723                         am.mHits++;
   1724                         if (am.isBlocking()) {
   1725                             return ActivityManager.START_CANCELED;
   1726                         }
   1727                         break;
   1728                     }
   1729                 }
   1730             }
   1731         }
   1732         try {
   1733             String[] resolvedTypes = new String[intents.length];
   1734             for (int i=0; i<intents.length; i++) {
   1735                 intents[i].migrateExtraStreamToClipData();
   1736                 intents[i].prepareToLeaveProcess(who);
   1737                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(who.getContentResolver());
   1738             }
   1739             int result = ActivityManager.getService()
   1740                 .startActivities(whoThread, who.getBasePackageName(), intents, resolvedTypes,
   1741                         token, options, userId);
   1742             checkStartActivityResult(result, intents[0]);
   1743             return result;
   1744         } catch (RemoteException e) {
   1745             throw new RuntimeException("Failure from system", e);
   1746         }
   1747     }
   1748 
   1749     /**
   1750      * Like {@link #execStartActivity(android.content.Context, android.os.IBinder,
   1751      * android.os.IBinder, String, android.content.Intent, int, android.os.Bundle)},
   1752      * but for calls from a {#link Fragment}.
   1753      *
   1754      * @param who The Context from which the activity is being started.
   1755      * @param contextThread The main thread of the Context from which the activity
   1756      *                      is being started.
   1757      * @param token Internal token identifying to the system who is starting
   1758      *              the activity; may be null.
   1759      * @param target Which element is performing the start (and thus receiving
   1760      *               any result).
   1761      * @param intent The actual Intent to start.
   1762      * @param requestCode Identifier for this request's result; less than zero
   1763      *                    if the caller is not expecting a result.
   1764      *
   1765      * @return To force the return of a particular result, return an
   1766      *         ActivityResult object containing the desired data; otherwise
   1767      *         return null.  The default implementation always returns null.
   1768      *
   1769      * @throws android.content.ActivityNotFoundException
   1770      *
   1771      * @see Activity#startActivity(Intent)
   1772      * @see Activity#startActivityForResult(Intent, int)
   1773      * @see Activity#startActivityFromChild
   1774      *
   1775      * {@hide}
   1776      */
   1777     public ActivityResult execStartActivity(
   1778         Context who, IBinder contextThread, IBinder token, String target,
   1779         Intent intent, int requestCode, Bundle options) {
   1780         IApplicationThread whoThread = (IApplicationThread) contextThread;
   1781         if (mActivityMonitors != null) {
   1782             synchronized (mSync) {
   1783                 final int N = mActivityMonitors.size();
   1784                 for (int i=0; i<N; i++) {
   1785                     final ActivityMonitor am = mActivityMonitors.get(i);
   1786                     ActivityResult result = null;
   1787                     if (am.ignoreMatchingSpecificIntents()) {
   1788                         result = am.onStartActivity(intent);
   1789                     }
   1790                     if (result != null) {
   1791                         am.mHits++;
   1792                         return result;
   1793                     } else if (am.match(who, null, intent)) {
   1794                         am.mHits++;
   1795                         if (am.isBlocking()) {
   1796                             return requestCode >= 0 ? am.getResult() : null;
   1797                         }
   1798                         break;
   1799                     }
   1800                 }
   1801             }
   1802         }
   1803         try {
   1804             intent.migrateExtraStreamToClipData();
   1805             intent.prepareToLeaveProcess(who);
   1806             int result = ActivityManager.getService()
   1807                 .startActivity(whoThread, who.getBasePackageName(), intent,
   1808                         intent.resolveTypeIfNeeded(who.getContentResolver()),
   1809                         token, target, requestCode, 0, null, options);
   1810             checkStartActivityResult(result, intent);
   1811         } catch (RemoteException e) {
   1812             throw new RuntimeException("Failure from system", e);
   1813         }
   1814         return null;
   1815     }
   1816 
   1817     /**
   1818      * Like {@link #execStartActivity(Context, IBinder, IBinder, Activity, Intent, int, Bundle)},
   1819      * but for starting as a particular user.
   1820      *
   1821      * @param who The Context from which the activity is being started.
   1822      * @param contextThread The main thread of the Context from which the activity
   1823      *                      is being started.
   1824      * @param token Internal token identifying to the system who is starting
   1825      *              the activity; may be null.
   1826      * @param target Which fragment is performing the start (and thus receiving
   1827      *               any result).
   1828      * @param intent The actual Intent to start.
   1829      * @param requestCode Identifier for this request's result; less than zero
   1830      *                    if the caller is not expecting a result.
   1831      *
   1832      * @return To force the return of a particular result, return an
   1833      *         ActivityResult object containing the desired data; otherwise
   1834      *         return null.  The default implementation always returns null.
   1835      *
   1836      * @throws android.content.ActivityNotFoundException
   1837      *
   1838      * @see Activity#startActivity(Intent)
   1839      * @see Activity#startActivityForResult(Intent, int)
   1840      * @see Activity#startActivityFromChild
   1841      *
   1842      * {@hide}
   1843      */
   1844     public ActivityResult execStartActivity(
   1845             Context who, IBinder contextThread, IBinder token, String resultWho,
   1846             Intent intent, int requestCode, Bundle options, UserHandle user) {
   1847         IApplicationThread whoThread = (IApplicationThread) contextThread;
   1848         if (mActivityMonitors != null) {
   1849             synchronized (mSync) {
   1850                 final int N = mActivityMonitors.size();
   1851                 for (int i=0; i<N; i++) {
   1852                     final ActivityMonitor am = mActivityMonitors.get(i);
   1853                     ActivityResult result = null;
   1854                     if (am.ignoreMatchingSpecificIntents()) {
   1855                         result = am.onStartActivity(intent);
   1856                     }
   1857                     if (result != null) {
   1858                         am.mHits++;
   1859                         return result;
   1860                     } else if (am.match(who, null, intent)) {
   1861                         am.mHits++;
   1862                         if (am.isBlocking()) {
   1863                             return requestCode >= 0 ? am.getResult() : null;
   1864                         }
   1865                         break;
   1866                     }
   1867                 }
   1868             }
   1869         }
   1870         try {
   1871             intent.migrateExtraStreamToClipData();
   1872             intent.prepareToLeaveProcess(who);
   1873             int result = ActivityManager.getService()
   1874                 .startActivityAsUser(whoThread, who.getBasePackageName(), intent,
   1875                         intent.resolveTypeIfNeeded(who.getContentResolver()),
   1876                         token, resultWho,
   1877                         requestCode, 0, null, options, user.getIdentifier());
   1878             checkStartActivityResult(result, intent);
   1879         } catch (RemoteException e) {
   1880             throw new RuntimeException("Failure from system", e);
   1881         }
   1882         return null;
   1883     }
   1884 
   1885     /**
   1886      * Special version!
   1887      * @hide
   1888      */
   1889     public ActivityResult execStartActivityAsCaller(
   1890             Context who, IBinder contextThread, IBinder token, Activity target,
   1891             Intent intent, int requestCode, Bundle options, boolean ignoreTargetSecurity,
   1892             int userId) {
   1893         IApplicationThread whoThread = (IApplicationThread) contextThread;
   1894         if (mActivityMonitors != null) {
   1895             synchronized (mSync) {
   1896                 final int N = mActivityMonitors.size();
   1897                 for (int i=0; i<N; i++) {
   1898                     final ActivityMonitor am = mActivityMonitors.get(i);
   1899                     ActivityResult result = null;
   1900                     if (am.ignoreMatchingSpecificIntents()) {
   1901                         result = am.onStartActivity(intent);
   1902                     }
   1903                     if (result != null) {
   1904                         am.mHits++;
   1905                         return result;
   1906                     } else if (am.match(who, null, intent)) {
   1907                         am.mHits++;
   1908                         if (am.isBlocking()) {
   1909                             return requestCode >= 0 ? am.getResult() : null;
   1910                         }
   1911                         break;
   1912                     }
   1913                 }
   1914             }
   1915         }
   1916         try {
   1917             intent.migrateExtraStreamToClipData();
   1918             intent.prepareToLeaveProcess(who);
   1919             int result = ActivityManager.getService()
   1920                 .startActivityAsCaller(whoThread, who.getBasePackageName(), intent,
   1921                         intent.resolveTypeIfNeeded(who.getContentResolver()),
   1922                         token, target != null ? target.mEmbeddedID : null,
   1923                         requestCode, 0, null, options, ignoreTargetSecurity, userId);
   1924             checkStartActivityResult(result, intent);
   1925         } catch (RemoteException e) {
   1926             throw new RuntimeException("Failure from system", e);
   1927         }
   1928         return null;
   1929     }
   1930 
   1931     /**
   1932      * Special version!
   1933      * @hide
   1934      */
   1935     public void execStartActivityFromAppTask(
   1936             Context who, IBinder contextThread, IAppTask appTask,
   1937             Intent intent, Bundle options) {
   1938         IApplicationThread whoThread = (IApplicationThread) contextThread;
   1939         if (mActivityMonitors != null) {
   1940             synchronized (mSync) {
   1941                 final int N = mActivityMonitors.size();
   1942                 for (int i=0; i<N; i++) {
   1943                     final ActivityMonitor am = mActivityMonitors.get(i);
   1944                     ActivityResult result = null;
   1945                     if (am.ignoreMatchingSpecificIntents()) {
   1946                         result = am.onStartActivity(intent);
   1947                     }
   1948                     if (result != null) {
   1949                         am.mHits++;
   1950                         return;
   1951                     } else if (am.match(who, null, intent)) {
   1952                         am.mHits++;
   1953                         if (am.isBlocking()) {
   1954                             return;
   1955                         }
   1956                         break;
   1957                     }
   1958                 }
   1959             }
   1960         }
   1961         try {
   1962             intent.migrateExtraStreamToClipData();
   1963             intent.prepareToLeaveProcess(who);
   1964             int result = appTask.startActivity(whoThread.asBinder(), who.getBasePackageName(),
   1965                     intent, intent.resolveTypeIfNeeded(who.getContentResolver()), options);
   1966             checkStartActivityResult(result, intent);
   1967         } catch (RemoteException e) {
   1968             throw new RuntimeException("Failure from system", e);
   1969         }
   1970         return;
   1971     }
   1972 
   1973     /*package*/ final void init(ActivityThread thread,
   1974             Context instrContext, Context appContext, ComponentName component,
   1975             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection) {
   1976         mThread = thread;
   1977         mMessageQueue = mThread.getLooper().myQueue();
   1978         mInstrContext = instrContext;
   1979         mAppContext = appContext;
   1980         mComponent = component;
   1981         mWatcher = watcher;
   1982         mUiAutomationConnection = uiAutomationConnection;
   1983     }
   1984 
   1985     /**
   1986      * Only sets the ActivityThread up, keeps everything else null because app is not being
   1987      * instrumented.
   1988      */
   1989     final void basicInit(ActivityThread thread) {
   1990         mThread = thread;
   1991     }
   1992 
   1993     /** @hide */
   1994     public static void checkStartActivityResult(int res, Object intent) {
   1995         if (!ActivityManager.isStartResultFatalError(res)) {
   1996             return;
   1997         }
   1998 
   1999         switch (res) {
   2000             case ActivityManager.START_INTENT_NOT_RESOLVED:
   2001             case ActivityManager.START_CLASS_NOT_FOUND:
   2002                 if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
   2003                     throw new ActivityNotFoundException(
   2004                             "Unable to find explicit activity class "
   2005                             + ((Intent)intent).getComponent().toShortString()
   2006                             + "; have you declared this activity in your AndroidManifest.xml?");
   2007                 throw new ActivityNotFoundException(
   2008                         "No Activity found to handle " + intent);
   2009             case ActivityManager.START_PERMISSION_DENIED:
   2010                 throw new SecurityException("Not allowed to start activity "
   2011                         + intent);
   2012             case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
   2013                 throw new AndroidRuntimeException(
   2014                         "FORWARD_RESULT_FLAG used while also requesting a result");
   2015             case ActivityManager.START_NOT_ACTIVITY:
   2016                 throw new IllegalArgumentException(
   2017                         "PendingIntent is not an activity");
   2018             case ActivityManager.START_NOT_VOICE_COMPATIBLE:
   2019                 throw new SecurityException(
   2020                         "Starting under voice control not allowed for: " + intent);
   2021             case ActivityManager.START_VOICE_NOT_ACTIVE_SESSION:
   2022                 throw new IllegalStateException(
   2023                         "Session calling startVoiceActivity does not match active session");
   2024             case ActivityManager.START_VOICE_HIDDEN_SESSION:
   2025                 throw new IllegalStateException(
   2026                         "Cannot start voice activity on a hidden session");
   2027             case ActivityManager.START_ASSISTANT_NOT_ACTIVE_SESSION:
   2028                 throw new IllegalStateException(
   2029                         "Session calling startAssistantActivity does not match active session");
   2030             case ActivityManager.START_ASSISTANT_HIDDEN_SESSION:
   2031                 throw new IllegalStateException(
   2032                         "Cannot start assistant activity on a hidden session");
   2033             case ActivityManager.START_CANCELED:
   2034                 throw new AndroidRuntimeException("Activity could not be started for "
   2035                         + intent);
   2036             default:
   2037                 throw new AndroidRuntimeException("Unknown error code "
   2038                         + res + " when starting " + intent);
   2039         }
   2040     }
   2041 
   2042     private final void validateNotAppThread() {
   2043         if (Looper.myLooper() == Looper.getMainLooper()) {
   2044             throw new RuntimeException(
   2045                 "This method can not be called from the main application thread");
   2046         }
   2047     }
   2048 
   2049     /**
   2050      * Gets the {@link UiAutomation} instance with no flags set.
   2051      * <p>
   2052      * <strong>Note:</strong> The APIs exposed via the returned {@link UiAutomation}
   2053      * work across application boundaries while the APIs exposed by the instrumentation
   2054      * do not. For example, {@link Instrumentation#sendPointerSync(MotionEvent)} will
   2055      * not allow you to inject the event in an app different from the instrumentation
   2056      * target, while {@link UiAutomation#injectInputEvent(android.view.InputEvent, boolean)}
   2057      * will work regardless of the current application.
   2058      * </p>
   2059      * <p>
   2060      * A typical test case should be using either the {@link UiAutomation} or
   2061      * {@link Instrumentation} APIs. Using both APIs at the same time is not
   2062      * a mistake by itself but a client has to be aware of the APIs limitations.
   2063      * </p>
   2064      * <p>
   2065      * Equivalent to {@code getUiAutomation(0)}. If a {@link UiAutomation} exists with different
   2066      * flags, the flags on that instance will be changed, and then it will be returned.
   2067      * </p>
   2068      * @return The UI automation instance.
   2069      *
   2070      * @see UiAutomation
   2071      */
   2072     public UiAutomation getUiAutomation() {
   2073         return getUiAutomation(0);
   2074     }
   2075 
   2076     /**
   2077      * Gets the {@link UiAutomation} instance with flags set.
   2078      * <p>
   2079      * <strong>Note:</strong> The APIs exposed via the returned {@link UiAutomation}
   2080      * work across application boundaries while the APIs exposed by the instrumentation
   2081      * do not. For example, {@link Instrumentation#sendPointerSync(MotionEvent)} will
   2082      * not allow you to inject the event in an app different from the instrumentation
   2083      * target, while {@link UiAutomation#injectInputEvent(android.view.InputEvent, boolean)}
   2084      * will work regardless of the current application.
   2085      * </p>
   2086      * <p>
   2087      * A typical test case should be using either the {@link UiAutomation} or
   2088      * {@link Instrumentation} APIs. Using both APIs at the same time is not
   2089      * a mistake by itself but a client has to be aware of the APIs limitations.
   2090      * </p>
   2091      * <p>
   2092      * If a {@link UiAutomation} exists with different flags, the flags on that instance will be
   2093      * changed, and then it will be returned.
   2094      * </p>
   2095      *
   2096      * @param flags The flags to be passed to the UiAutomation, for example
   2097      *        {@link UiAutomation#FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES}.
   2098      *
   2099      * @return The UI automation instance.
   2100      *
   2101      * @see UiAutomation
   2102      */
   2103     public UiAutomation getUiAutomation(@UiAutomationFlags int flags) {
   2104         boolean mustCreateNewAutomation = (mUiAutomation == null) || (mUiAutomation.isDestroyed());
   2105 
   2106         if (mUiAutomationConnection != null) {
   2107             if (!mustCreateNewAutomation && (mUiAutomation.getFlags() == flags)) {
   2108                 return mUiAutomation;
   2109             }
   2110             if (mustCreateNewAutomation) {
   2111                 mUiAutomation = new UiAutomation(getTargetContext().getMainLooper(),
   2112                         mUiAutomationConnection);
   2113             } else {
   2114                 mUiAutomation.disconnect();
   2115             }
   2116             mUiAutomation.connect(flags);
   2117             return mUiAutomation;
   2118         }
   2119         return null;
   2120     }
   2121 
   2122     /**
   2123      * Takes control of the execution of messages on the specified looper until
   2124      * {@link TestLooperManager#release} is called.
   2125      */
   2126     public TestLooperManager acquireLooperManager(Looper looper) {
   2127         checkInstrumenting("acquireLooperManager");
   2128         return new TestLooperManager(looper);
   2129     }
   2130 
   2131     private final class InstrumentationThread extends Thread {
   2132         public InstrumentationThread(String name) {
   2133             super(name);
   2134         }
   2135         public void run() {
   2136             try {
   2137                 Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_DISPLAY);
   2138             } catch (RuntimeException e) {
   2139                 Log.w(TAG, "Exception setting priority of instrumentation thread "
   2140                         + Process.myTid(), e);
   2141             }
   2142             if (mAutomaticPerformanceSnapshots) {
   2143                 startPerformanceSnapshot();
   2144             }
   2145             onStart();
   2146         }
   2147     }
   2148 
   2149     private static final class EmptyRunnable implements Runnable {
   2150         public void run() {
   2151         }
   2152     }
   2153 
   2154     private static final class SyncRunnable implements Runnable {
   2155         private final Runnable mTarget;
   2156         private boolean mComplete;
   2157 
   2158         public SyncRunnable(Runnable target) {
   2159             mTarget = target;
   2160         }
   2161 
   2162         public void run() {
   2163             mTarget.run();
   2164             synchronized (this) {
   2165                 mComplete = true;
   2166                 notifyAll();
   2167             }
   2168         }
   2169 
   2170         public void waitForComplete() {
   2171             synchronized (this) {
   2172                 while (!mComplete) {
   2173                     try {
   2174                         wait();
   2175                     } catch (InterruptedException e) {
   2176                     }
   2177                 }
   2178             }
   2179         }
   2180     }
   2181 
   2182     private static final class ActivityWaiter {
   2183         public final Intent intent;
   2184         public Activity activity;
   2185 
   2186         public ActivityWaiter(Intent _intent) {
   2187             intent = _intent;
   2188         }
   2189     }
   2190 
   2191     private final class ActivityGoing implements MessageQueue.IdleHandler {
   2192         private final ActivityWaiter mWaiter;
   2193 
   2194         public ActivityGoing(ActivityWaiter waiter) {
   2195             mWaiter = waiter;
   2196         }
   2197 
   2198         public final boolean queueIdle() {
   2199             synchronized (mSync) {
   2200                 mWaitingActivities.remove(mWaiter);
   2201                 mSync.notifyAll();
   2202             }
   2203             return false;
   2204         }
   2205     }
   2206 
   2207     private static final class Idler implements MessageQueue.IdleHandler {
   2208         private final Runnable mCallback;
   2209         private boolean mIdle;
   2210 
   2211         public Idler(Runnable callback) {
   2212             mCallback = callback;
   2213             mIdle = false;
   2214         }
   2215 
   2216         public final boolean queueIdle() {
   2217             if (mCallback != null) {
   2218                 mCallback.run();
   2219             }
   2220             synchronized (this) {
   2221                 mIdle = true;
   2222                 notifyAll();
   2223             }
   2224             return false;
   2225         }
   2226 
   2227         public void waitForIdle() {
   2228             synchronized (this) {
   2229                 while (!mIdle) {
   2230                     try {
   2231                         wait();
   2232                     } catch (InterruptedException e) {
   2233                     }
   2234                 }
   2235             }
   2236         }
   2237     }
   2238 }
   2239