FileDocCategorySizeDatePackage
Instrumentation.javaAPI DocAndroid 1.5 API60876Wed May 06 22:41:54 BST 2009android.app

Instrumentation

public class Instrumentation extends Object
Base class for implementing application instrumentation code. When running with instrumentation turned on, this class will be instantiated for you before any of the application code, allowing you to monitor all of the interaction the system has with the application. An Instrumentation implementation is described to the system through an AndroidManifest.xml's <instrumentation> tag.

Fields Summary
public static final String
REPORT_KEY_IDENTIFIER
If included in the status or final bundle sent to an IInstrumentationWatcher, this key identifies the class that is writing the report. This can be used to provide more structured logging or reporting capabilities in the IInstrumentationWatcher.
public static final String
REPORT_KEY_STREAMRESULT
If included in the status or final bundle sent to an IInstrumentationWatcher, this key identifies a string which can simply be printed to the output stream. Using these streams provides a "pretty printer" version of the status & final packets. Any bundles including this key should also include the complete set of raw key/value pairs, so that the instrumentation can also be launched, and results collected, by an automated system.
private static final String
TAG
private final Object
mSync
private ActivityThread
mThread
private android.os.MessageQueue
mMessageQueue
private android.content.Context
mInstrContext
private android.content.Context
mAppContext
private android.content.ComponentName
mComponent
private Thread
mRunner
private List
mWaitingActivities
private List
mActivityMonitors
private IInstrumentationWatcher
mWatcher
private long
mPreCpuTime
private long
mStart
private boolean
mAutomaticPerformanceSnapshots
private android.os.Bundle
mPrePerfMetrics
private android.os.Bundle
mPerfMetrics
Constructors Summary
public Instrumentation()


      
    
Methods Summary
public voidaddMonitor(android.app.Instrumentation$ActivityMonitor monitor)
Add a new {@link ActivityMonitor} that will be checked whenever an activity is started. The monitor is added after any existing ones; the monitor will be hit only if none of the existing monitors can themselves handle the Intent.

param
monitor The new ActivityMonitor to see.
see
#addMonitor(IntentFilter, ActivityResult, boolean)
see
#checkMonitorHit

        synchronized (mSync) {
            if (mActivityMonitors == null) {
                mActivityMonitors = new ArrayList();
            }
            mActivityMonitors.add(monitor);
        }
    
