Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 78552f3d authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Enable sync-related Instrumentation APIs" into main

parents c2683f23 ecdcff63
Loading
Loading
Loading
Loading
+15 −12
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.MessageQueue;
@@ -132,6 +133,7 @@ public class Instrumentation {

    private final Object mSync = new Object();
    private ActivityThread mThread = null;
    private Handler mMainHandler = null;
    private MessageQueue mMessageQueue = null;
    private Context mInstrContext;
    private Context mAppContext;
@@ -447,9 +449,10 @@ public class Instrumentation {
     * @param recipient Called the next time the thread's message queue is
     *                  idle.
     */
    @RavenwoodKeep
    public void waitForIdle(Runnable recipient) {
        mMessageQueue.addIdleHandler(new Idler(recipient));
        mThread.getHandler().post(new EmptyRunnable());
        mMainHandler.post(new EmptyRunnable());
    }

    /**
@@ -457,11 +460,12 @@ public class Instrumentation {
     * from the main application thread -- use {@link #start} to execute
     * instrumentation in its own thread.
     */
    @RavenwoodKeep
    public void waitForIdleSync() {
        validateNotAppThread();
        Idler idler = new Idler(null);
        mMessageQueue.addIdleHandler(idler);
        mThread.getHandler().post(new EmptyRunnable());
        mMainHandler.post(new EmptyRunnable());
        idler.waitForIdle();
    }

@@ -472,18 +476,11 @@ public class Instrumentation {
     * 
     * @param runner The code to run on the main thread.
     */
    @RavenwoodReplace(blockedBy = ActivityThread.class)
    @RavenwoodKeep
    public void runOnMainSync(Runnable runner) {
        validateNotAppThread();
        SyncRunnable sr = new SyncRunnable(runner);
        mThread.getHandler().post(sr);
        sr.waitForComplete();
    }

    private void runOnMainSync$ravenwood(Runnable runner) {
        validateNotAppThread();
        SyncRunnable sr = new SyncRunnable(runner);
        mInstrContext.getMainExecutor().execute(sr);
        mMainHandler.post(sr);
        sr.waitForComplete();
    }

@@ -2383,6 +2380,7 @@ public class Instrumentation {
            Context instrContext, Context appContext, ComponentName component, 
            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection) {
        mThread = thread;
        mMainHandler = thread.getHandler();
        mMessageQueue = mThread.getLooper().myQueue();
        mInstrContext = instrContext;
        mAppContext = appContext;
@@ -2397,15 +2395,18 @@ public class Instrumentation {
     */
    final void basicInit(ActivityThread thread) {
        mThread = thread;
        mMainHandler = thread.getHandler();
    }

    /**
     * Only sets the Context up, keeps everything else null.
     * Initialize the minimam fields needed for Ravenwood.
     *
     * @hide
     */
    @RavenwoodKeep
    public final void basicInit(Context instrContext, Context appContext, UiAutomation ui) {
        mMainHandler = instrContext.getMainThreadHandler();
        mMessageQueue = mMainHandler.getLooper().getQueue();
        mInstrContext = instrContext;
        mAppContext = appContext;
        mUiAutomation = ui;
@@ -2602,6 +2603,7 @@ public class Instrumentation {
        }
    }

    @RavenwoodKeepWholeClass
    private static final class EmptyRunnable implements Runnable {
        public void run() {
        }
@@ -2661,6 +2663,7 @@ public class Instrumentation {
        }
    }

    @RavenwoodKeepWholeClass
    private static final class Idler implements MessageQueue.IdleHandler {
        private final Runnable mCallback;
        private boolean mIdle;
+20 −15
Original line number Diff line number Diff line
@@ -82,7 +82,6 @@ import org.junit.runner.Description;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@@ -121,9 +120,6 @@ public class RavenwoodRuntimeEnvironmentController {
    private static final String ANDROID_LOG_TAGS = "ANDROID_LOG_TAGS";
    private static final String RAVENWOOD_ANDROID_LOG_TAGS = "RAVENWOOD_" + ANDROID_LOG_TAGS;

    static volatile Thread sTestThread;
    static volatile Thread sMainThread;

    /**
     * When enabled, attempt to dump all thread stacks just before we hit the
     * overall Tradefed timeout, to aid in debugging deadlocks.
@@ -213,11 +209,18 @@ public class RavenwoodRuntimeEnvironmentController {
    private static final String DEFAULT_INSTRUMENTATION_CLASS =
            "androidx.test.runner.AndroidJUnitRunner";

    static volatile Thread sTestThread;
    static volatile HandlerThread sMainThread;

    private static final int sMyPid = new Random().nextInt(100, 32768);
    private static int sTargetSdkLevel;

    private static String sTestPackageName;
    private static String sTargetPackageName;
    private static String sInstrumentationClass;

    static volatile RavenwoodContext sInstContext;
    static volatile RavenwoodContext sTargetContext;
    private static Instrumentation sInstrumentation;
    private static final long sCallingIdentity =
            packBinderIdentityToken(false, FIRST_APPLICATION_UID, sMyPid);
@@ -381,20 +384,20 @@ public class RavenwoodRuntimeEnvironmentController {
            };
        }

        var instContext = new RavenwoodContext(
        sInstContext = new RavenwoodContext(
                sTestPackageName, main, instResourcesLoader);
        var targetContext = new RavenwoodContext(
        sTargetContext = new RavenwoodContext(
                sTargetPackageName, main, targetResourcesLoader);

        // Set up app context.
        var appContext = new RavenwoodContext(sTargetPackageName, main, targetResourcesLoader);
        appContext.setApplicationContext(appContext);
        if (isSelfInstrumenting) {
            instContext.setApplicationContext(appContext);
            targetContext.setApplicationContext(appContext);
            sInstContext.setApplicationContext(appContext);
            sTargetContext.setApplicationContext(appContext);
        } else {
            // When instrumenting into another APK, the test context doesn't have an app context.
            targetContext.setApplicationContext(appContext);
            sTargetContext.setApplicationContext(appContext);
        }

        // Set up ActivityThread.currentSystemContext(), which is technically a different
@@ -422,7 +425,7 @@ public class RavenwoodRuntimeEnvironmentController {
                }
            }

            sInstrumentation.basicInit(instContext, targetContext, null);
            initInstrumentation();
            sInstrumentation.onCreate(instArgs);
        });
        InstrumentationRegistry.registerInstance(sInstrumentation, instArgs);
@@ -463,15 +466,17 @@ public class RavenwoodRuntimeEnvironmentController {
        }
    }

    private static void initInstrumentation() {
        // We need to recreate the mocks for each test class, because sometimes tests
        // will call Mockito.framework().clearInlineMocks() after execution.
        sInstrumentation.basicInit(sInstContext, sTargetContext, createMockUiAutomation());
    }

    /**
     * Partially reset and initialize before each test class invocation
     */
    public static void initForRunner() {
        var targetContext = sInstrumentation.getTargetContext();
        var instContext = sInstrumentation.getContext();
        // We need to recreate the mock UiAutomation for each test class, because sometimes tests
        // will call Mockito.framework().clearInlineMocks() after execution.
        sInstrumentation.basicInit(instContext, targetContext, createMockUiAutomation());
        initInstrumentation();

        // Reset some global state
        Process_ravenwood.reset();