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