public android.app.Instrumentation$ActivityMonitoraddMonitor(android.content.IntentFilter filter, android.app.Instrumentation$ActivityResult result, boolean block)
A convenience wrapper for {@link #addMonitor(ActivityMonitor)} that creates an intent filter matching {@link ActivityMonitor} for you and returns it.

param
filter The set of intents this monitor is responsible for.
param
result A canned result to return if the monitor is hit; can be null.
param
block Controls whether the monitor should block the activity start (returning its canned result) or let the call proceed.
return
The newly created and added activity monitor.
see
#addMonitor(ActivityMonitor)
see
#checkMonitorHit

        ActivityMonitor am = new ActivityMonitor(filter, result, block);
        addMonitor(am);
        return am;
    
public android.app.Instrumentation$ActivityMonitoraddMonitor(java.lang.String cls, android.app.Instrumentation$ActivityResult result, boolean block)
A convenience wrapper for {@link #addMonitor(ActivityMonitor)} that creates a class matching {@link ActivityMonitor} for you and returns it.

param
cls The activity class this monitor is responsible for.
param
result A canned result to return if the monitor is hit; can be null.
param
block Controls whether the monitor should block the activity start (returning its canned result) or let the call proceed.
return
The newly created and added activity monitor.
see
#addMonitor(ActivityMonitor)
see
#checkMonitorHit

        ActivityMonitor am = new ActivityMonitor(cls, result, block);
        addMonitor(am);
        return am;
    
private voidaddPerfMetricInt(java.lang.String key, int value)

        mPerfMetrics.putInt("performance." + key, value);
    
private voidaddPerfMetricLong(java.lang.String key, long value)

        mPerfMetrics.putLong("performance." + key, value);
    
private voidaddValue(java.lang.String key, int value, android.os.Bundle results)
If Results already contains Key, it appends Value to the key's ArrayList associated with the key. If the key doesn't already exist in results, it adds the key/value pair to results.

        if (results.containsKey(key)) {
            List<Integer> list = results.getIntegerArrayList(key);
            if (list != null) {
                list.add(value);
            }
        } else {
            ArrayList<Integer> list = new ArrayList<Integer>();
            list.add(value);
            results.putIntegerArrayList(key, list);
        }
    
public voidcallActivityOnCreate(Activity activity, android.os.Bundle icicle)
Perform calling of an activity's {@link Activity#onCreate} method. The default implementation simply calls through to that method.

param
activity The activity being created.
param
icicle The previously frozen state (or null) to pass through to onCreate().

        if (mWaitingActivities != null) {
            synchronized (mSync) {
                final int N = mWaitingActivities.size();
                for (int i=0; i<N; i++) {
                    final ActivityWaiter aw = mWaitingActivities.get(i);
                    final Intent intent = aw.intent;
                    if (intent.filterEquals(activity.getIntent())) {
                        aw.activity = activity;
                        mMessageQueue.addIdleHandler(new ActivityGoing(aw));
                    }
                }
            }
        }
        
        activity.onCreate(icicle);
        
        if (mActivityMonitors != null) {
            synchronized (mSync) {
                final int N = mActivityMonitors.size();
                for (int i=0; i<N; i++) {
                    final ActivityMonitor am = mActivityMonitors.get(i);
                    am.match(activity, activity, activity.getIntent());
                }
            }
        }
    
public voidcallActivityOnDestroy(Activity activity)

      if (mWaitingActivities != null) {
          synchronized (mSync) {
              final int N = mWaitingActivities.size();
              for (int i=0; i<N; i++) {
                  final ActivityWaiter aw = mWaitingActivities.get(i);
                  final Intent intent = aw.intent;
                  if (intent.filterEquals(activity.getIntent())) {
                      aw.activity = activity;
                      mMessageQueue.addIdleHandler(new ActivityGoing(aw));
                  }
              }
          }
      }
      
      activity.onDestroy();
      
      if (mActivityMonitors != null) {
          synchronized (mSync) {
              final int N = mActivityMonitors.size();
              for (int i=0; i<N; i++) {
                  final ActivityMonitor am = mActivityMonitors.get(i);
                  am.match(activity, activity, activity.getIntent());
              }
          }
      }
  
public voidcallActivityOnNewIntent(Activity activity, android.content.Intent intent)
Perform calling of an activity's {@link Activity#onNewIntent} method. The default implementation simply calls through to that method.

param
activity The activity receiving a new Intent.
param
intent The new intent being received.

        activity.onNewIntent(intent);
    
public voidcallActivityOnPause(Activity activity)
Perform calling of an activity's {@link Activity#onPause} method. The default implementation simply calls through to that method.

param
activity The activity being paused.

        activity.performPause();
    
public voidcallActivityOnPostCreate(Activity activity, android.os.Bundle icicle)
Perform calling of an activity's {@link Activity#onPostCreate} method. The default implementation simply calls through to that method.

param
activity The activity being created.
param
icicle The previously frozen state (or null) to pass through to onPostCreate().

        activity.onPostCreate(icicle);
    
public voidcallActivityOnRestart(Activity activity)
Perform calling of an activity's {@link Activity#onRestart} method. The default implementation simply calls through to that method.

param
activity The activity being restarted.

        activity.onRestart();
    
public voidcallActivityOnRestoreInstanceState(Activity activity, android.os.Bundle savedInstanceState)
Perform calling of an activity's {@link Activity#onRestoreInstanceState} method. The default implementation simply calls through to that method.

param
activity The activity being restored.
param
savedInstanceState The previously saved state being restored.

        activity.performRestoreInstanceState(savedInstanceState);
    
public voidcallActivityOnResume(Activity activity)
Perform calling of an activity's {@link Activity#onResume} method. The default implementation simply calls through to that method.

param
activity The activity being resumed.

        activity.onResume();
        
        if (mActivityMonitors != null) {
            synchronized (mSync) {
                final int N = mActivityMonitors.size();
                for (int i=0; i<N; i++) {
                    final ActivityMonitor am = mActivityMonitors.get(i);
                    am.match(activity, activity, activity.getIntent());
                }
            }
        }
    
public voidcallActivityOnSaveInstanceState(Activity activity, android.os.Bundle outState)
Perform calling of an activity's {@link Activity#onPause} method. The default implementation simply calls through to that method.

param
activity The activity being saved.
param
outState The bundle to pass to the call.

        activity.performSaveInstanceState(outState);
    
public voidcallActivityOnStart(Activity activity)
Perform calling of an activity's {@link Activity#onStart} method. The default implementation simply calls through to that method.

param
activity The activity being started.

        activity.onStart();
    
public voidcallActivityOnStop(Activity activity)
Perform calling of an activity's {@link Activity#onStop} method. The default implementation simply calls through to that method.

param
activity The activity being stopped.

        activity.onStop();
    
public voidcallActivityOnUserLeaving(Activity activity)
Perform calling of an activity's {@link Activity#onUserLeaveHint} method. The default implementation simply calls through to that method.

param
activity The activity being notified that the user has navigated away

        activity.performUserLeaving();
    
public voidcallApplicationOnCreate(Application app)
Perform calling of the application's {@link Application#onCreate} method. The default implementation simply calls through to that method.

param
app The application being created.

        app.onCreate();
    
public booleancheckMonitorHit(android.app.Instrumentation$ActivityMonitor monitor, int minHits)
Test whether an existing {@link ActivityMonitor} has been hit. If the monitor has been hit at least minHits times, then it will be removed from the activity monitor list and true returned. Otherwise it is left as-is and false is returned.

param
monitor The ActivityMonitor to check.
param
minHits The minimum number of hits required.
return
True if the hit count has been reached, else false.
see
#addMonitor

        waitForIdleSync();
        synchronized (mSync) {
            if (monitor.getHits() < minHits) {
                return false;
            }
            mActivityMonitors.remove(monitor);
        }
        return true;
    
static voidcheckStartActivityResult(int res, android.content.Intent intent)

        if (res >= IActivityManager.START_SUCCESS) {
            return;
        }
        
        switch (res) {
            case IActivityManager.START_INTENT_NOT_RESOLVED:
            case IActivityManager.START_CLASS_NOT_FOUND:
                if (intent.getComponent() != null)
                    throw new ActivityNotFoundException(
                            "Unable to find explicit activity class "
                            + intent.getComponent().toShortString()
                            + "; have you declared this activity in your AndroidManifest.xml?");
                throw new ActivityNotFoundException(
                        "No Activity found to handle " + intent);
            case IActivityManager.START_PERMISSION_DENIED:
                throw new SecurityException("Not allowed to start activity "
                        + intent);
            case IActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
                throw new AndroidRuntimeException(
                        "FORWARD_RESULT_FLAG used while also requesting a result");
            default:
                throw new AndroidRuntimeException("Unknown error code "
                        + res + " when starting " + intent);
        }
    
public voidendPerformanceSnapshot()

        if (!isProfiling()) {
            // Stop the timing. This must be done first before any other counting is stopped.
            long cpuTime = Process.getElapsedCpuTime();
            long duration = SystemClock.uptimeMillis();
            
            stopAllocCounting();
            
            long nativeMax = Debug.getNativeHeapSize() / 1024;
            long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
            long nativeFree = Debug.getNativeHeapFreeSize() / 1024;

            Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
            Debug.getMemoryInfo(memInfo);

            Runtime runtime = Runtime.getRuntime();

            long dalvikMax = runtime.totalMemory() / 1024;
            long dalvikFree = runtime.freeMemory() / 1024;
            long dalvikAllocated = dalvikMax - dalvikFree;
            
            // Add final binder counts
            Bundle binderCounts = getBinderCounts();
            for (String key: binderCounts.keySet()) {
                addPerfMetricLong(key, binderCounts.getLong(key));
            }
            
            // Add alloc counts
            Bundle allocCounts = getAllocCounts();
            for (String key: allocCounts.keySet()) {
                addPerfMetricLong(key, allocCounts.getLong(key));
            }
            
            addPerfMetricLong("execution_time", duration - mStart);
            addPerfMetricLong("pre_cpu_time", mPreCpuTime);
            addPerfMetricLong("cpu_time", cpuTime - mPreCpuTime);

            addPerfMetricLong("native_size", nativeMax);
            addPerfMetricLong("native_allocated", nativeAllocated);
            addPerfMetricLong("native_free", nativeFree);
            addPerfMetricInt("native_pss", memInfo.nativePss);
            addPerfMetricInt("native_private_dirty", memInfo.nativePrivateDirty);
            addPerfMetricInt("native_shared_dirty", memInfo.nativeSharedDirty);
            
            addPerfMetricLong("java_size", dalvikMax);
            addPerfMetricLong("java_allocated", dalvikAllocated);
            addPerfMetricLong("java_free", dalvikFree);
            addPerfMetricInt("java_pss", memInfo.dalvikPss);
            addPerfMetricInt("java_private_dirty", memInfo.dalvikPrivateDirty);
            addPerfMetricInt("java_shared_dirty", memInfo.dalvikSharedDirty);
            
            addPerfMetricInt("other_pss", memInfo.otherPss);
            addPerfMetricInt("other_private_dirty", memInfo.otherPrivateDirty);
            addPerfMetricInt("other_shared_dirty", memInfo.otherSharedDirty);
            
        }
    
public android.app.Instrumentation$ActivityResultexecStartActivity(android.content.Context who, android.os.IBinder contextThread, android.os.IBinder token, Activity target, android.content.Intent intent, int requestCode)
Execute a startActivity call made by the application. The default implementation takes care of updating any active {@link ActivityMonitor} objects and dispatches this call to the system activity manager; you can override this to watch for the application to start an activity, and modify what happens when it does.

This method returns an {@link ActivityResult} object, which you can use when intercepting application calls to avoid performing the start activity action but still return the result the application is expecting. To do this, override this method to catch the call to start activity so that it returns a new ActivityResult containing the results you would like the application to see, and don't call up to the super class. Note that an application is only expecting a result if requestCode is >= 0.

This method throws {@link android.content.ActivityNotFoundException} if there was no Activity found to run the given Intent.

param
who The Context from which the activity is being started.
param
contextThread The main thread of the Context from which the activity is being started.
param
token Internal token identifying to the system who is starting the activity; may be null.
param
target Which activity is perform the start (and thus receiving any result); may be null if this call is not being made from an activity.
param
intent The actual Intent to start.
param
requestCode Identifier for this request's result; less than zero if the caller is not expecting a result.
return
To force the return of a particular result, return an ActivityResult object containing the desired data; otherwise return null. The default implementation always returns null.
throws
android.content.ActivityNotFoundException
see
Activity#startActivity(Intent)
see
Activity#startActivityForResult(Intent, int)
see
Activity#startActivityFromChild {@hide}

        IApplicationThread whoThread = (IApplicationThread) contextThread;
        if (mActivityMonitors != null) {
            synchronized (mSync) {
                final int N = mActivityMonitors.size();
                for (int i=0; i<N; i++) {
                    final ActivityMonitor am = mActivityMonitors.get(i);
                    if (am.match(who, null, intent)) {
                        am.mHits++;
                        if (am.isBlocking()) {
                            return requestCode >= 0 ? am.getResult() : null;
                        }
                        break;
                    }
                }
            }
        }
        try {
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        null, 0, token, target != null ? target.mEmbeddedID : null,
                        requestCode, false, false);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
        }
        return null;
    
public voidfinish(int resultCode, android.os.Bundle results)
Terminate instrumentation of the application. This will cause the application process to exit, removing this instrumentation from the next time the application is started.

param
resultCode Overall success/failure of instrumentation.
param
results Any results to send back to the code that started the instrumentation.

        if (mAutomaticPerformanceSnapshots) {
            endPerformanceSnapshot();
        }
        if (mPerfMetrics != null) {
            results.putAll(mPerfMetrics);
        }
        mThread.finishInstrumentation(resultCode, results);
    
public android.os.BundlegetAllocCounts()
Returns a bundle with the current results from the allocation counting.

        Bundle results = new Bundle();
        results.putLong("global_alloc_count", Debug.getGlobalAllocCount());
        results.putLong("global_alloc_size", Debug.getGlobalAllocSize());
        results.putLong("global_freed_count", Debug.getGlobalFreedCount());
        results.putLong("global_freed_size", Debug.getGlobalFreedSize());
        results.putLong("gc_invocation_count", Debug.getGlobalGcInvocationCount());    
        return results;
    
public android.os.BundlegetBinderCounts()
Returns a bundle with the counts for various binder counts for this process. Currently the only two that are reported are the number of send and the number of received transactions.

        Bundle results = new Bundle();
        results.putLong("sent_transactions", Debug.getBinderSentTransactions());
        results.putLong("received_transactions", Debug.getBinderReceivedTransactions());
        return results;
    
public android.content.ComponentNamegetComponentName()
Returns complete component name of this instrumentation.

return
Returns the complete component name for this instrumentation.

        return mComponent;
    
public android.content.ContextgetContext()
Return the Context of this instrumentation's package. Note that this is often different than the Context of the application being instrumentated, since the instrumentation code often lives is a different package than that of the application it is running against. See {@link #getTargetContext} to retrieve a Context for the target application.

return
The instrumentation's package context.
see
#getTargetContext

        return mInstrContext;
    
public android.content.ContextgetTargetContext()
Return a Context for the target application being instrumented. Note that this is often different than the Context of the instrumentation code, since the instrumentation code often lives is a different package than that of the application it is running against. See {@link #getContext} to retrieve a Context for the instrumentation code.

return
A Context in the target application.
see
#getContext

        return mAppContext;
    
final voidinit(ActivityThread thread, android.content.Context instrContext, android.content.Context appContext, android.content.ComponentName component, IInstrumentationWatcher watcher)

        mThread = thread;
        mMessageQueue = mThread.getLooper().myQueue();
        mInstrContext = instrContext;
        mAppContext = appContext;
        mComponent = component;
        mWatcher = watcher;
    
public booleaninvokeContextMenuAction(Activity targetActivity, int id, int flag)
Show the context menu for the currently focused view and executes a particular context menu item.

param
targetActivity The activity in question.
param
id The identifier associated with the context menu item.
param
flag Additional flags, if any.
return
Whether the invocation was successful (for example, it could be false if item is disabled).

        validateNotAppThread();
        
        // Bring up context menu for current focus.
        // It'd be nice to do this through code, but currently ListView depends on
        //   long press to set metadata for its selected child
        
        final KeyEvent downEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER); 
        sendKeySync(downEvent);

        // Need to wait for long press
        waitForIdleSync();
        try {
            Thread.sleep(ViewConfiguration.getLongPressTimeout());
        } catch (InterruptedException e) {
            Log.e(TAG, "Could not sleep for long press timeout", e);
            return false;
        }

        final KeyEvent upEvent = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER); 
        sendKeySync(upEvent);

        // Wait for context menu to appear
        waitForIdleSync();
        
        class ContextMenuRunnable implements Runnable {
            private final Activity activity;
            private final int identifier;
            private final int flags;
            boolean returnValue;
            
            public ContextMenuRunnable(Activity _activity, int _identifier,
                                    int _flags) {
                activity = _activity;
                identifier = _identifier;
                flags = _flags;
            }
            
            public void run() {
                Window win = activity.getWindow();
                returnValue = win.performContextMenuIdentifierAction(
                            identifier, 
                            flags);                
            }
            
        }        
        
        ContextMenuRunnable cmr = new ContextMenuRunnable(targetActivity, id, flag);
        runOnMainSync(cmr);
        return cmr.returnValue;
    
