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