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