public booleaninvokeMenuActionSync(Activity targetActivity, int id, int flag)
Execute a particular menu item.

param
targetActivity The activity in question.
param
id The identifier associated with the menu item.
param
flag Additional flags, if any.
return
Whether the invocation was successful (for example, it could be false if item is disabled).

        class MenuRunnable implements Runnable {
            private final Activity activity;
            private final int identifier;
            private final int flags;
            boolean returnValue;
            
            public MenuRunnable(Activity _activity, int _identifier,
                                    int _flags) {
                activity = _activity;
                identifier = _identifier;
                flags = _flags;
            }
            
            public void run() {
                Window win = activity.getWindow();
                
                returnValue = win.performPanelIdentifierAction(
                            Window.FEATURE_OPTIONS_PANEL,
                            identifier, 
                            flags);                
            }
            
        }        
        MenuRunnable mr = new MenuRunnable(targetActivity, id, flag);
        runOnMainSync(mr);
        return mr.returnValue;
    
public booleanisProfiling()
Check whether this instrumentation was started with profiling enabled.

return
Returns true if profiling was enabled when starting, else false.

        return mThread.isProfiling();
    
public ActivitynewActivity(java.lang.Class clazz, android.content.Context context, android.os.IBinder token, Application application, android.content.Intent intent, android.content.pm.ActivityInfo info, java.lang.CharSequence title, Activity parent, java.lang.String id, java.lang.Object lastNonConfigurationInstance)
Perform instantiation of an {@link Activity} object. This method is intended for use with unit tests, such as android.test.ActivityUnitTestCase. The activity will be useable locally but will be missing some of the linkages necessary for use within the sytem.

