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