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