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