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