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