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