param
clazz The Class of the desired Activity
param
context The base context for the activity to use
param
token The token for this activity to communicate with
param
application The application object (if any)
param
intent The intent that started this Activity
param
info ActivityInfo from the manifest
param
title The title, typically retrieved from the ActivityInfo record
param
parent The parent Activity (if any)
param
id The embedded Id (if any)
param
lastNonConfigurationInstance Arbitrary object that will be available via {@link Activity#getLastNonConfigurationInstance() Activity.getLastNonConfigurationInstance()}.
return
Returns the instantiated activity
throws
InstantiationException
throws
IllegalAccessException

        Activity activity = (Activity)clazz.newInstance();
        ActivityThread aThread = null;
        activity.attach(context, aThread, this, token, application, intent, info, title,
                parent, id, lastNonConfigurationInstance, new Configuration());
        return activity;
    
public ActivitynewActivity(java.lang.ClassLoader cl, java.lang.String className, android.content.Intent intent)
Perform instantiation of the process's {@link Activity} object. The default implementation provides the normal system behavior.

param
cl The ClassLoader with which to instantiate the object.
param
className The name of the class implementing the Activity object.
param
intent The Intent object that specified the activity class being instantiated.
return
The newly instantiated Activity object.

        return (Activity)cl.loadClass(className).newInstance();
    
public ApplicationnewApplication(java.lang.ClassLoader cl, java.lang.String className, android.content.Context context)
Perform instantiation of the process's {@link Application} object. The default implementation provides the normal system behavior.

param
cl The ClassLoader with which to instantiate the object.
param
className The name of the class implementing the Application object.
param
context The context to initialize the application with
return
The newly instantiated Application object.

        return newApplication(cl.loadClass(className), context);
    
public static ApplicationnewApplication(java.lang.Class clazz, android.content.Context context)
Perform instantiation of the process's {@link Application} object. The default implementation provides the normal system behavior.

param
clazz The class used to create an Application object from.
param
context The context to initialize the application with
return
The newly instantiated Application object.

        Application app = (Application)clazz.newInstance();
        app.attach(context);
        return app;
    
public voidonCreate(android.os.Bundle arguments)
Called when the instrumentation is starting, before any application code has been loaded. Usually this will be implemented to simply call {@link #start} to begin the instrumentation thread, which will then continue execution in {@link #onStart}.

If you do not need your own thread -- that is you are writing your instrumentation to be completely asynchronous (returning to the event loop so that the application can run), you can simply begin your instrumentation here, for example call {@link Context#startActivity} to begin the appropriate first activity of the application.

param
arguments Any additional arguments that were supplied when the instrumentation was started.

    
public voidonDestroy()
Called when the instrumented application is stopping, after all of the normal application cleanup has occurred.

    
public booleanonException(java.lang.Object obj, java.lang.Throwable e)
This is called whenever the system captures an unhandled exception that was thrown by the application. The default implementation simply returns false, allowing normal system handling of the exception to take place.

param
obj The client object that generated the exception. May be an Application, Activity, BroadcastReceiver, Service, or null.
param
e The exception that was thrown.
return
To allow normal system exception process to occur, return false. If true is returned, the system will proceed as if the exception didn't happen.

        return false;
    
public voidonStart()
Method where the instrumentation thread enters execution. This allows you to run your instrumentation code in a separate thread than the application, so that it can perform blocking operation such as {@link #sendKeySync} or {@link #startActivitySync}.

You will typically want to call finish() when this function is done, to end your instrumentation.

    
public voidremoveMonitor(android.app.Instrumentation$ActivityMonitor monitor)
Remove an {@link ActivityMonitor} that was previously added with {@link #addMonitor}.

param
monitor The monitor to remove.
see
#addMonitor

        synchronized (mSync) {
            mActivityMonitors.remove(monitor);
        }
    
public voidrunOnMainSync(java.lang.Runnable runner)
Execute a call on the application's main thread, blocking until it is complete. Useful for doing things that are not thread-safe, such as looking at or modifying the view hierarchy.

param
runner The code to run on the main thread.

        validateNotAppThread();
        SyncRunnable sr = new SyncRunnable(runner);
        mThread.getHandler().post(sr);
        sr.waitForComplete();
    
public voidsendCharacterSync(int keyCode)
Higher-level method for sending both the down and up key events for a particular character key code. Equivalent to creating both KeyEvent objects by hand and calling {@link #sendKeySync}. The event appears as if it came from keyboard 0, the built in one.

param
keyCode The key code of the character to send.

        sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, keyCode));
        sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, keyCode));
    
public voidsendKeyDownUpSync(int key)
Sends an up and down key event sync to the currently focused window.

param
key The integer keycode for the event.

        
        sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, key));
        sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, key));
    
