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