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