public voidsendKeySync(android.view.KeyEvent event)
Send a key event to the currently focused window/view and wait for it to be processed. Finished at some point after the recipient has returned from its event processing, though it may not have completely finished reacting from the event -- for example, if it needs to update its display as a result, it may still be in the process of doing that.

param
event The event to send to the current focus.

        validateNotAppThread();
        try {
            (IWindowManager.Stub.asInterface(ServiceManager.getService("window")))
                .injectKeyEvent(event, true);
        } catch (RemoteException e) {
        }
    
public voidsendPointerSync(android.view.MotionEvent event)
Dispatch a pointer event. Finished at some point after the recipient has returned from its event processing, though it may not have completely finished reacting from the event -- for example, if it needs to update its display as a result, it may still be in the process of doing that.

param
event A motion event describing the pointer action. (As noted in {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use {@link SystemClock#uptimeMillis()} as the timebase.

        validateNotAppThread();
        try {
            (IWindowManager.Stub.asInterface(ServiceManager.getService("window")))
                .injectPointerEvent(event, true);
        } catch (RemoteException e) {
        }
    
public voidsendStatus(int resultCode, android.os.Bundle results)
Provide a status report about the application.

param
resultCode Current success/failure of instrumentation.
param
results Any results to send back to the code that started the instrumentation.

        if (mWatcher != null) {
            try {
                mWatcher.instrumentationStatus(mComponent, resultCode, results);
            }
            catch (RemoteException e) {
                mWatcher = null;
            }
        }
    
public voidsendStringSync(java.lang.String text)
Sends the key events corresponding to the text to the app being instrumented.

param
text The text to be sent.

        if (text == null) {
            return;
        }
        KeyCharacterMap keyCharacterMap = 
            KeyCharacterMap.load(KeyCharacterMap.BUILT_IN_KEYBOARD);
        
        KeyEvent[] events = keyCharacterMap.getEvents(text.toCharArray());
        
        if (events != null) {
            for (int i = 0; i < events.length; i++) {
                sendKeySync(events[i]);
            }
        }        
    
public voidsendTrackballEventSync(android.view.MotionEvent event)
Dispatch a trackball event. Finished at some point after the recipient has returned from its event processing, though it may not have completely finished reacting from the event -- for example, if it needs to update its display as a result, it may still be in the process of doing that.

param
event A motion event describing the trackball action. (As noted in {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use {@link SystemClock#uptimeMillis()} as the timebase.

        validateNotAppThread();
        try {
            (IWindowManager.Stub.asInterface(ServiceManager.getService("window")))
                .injectTrackballEvent(event, true);
        } catch (RemoteException e) {
        }
    
public voidsetAutomaticPerformanceSnapshots()

        mAutomaticPerformanceSnapshots = true;
    
public voidsetInTouchMode(boolean inTouch)
Force the global system in or out of touch mode. This can be used if your instrumentation relies on the UI being in one more or the other when it starts.

param
inTouch Set to true to be in touch mode, false to be in focus mode.

        try {
            IWindowManager.Stub.asInterface(
                    ServiceManager.getService("window")).setInTouchMode(inTouch);
        } catch (RemoteException e) {
            // Shouldn't happen!
        }
    
public voidstart()
Create and start a new thread in which to run instrumentation. This new thread will call to {@link #onStart} where you can implement the instrumentation.

        if (mRunner != null) {
            throw new RuntimeException("Instrumentation already started");
        }
        mRunner = new InstrumentationThread("Instr: " + getClass().getName());
        mRunner.start();
    
public ActivitystartActivitySync(android.content.Intent intent)
Start a new activity and wait for it to begin running before returning. In addition to being synchronous, this method as some semantic differences from the standard {@link Context#startActivity} call: the activity component is resolved before talking with the activity manager (its class name is specified in the Intent that this method ultimately starts), and it does not allow you to start activities that run in a different process. In addition, if the given Intent resolves to multiple activities, instead of displaying a dialog for the user to select an activity, an exception will be thrown.

The function returns as soon as the activity goes idle following the call to its {@link Activity#onCreate}. Generally this means it has gone through the full initialization including {@link Activity#onResume} and drawn and displayed its initial window.

param
intent Description of the activity to start.
see
Context#startActivity

        validateNotAppThread();

        synchronized (mSync) {
            intent = new Intent(intent);
    
            ActivityInfo ai = intent.resolveActivityInfo(
                getTargetContext().getPackageManager(), 0);
            if (ai == null) {
                throw new RuntimeException("Unable to resolve activity for: " + intent);
            }
            if (!ai.applicationInfo.processName.equals(
                    getTargetContext().getPackageName())) {
                // todo: if this intent is ambiguous, look here to see if
                // there is a single match that is in our package.
                throw new RuntimeException("Intent resolved to different package "
                                           + ai.applicationInfo.packageName + ": "
                                           + intent);
            }
    
            intent.setComponent(new ComponentName(
                    ai.applicationInfo.packageName, ai.name));
            final ActivityWaiter aw = new ActivityWaiter(intent);

            if (mWaitingActivities == null) {
                mWaitingActivities = new ArrayList();
            }
            mWaitingActivities.add(aw);

            getTargetContext().startActivity(intent);

            do {
                try {
                    mSync.wait();
                } catch (InterruptedException e) {
                }
            } while (mWaitingActivities.contains(aw));
         
            return aw.activity;
        }
    
public voidstartAllocCounting()

        // Before we start trigger a GC and reset the debug counts. Run the 
        // finalizers and another GC before starting and stopping the alloc
        // counts. This will free up any objects that were just sitting around 
        // waiting for their finalizers to be run.
        Runtime.getRuntime().gc();
        Runtime.getRuntime().runFinalization();
        Runtime.getRuntime().gc();

        Debug.resetAllCounts();
        
        // start the counts
        Debug.startAllocCounting();
    
public voidstartPerformanceSnapshot()

        mStart = 0;
        if (!isProfiling()) {
            // Add initial binder counts
            Bundle binderCounts = getBinderCounts();
            for (String key: binderCounts.keySet()) {
                addPerfMetricLong("pre_" + key, binderCounts.getLong(key));
            }

            // Force a GC and zero out the performance counters.  Do this
            // before reading initial CPU/wall-clock times so we don't include
            // the cost of this setup in our final metrics.
            startAllocCounting();

            // Record CPU time up to this point, and start timing.  Note:  this
            // must happen at the end of this method, otherwise the timing will
            // include noise.
            mStart = SystemClock.uptimeMillis();
            mPreCpuTime = Process.getElapsedCpuTime();
        }
    
public voidstartProfiling()
This method will start profiling if isProfiling() returns true. You should only call this method if you set the handleProfiling attribute in the manifest file for this Instrumentation to true.

        if (mThread.isProfiling()) {
            File file = new File(mThread.getProfileFilePath());
            file.getParentFile().mkdirs();
            Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
        }
    
public voidstopAllocCounting()

        Runtime.getRuntime().gc();
        Runtime.getRuntime().runFinalization();
        Runtime.getRuntime().gc();
        Debug.stopAllocCounting();
    
public voidstopProfiling()
Stops profiling if isProfiling() returns true.

        if (mThread.isProfiling()) {
            Debug.stopMethodTracing();
        }
    
private final voidvalidateNotAppThread()

        if (ActivityThread.currentActivityThread() != null) {
            throw new RuntimeException(
                "This method can not be called from the main application thread");
        }
    
public voidwaitForIdle(java.lang.Runnable recipient)
Schedule a callback for when the application's main thread goes idle (has no more events to process).

param
recipient Called the next time the thread's message queue is idle.

        mMessageQueue.addIdleHandler(new Idler(recipient));
        mThread.getHandler().post(new EmptyRunnable());
    
public voidwaitForIdleSync()
Synchronously wait for the application to be idle. Can not be called from the main application thread -- use {@link #start} to execute instrumentation in its own thread.

        validateNotAppThread();
        Idler idler = new Idler(null);
        mMessageQueue.addIdleHandler(idler);
        mThread.getHandler().post(new EmptyRunnable());
        idler.waitForIdle();
    
public ActivitywaitForMonitor(android.app.Instrumentation$ActivityMonitor monitor)
Wait for an existing {@link ActivityMonitor} to be hit. Once the monitor has been hit, it is removed from the activity monitor list and the first created Activity object that matched it is returned.

param
monitor The ActivityMonitor to wait for.
return
The Activity object that matched the monitor.

        Activity activity = monitor.waitForActivity();
        synchronized (mSync) {
            mActivityMonitors.remove(monitor);
        }
        return activity;
    
public ActivitywaitForMonitorWithTimeout(android.app.Instrumentation$ActivityMonitor monitor, long timeOut)
Wait for an existing {@link ActivityMonitor} to be hit till the timeout expires. Once the monitor has been hit, it is removed from the activity monitor list and the first created Activity object that matched it is returned. If the timeout expires, a null object is returned.

param
monitor The ActivityMonitor to wait for.
param
timeOut The timeout value in secs.
return
The Activity object that matched the monitor.

        Activity activity = monitor.waitForActivityWithTimeout(timeOut);
        synchronized (mSync) {
            mActivityMonitors.remove(monitor);
        }
        return activity;