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

Commit fd353244 authored by Makoto Onuki's avatar Makoto Onuki Committed by Android (Google) Code Review
Browse files

Merge "Support test / target context, app context" into main

parents 9b1b590a 55cb426b
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -2408,9 +2408,9 @@ public class Instrumentation {
     * @hide
     */
    @android.ravenwood.annotation.RavenwoodKeep
    public final void basicInit(Context context) {
        mInstrContext = context;
        mAppContext = context;
    public final void basicInit(Context instrContext, Context appContext) {
        mInstrContext = instrContext;
        mAppContext = appContext;
    }

    /** @hide */
+11 −0
Original line number Diff line number Diff line
@@ -7,6 +7,9 @@
    { "name": "RavenwoodMockitoTest_device" },
    { "name": "RavenwoodBivalentTest_device" },

    { "name": "RavenwoodBivalentInstTest_nonself_inst" },
    { "name": "RavenwoodBivalentInstTest_self_inst_device" },

    // The sysui tests should match vendor/unbundled_google/packages/SystemUIGoogle/TEST_MAPPING
    {
      "name": "SystemUIGoogleTests",
@@ -137,6 +140,14 @@
      "name": "PowerStatsTestsRavenwood",
      "host": true
    },
    {
      "name": "RavenwoodBivalentInstTest_nonself_inst",
      "host": true
    },
    {
      "name": "RavenwoodBivalentInstTest_self_inst",
      "host": true
    },
    {
      "name": "RavenwoodBivalentTest",
      "host": true
+8 −8
Original line number Diff line number Diff line
@@ -108,7 +108,7 @@ public class RavenwoodAwareTestRunnerHook {
        Log.v(TAG, "onBeforeInnerRunnerStart: description=" + description);

        // Prepare the environment before the inner runner starts.
        RavenwoodRunnerState.forRunner(runner).enterTestClass(description);
        runner.mState.enterTestClass(description);
    }

    /**
@@ -119,7 +119,7 @@ public class RavenwoodAwareTestRunnerHook {
        Log.v(TAG, "onAfterInnerRunnerFinished: description=" + description);

        RavenwoodTestStats.getInstance().onClassFinished(description);
        RavenwoodRunnerState.forRunner(runner).exitTestClass();
        runner.mState.exitTestClass();
    }

    /**
@@ -133,10 +133,10 @@ public class RavenwoodAwareTestRunnerHook {

        if (scope == Scope.Instance && order == Order.Outer) {
            // Start of a test method.
            RavenwoodRunnerState.forRunner(runner).enterTestMethod(description);
            runner.mState.enterTestMethod(description);
        }

        final var classDescription = RavenwoodRunnerState.forRunner(runner).getClassDescription();
        final var classDescription = runner.mState.getClassDescription();

        // Class-level annotations are checked by the runner already, so we only check
        // method-level annotations here.
@@ -160,11 +160,11 @@ public class RavenwoodAwareTestRunnerHook {
            Scope scope, Order order, Throwable th) {
        Log.v(TAG, "onAfter: description=" + description + ", " + scope + ", " + order + ", " + th);

        final var classDescription = RavenwoodRunnerState.forRunner(runner).getClassDescription();
        final var classDescription = runner.mState.getClassDescription();

        if (scope == Scope.Instance && order == Order.Outer) {
            // End of a test method.
            RavenwoodRunnerState.forRunner(runner).exitTestMethod();
            runner.mState.exitTestMethod();
            RavenwoodTestStats.getInstance().onTestFinished(classDescription, description,
                    th == null ? Result.Passed : Result.Failed);
        }
@@ -214,7 +214,7 @@ public class RavenwoodAwareTestRunnerHook {
            Description description, RavenwoodRule rule) throws Throwable {
        Log.v(TAG, "onRavenwoodRuleEnter: description=" + description);

        RavenwoodRunnerState.forRunner(runner).enterRavenwoodRule(rule);
        runner.mState.enterRavenwoodRule(rule);
    }


@@ -225,6 +225,6 @@ public class RavenwoodAwareTestRunnerHook {
            Description description, RavenwoodRule rule) throws Throwable {
        Log.v(TAG, "onRavenwoodRuleExit: description=" + description);

        RavenwoodRunnerState.forRunner(runner).exitRavenwoodRule(rule);
        runner.mState.exitRavenwoodRule(rule);
    }
}
 No newline at end of file
+81 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package android.platform.test.ravenwood;

import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_EMPTY_RESOURCES_APK;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import android.annotation.Nullable;
import android.app.ResourcesManager;
import android.content.res.Resources;
import android.view.DisplayAdjustments;

import java.io.File;
import java.util.HashMap;

/**
 * Used to store various states associated with {@link RavenwoodConfig} that's inly needed
 * in junit-impl.
 *
 * We don't want to put it in junit-src to avoid having to recompile all the downstream
 * dependencies after changing this class.
 *
 * All members must be called from the runner's main thread.
 */
public class RavenwoodConfigState {
    private static final String TAG = "RavenwoodConfigState";

    private final RavenwoodConfig mConfig;

    public RavenwoodConfigState(RavenwoodConfig config) {
        mConfig = config;
    }

    /** Map from path -> resources. */
    private final HashMap<File, Resources> mCachedResources = new HashMap<>();

    /**
     * Load {@link Resources} from an APK, with cache.
     */
    public Resources loadResources(@Nullable File apkPath) {
        var cached = mCachedResources.get(apkPath);
        if (cached != null) {
            return cached;
        }

        var fileToLoad = apkPath != null ? apkPath : new File(RAVENWOOD_EMPTY_RESOURCES_APK);

        assertTrue("File " + fileToLoad + " doesn't exist.", fileToLoad.isFile());

        final String path = fileToLoad.getAbsolutePath();
        final var emptyPaths = new String[0];

        ResourcesManager.getInstance().initializeApplicationPaths(path, emptyPaths);

        final var ret = ResourcesManager.getInstance().getResources(null, path,
                emptyPaths, emptyPaths, emptyPaths,
                emptyPaths, null, null,
                new DisplayAdjustments().getCompatibilityInfo(),
                RavenwoodRuntimeEnvironmentController.class.getClassLoader(), null);

        assertNotNull(ret);

        mCachedResources.put(apkPath, ret);
        return ret;
    }
}
+19 −7
Original line number Diff line number Diff line
@@ -60,6 +60,8 @@ public class RavenwoodContext extends RavenwoodBaseContext {
    private final File mCacheDir;
    private final Supplier<Resources> mResourcesSupplier;

    private RavenwoodContext mAppContext;

    @GuardedBy("mLock")
    private Resources mResources;

@@ -77,8 +79,8 @@ public class RavenwoodContext extends RavenwoodBaseContext {
        mPackageName = packageName;
        mMainThread = mainThread;
        mResourcesSupplier = resourcesSupplier;
        mFilesDir = createTempDir("files-dir");
        mCacheDir = createTempDir("cache-dir");
        mFilesDir = createTempDir(packageName + "_files-dir");
        mCacheDir = createTempDir(packageName + "_cache-dir");

        // Services provided by a typical shipping device
        registerService(ClipboardManager.class,
@@ -131,34 +133,35 @@ public class RavenwoodContext extends RavenwoodBaseContext {
    @Override
    public Looper getMainLooper() {
        Objects.requireNonNull(mMainThread,
                "Test must request setProvideMainThread() via RavenwoodRule");
                "Test must request setProvideMainThread() via RavenwoodConfig");
        return mMainThread.getLooper();
    }

    @Override
    public Handler getMainThreadHandler() {
        Objects.requireNonNull(mMainThread,
                "Test must request setProvideMainThread() via RavenwoodRule");
                "Test must request setProvideMainThread() via RavenwoodConfig");
        return mMainThread.getThreadHandler();
    }

    @Override
    public Executor getMainExecutor() {
        Objects.requireNonNull(mMainThread,
                "Test must request setProvideMainThread() via RavenwoodRule");
                "Test must request setProvideMainThread() via RavenwoodConfig");
        return mMainThread.getThreadExecutor();
    }

    @Override
    public String getPackageName() {
        return Objects.requireNonNull(mPackageName,
                "Test must request setPackageName() via RavenwoodRule");
                "Test must request setPackageName() (or setTargetPackageName())"
                + " via RavenwoodConfig");
    }

    @Override
    public String getOpPackageName() {
        return Objects.requireNonNull(mPackageName,
                "Test must request setPackageName() via RavenwoodRule");
                "Test must request setPackageName() via RavenwoodConfig");
    }

    @Override
@@ -227,6 +230,15 @@ public class RavenwoodContext extends RavenwoodBaseContext {
        return new File(RAVENWOOD_RESOURCE_APK).getAbsolutePath();
    }

    public void setApplicationContext(RavenwoodContext appContext) {
        mAppContext = appContext;
    }

    @Override
    public Context getApplicationContext() {
        return mAppContext;
    }

    /**
     * Wrap the given {@link Supplier} to become memoized.
     *
Loading