[go: nahoru, domu]

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