Loading core/java/android/app/Instrumentation.java +9 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,8 @@ import android.ravenwood.annotation.RavenwoodIgnore; import android.ravenwood.annotation.RavenwoodKeep; import android.ravenwood.annotation.RavenwoodKeepPartialClass; import android.ravenwood.annotation.RavenwoodKeepWholeClass; import android.ravenwood.annotation.RavenwoodRedirect; import android.ravenwood.annotation.RavenwoodRedirectionClass; import android.ravenwood.annotation.RavenwoodReplace; import android.util.AndroidRuntimeException; import android.util.Log; Loading Loading @@ -87,6 +89,7 @@ import java.util.concurrent.TimeoutException; * <instrumentation> tag. */ @RavenwoodKeepPartialClass @RavenwoodRedirectionClass("Instrumentation_ravenwood") public class Instrumentation { /** Loading Loading @@ -152,6 +155,10 @@ public class Instrumentation { public Instrumentation() { } @RavenwoodRedirect private static void checkPendingExceptionOnRavenwood() { } /** * Called for methods that shouldn't be called by standard apps and * should only be used in instrumentation environments. This is not Loading Loading @@ -467,6 +474,7 @@ public class Instrumentation { mMessageQueue.addIdleHandler(idler); mMainHandler.post(new EmptyRunnable()); idler.waitForIdle(); checkPendingExceptionOnRavenwood(); } /** Loading @@ -482,6 +490,7 @@ public class Instrumentation { SyncRunnable sr = new SyncRunnable(runner); mMainHandler.post(sr); sr.waitForComplete(); checkPendingExceptionOnRavenwood(); } boolean isSdkSandboxAllowedToStartActivities() { Loading core/java/android/app/Instrumentation_ravenwood.java 0 → 100644 +29 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.app; import android.platform.test.ravenwood.RavenwoodUtils; public class Instrumentation_ravenwood { private static final String TAG = "Instrumentation_ravenwood"; private Instrumentation_ravenwood() { } static void checkPendingExceptionOnRavenwood() { RavenwoodUtils.getMainHandler().post(() -> {}); } } ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodMethodCallLogger.java +32 −12 Original line number Diff line number Diff line Loading @@ -64,8 +64,18 @@ import java.util.regex.Pattern; public class RavenwoodMethodCallLogger { private static final String TAG = "RavenwoodMethodCallLogger"; private static final boolean LOG_ALL_METHODS = "1".equals( System.getenv("RAVENWOOD_METHOD_LOG_NO_FILTER")); public enum LogMode { Default, None, All, } private static final LogMode LOG_MODE = switch ("" + System.getenv("RAVENWOOD_METHOD_LOG_MODE")) { case "all" -> LogMode.All; case "0" -> LogMode.None; default -> LogMode.Default; }; /** The policy file is created with this filename. */ private static final String CALLED_METHOD_POLICY_FILE = "/tmp/ravenwood-called-methods.txt"; Loading @@ -79,13 +89,13 @@ public class RavenwoodMethodCallLogger { /** It's a singleton, except we create different instances for unit tests. */ @VisibleForTesting public RavenwoodMethodCallLogger(boolean logAllMethods) { mLogAllMethods = logAllMethods; public RavenwoodMethodCallLogger(LogMode logMode) { mLogMode = logMode; } /** Singleton instance */ private static final RavenwoodMethodCallLogger sInstance = new RavenwoodMethodCallLogger(LOG_ALL_METHODS); new RavenwoodMethodCallLogger(LOG_MODE); /** * @return the singleton instance. Loading @@ -109,7 +119,7 @@ public class RavenwoodMethodCallLogger { private volatile PrintStream mOut = System.out; private final boolean mLogAllMethods; private final LogMode mLogMode; private static class MethodDesc { public final String name; Loading Loading @@ -165,6 +175,10 @@ public class RavenwoodMethodCallLogger { sIgnoreClasses.add(android.util.Slog.class); sIgnoreClasses.add(android.util.EventLog.class); sIgnoreClasses.add(android.util.TimingsTraceLog.class); sIgnoreClasses.add(android.util.MathUtils.class); sIgnoreClasses.add(android.app.PropertyInvalidatedCache.class); sIgnoreClasses.add(android.os.IpcDataCache.class); sIgnoreClasses.add(android.text.FontConfig.class); Loading Loading @@ -208,8 +222,13 @@ public class RavenwoodMethodCallLogger { * Using class objects allow us to easily check inheritance too. */ private boolean shouldIgnoreClass(Class<?> clazz) { if (mLogAllMethods) { switch (mLogMode) { case All: return false; case None: return true; default: break; } if (sIgnoreClasses.contains(clazz)) { return true; Loading Loading @@ -476,7 +495,8 @@ public class RavenwoodMethodCallLogger { } wr.println(); } Log.i(TAG, String.format("Wrote called methods to %s (%d classes, %d methods)", Log.i(TAG, String.format( "Wrote called methods to file://%s (%d classes, %d methods)", outputFileNameForLogging, classCount, methodCount)); } catch (Exception e) { Log.w(TAG, "Exception while dumping called methods", e); Loading ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java +8 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,9 @@ public final class RavenwoodRunnerState { private static final String RAVENWOOD_RULE_ERROR = "RavenwoodRule(s) are not executed in the correct order"; private static final boolean ALLOW_ALL_SYSPROP_READS = "1".equals( System.getenv("RAVENWOOD_ALLOW_ALL_SYSPROP_READS")); private static final List<Pair<RavenwoodRule, RavenwoodPropertyState>> sActiveProperties = new ArrayList<>(); Loading Loading @@ -155,6 +158,11 @@ public final class RavenwoodRunnerState { || sActiveProperties.stream().anyMatch(p -> p.second.isKeyAccessible(key, write)); if (!result) { if (ALLOW_ALL_SYSPROP_READS && !write) { Log.w(TAG, "Unallow-listed property read detected: key=" + key); return; } throw new IllegalArgumentException((write ? "Write" : "Read") + " access to system property '" + key + "' denied via RavenwoodRule"); } Loading ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodTestStats.java +2 −2 Original line number Diff line number Diff line Loading @@ -217,7 +217,7 @@ public class RavenwoodTestStats { }); mOutputWriter.flush(); mStats.clear(); Log.i(TAG, "Added result to stats file: " + mOutputSymlinkFile); Log.i(TAG, "Added result to stats file: file://" + mOutputSymlinkFile); } private static void createCalledMethodPolicyFile() { Loading Loading
core/java/android/app/Instrumentation.java +9 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,8 @@ import android.ravenwood.annotation.RavenwoodIgnore; import android.ravenwood.annotation.RavenwoodKeep; import android.ravenwood.annotation.RavenwoodKeepPartialClass; import android.ravenwood.annotation.RavenwoodKeepWholeClass; import android.ravenwood.annotation.RavenwoodRedirect; import android.ravenwood.annotation.RavenwoodRedirectionClass; import android.ravenwood.annotation.RavenwoodReplace; import android.util.AndroidRuntimeException; import android.util.Log; Loading Loading @@ -87,6 +89,7 @@ import java.util.concurrent.TimeoutException; * <instrumentation> tag. */ @RavenwoodKeepPartialClass @RavenwoodRedirectionClass("Instrumentation_ravenwood") public class Instrumentation { /** Loading Loading @@ -152,6 +155,10 @@ public class Instrumentation { public Instrumentation() { } @RavenwoodRedirect private static void checkPendingExceptionOnRavenwood() { } /** * Called for methods that shouldn't be called by standard apps and * should only be used in instrumentation environments. This is not Loading Loading @@ -467,6 +474,7 @@ public class Instrumentation { mMessageQueue.addIdleHandler(idler); mMainHandler.post(new EmptyRunnable()); idler.waitForIdle(); checkPendingExceptionOnRavenwood(); } /** Loading @@ -482,6 +490,7 @@ public class Instrumentation { SyncRunnable sr = new SyncRunnable(runner); mMainHandler.post(sr); sr.waitForComplete(); checkPendingExceptionOnRavenwood(); } boolean isSdkSandboxAllowedToStartActivities() { Loading
core/java/android/app/Instrumentation_ravenwood.java 0 → 100644 +29 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.app; import android.platform.test.ravenwood.RavenwoodUtils; public class Instrumentation_ravenwood { private static final String TAG = "Instrumentation_ravenwood"; private Instrumentation_ravenwood() { } static void checkPendingExceptionOnRavenwood() { RavenwoodUtils.getMainHandler().post(() -> {}); } }
ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodMethodCallLogger.java +32 −12 Original line number Diff line number Diff line Loading @@ -64,8 +64,18 @@ import java.util.regex.Pattern; public class RavenwoodMethodCallLogger { private static final String TAG = "RavenwoodMethodCallLogger"; private static final boolean LOG_ALL_METHODS = "1".equals( System.getenv("RAVENWOOD_METHOD_LOG_NO_FILTER")); public enum LogMode { Default, None, All, } private static final LogMode LOG_MODE = switch ("" + System.getenv("RAVENWOOD_METHOD_LOG_MODE")) { case "all" -> LogMode.All; case "0" -> LogMode.None; default -> LogMode.Default; }; /** The policy file is created with this filename. */ private static final String CALLED_METHOD_POLICY_FILE = "/tmp/ravenwood-called-methods.txt"; Loading @@ -79,13 +89,13 @@ public class RavenwoodMethodCallLogger { /** It's a singleton, except we create different instances for unit tests. */ @VisibleForTesting public RavenwoodMethodCallLogger(boolean logAllMethods) { mLogAllMethods = logAllMethods; public RavenwoodMethodCallLogger(LogMode logMode) { mLogMode = logMode; } /** Singleton instance */ private static final RavenwoodMethodCallLogger sInstance = new RavenwoodMethodCallLogger(LOG_ALL_METHODS); new RavenwoodMethodCallLogger(LOG_MODE); /** * @return the singleton instance. Loading @@ -109,7 +119,7 @@ public class RavenwoodMethodCallLogger { private volatile PrintStream mOut = System.out; private final boolean mLogAllMethods; private final LogMode mLogMode; private static class MethodDesc { public final String name; Loading Loading @@ -165,6 +175,10 @@ public class RavenwoodMethodCallLogger { sIgnoreClasses.add(android.util.Slog.class); sIgnoreClasses.add(android.util.EventLog.class); sIgnoreClasses.add(android.util.TimingsTraceLog.class); sIgnoreClasses.add(android.util.MathUtils.class); sIgnoreClasses.add(android.app.PropertyInvalidatedCache.class); sIgnoreClasses.add(android.os.IpcDataCache.class); sIgnoreClasses.add(android.text.FontConfig.class); Loading Loading @@ -208,8 +222,13 @@ public class RavenwoodMethodCallLogger { * Using class objects allow us to easily check inheritance too. */ private boolean shouldIgnoreClass(Class<?> clazz) { if (mLogAllMethods) { switch (mLogMode) { case All: return false; case None: return true; default: break; } if (sIgnoreClasses.contains(clazz)) { return true; Loading Loading @@ -476,7 +495,8 @@ public class RavenwoodMethodCallLogger { } wr.println(); } Log.i(TAG, String.format("Wrote called methods to %s (%d classes, %d methods)", Log.i(TAG, String.format( "Wrote called methods to file://%s (%d classes, %d methods)", outputFileNameForLogging, classCount, methodCount)); } catch (Exception e) { Log.w(TAG, "Exception while dumping called methods", e); Loading
ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java +8 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,9 @@ public final class RavenwoodRunnerState { private static final String RAVENWOOD_RULE_ERROR = "RavenwoodRule(s) are not executed in the correct order"; private static final boolean ALLOW_ALL_SYSPROP_READS = "1".equals( System.getenv("RAVENWOOD_ALLOW_ALL_SYSPROP_READS")); private static final List<Pair<RavenwoodRule, RavenwoodPropertyState>> sActiveProperties = new ArrayList<>(); Loading Loading @@ -155,6 +158,11 @@ public final class RavenwoodRunnerState { || sActiveProperties.stream().anyMatch(p -> p.second.isKeyAccessible(key, write)); if (!result) { if (ALLOW_ALL_SYSPROP_READS && !write) { Log.w(TAG, "Unallow-listed property read detected: key=" + key); return; } throw new IllegalArgumentException((write ? "Write" : "Read") + " access to system property '" + key + "' denied via RavenwoodRule"); } Loading
ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodTestStats.java +2 −2 Original line number Diff line number Diff line Loading @@ -217,7 +217,7 @@ public class RavenwoodTestStats { }); mOutputWriter.flush(); mStats.clear(); Log.i(TAG, "Added result to stats file: " + mOutputSymlinkFile); Log.i(TAG, "Added result to stats file: file://" + mOutputSymlinkFile); } private static void createCalledMethodPolicyFile() { Loading