diff options
70 files changed, 1842 insertions, 198 deletions
diff --git a/api/OWNERS b/api/OWNERS index f2bcf13d2d2e..31ffa8cd4e9f 100644 --- a/api/OWNERS +++ b/api/OWNERS @@ -1,4 +1,3 @@ -hansson@google.com # Modularization team file:platform/packages/modules/common:/OWNERS diff --git a/cmds/idmap2/OWNERS b/cmds/idmap2/OWNERS index 062ffd41348a..def9f401e51f 100644 --- a/cmds/idmap2/OWNERS +++ b/cmds/idmap2/OWNERS @@ -1,4 +1,3 @@ set noparent -toddke@google.com patb@google.com zyy@google.com diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java index 7eacaac29d4b..bb35e6cf1bfa 100644 --- a/core/java/android/app/Instrumentation.java +++ b/core/java/android/app/Instrumentation.java @@ -190,6 +190,7 @@ public class Instrumentation { * @param arguments Any additional arguments that were supplied when the * instrumentation was started. */ + @android.ravenwood.annotation.RavenwoodKeep public void onCreate(Bundle arguments) { } diff --git a/core/java/android/app/contentsuggestions/OWNERS b/core/java/android/app/contentsuggestions/OWNERS index 5f8de77c9dda..3d21a6a2b58f 100644 --- a/core/java/android/app/contentsuggestions/OWNERS +++ b/core/java/android/app/contentsuggestions/OWNERS @@ -1,4 +1,3 @@ # Bug component: 643919 hackz@google.com -volnov@google.com diff --git a/core/java/android/app/ondeviceintelligence/OWNERS b/core/java/android/app/ondeviceintelligence/OWNERS index 85e9e653e6fb..0e8110aeee1b 100644 --- a/core/java/android/app/ondeviceintelligence/OWNERS +++ b/core/java/android/app/ondeviceintelligence/OWNERS @@ -3,4 +3,3 @@ sandeepbandaru@google.com shivanker@google.com hackz@google.com -volnov@google.com diff --git a/core/java/android/app/wearable/OWNERS b/core/java/android/app/wearable/OWNERS index 497eaf0e40f1..56c8ca57a293 100644 --- a/core/java/android/app/wearable/OWNERS +++ b/core/java/android/app/wearable/OWNERS @@ -2,4 +2,3 @@ charliewang@google.com hackz@google.com oni@google.com tomchan@google.com -volnov@google.com
\ No newline at end of file diff --git a/core/java/android/content/integrity/OWNERS b/core/java/android/content/integrity/OWNERS index 20c758aedd67..ca65fdab99b1 100644 --- a/core/java/android/content/integrity/OWNERS +++ b/core/java/android/content/integrity/OWNERS @@ -1,5 +1,4 @@ # Bug component: 722021 toddke@android.com -toddke@google.com patb@google.com diff --git a/core/java/android/content/pm/parsing/OWNERS b/core/java/android/content/pm/parsing/OWNERS index 8049d5cb7fa2..445a8330037b 100644 --- a/core/java/android/content/pm/parsing/OWNERS +++ b/core/java/android/content/pm/parsing/OWNERS @@ -2,4 +2,3 @@ chiuwinson@google.com patb@google.com -toddke@google.com diff --git a/core/java/android/content/pm/permission/OWNERS b/core/java/android/content/pm/permission/OWNERS index cf7e6890876a..8ef84745c99f 100644 --- a/core/java/android/content/pm/permission/OWNERS +++ b/core/java/android/content/pm/permission/OWNERS @@ -3,6 +3,5 @@ include platform/frameworks/base:/core/java/android/permission/OWNERS toddke@android.com -toddke@google.com patb@google.com diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS index 727dcbaca4bf..a6785bab56f3 100644 --- a/core/java/android/os/OWNERS +++ b/core/java/android/os/OWNERS @@ -78,7 +78,7 @@ per-file Trace.java = file:/TRACE_OWNERS per-file PatternMatcher* = file:/PACKAGE_MANAGER_OWNERS # PermissionEnforcer -per-file PermissionEnforcer.java = tweek@google.com, brufino@google.com +per-file PermissionEnforcer.java = tweek@google.com # RemoteCallbackList per-file RemoteCallbackList.java = shayba@google.com diff --git a/core/java/android/speech/OWNERS b/core/java/android/speech/OWNERS index 32f482264103..f228ba46be0c 100644 --- a/core/java/android/speech/OWNERS +++ b/core/java/android/speech/OWNERS @@ -1,3 +1,2 @@ -volnov@google.com eugeniom@google.com schfan@google.com diff --git a/core/java/com/android/internal/util/OWNERS b/core/java/com/android/internal/util/OWNERS index 9be8ea7aadc4..d174fe36e460 100644 --- a/core/java/com/android/internal/util/OWNERS +++ b/core/java/com/android/internal/util/OWNERS @@ -1,8 +1,8 @@ -per-file AsyncChannel* = lorenzo@google.com, satk@google.com, etancohen@google.com +per-file AsyncChannel* = lorenzo@google.com, satk@google.com per-file MessageUtils*, Protocol*, RingBuffer*, TokenBucket* = jchalard@google.com, lorenzo@google.com, satk@google.com per-file *Notification* = file:/services/core/java/com/android/server/notification/OWNERS per-file *ContrastColor* = file:/services/core/java/com/android/server/notification/OWNERS -per-file Protocol* = etancohen@google.com, lorenzo@google.com +per-file Protocol* =lorenzo@google.com per-file State* = jchalard@google.com, lorenzo@google.com, satk@google.com per-file *Dump* = file:/core/java/com/android/internal/util/dump/OWNERS per-file *Screenshot* = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS diff --git a/core/res/OWNERS b/core/res/OWNERS index faed4d80f39b..a208f7f1a3ad 100644 --- a/core/res/OWNERS +++ b/core/res/OWNERS @@ -9,7 +9,6 @@ hackbod@google.com ilyamaty@google.com jbolinger@google.com jsharkey@android.com -jsharkey@google.com juliacr@google.com kchyn@google.com michaelwr@google.com diff --git a/drm/java/android/drm/OWNERS b/drm/java/android/drm/OWNERS index 43871001c9ad..b65cce70225e 100644 --- a/drm/java/android/drm/OWNERS +++ b/drm/java/android/drm/OWNERS @@ -1,4 +1,3 @@ # Bug component: 49079 -jtinker@google.com robertshih@google.com diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/OWNERS index 6207e5b020f7..7e557860365e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/OWNERS +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/OWNERS @@ -4,5 +4,4 @@ madym@google.com mattsziklay@google.com mdehaini@google.com pbdr@google.com -tkachenkoi@google.com vaniadesmonda@google.com diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp index 23cd3ce965ff..c75db29c6699 100644 --- a/libs/hwui/Android.bp +++ b/libs/hwui/Android.bp @@ -203,6 +203,9 @@ java_sdk_library { visibility: [ "//frameworks/base", // Framework ], + impl_library_visibility: [ + "//frameworks/base/ravenwood", + ], srcs: [ ":framework-graphics-srcs", @@ -227,6 +230,14 @@ java_sdk_library { } filegroup { + name: "framework-graphics-ravenwood-policies", + srcs: [ + "framework-graphics-ravenwood-policies.txt", + ], + visibility: ["//frameworks/base/ravenwood"], +} + +filegroup { name: "framework-graphics-srcs", srcs: [ "apex/java/**/*.java", diff --git a/libs/hwui/framework-graphics-ravenwood-policies.txt b/libs/hwui/framework-graphics-ravenwood-policies.txt new file mode 100644 index 000000000000..7296225ccfe8 --- /dev/null +++ b/libs/hwui/framework-graphics-ravenwood-policies.txt @@ -0,0 +1 @@ +class android.graphics.ColorMatrix keepclass diff --git a/media/java/android/media/musicrecognition/OWNERS b/media/java/android/media/musicrecognition/OWNERS index 037b04831260..820be004efd5 100644 --- a/media/java/android/media/musicrecognition/OWNERS +++ b/media/java/android/media/musicrecognition/OWNERS @@ -1,5 +1,4 @@ # Bug component: 830636 oni@google.com -volnov@google.com diff --git a/opengl/java/android/opengl/OWNERS b/opengl/java/android/opengl/OWNERS index e340bc62567a..4ec9e29c48b0 100644 --- a/opengl/java/android/opengl/OWNERS +++ b/opengl/java/android/opengl/OWNERS @@ -3,4 +3,3 @@ sumir@google.com prahladk@google.com ianelliott@google.com -lpy@google.com diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS b/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS index b9449acc6f7d..50bfe8c7cd78 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS @@ -1,6 +1,5 @@ # Default reviewers for this and subdirectories. andychou@google.com -arcwang@google.com asapperstein@google.com changbetty@google.com qal@google.com diff --git a/packages/Shell/OWNERS b/packages/Shell/OWNERS index dd939bbe041e..22663b84faf4 100644 --- a/packages/Shell/OWNERS +++ b/packages/Shell/OWNERS @@ -6,7 +6,6 @@ nandana@google.com svetoslavganov@google.com hackbod@google.com yamasani@google.com -toddke@google.com patb@google.com cbrubaker@google.com omakoto@google.com diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaProcessingHelper.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaProcessingHelper.kt index 2bdee67dd57a..ba135f94dc56 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaProcessingHelper.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaProcessingHelper.kt @@ -22,6 +22,7 @@ import android.content.Context import android.graphics.drawable.Icon import android.media.session.MediaController import android.media.session.PlaybackState +import android.os.BadParcelableException import android.util.Log import com.android.systemui.Flags.mediaControlsPostsOptimization import com.android.systemui.biometrics.Utils.toBitmap @@ -109,7 +110,12 @@ private fun areCustomActionsEqual( } if (firstAction.extras != null) { firstAction.extras.keySet().forEach { key -> - if (firstAction.extras[key] != secondAction.extras[key]) { + try { + if (firstAction.extras[key] != secondAction.extras[key]) { + return false + } + } catch (e: BadParcelableException) { + Log.e(TAG, "Cannot unparcel extras", e) return false } } diff --git a/ravenwood/Android.bp b/ravenwood/Android.bp index adbb3afb4130..ccbc46fdb03b 100644 --- a/ravenwood/Android.bp +++ b/ravenwood/Android.bp @@ -121,6 +121,7 @@ java_library { name: "ravenwood-helper-framework-runtime", srcs: [ "runtime-helper-src/framework/**/*.java", + ":framework-graphics-srcs", ], static_libs: [ "ravenwood-runtime-common", @@ -278,6 +279,7 @@ cc_library_host_shared { cc_library_host_shared { name: "libravenwood_runtime", defaults: ["ravenwood_jni_defaults"], + header_libs: ["libicuuc_headers"], srcs: [ "runtime-jni/ravenwood_runtime.cpp", "runtime-jni/ravenwood_os_constants.cpp", @@ -372,6 +374,13 @@ platform_compat_config { visibility: ["//visibility:private"], } +java_library { + name: "ext-ravenwood", + installable: false, + static_libs: ["ext"], + visibility: ["//visibility:private"], +} + filegroup { name: "ravenwood-data", device_common_srcs: [ @@ -637,6 +646,7 @@ android_ravenwood_libgroup { libs: [ "100-framework-minus-apex.ravenwood", "200-kxml2-android", + "ext-ravenwood", "ravenwood-runtime-common-ravenwood", @@ -661,6 +671,9 @@ android_ravenwood_libgroup { // StatsD "framework-statsd.ravenwood", + // Graphics + "framework-graphics.ravenwood", + // Provide runtime versions of utils linked in below "junit", "truth", diff --git a/ravenwood/Framework.bp b/ravenwood/Framework.bp index 99fc31b258e9..e36677189e02 100644 --- a/ravenwood/Framework.bp +++ b/ravenwood/Framework.bp @@ -399,3 +399,57 @@ java_genrule { "framework-statsd.ravenwood.jar", ], } + +////////////////////// +// framework-graphics +////////////////////// + +java_genrule { + name: "framework-graphics.ravenwood-base", + tools: ["hoststubgen"], + cmd: "$(location hoststubgen) " + + "@$(location :ravenwood-standard-options) " + + + "--debug-log $(location framework-graphics.log) " + + "--stats-file $(location framework-graphics_stats.csv) " + + "--supported-api-list-file $(location framework-graphics_apis.csv) " + + "--gen-keep-all-file $(location framework-graphics_keep_all.txt) " + + "--gen-input-dump-file $(location framework-graphics_dump.txt) " + + + "--out-impl-jar $(location ravenwood.jar) " + + "--in-jar $(location :framework-graphics.impl{.jar}) " + + + "--policy-override-file $(location :ravenwood-common-policies) " + + "--policy-override-file $(location :framework-graphics-ravenwood-policies) ", + srcs: [ + ":framework-graphics.impl{.jar}", + + ":ravenwood-common-policies", + ":framework-graphics-ravenwood-policies", + ":ravenwood-standard-options", + ], + out: [ + "ravenwood.jar", + + // Following files are created just as FYI. + "framework-graphics_keep_all.txt", + "framework-graphics_dump.txt", + + "framework-graphics.log", + "framework-graphics_stats.csv", + "framework-graphics_apis.csv", + ], + visibility: ["//visibility:private"], +} + +java_genrule { + name: "framework-graphics.ravenwood", + defaults: ["ravenwood-internal-only-visibility-genrule"], + cmd: "cp $(in) $(out)", + srcs: [ + ":framework-graphics.ravenwood-base{ravenwood.jar}", + ], + out: [ + "framework-graphics.ravenwood.jar", + ], +} diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java index 3ebef02284d6..b6167665c985 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java @@ -23,13 +23,10 @@ import static org.junit.Assume.assumeTrue; import android.annotation.NonNull; import android.annotation.Nullable; -import android.os.Bundle; import android.platform.test.annotations.RavenwoodTestRunnerInitializing; import android.platform.test.annotations.internal.InnerRunner; import android.util.Log; -import androidx.test.platform.app.InstrumentationRegistry; - import com.android.ravenwood.common.RavenwoodCommonUtils; import org.junit.rules.TestRule; @@ -285,11 +282,6 @@ public final class RavenwoodAwareTestRunner extends RavenwoodAwareTestRunnerBase private boolean onBefore(Description description, Scope scope, Order order) { Log.v(TAG, "onBefore: description=" + description + ", " + scope + ", " + order); - if (scope == Scope.Instance && order == Order.Outer) { - // Start of a test method. - mState.enterTestMethod(description); - } - final var classDescription = getDescription(); // Class-level annotations are checked by the runner already, so we only check @@ -299,6 +291,12 @@ public final class RavenwoodAwareTestRunner extends RavenwoodAwareTestRunnerBase return false; } } + + if (scope == Scope.Instance && order == Order.Outer) { + // Start of a test method. + mState.enterTestMethod(description); + } + return true; } @@ -314,8 +312,7 @@ public final class RavenwoodAwareTestRunner extends RavenwoodAwareTestRunnerBase if (scope == Scope.Instance && order == Order.Outer) { // End of a test method. - mState.exitTestMethod(); - + mState.exitTestMethod(description); } // If RUN_DISABLED_TESTS is set, and the method did _not_ throw, make it an error. diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java index a3326337d485..9e6b12f60add 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java @@ -230,6 +230,16 @@ public class RavenwoodContext extends RavenwoodBaseContext { return mAppContext; } + @Override + public boolean isRestricted() { + return false; + } + + @Override + public boolean canLoadUnsafeResources() { + return true; + } + /** * Wrap the given {@link Supplier} to become memoized. * diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodNativeLoader.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodNativeLoader.java index a208d6dce2ce..7e935d0451ae 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodNativeLoader.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodNativeLoader.java @@ -48,6 +48,7 @@ public final class RavenwoodNativeLoader { android.content.res.AssetManager.class, android.content.res.StringBlock.class, android.content.res.XmlBlock.class, + android.text.AndroidCharacter.class, }; /** @@ -61,15 +62,49 @@ public final class RavenwoodNativeLoader { android.graphics.Path.class, android.graphics.Color.class, android.graphics.ColorSpace.class, + android.graphics.Bitmap.class, + android.graphics.BitmapFactory.class, + android.graphics.BitmapRegionDecoder.class, + android.graphics.Camera.class, + android.graphics.Canvas.class, + android.graphics.CanvasProperty.class, + android.graphics.ColorFilter.class, + android.graphics.DrawFilter.class, + android.graphics.FontFamily.class, + android.graphics.Gainmap.class, + android.graphics.ImageDecoder.class, + android.graphics.MaskFilter.class, + android.graphics.NinePatch.class, + android.graphics.Paint.class, + android.graphics.PathEffect.class, + android.graphics.PathIterator.class, + android.graphics.PathMeasure.class, + android.graphics.Picture.class, + android.graphics.RecordingCanvas.class, + android.graphics.Region.class, + android.graphics.RenderNode.class, + android.graphics.Shader.class, + android.graphics.RenderEffect.class, + android.graphics.Typeface.class, + android.graphics.YuvImage.class, + android.graphics.fonts.Font.class, + android.graphics.fonts.FontFamily.class, + android.graphics.text.LineBreaker.class, + android.graphics.text.MeasuredText.class, + android.graphics.text.TextRunShaper.class, + android.graphics.text.GraphemeBreak.class, + android.util.PathParser.class, }; /** * Extra strings needed to pass to register_android_graphics_classes(). * - * `android.graphics.Graphics` is not actually a class, so we just hardcode it here. + * Several entries are not actually a class, so we just hardcode them here. */ public final static String[] GRAPHICS_EXTRA_INIT_PARAMS = new String[] { - "android.graphics.Graphics" + "android.graphics.Graphics", + "android.graphics.ByteBufferStreamAdaptor", + "android.graphics.CreateJavaOutputStreamAdaptor" }; private RavenwoodNativeLoader() { diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java index 70bc52bdaa12..705186edba00 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java @@ -81,12 +81,15 @@ public final class RavenwoodRunnerState { RavenwoodRuntimeEnvironmentController.exitTestClass(); } + /** Called when a test method is about to start */ public void enterTestMethod(Description description) { mMethodDescription = description; - RavenwoodRuntimeEnvironmentController.initForMethod(); + RavenwoodRuntimeEnvironmentController.enterTestMethod(description); } - public void exitTestMethod() { + /** Called when a test method finishes */ + public void exitTestMethod(Description description) { + RavenwoodRuntimeEnvironmentController.exitTestMethod(description); mMethodDescription = null; } diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java index ae88bb234e9d..33c4e86d885d 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java @@ -43,6 +43,7 @@ import android.app.UiAutomation; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.res.Resources; +import android.graphics.Typeface; import android.icu.util.ULocale; import android.os.Binder; import android.os.Build; @@ -50,6 +51,7 @@ import android.os.Build.VERSION_CODES; import android.os.Bundle; import android.os.HandlerThread; import android.os.Looper; +import android.os.Message; import android.os.Process_ravenwood; import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; @@ -73,6 +75,7 @@ import com.android.ravenwood.common.SneakyThrow; import com.android.server.LocalServices; import com.android.server.compat.PlatformCompat; +import org.junit.AssumptionViolatedException; import org.junit.internal.management.ManagementFactory; import org.junit.runner.Description; @@ -80,6 +83,7 @@ import java.io.File; import java.io.IOException; import java.io.PrintStream; import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.Locale; import java.util.Map; @@ -92,6 +96,7 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Supplier; +import java.util.stream.Collectors; /** * Responsible for initializing and the environment. @@ -106,32 +111,60 @@ public class RavenwoodRuntimeEnvironmentController { @SuppressWarnings("UnusedVariable") private static final PrintStream sStdErr = System.err; - private static final String MAIN_THREAD_NAME = "RavenwoodMain"; + private static final String MAIN_THREAD_NAME = "Ravenwood:Main"; + private static final String TESTS_THREAD_NAME = "Ravenwood:Test"; + private static final String LIBRAVENWOOD_INITIALIZER_NAME = "ravenwood_initializer"; private static final String RAVENWOOD_NATIVE_RUNTIME_NAME = "ravenwood_runtime"; 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. + * + * Note, this timeout will _not_ stop the test, as there isn't really a clean way to do it. + * It'll merely print stacktraces. */ private static final boolean ENABLE_TIMEOUT_STACKS = - "1".equals(System.getenv("RAVENWOOD_ENABLE_TIMEOUT_STACKS")); + !"0".equals(System.getenv("RAVENWOOD_ENABLE_TIMEOUT_STACKS")); + + private static final boolean TOLERATE_LOOPER_ASSERTS = + !"0".equals(System.getenv("RAVENWOOD_TOLERATE_LOOPER_ASSERTS")); + + static final int DEFAULT_TIMEOUT_SECONDS = 10; + private static final int TIMEOUT_MILLIS = getTimeoutSeconds() * 1000; + + static int getTimeoutSeconds() { + var e = System.getenv("RAVENWOOD_TIMEOUT_SECONDS"); + if (e == null || e.isEmpty()) { + return DEFAULT_TIMEOUT_SECONDS; + } + return Integer.parseInt(e); + } - private static final int TIMEOUT_MILLIS = 9_000; private static final ScheduledExecutorService sTimeoutExecutor = - Executors.newScheduledThreadPool(1); + Executors.newScheduledThreadPool(1, (Runnable r) -> { + Thread t = Executors.defaultThreadFactory().newThread(r); + t.setName("Ravenwood:TimeoutMonitor"); + t.setDaemon(true); + return t; + }); - private static ScheduledFuture<?> sPendingTimeout; + private static volatile ScheduledFuture<?> sPendingTimeout; /** * When enabled, attempt to detect uncaught exceptions from background threads. */ private static final boolean ENABLE_UNCAUGHT_EXCEPTION_DETECTION = - "1".equals(System.getenv("RAVENWOOD_ENABLE_UNCAUGHT_EXCEPTION_DETECTION")); + !"0".equals(System.getenv("RAVENWOOD_ENABLE_UNCAUGHT_EXCEPTION_DETECTION")); + + private static final boolean DIE_ON_UNCAUGHT_EXCEPTION = true; /** * When set, an unhandled exception was discovered (typically on a background thread), and we @@ -140,12 +173,6 @@ public class RavenwoodRuntimeEnvironmentController { private static final AtomicReference<Throwable> sPendingUncaughtException = new AtomicReference<>(); - private static final Thread.UncaughtExceptionHandler sUncaughtExceptionHandler = - (thread, throwable) -> { - // Remember the first exception we discover - sPendingUncaughtException.compareAndSet(null, throwable); - }; - // TODO: expose packCallingIdentity function in libbinder and use it directly // See: packCallingIdentity in frameworks/native/libs/binder/IPCThreadState.cpp private static long packBinderIdentityToken( @@ -186,6 +213,8 @@ public class RavenwoodRuntimeEnvironmentController { * Initialize the global environment. */ public static void globalInitOnce() { + sTestThread = Thread.currentThread(); + Thread.currentThread().setName(TESTS_THREAD_NAME); synchronized (sInitializationLock) { if (!sInitialized) { // globalInitOnce() is called from class initializer, which cause @@ -193,6 +222,7 @@ public class RavenwoodRuntimeEnvironmentController { sInitialized = true; // This is the first call. + final long start = System.currentTimeMillis(); try { globalInitInner(); } catch (Throwable th) { @@ -201,6 +231,9 @@ public class RavenwoodRuntimeEnvironmentController { sExceptionFromGlobalInit = th; SneakyThrow.sneakyThrow(th); } + final long end = System.currentTimeMillis(); + // TODO Show user/system time too + Log.e(TAG, "globalInit() took " + (end - start) + "ms"); } else { // Subsequent calls. If the first call threw, just throw the same error, to prevent // the test from running. @@ -219,7 +252,8 @@ public class RavenwoodRuntimeEnvironmentController { RavenwoodCommonUtils.log(TAG, "globalInitInner()"); if (ENABLE_UNCAUGHT_EXCEPTION_DETECTION) { - Thread.setDefaultUncaughtExceptionHandler(sUncaughtExceptionHandler); + Thread.setDefaultUncaughtExceptionHandler( + RavenwoodRuntimeEnvironmentController::reportUncaughtExceptions); } // Some process-wide initialization: @@ -246,6 +280,13 @@ public class RavenwoodRuntimeEnvironmentController { // Do the basic set up for the android sysprops. RavenwoodSystemProperties.initialize(); + // Set ICU data file + String icuData = RavenwoodCommonUtils.getRavenwoodRuntimePath() + + "ravenwood-data/" + + RavenwoodRuntimeNative.getIcuDataName() + + ".dat"; + RavenwoodRuntimeNative.setSystemProperty("ro.icu.data.path", icuData); + // Enable all log levels for native logging, until we'll have a way to change the native // side log level at runtime. // Do this after loading RAVENWOOD_NATIVE_RUNTIME_NAME (which backs Os.setenv()), @@ -268,6 +309,12 @@ public class RavenwoodRuntimeEnvironmentController { Objects.requireNonNull(Build.TYPE); Objects.requireNonNull(Build.VERSION.SDK); + // Fonts can only be initialized once + // AOSP only: typeface is not supported on AOSP. + // Typeface.init(); + // Typeface.loadPreinstalledSystemFontMap(); + // Typeface.loadNativeSystemFonts(); + System.setProperty(RAVENWOOD_VERSION_JAVA_SYSPROP, "1"); // This will let AndroidJUnit4 use the original runner. System.setProperty("android.junit.runner", @@ -291,6 +338,7 @@ public class RavenwoodRuntimeEnvironmentController { ActivityManager.init$ravenwood(SYSTEM.getIdentifier()); final var main = new HandlerThread(MAIN_THREAD_NAME); + sMainThread = main; main.start(); Looper.setMainLooperForTest(main.getLooper()); @@ -337,9 +385,20 @@ public class RavenwoodRuntimeEnvironmentController { var systemServerContext = new RavenwoodContext(ANDROID_PACKAGE_NAME, main, systemResourcesLoader); - sInstrumentation = new Instrumentation(); - sInstrumentation.basicInit(instContext, targetContext, null); - InstrumentationRegistry.registerInstance(sInstrumentation, Bundle.EMPTY); + var instArgs = Bundle.EMPTY; + RavenwoodUtils.runOnMainThreadSync(() -> { + try { + // TODO We should get the instrumentation class name from the build file or + // somewhere. + var InstClass = Class.forName("android.app.Instrumentation"); + sInstrumentation = (Instrumentation) InstClass.getConstructor().newInstance(); + sInstrumentation.basicInit(instContext, targetContext, null); + sInstrumentation.onCreate(instArgs); + } catch (Exception e) { + SneakyThrow.sneakyThrow(e); + } + }); + InstrumentationRegistry.registerInstance(sInstrumentation, instArgs); RavenwoodSystemServer.init(systemServerContext); @@ -386,22 +445,46 @@ public class RavenwoodRuntimeEnvironmentController { SystemProperties.clearChangeCallbacksForTest(); - if (ENABLE_TIMEOUT_STACKS) { - sPendingTimeout = sTimeoutExecutor.schedule( - RavenwoodRuntimeEnvironmentController::dumpStacks, - TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); - } - if (ENABLE_UNCAUGHT_EXCEPTION_DETECTION) { - maybeThrowPendingUncaughtException(false); - } + maybeThrowPendingUncaughtException(); } /** - * Partially reset and initialize before each test method invocation + * Called when a test method is about to be started. */ - public static void initForMethod() { + public static void enterTestMethod(Description description) { // TODO(b/375272444): this is a hacky workaround to ensure binder identity Binder.restoreCallingIdentity(sCallingIdentity); + + scheduleTimeout(); + } + + /** + * Called when a test method finished. + */ + public static void exitTestMethod(Description description) { + cancelTimeout(); + maybeThrowPendingUncaughtException(); + } + + private static void scheduleTimeout() { + if (!ENABLE_TIMEOUT_STACKS) { + return; + } + cancelTimeout(); + + sPendingTimeout = sTimeoutExecutor.schedule( + RavenwoodRuntimeEnvironmentController::onTestTimedOut, + TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); + } + + private static void cancelTimeout() { + if (!ENABLE_TIMEOUT_STACKS) { + return; + } + var pt = sPendingTimeout; + if (pt != null) { + pt.cancel(false); + } } private static void initializeCompatIds() { @@ -460,15 +543,36 @@ public class RavenwoodRuntimeEnvironmentController { } /** + * Return if an exception is benign and okay to continue running the main looper even + * if we detect it. + */ + private static boolean isThrowableBenign(Throwable th) { + return th instanceof AssertionError || th instanceof AssumptionViolatedException; + } + + static void dispatchMessage(Message msg) { + try { + msg.getTarget().dispatchMessage(msg); + } catch (Throwable th) { + var desc = String.format("Detected %s on looper thread %s", th.getClass().getName(), + Thread.currentThread()); + sStdErr.println(desc); + if (TOLERATE_LOOPER_ASSERTS && isThrowableBenign(th)) { + sStdErr.printf("*** Continuing the test because it's %s ***\n", + th.getClass().getSimpleName()); + var e = new Exception(desc, th); + sPendingUncaughtException.compareAndSet(null, e); + return; + } + throw th; + } + } + + /** * A callback when a test class finishes its execution, mostly only for debugging. */ public static void exitTestClass() { - if (ENABLE_TIMEOUT_STACKS) { - sPendingTimeout.cancel(false); - } - if (ENABLE_UNCAUGHT_EXCEPTION_DETECTION) { - maybeThrowPendingUncaughtException(true); - } + maybeThrowPendingUncaughtException(); } public static void logTestRunner(String label, Description description) { @@ -478,35 +582,70 @@ public class RavenwoodRuntimeEnvironmentController { + "(" + description.getTestClass().getName() + ")"); } - private static void dumpStacks() { - final PrintStream out = System.err; - out.println("-----BEGIN ALL THREAD STACKS-----"); - final Map<Thread, StackTraceElement[]> stacks = Thread.getAllStackTraces(); - for (Map.Entry<Thread, StackTraceElement[]> stack : stacks.entrySet()) { - out.println(); - Thread t = stack.getKey(); - out.println(t.toString() + " ID=" + t.getId()); - for (StackTraceElement e : stack.getValue()) { - out.println("\tat " + e); - } + private static void maybeThrowPendingUncaughtException() { + final Throwable pending = sPendingUncaughtException.getAndSet(null); + if (pending != null) { + throw new IllegalStateException("Found an uncaught exception", pending); } - out.println("-----END ALL THREAD STACKS-----"); } /** - * If there's a pending uncaught exception, consume and throw it now. Typically used to - * report an exception on a background thread as a failure for the currently running test. + * Prints the stack trace from all threads. */ - private static void maybeThrowPendingUncaughtException(boolean duringReset) { - final Throwable pending = sPendingUncaughtException.getAndSet(null); - if (pending != null) { - if (duringReset) { - throw new IllegalStateException( - "Found an uncaught exception during this test", pending); - } else { - throw new IllegalStateException( - "Found an uncaught exception before this test started", pending); + private static void onTestTimedOut() { + sStdErr.println("********* SLOW TEST DETECTED ********"); + dumpStacks(null, null); + } + + private static final Object sDumpStackLock = new Object(); + + /** + * Prints the stack trace from all threads. + */ + private static void dumpStacks( + @Nullable Thread exceptionThread, @Nullable Throwable throwable) { + cancelTimeout(); + synchronized (sDumpStackLock) { + final PrintStream out = sStdErr; + out.println("-----BEGIN ALL THREAD STACKS-----"); + + var stacks = Thread.getAllStackTraces(); + var threads = stacks.keySet().stream().sorted( + Comparator.comparingLong(Thread::getId)).collect(Collectors.toList()); + + // Put the test and the main thread at the top. + var testThread = sTestThread; + var mainThread = sMainThread; + if (mainThread != null) { + threads.remove(mainThread); + threads.add(0, mainThread); } + if (testThread != null) { + threads.remove(testThread); + threads.add(0, testThread); + } + // Put the exception thread at the top. + // Also inject the stacktrace from the exception. + if (exceptionThread != null) { + threads.remove(exceptionThread); + threads.add(0, exceptionThread); + stacks.put(exceptionThread, throwable.getStackTrace()); + } + for (var th : threads) { + out.println(); + + out.print("Thread"); + if (th == exceptionThread) { + out.print(" [** EXCEPTION THREAD **]"); + } + out.print(": " + th.getName() + " / " + th); + out.println(); + + for (StackTraceElement e : stacks.get(th)) { + out.println("\tat " + e); + } + } + out.println("-----END ALL THREAD STACKS-----"); } } @@ -532,13 +671,17 @@ public class RavenwoodRuntimeEnvironmentController { () -> Class.forName("org.mockito.Matchers")); } - // TODO: use the real UiAutomation class instead of a mock - private static UiAutomation createMockUiAutomation() { - sAdoptedPermissions = Collections.emptySet(); - var mock = mock(UiAutomation.class, inv -> { + static <T> T makeDefaultThrowMock(Class<T> clazz) { + return mock(clazz, inv -> { HostTestUtils.onThrowMethodCalled(); return null; }); + } + + // TODO: use the real UiAutomation class instead of a mock + private static UiAutomation createMockUiAutomation() { + sAdoptedPermissions = Collections.emptySet(); + var mock = makeDefaultThrowMock(UiAutomation.class); doAnswer(inv -> { sAdoptedPermissions = UiAutomation.ALL_PERMISSIONS; return null; @@ -573,6 +716,23 @@ public class RavenwoodRuntimeEnvironmentController { } } + private static void reportUncaughtExceptions(Thread th, Throwable e) { + sStdErr.printf("Uncaught exception detected: %s: %s\n", + th, RavenwoodCommonUtils.getStackTraceString(e)); + + doBugreport(th, e, DIE_ON_UNCAUGHT_EXCEPTION); + } + + private static void doBugreport( + @Nullable Thread exceptionThread, @Nullable Throwable throwable, + boolean killSelf) { + // TODO: Print more information + dumpStacks(exceptionThread, throwable); + if (killSelf) { + System.exit(13); + } + } + private static void dumpJavaProperties() { Log.v(TAG, "JVM properties:"); dumpMap(System.getProperties()); @@ -588,7 +748,6 @@ public class RavenwoodRuntimeEnvironmentController { Log.v(TAG, " " + key + "=" + map.get(key)); } } - private static void dumpOtherInfo() { Log.v(TAG, "Other key information:"); var jloc = Locale.getDefault(); diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java index 70c161c1f19a..819d93a9c336 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java @@ -26,6 +26,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; @@ -45,6 +46,9 @@ public class RavenwoodSystemProperties { /** The default values. */ static final Map<String, String> sDefaultValues = new HashMap<>(); + static final Set<String> sReadableKeys = new HashSet<>(); + static final Set<String> sWritableKeys = new HashSet<>(); + private static final String[] PARTITIONS = { "bootimage", "odm", @@ -88,9 +92,24 @@ public class RavenwoodSystemProperties { ravenwoodProps.forEach((key, origValue) -> { final String value; - // If a value starts with "$$$", then this is a reference to the device-side value. if (origValue.startsWith("$$$")) { + // If a value starts with "$$$", then: + // - If it's "$$$r", the key is allowed to read. + // - If it's "$$$w", the key is allowed to write. + // - Otherwise, it's a reference to the device-side value. + // In case of $$$r and $$$w, if the key ends with a '.', then it'll be treaded + // as a prefix match. var deviceKey = origValue.substring(3); + if ("r".equals(deviceKey)) { + sReadableKeys.add(key); + Log.v(TAG, key + " (readable)"); + return; + } else if ("w".equals(deviceKey)) { + sWritableKeys.add(key); + Log.v(TAG, key + " (writable)"); + return; + } + var deviceValue = deviceProps.get(deviceKey); if (deviceValue == null) { throw new RuntimeException("Failed to initialize system properties. Key '" @@ -131,50 +150,38 @@ public class RavenwoodSystemProperties { sDefaultValues.forEach(RavenwoodRuntimeNative::setSystemProperty); } - private static boolean isKeyReadable(String key) { - // All writable keys are also readable - if (isKeyWritable(key)) return true; + private static boolean checkAllowedInner(String key, Set<String> allowed) { + if (allowed.contains(key)) { + return true; + } - final String root = getKeyRoot(key); + // Also search for a prefix match. + for (var k : allowed) { + if (k.endsWith(".") && key.startsWith(k)) { + return true; + } + } + return false; + } - // This set is carefully curated to help identify situations where a test may - // accidentally depend on a default value of an obscure property whose owner hasn't - // decided how Ravenwood should behave. - if (root.startsWith("boot.")) return true; - if (root.startsWith("build.")) return true; - if (root.startsWith("product.")) return true; - if (root.startsWith("soc.")) return true; - if (root.startsWith("system.")) return true; + private static boolean checkAllowed(String key, Set<String> allowed) { + return checkAllowedInner(key, allowed) || checkAllowedInner(getKeyRoot(key), allowed); + } + private static boolean isKeyReadable(String key) { // All core values should be readable - if (sDefaultValues.containsKey(key)) return true; - - // Hardcoded allowlist - return switch (key) { - case "gsm.version.baseband", - "no.such.thing", - "qemu.sf.lcd_density", - "ro.bootloader", - "ro.hardware", - "ro.hw_timeout_multiplier", - "ro.odm.build.media_performance_class", - "ro.sf.lcd_density", - "ro.treble.enabled", - "ro.vndk.version", - "ro.icu.data.path" -> true; - default -> false; - }; + if (sDefaultValues.containsKey(key)) { + return true; + } + if (checkAllowed(key, sReadableKeys)) { + return true; + } + // All writable keys are also readable + return isKeyWritable(key); } private static boolean isKeyWritable(String key) { - final String root = getKeyRoot(key); - - if (root.startsWith("debug.")) return true; - - // For PropertyInvalidatedCache - if (root.startsWith("cache_key.")) return true; - - return false; + return checkAllowed(key, sWritableKeys); } static boolean isKeyAccessible(String key, boolean write) { diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodUtils.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodUtils.java index 19c1bffaebcd..3e2c4051b792 100644 --- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodUtils.java +++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodUtils.java @@ -15,7 +15,20 @@ */ package android.platform.test.ravenwood; +import static com.android.ravenwood.common.RavenwoodCommonUtils.ReflectedMethod.reflectMethod; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.Handler; +import android.os.Looper; + import com.android.ravenwood.common.RavenwoodCommonUtils; +import com.android.ravenwood.common.SneakyThrow; + +import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Supplier; /** * Utilities for writing (bivalent) ravenwood tests. @@ -47,4 +60,129 @@ public class RavenwoodUtils { public static void loadJniLibrary(String libname) { RavenwoodCommonUtils.loadJniLibrary(libname); } + + private class MainHandlerHolder { + static Handler sMainHandler = new Handler(Looper.getMainLooper()); + } + + /** + * Returns the main thread handler. + */ + public static Handler getMainHandler() { + return MainHandlerHolder.sMainHandler; + } + + /** + * Run a Callable on Handler and wait for it to complete. + */ + @Nullable + public static <T> T runOnHandlerSync(@NonNull Handler h, @NonNull Callable<T> c) { + var result = new AtomicReference<T>(); + var thrown = new AtomicReference<Throwable>(); + var latch = new CountDownLatch(1); + h.post(() -> { + try { + result.set(c.call()); + } catch (Throwable th) { + thrown.set(th); + } + latch.countDown(); + }); + try { + latch.await(); + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted while waiting on the Runnable", e); + } + var th = thrown.get(); + if (th != null) { + SneakyThrow.sneakyThrow(th); + } + return result.get(); + } + + + /** + * Run a Runnable on Handler and wait for it to complete. + */ + @Nullable + public static void runOnHandlerSync(@NonNull Handler h, @NonNull Runnable r) { + runOnHandlerSync(h, () -> { + r.run(); + return null; + }); + } + + /** + * Run a Callable on main thread and wait for it to complete. + */ + @Nullable + public static <T> T runOnMainThreadSync(@NonNull Callable<T> c) { + return runOnHandlerSync(getMainHandler(), c); + } + + /** + * Run a Runnable on main thread and wait for it to complete. + */ + @Nullable + public static void runOnMainThreadSync(@NonNull Runnable r) { + runOnHandlerSync(getMainHandler(), r); + } + + public static class MockitoHelper { + private MockitoHelper() { + } + + /** + * Allow verifyZeroInteractions to work on ravenwood. It was replaced with a different + * method on. (Maybe we should do it in Ravenizer.) + */ + public static void verifyZeroInteractions(Object... mocks) { + if (RavenwoodRule.isOnRavenwood()) { + // Mockito 4 or later + reflectMethod("org.mockito.Mockito", "verifyNoInteractions", Object[].class) + .callStatic(new Object[]{mocks}); + } else { + // Mockito 2 + reflectMethod("org.mockito.Mockito", "verifyZeroInteractions", Object[].class) + .callStatic(new Object[]{mocks}); + } + } + } + + + /** + * Wrap the given {@link Supplier} to become memoized. + * + * The underlying {@link Supplier} will only be invoked once, and that result will be cached + * and returned for any future requests. + */ + static <T> Supplier<T> memoize(ThrowingSupplier<T> supplier) { + return new Supplier<>() { + private T mInstance; + + @Override + public T get() { + synchronized (this) { + if (mInstance == null) { + mInstance = create(); + } + return mInstance; + } + } + + private T create() { + try { + return supplier.get(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + }; + } + + /** Used by {@link #memoize(ThrowingSupplier)} */ + public interface ThrowingSupplier<T> { + /** */ + T get() throws Exception; + } } diff --git a/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java b/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java index a967a3fff0d7..893b354d4645 100644 --- a/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java +++ b/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java @@ -26,10 +26,12 @@ import java.io.FileInputStream; import java.io.PrintStream; import java.io.PrintWriter; import java.io.StringWriter; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; +import java.util.Objects; import java.util.function.Supplier; public class RavenwoodCommonUtils { @@ -329,4 +331,70 @@ public class RavenwoodCommonUtils { public static <T> T withDefault(@Nullable T value, @Nullable T def) { return value != null ? value : def; } + + /** + * Utility for calling a method with reflections. Used to call a method by name. + * Note, this intentionally does _not_ support non-public methods, as we generally + * shouldn't violate java visibility in ravenwood. + * + * @param <TTHIS> class owning the method. + */ + public static class ReflectedMethod<TTHIS> { + private final Class<TTHIS> mThisClass; + private final Method mMethod; + + private ReflectedMethod(Class<TTHIS> thisClass, Method method) { + mThisClass = thisClass; + mMethod = method; + } + + /** Factory method. */ + @SuppressWarnings("unchecked") + public static <TTHIS> ReflectedMethod<TTHIS> reflectMethod( + @NonNull Class<TTHIS> clazz, @NonNull String methodName, + @NonNull Class<?>... argTypes) { + try { + return new ReflectedMethod(clazz, clazz.getMethod(methodName, argTypes)); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + + /** Factory method. */ + @SuppressWarnings("unchecked") + public static <TTHIS> ReflectedMethod<TTHIS> reflectMethod( + @NonNull String className, @NonNull String methodName, + @NonNull Class<?>... argTypes) { + try { + return reflectMethod((Class<TTHIS>) Class.forName(className), methodName, argTypes); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + /** Call the instance method */ + @SuppressWarnings("unchecked") + public <RET> RET call(@NonNull TTHIS thisObject, @NonNull Object... args) { + try { + return (RET) mMethod.invoke(Objects.requireNonNull(thisObject), args); + } catch (InvocationTargetException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + /** Call the static method */ + @SuppressWarnings("unchecked") + public <RET> RET callStatic(@NonNull Object... args) { + try { + return (RET) mMethod.invoke(null, args); + } catch (InvocationTargetException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + } + + /** Handy method to create an array */ + public static <T> T[] arr(@NonNull T... objects) { + return objects; + } } diff --git a/ravenwood/runtime-helper-src/framework/android/util/Log_ravenwood.java b/ravenwood/runtime-helper-src/framework/android/util/Log_ravenwood.java index 7ab9cda378b7..855a4ff21671 100644 --- a/ravenwood/runtime-helper-src/framework/android/util/Log_ravenwood.java +++ b/ravenwood/runtime-helper-src/framework/android/util/Log_ravenwood.java @@ -21,7 +21,6 @@ import android.util.Log.Level; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.RuntimeInit; import com.android.ravenwood.RavenwoodRuntimeNative; -import com.android.ravenwood.common.RavenwoodCommonUtils; import java.io.PrintStream; import java.text.SimpleDateFormat; @@ -164,7 +163,7 @@ public class Log_ravenwood { * Return the "real" {@code System.out} if it's been swapped by {@code RavenwoodRuleImpl}, so * that we don't end up in a recursive loop. */ - private static PrintStream getRealOut() { + public static PrintStream getRealOut() { if (RuntimeInit.sOut$ravenwood != null) { return RuntimeInit.sOut$ravenwood; } else { diff --git a/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodJdkPatch.java b/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodJdkPatch.java index 96aed4b3401d..d5a96ddc3a98 100644 --- a/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodJdkPatch.java +++ b/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodJdkPatch.java @@ -20,6 +20,7 @@ import com.android.ravenwood.common.JvmWorkaround; import java.io.FileDescriptor; import java.util.LinkedHashMap; import java.util.Map; +import java.util.regex.Pattern; /** * Class to host APIs that exist in libcore, but not in standard JRE. @@ -46,4 +47,22 @@ public class RavenwoodJdkPatch { final var it = map.entrySet().iterator(); return it.hasNext() ? it.next() : null; } + + /** + * Implements Pattern.compile(String) + * + * ART always assumes UNICODE_CHARACTER_CLASS is set. + */ + public static Pattern compilePattern(String regex) { + return Pattern.compile(regex, Pattern.UNICODE_CHARACTER_CLASS); + } + + /** + * Implements Pattern.compile(String, int) + * + * ART always assumes UNICODE_CHARACTER_CLASS is set. + */ + public static Pattern compilePattern(String regex, int flag) { + return Pattern.compile(regex, flag | Pattern.UNICODE_CHARACTER_CLASS); + } } diff --git a/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodRuntimeNative.java b/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodRuntimeNative.java index acbcdf1926db..0d82a8691881 100644 --- a/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodRuntimeNative.java +++ b/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodRuntimeNative.java @@ -66,6 +66,8 @@ public class RavenwoodRuntimeNative { public static native int gettid(); + public static native String getIcuDataName(); + public static long lseek(FileDescriptor fd, long offset, int whence) throws ErrnoException { return nLseek(JvmWorkaround.getInstance().getFdInt(fd), offset, whence); } diff --git a/ravenwood/runtime-helper-src/libcore-fake/dalvik/system/CloseGuard.java b/ravenwood/runtime-helper-src/libcore-fake/dalvik/system/CloseGuard.java new file mode 100644 index 000000000000..82bab64f22f3 --- /dev/null +++ b/ravenwood/runtime-helper-src/libcore-fake/dalvik/system/CloseGuard.java @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2010 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 dalvik.system; + +/** + * A no-op copy of libcore/dalvik/src/main/java/dalvik/system/CloseGuard.java + */ +public final class CloseGuard { + + /** + * Returns a CloseGuard instance. {@code #open(String)} can be used to set + * up the instance to warn on failure to close. + * + * @return {@link CloseGuard} instance. + * + * @hide + */ + public static CloseGuard get() { + return new CloseGuard(); + } + + /** + * Enables/disables stack capture and tracking. A call stack is captured + * during open(), and open/close events are reported to the Tracker, only + * if enabled is true. If a stack trace was captured, the {@link + * #getReporter() reporter} is informed of unclosed resources; otherwise a + * one-line warning is logged. + * + * @param enabled whether stack capture and tracking is enabled. + * + * @hide + */ + public static void setEnabled(boolean enabled) { + } + + /** + * True if CloseGuard stack capture and tracking are enabled. + * + * @hide + */ + public static boolean isEnabled() { + return false; + } + + /** + * Used to replace default Reporter used to warn of CloseGuard + * violations when stack tracking is enabled. Must be non-null. + * + * @param rep replacement for default Reporter. + * + * @hide + */ + public static void setReporter(Reporter rep) { + if (rep == null) { + throw new NullPointerException("reporter == null"); + } + } + + /** + * Returns non-null CloseGuard.Reporter. + * + * @return CloseGuard's Reporter. + * + * @hide + */ + public static Reporter getReporter() { + return null; + } + + /** + * Sets the {@link Tracker} that is notified when resources are allocated and released. + * The Tracker is invoked only if CloseGuard {@link #isEnabled()} held when {@link #open()} + * was called. A null argument disables tracking. + * + * <p>This is only intended for use by {@code dalvik.system.CloseGuardSupport} class and so + * MUST NOT be used for any other purposes. + * + * @hide + */ + public static void setTracker(Tracker tracker) { + } + + /** + * Returns {@link #setTracker(Tracker) last Tracker that was set}, or null to indicate + * there is none. + * + * <p>This is only intended for use by {@code dalvik.system.CloseGuardSupport} class and so + * MUST NOT be used for any other purposes. + * + * @hide + */ + public static Tracker getTracker() { + return null; + } + + private CloseGuard() {} + + /** + * {@code open} initializes the instance with a warning that the caller + * should have explicitly called the {@code closer} method instead of + * relying on finalization. + * + * @param closer non-null name of explicit termination method. Printed by warnIfOpen. + * @throws NullPointerException if closer is null. + * + * @hide + */ + public void open(String closer) { + openWithCallSite(closer, null /* callsite */); + } + + /** + * Like {@link #open(String)}, but with explicit callsite string being passed in for better + * performance. + * <p> + * This only has better performance than {@link #open(String)} if {@link #isEnabled()} returns {@code true}, which + * usually shouldn't happen on release builds. + * + * @param closer Non-null name of explicit termination method. Printed by warnIfOpen. + * @param callsite Non-null string uniquely identifying the callsite. + * + * @hide + */ + public void openWithCallSite(String closer, String callsite) { + } + + // We keep either an allocation stack containing the closer String or, when + // in disabled state, just the closer String. + // We keep them in a single field only to minimize overhead. + private Object /* String or Throwable */ closerNameOrAllocationInfo; + + /** + * Marks this CloseGuard instance as closed to avoid warnings on + * finalization. + * + * @hide + */ + public void close() { + } + + /** + * Logs a warning if the caller did not properly cleanup by calling an + * explicit close method before finalization. If CloseGuard was enabled + * when the CloseGuard was created, passes the stacktrace associated with + * the allocation to the current reporter. If it was not enabled, it just + * directly logs a brief message. + * + * @hide + */ + public void warnIfOpen() { + } + + + /** + * Interface to allow customization of tracking behaviour. + * + * <p>This is only intended for use by {@code dalvik.system.CloseGuardSupport} class and so + * MUST NOT be used for any other purposes. + * + * @hide + */ + public interface Tracker { + void open(Throwable allocationSite); + void close(Throwable allocationSite); + } + + /** + * Interface to allow customization of reporting behavior. + * @hide + */ + public interface Reporter { + /** + * + * @hide + */ + void report(String message, Throwable allocationSite); + + /** + * + * @hide + */ + default void report(String message) {} + } +} diff --git a/ravenwood/runtime-helper-src/libcore-fake/dalvik/system/VMRuntime.java b/ravenwood/runtime-helper-src/libcore-fake/dalvik/system/VMRuntime.java index eaadac6a8b92..50cfd3bbe863 100644 --- a/ravenwood/runtime-helper-src/libcore-fake/dalvik/system/VMRuntime.java +++ b/ravenwood/runtime-helper-src/libcore-fake/dalvik/system/VMRuntime.java @@ -57,4 +57,12 @@ public class VMRuntime { public int getTargetSdkVersion() { return RavenwoodRuntimeState.sTargetSdkLevel; } + + /** Ignored on ravenwood. */ + public void registerNativeAllocation(long bytes) { + } + + /** Ignored on ravenwood. */ + public void registerNativeFree(long bytes) { + } } diff --git a/ravenwood/runtime-helper-src/libcore-fake/libcore/io/IoBridge.java b/ravenwood/runtime-helper-src/libcore-fake/libcore/io/IoBridge.java new file mode 100644 index 000000000000..2a1ee2542982 --- /dev/null +++ b/ravenwood/runtime-helper-src/libcore-fake/libcore/io/IoBridge.java @@ -0,0 +1,63 @@ +/* + * 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 libcore.io; + +import android.system.ErrnoException; +import android.system.Os; +import android.system.OsConstants; + +import java.io.FileDescriptor; +import java.io.FileNotFoundException; +import java.io.IOException; + +public class IoBridge { + + public static void closeAndSignalBlockedThreads(FileDescriptor fd) throws IOException { + if (fd == null) { + return; + } + try { + Os.close(fd); + } catch (ErrnoException errnoException) { + throw errnoException.rethrowAsIOException(); + } + } + + public static FileDescriptor open(String path, int flags) throws FileNotFoundException { + FileDescriptor fd = null; + try { + fd = Os.open(path, flags, 0666); + // Posix open(2) fails with EISDIR only if you ask for write permission. + // Java disallows reading directories too.f + if (OsConstants.S_ISDIR(Os.fstat(fd).st_mode)) { + throw new ErrnoException("open", OsConstants.EISDIR); + } + return fd; + } catch (ErrnoException errnoException) { + try { + if (fd != null) { + closeAndSignalBlockedThreads(fd); + } + } catch (IOException ignored) { + } + FileNotFoundException ex = new FileNotFoundException(path + ": " + + errnoException.getMessage()); + ex.initCause(errnoException); + throw ex; + } + } +} diff --git a/ravenwood/runtime-helper-src/libcore-fake/libcore/util/NativeAllocationRegistry.java b/ravenwood/runtime-helper-src/libcore-fake/libcore/util/NativeAllocationRegistry.java index ad86135de32e..985e00e8641d 100644 --- a/ravenwood/runtime-helper-src/libcore-fake/libcore/util/NativeAllocationRegistry.java +++ b/ravenwood/runtime-helper-src/libcore-fake/libcore/util/NativeAllocationRegistry.java @@ -35,6 +35,11 @@ public class NativeAllocationRegistry { return new NativeAllocationRegistry(classLoader, freeFunction, size); } + public static NativeAllocationRegistry createNonmalloced( + Class clazz, long freeFunction, long size) { + return new NativeAllocationRegistry(clazz.getClassLoader(), freeFunction, size); + } + public static NativeAllocationRegistry createMalloced( ClassLoader classLoader, long freeFunction, long size) { return new NativeAllocationRegistry(classLoader, freeFunction, size); @@ -45,6 +50,11 @@ public class NativeAllocationRegistry { return new NativeAllocationRegistry(classLoader, freeFunction, 0); } + public static NativeAllocationRegistry createMalloced( + Class clazz, long freeFunction, long size) { + return new NativeAllocationRegistry(clazz.getClassLoader(), freeFunction, size); + } + public NativeAllocationRegistry(ClassLoader classLoader, long freeFunction, long size) { if (size < 0) { throw new IllegalArgumentException("Invalid native allocation size: " + size); @@ -52,21 +62,67 @@ public class NativeAllocationRegistry { mFreeFunction = freeFunction; } + private class CleanerThunk implements Runnable { + private long nativePtr; + + public CleanerThunk() { + nativePtr = 0; + } + + public void setNativePtr(long ptr) { + nativePtr = ptr; + } + + @Override + public void run() { + if (nativePtr != 0) { + applyFreeFunction(mFreeFunction, nativePtr); + } + } + } + + private static class CleanableRunner implements Runnable { + private final Cleaner.Cleanable mCleanable; + + public CleanableRunner(Cleaner.Cleanable cleanable) { + mCleanable = cleanable; + } + + public void run() { + mCleanable.clean(); + } + } + public Runnable registerNativeAllocation(Object referent, long nativePtr) { if (referent == null) { throw new IllegalArgumentException("referent is null"); } + if (mFreeFunction == 0) { + return () -> {}; // do nothing + } if (nativePtr == 0) { throw new IllegalArgumentException("nativePtr is null"); } - final Runnable releaser = () -> { - RavenwoodRuntimeNative.applyFreeFunction(mFreeFunction, nativePtr); - }; - sCleaner.register(referent, releaser); + final CleanerThunk thunk; + final CleanableRunner result; + try { + thunk = new CleanerThunk(); + final var cleanable = sCleaner.register(referent, thunk); + result = new CleanableRunner(cleanable); + } catch (VirtualMachineError vme /* probably OutOfMemoryError */) { + applyFreeFunction(mFreeFunction, nativePtr); + throw vme; + } + // Enable the cleaner only after we can no longer throw anything, including OOME. + thunk.setNativePtr(nativePtr); // Ensure that cleaner doesn't get invoked before we enable it. Reference.reachabilityFence(referent); - return releaser; + return result; + } + + public static void applyFreeFunction(long freeFunction, long nativePtr) { + RavenwoodRuntimeNative.applyFreeFunction(freeFunction, nativePtr); } } diff --git a/ravenwood/runtime-jni/ravenwood_runtime.cpp b/ravenwood/runtime-jni/ravenwood_runtime.cpp index 8d8ed7119e84..01ebdc953539 100644 --- a/ravenwood/runtime-jni/ravenwood_runtime.cpp +++ b/ravenwood/runtime-jni/ravenwood_runtime.cpp @@ -20,6 +20,7 @@ #include <sys/syscall.h> #include <unistd.h> #include <utils/misc.h> +#include <unicode/utypes.h> #include <string> @@ -183,6 +184,10 @@ static jint Linux_gettid(JNIEnv* env, jobject) { return syscall(__NR_gettid); } +static jstring getIcuDataName(JNIEnv* env, jclass clazz) { + return env->NewStringUTF(U_ICUDATA_NAME); +} + // ---- Registration ---- extern void register_android_system_OsConstants(JNIEnv* env); @@ -201,6 +206,7 @@ static const JNINativeMethod sMethods[] = { "setenv", "(Ljava/lang/String;Ljava/lang/String;Z)V", (void*)Linux_setenv }, { "getpid", "()I", (void*)Linux_getpid }, { "gettid", "()I", (void*)Linux_gettid }, + { "getIcuDataName", "()Ljava/lang/String;", (void*)getIcuDataName }, }; extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) { diff --git a/ravenwood/scripts/add-annotations.sh b/ravenwood/scripts/add-annotations.sh index 3e86037d7c7b..8c394f51d8c4 100755 --- a/ravenwood/scripts/add-annotations.sh +++ b/ravenwood/scripts/add-annotations.sh @@ -35,7 +35,7 @@ set -e # We add this line to each methods found. # Note, if we used a single @, that'd be handled as an at file. Use # the double-at instead. -annotation="@@android.platform.test.annotations.DisabledOnRavenwood" +annotation="@@android.platform.test.annotations.DisabledOnRavenwood(reason = \"bulk-disabled by script\")" while getopts "t:" opt; do case "$opt" in t) diff --git a/ravenwood/tests/coretest/Android.bp b/ravenwood/tests/coretest/Android.bp index 9dd7cc683719..182a7cf3d3de 100644 --- a/ravenwood/tests/coretest/Android.bp +++ b/ravenwood/tests/coretest/Android.bp @@ -33,3 +33,34 @@ android_ravenwood_test { }, auto_gen_config: true, } + +// Same as RavenwoodCoreTest, but it excludes tests using platform-parametric-runner-lib, +// because that modules has too many dependencies and slow to build incrementally. +android_ravenwood_test { + name: "RavenwoodCoreTest-light", + + static_libs: [ + "androidx.annotation_annotation", + "androidx.test.ext.junit", + "androidx.test.rules", + + // This library should be removed by Ravenizer + "mockito-target-minus-junit4", + ], + libs: [ + // We access internal private classes + "ravenwood-junit-impl", + ], + srcs: [ + "test/**/*.java", + "test/**/*.kt", + ], + + exclude_srcs: [ + "test/com/android/ravenwoodtest/runnercallbacktests/*", + ], + ravenizer: { + strip_mockito: true, + }, + auto_gen_config: true, +} diff --git a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodMainThreadTest.java b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodMainThreadTest.java new file mode 100644 index 000000000000..68387d76b675 --- /dev/null +++ b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodMainThreadTest.java @@ -0,0 +1,82 @@ +/* + * 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 com.android.ravenwoodtest.coretest; + +import static com.google.common.truth.Truth.assertThat; + +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; + +import android.platform.test.ravenwood.RavenwoodUtils; + +import org.junit.Test; + +import java.util.concurrent.atomic.AtomicReference; + +public class RavenwoodMainThreadTest { + private static final boolean RUN_UNSAFE_TESTS = + "1".equals(System.getenv("RAVENWOOD_RUN_UNSAFE_TESTS")); + + @Test + public void testRunOnMainThread() { + AtomicReference<Thread> thr = new AtomicReference<>(); + RavenwoodUtils.runOnMainThreadSync(() -> { + thr.set(Thread.currentThread()); + }); + var th = thr.get(); + assertThat(th).isNotNull(); + assertThat(th).isNotEqualTo(Thread.currentThread()); + } + + /** + * Sleep a long time on the main thread. This test would then "pass", but Ravenwood + * should show the stack traces. + * + * This is "unsafe" because this test is slow. + */ + @Test + public void testUnsafeMainThreadHang() { + assumeTrue(RUN_UNSAFE_TESTS); + + // The test should time out. + RavenwoodUtils.runOnMainThreadSync(() -> { + try { + Thread.sleep(30_000); + } catch (InterruptedException e) { + fail("Interrupted"); + } + }); + } + + /** + * AssertionError on the main thread would be swallowed and reported "normally". + * (Other kinds of exceptions would be caught by the unhandled exception handler, and kills + * the process) + * + * This is "unsafe" only because this feature can be disabled via the env var. + */ + @Test + public void testUnsafeAssertFailureOnMainThread() { + assumeTrue(RUN_UNSAFE_TESTS); + + assertThrows(AssertionError.class, () -> { + RavenwoodUtils.runOnMainThreadSync(() -> { + fail(); + }); + }); + } +} diff --git a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodReflectorTest.java b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodReflectorTest.java new file mode 100644 index 000000000000..421fb50e0c9a --- /dev/null +++ b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodReflectorTest.java @@ -0,0 +1,63 @@ +/* + * 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 com.android.ravenwoodtest.coretest; + +import static com.google.common.truth.Truth.assertThat; + +import com.android.ravenwood.common.RavenwoodCommonUtils.ReflectedMethod; + +import org.junit.Test; + +/** + * Tests for {@link ReflectedMethod}. + */ +public class RavenwoodReflectorTest { + /** test target */ + public class Target { + private final int mVar; + + /** test target */ + public Target(int var) { + mVar = var; + } + + /** test target */ + public int foo(int x) { + return x + mVar; + } + + /** test target */ + public static int bar(int x) { + return x + 1; + } + } + + /** Test for a non-static method call */ + @Test + public void testNonStatic() { + var obj = new Target(5); + + var m = ReflectedMethod.reflectMethod(Target.class, "foo", int.class); + assertThat((int) m.call(obj, 2)).isEqualTo(7); + } + + /** Test for a static method call */ + @Test + public void testStatic() { + var m = ReflectedMethod.reflectMethod(Target.class, "bar", int.class); + assertThat((int) m.callStatic(1)).isEqualTo(2); + } +} diff --git a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodSystemPropertiesTest.java b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodSystemPropertiesTest.java new file mode 100644 index 000000000000..454f5a9576d9 --- /dev/null +++ b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodSystemPropertiesTest.java @@ -0,0 +1,65 @@ +/* + * 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 com.android.ravenwoodtest.coretest; + +import static com.google.common.truth.Truth.assertThat; + +import static org.junit.Assert.fail; + +import android.os.SystemProperties; + +import org.junit.Test; + +public class RavenwoodSystemPropertiesTest { + @Test + public void testRead() { + assertThat(SystemProperties.get("ro.board.first_api_level")).isEqualTo("1"); + } + + @Test + public void testWrite() { + SystemProperties.set("debug.xxx", "5"); + assertThat(SystemProperties.get("debug.xxx")).isEqualTo("5"); + } + + private static void assertException(String expectedMessage, Runnable r) { + try { + r.run(); + fail("Excepted exception with message '" + expectedMessage + "' but wasn't thrown"); + } catch (RuntimeException e) { + if (e.getMessage().contains(expectedMessage)) { + return; + } + fail("Excepted exception with message '" + expectedMessage + "' but was '" + + e.getMessage() + "'"); + } + } + + + @Test + public void testReadDisallowed() { + assertException("Read access to system property 'nonexisitent' denied", () -> { + SystemProperties.get("nonexisitent"); + }); + } + + @Test + public void testWriteDisallowed() { + assertException("failed to set system property \"ro.board.first_api_level\" ", () -> { + SystemProperties.set("ro.board.first_api_level", "2"); + }); + } +} diff --git a/ravenwood/tests/minimum-test/test/com/android/ravenwoodtest/RavenwoodMinimumTest.java b/ravenwood/tests/minimum-test/test/com/android/ravenwoodtest/RavenwoodMinimumTest.java index 30abaa2e7d38..b1a40f082656 100644 --- a/ravenwood/tests/minimum-test/test/com/android/ravenwoodtest/RavenwoodMinimumTest.java +++ b/ravenwood/tests/minimum-test/test/com/android/ravenwoodtest/RavenwoodMinimumTest.java @@ -16,28 +16,27 @@ package com.android.ravenwoodtest; import android.platform.test.annotations.IgnoreUnderRavenwood; -import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.ext.junit.runners.AndroidJUnit4; import org.junit.Assert; -import org.junit.Rule; +import org.junit.Assume; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) public class RavenwoodMinimumTest { - @Rule - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProcessApp() - .build(); - @Test public void testSimple() { Assert.assertTrue(android.os.Process.isApplicationUid(android.os.Process.myUid())); } @Test + public void testAssumeNot() { + Assume.assumeFalse(android.os.Process.isApplicationUid(android.os.Process.myUid())); + } + + @Test @IgnoreUnderRavenwood public void testIgnored() { throw new RuntimeException("Shouldn't be executed under ravenwood"); diff --git a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt index c196a09e18d1..7462cc2f384a 100644 --- a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt +++ b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt @@ -30,6 +30,10 @@ android.util.AndroidRuntimeException android.util.ArrayMap android.util.ArraySet android.util.AtomicFile +android.util.AtomicFileOutputStream +android.util.AtomicFileBufferedOutputStream +android.util.AtomicFilePrintWriter +android.util.AtomicFileBufferedPrintWriter android.util.BackupUtils android.util.Base64 android.util.Base64DataException @@ -111,6 +115,7 @@ android.util.UtilConfig android.util.Xml android.util.proto.EncodedBuffer +android.util.proto.ProtoFieldFilter android.util.proto.ProtoInputStream android.util.proto.ProtoOutputStream android.util.proto.ProtoParseException @@ -146,6 +151,10 @@ android.os.Looper android.os.Message android.os.MessageQueue android.os.MessageQueue_ravenwood +android.os.PerfettoTrace +android.os.PerfettoTrace$Category +android.os.PerfettoTrackEventExtra +android.os.PerfettoTrackEventExtra$NoOpBuilder android.os.PackageTagsList android.os.Parcel android.os.ParcelFileDescriptor @@ -250,6 +259,8 @@ android.database.sqlite.SQLiteClosable android.database.sqlite.SQLiteException android.text.TextUtils +android.text.Html +android.text.HtmlToSpannedConverter android.accounts.Account @@ -269,6 +280,10 @@ android.graphics.PointF android.graphics.Rect android.graphics.RectF +android.graphics.fonts.SystemFonts + +android.graphics.text.LineBreakConfig + android.content.ContentProvider android.app.ActivityManager @@ -374,3 +389,228 @@ android.app.compat.* com.android.server.compat.* com.android.internal.compat.* android.app.AppCompatCallbacks +android.graphics.AvoidXfermode +android.graphics.BLASTBufferQueue +android.graphics.BaseCanvas +android.graphics.BaseRecordingCanvas +android.graphics.Bitmap +android.graphics.BitmapFactory +android.graphics.BitmapRegionDecoder +android.graphics.BitmapShader +android.graphics.BlendMode +android.graphics.BlendModeColorFilter +android.graphics.BlurMaskFilter +android.graphics.Camera +android.graphics.Canvas +android.graphics.CanvasProperty +android.graphics.ColorFilter +android.graphics.ColorMatrix +android.graphics.ColorMatrixColorFilter +android.graphics.Compatibility +android.graphics.ComposePathEffect +android.graphics.ComposeShader +android.graphics.CornerPathEffect +android.graphics.DashPathEffect +android.graphics.DiscretePathEffect +android.graphics.DrawFilter +android.graphics.EmbossMaskFilter +android.graphics.FontFamily +android.graphics.FontListParser +android.graphics.ForceDarkType +android.graphics.FrameInfo +android.graphics.Gainmap +android.graphics.GraphicBuffer +android.graphics.GraphicsProtos +android.graphics.GraphicsStatsService +android.graphics.HardwareBufferRenderer +android.graphics.HardwareRenderer +android.graphics.HardwareRendererObserver +android.graphics.ImageDecoder +android.graphics.ImageFormat +android.graphics.LayerRasterizer +android.graphics.LeakyTypefaceStorage +android.graphics.LightingColorFilter +android.graphics.LinearGradient +android.graphics.MaskFilter +android.graphics.Mesh +android.graphics.MeshSpecification +android.graphics.Movie +android.graphics.NinePatch +android.graphics.Paint +android.graphics.PaintFlagsDrawFilter +android.graphics.PathDashPathEffect +android.graphics.PathEffect +android.graphics.PathIterator +android.graphics.PathMeasure +android.graphics.Picture +android.graphics.PixelXorXfermode +android.graphics.PorterDuff +android.graphics.PorterDuffColorFilter +android.graphics.PorterDuffXfermode +android.graphics.PostProcessor +android.graphics.RadialGradient +android.graphics.Rasterizer +android.graphics.RecordingCanvas +android.graphics.Region +android.graphics.RegionIterator +android.graphics.RenderEffect +android.graphics.RenderNode +android.graphics.RuntimeColorFilter +android.graphics.RuntimeShader +android.graphics.RuntimeXfermode +android.graphics.Shader +android.graphics.SumPathEffect +android.graphics.SurfaceTexture +android.graphics.SweepGradient +android.graphics.TableMaskFilter +android.graphics.TemporaryBuffer +android.graphics.TextureLayer +android.graphics.Typeface +android.graphics.Xfermode +android.graphics.YuvImage +android.graphics.fonts.Font +android.graphics.fonts.FontCustomizationParser +android.graphics.fonts.FontFamily +android.graphics.fonts.FontFamilyUpdateRequest +android.graphics.fonts.FontFileUpdateRequest +android.graphics.fonts.FontFileUtil +android.graphics.fonts.FontStyle +android.graphics.fonts.FontVariationAxis +android.graphics.text.GraphemeBreak +android.graphics.text.LineBreaker +android.graphics.text.MeasuredText +android.graphics.text.PositionedGlyphs +android.graphics.text.TextRunShaper +android.text.AlteredCharSequence +android.text.AndroidBidi +android.text.AndroidCharacter +android.text.Annotation +android.text.AutoGrowArray +android.text.AutoText +android.text.BidiFormatter +android.text.BoringLayout +android.text.CharSequenceCharacterIterator +android.text.ClipboardManager +android.text.DynamicLayout +android.text.Editable +android.text.Emoji +android.text.EmojiConsistency +android.text.FontConfig +android.text.GetChars +android.text.GraphemeClusterSegmentFinder +android.text.GraphicsOperations +android.text.Highlights +android.text.Hyphenator +android.text.InputFilter +android.text.InputType +android.text.Layout +android.text.LoginFilter +android.text.MeasuredParagraph +android.text.NoCopySpan +android.text.PackedIntVector +android.text.PackedObjectVector +android.text.ParcelableSpan +android.text.PrecomputedText +android.text.SegmentFinder +android.text.Selection +android.text.SpanColors +android.text.SpanSet +android.text.SpanWatcher +android.text.Spannable +android.text.SpannableString +android.text.SpannableStringBuilder +android.text.SpannableStringInternal +android.text.Spanned +android.text.SpannedString +android.text.StaticLayout +android.text.TextDirectionHeuristic +android.text.TextDirectionHeuristics +android.text.TextLine +android.text.TextPaint +android.text.TextShaper +android.text.TextWatcher +android.text.WordSegmentFinder +android.text.format.DateFormat +android.text.format.DateIntervalFormat +android.text.format.DateTimeFormat +android.text.format.DateUtils +android.text.format.DateUtilsBridge +android.text.format.Formatter +android.text.format.RelativeDateTimeFormatter +android.text.format.Time +android.text.format.TimeFormatter +android.text.format.TimeMigrationUtils +android.text.method.AllCapsTransformationMethod +android.text.method.ArrowKeyMovementMethod +android.text.method.BaseKeyListener +android.text.method.BaseMovementMethod +android.text.method.CharacterPickerDialog +android.text.method.DateKeyListener +android.text.method.DateTimeKeyListener +android.text.method.DialerKeyListener +android.text.method.DigitsKeyListener +android.text.method.HideReturnsTransformationMethod +android.text.method.InsertModeTransformationMethod +android.text.method.KeyListener +android.text.method.LinkMovementMethod +android.text.method.MetaKeyKeyListener +android.text.method.MovementMethod +android.text.method.MultiTapKeyListener +android.text.method.NumberKeyListener +android.text.method.OffsetMapping +android.text.method.PasswordTransformationMethod +android.text.method.QwertyKeyListener +android.text.method.ReplacementTransformationMethod +android.text.method.ScrollingMovementMethod +android.text.method.SingleLineTransformationMethod +android.text.method.TextKeyListener +android.text.method.TimeKeyListener +android.text.method.Touch +android.text.method.TransformationMethod +android.text.method.TransformationMethod2 +android.text.method.TranslationTransformationMethod +android.text.method.WordIterator +android.text.style.AbsoluteSizeSpan +android.text.style.AccessibilityClickableSpan +android.text.style.AccessibilityReplacementSpan +android.text.style.AccessibilityURLSpan +android.text.style.AlignmentSpan +android.text.style.BackgroundColorSpan +android.text.style.BulletSpan +android.text.style.CharacterStyle +android.text.style.ClickableSpan +android.text.style.ForegroundColorSpan +android.text.style.IconMarginSpan +android.text.style.LeadingMarginSpan +android.text.style.LineBackgroundSpan +android.text.style.LineBreakConfigSpan +android.text.style.LineHeightSpan +android.text.style.LocaleSpan +android.text.style.MaskFilterSpan +android.text.style.MetricAffectingSpan +android.text.style.NoWritingToolsSpan +android.text.style.ParagraphStyle +android.text.style.QuoteSpan +android.text.style.RasterizerSpan +android.text.style.RelativeSizeSpan +android.text.style.ReplacementSpan +android.text.style.ScaleXSpan +android.text.style.SpanUtils +android.text.style.SpellCheckSpan +android.text.style.StrikethroughSpan +android.text.style.StyleSpan +android.text.style.SubscriptSpan +android.text.style.SuggestionRangeSpan +android.text.style.SuggestionSpan +android.text.style.SuperscriptSpan +android.text.style.TabStopSpan +android.text.style.TextAppearanceSpan +android.text.style.TtsSpan +android.text.style.TypefaceSpan +android.text.style.URLSpan +android.text.style.UnderlineSpan +android.text.style.UpdateAppearance +android.text.style.UpdateLayout +android.text.style.WrapTogetherSpan +android.text.util.Rfc822Token +android.text.util.Rfc822Tokenizer diff --git a/ravenwood/texts/ravenwood-build.prop b/ravenwood/texts/ravenwood-build.prop index 93a18cffec50..974ea296f0ed 100644 --- a/ravenwood/texts/ravenwood-build.prop +++ b/ravenwood/texts/ravenwood-build.prop @@ -8,7 +8,43 @@ ro.soc.manufacturer=Android ro.soc.model=Ravenwood ro.debuggable=1 -# The ones starting with "ro.product" or "ro.bild" will be copied to all "partitions" too. +persist.sys.locale=en-US +ro.product.locale=en-US + +ro.hwui.max_texture_allocation_size=104857600 + +# Allowlist control: +# This set is carefully curated to help identify situations where a test may +# accidentally depend on a default value of an obscure property whose owner hasn't +# decided how Ravenwood should behave. + +boot.=$$$r +build.=$$$r +product.=$$$r +soc.=$$$r +system.=$$$r +wm.debug.=$$$r +wm.extensions.=$$$r + +gsm.version.baseband=$$$r +no.such.thing=$$$r +qemu.sf.lcd_density=$$$r +ro.bootloader=$$$r +ro.hardware=$$$r +ro.hw_timeout_multiplier=$$$r +ro.odm.build.media_performance_class=$$$r +ro.sf.lcd_density=$$$r +ro.treble.enabled=$$$r +ro.vndk.version=$$$r +ro.icu.data.path=$$$r + +# Writable keys +debug.=$$$w + +# For PropertyInvalidatedCache +cache_key.=$$$w + +# The ones starting with "ro.product" or "ro.build" will be copied to all "partitions" too. # See RavenwoodSystemProperties. ro.product.brand=Android ro.product.device=Ravenwood diff --git a/ravenwood/texts/ravenwood-common-policies.txt b/ravenwood/texts/ravenwood-common-policies.txt index fd4ea6cf40c2..f0f4b8580f7d 100644 --- a/ravenwood/texts/ravenwood-common-policies.txt +++ b/ravenwood/texts/ravenwood-common-policies.txt @@ -21,3 +21,7 @@ class java.io.FileDescriptor # no-pta method setInt$ @com.android.ravenwood.RavenwoodJdkPatch.setInt$ class java.util.LinkedHashMap # no-pta method eldest @com.android.ravenwood.RavenwoodJdkPatch.eldest + +# Always set flag UNICODE_CHARACTER_CLASS when compiling regex +class java.util.regex.Pattern keep + method compile @com.android.ravenwood.RavenwoodJdkPatch.compilePattern diff --git a/ravenwood/texts/ravenwood-framework-policies.txt b/ravenwood/texts/ravenwood-framework-policies.txt index bd51b9303f7e..5c1766241698 100644 --- a/ravenwood/texts/ravenwood-framework-policies.txt +++ b/ravenwood/texts/ravenwood-framework-policies.txt @@ -65,3 +65,22 @@ class android.text.ClipboardManager keep # no-pta # Just enough to allow ResourcesManager to run class android.hardware.display.DisplayManagerGlobal keep # no-pta method getInstance ()Landroid/hardware/display/DisplayManagerGlobal; ignore # no-pta + +# Bare minimum to support running ImageDecoderTest +class android.graphics.drawable.Drawable$ConstantState keepclass # no-pta +class android.graphics.drawable.BitmapDrawable$BitmapState keepclass # no-pta +class android.graphics.drawable.BitmapDrawable keep # no-pta + method <init> (Landroid/content/res/Resources;Landroid/graphics/Bitmap;)V keep + method init * keep + method updateLocalState * keep + method computeBitmapSize * keep + method getIntrinsicWidth * keep + method getIntrinsicHeight * keep + method getBitmap * keep +class android.graphics.drawable.Drawable keep # no-pta + method <init> ()V keep + method resolveDensity * keep + method updateBlendModeFilter * ignore + +class android.os.StrictMode keep # no-pta + method noteSlowCall (Ljava/lang/String;)V ignore diff --git a/ravenwood/texts/ravenwood-services-jarjar-rules.txt b/ravenwood/texts/ravenwood-services-jarjar-rules.txt index 8fdd3408f74d..64a0e2548e2e 100644 --- a/ravenwood/texts/ravenwood-services-jarjar-rules.txt +++ b/ravenwood/texts/ravenwood-services-jarjar-rules.txt @@ -5,7 +5,7 @@ rule com.android.server.pm.pkg.AndroidPackageSplit @0 # Rename all other service internals so that tests can continue to statically # link services code when owners aren't ready to support on Ravenwood -rule com.android.server.** repackaged.@0 +rule com.android.server.** repackaged.services.@0 # TODO: support AIDL generated Parcelables via hoststubgen -rule android.hardware.power.stats.** repackaged.@0 +rule android.hardware.power.stats.** repackaged.services.@0 diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/FilterRemapper.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/FilterRemapper.kt index c5a2f9ff5e96..bba4681d3838 100644 --- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/FilterRemapper.kt +++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/FilterRemapper.kt @@ -15,6 +15,7 @@ */ package com.android.hoststubgen.filters +import com.android.hoststubgen.log import org.objectweb.asm.commons.Remapper /** @@ -23,19 +24,25 @@ import org.objectweb.asm.commons.Remapper class FilterRemapper(val filter: OutputFilter) : Remapper() { private val cache = mutableMapOf<String, String>() - override fun mapType(typeInternalName: String?): String? { + + override fun map(typeInternalName: String?): String? { if (typeInternalName == null) { return null } cache[typeInternalName]?.let { + // log.d("Cached rename from $typeInternalName to $it") return it } - var mapped = filter.remapType(typeInternalName) ?: typeInternalName + var mapped = filter.remapType(typeInternalName) + if (mapped != null) { + log.d("Renaming type $typeInternalName to $mapped") + } else { + // log.d("Not renaming type $typeInternalName") + } + mapped = mapped ?: typeInternalName cache[typeInternalName] = mapped return mapped } - - // TODO Do we need to implement mapPackage(), etc too? }
\ No newline at end of file diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyRemapperFilter.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyRemapperFilter.kt index a78c6552b8d0..bc90d1248322 100644 --- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyRemapperFilter.kt +++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyRemapperFilter.kt @@ -15,7 +15,6 @@ */ package com.android.hoststubgen.filters -import com.android.hoststubgen.log import java.util.regex.Pattern /** @@ -34,17 +33,12 @@ class TextFilePolicyRemapperFilter( val typeInternalNamePrefix: String, ) - private val cache = mutableMapOf<String, String>() - override fun remapType(className: String): String? { - var mapped: String = className typeRenameSpecs.forEach { if (it.typeInternalNamePattern.matcher(className).matches()) { - mapped = it.typeInternalNamePrefix + className - log.d("Renaming type $className to $mapped") + return it.typeInternalNamePrefix + className } } - cache[className] = mapped - return mapped + return null } } diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/01-hoststubgen-test-tiny-framework-orig-dump.txt b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/01-hoststubgen-test-tiny-framework-orig-dump.txt index 635f66d8e90c..e846d6e19ed9 100644 --- a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/01-hoststubgen-test-tiny-framework-orig-dump.txt +++ b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/01-hoststubgen-test-tiny-framework-orig-dump.txt @@ -3198,7 +3198,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClas flags: (0x0021) ACC_PUBLIC, ACC_SUPER this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller super_class: #x // java/lang/Object - interfaces: 0, fields: 0, methods: 2, attributes: 2 + interfaces: 0, fields: 0, methods: 3, attributes: 2 Constant pool: { public com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller(); @@ -3229,6 +3229,22 @@ Constant pool: LocalVariableTable: Start Length Slot Name Signature 0 12 0 value I + + public static int bar(int); + descriptor: (I)I + flags: (0x0009) ACC_PUBLIC, ACC_STATIC + Code: + stack=2, locals=1, args_size=1 + x: iload_0 + x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getArray:(I)[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + x: iconst_0 + x: aaload + x: invokevirtual #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getValue:()I + x: ireturn + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 10 0 value I } SourceFile: "TinyFrameworkRenamedClassCaller.java" RuntimeInvisibleAnnotations: @@ -3242,7 +3258,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed flags: (0x0021) ACC_PUBLIC, ACC_SUPER this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed super_class: #x // java/lang/Object - interfaces: 0, fields: 1, methods: 2, attributes: 2 + interfaces: 0, fields: 1, methods: 3, attributes: 2 Constant pool: { private final int mValue; @@ -3278,6 +3294,26 @@ Constant pool: LocalVariableTable: Start Length Slot Name Signature 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + + public static com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed[] getArray(int); + descriptor: (I)[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + flags: (0x0009) ACC_PUBLIC, ACC_STATIC + Code: + stack=6, locals=1, args_size=1 + x: iconst_1 + x: anewarray #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed + x: dup + x: iconst_0 + x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed + x: dup + x: iload_0 + x: invokespecial #x // Method "<init>":(I)V + x: aastore + x: areturn + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 16 0 value I } SourceFile: "TinyFrameworkToBeRenamed.java" RuntimeInvisibleAnnotations: diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/03-hoststubgen-test-tiny-framework-host-dump.txt b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/03-hoststubgen-test-tiny-framework-host-dump.txt index 51a33554afa9..be95fe03d74f 100644 --- a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/03-hoststubgen-test-tiny-framework-host-dump.txt +++ b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/03-hoststubgen-test-tiny-framework-host-dump.txt @@ -3392,7 +3392,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClas flags: (0x0021) ACC_PUBLIC, ACC_SUPER this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller super_class: #x // java/lang/Object - interfaces: 0, fields: 0, methods: 2, attributes: 3 + interfaces: 0, fields: 0, methods: 3, attributes: 3 Constant pool: { public com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller(); @@ -3429,6 +3429,25 @@ Constant pool: RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep + + public static int bar(int); + descriptor: (I)I + flags: (0x0009) ACC_PUBLIC, ACC_STATIC + Code: + stack=2, locals=1, args_size=1 + x: iload_0 + x: invokestatic #x // Method rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getArray:(I)[Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + x: iconst_0 + x: aaload + x: invokevirtual #x // Method rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getValue:()I + x: ireturn + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 10 0 value I + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep } SourceFile: "TinyFrameworkRenamedClassCaller.java" RuntimeVisibleAnnotations: @@ -3867,7 +3886,7 @@ public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFramew flags: (0x0021) ACC_PUBLIC, ACC_SUPER this_class: #x // rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed super_class: #x // java/lang/Object - interfaces: 0, fields: 1, methods: 2, attributes: 3 + interfaces: 0, fields: 1, methods: 3, attributes: 3 Constant pool: { private final int mValue; @@ -3891,7 +3910,7 @@ Constant pool: LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + 0 10 0 this Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; 0 10 1 value I RuntimeVisibleAnnotations: x: #x() @@ -3908,7 +3927,30 @@ Constant pool: LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + 0 5 0 this Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep + + public static rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed[] getArray(int); + descriptor: (I)[Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + flags: (0x0009) ACC_PUBLIC, ACC_STATIC + Code: + stack=6, locals=1, args_size=1 + x: iconst_1 + x: anewarray #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed + x: dup + x: iconst_0 + x: new #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed + x: dup + x: iload_0 + x: invokespecial #x // Method "<init>":(I)V + x: aastore + x: areturn + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 16 0 value I RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/13-hoststubgen-test-tiny-framework-host-ext-dump.txt b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/13-hoststubgen-test-tiny-framework-host-ext-dump.txt index a466a2e2c3a7..667981fcb7e8 100644 --- a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/13-hoststubgen-test-tiny-framework-host-ext-dump.txt +++ b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/13-hoststubgen-test-tiny-framework-host-ext-dump.txt @@ -4241,7 +4241,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClas flags: (0x0021) ACC_PUBLIC, ACC_SUPER this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller super_class: #x // java/lang/Object - interfaces: 0, fields: 0, methods: 3, attributes: 3 + interfaces: 0, fields: 0, methods: 4, attributes: 3 Constant pool: { private static {}; @@ -4298,6 +4298,30 @@ Constant pool: RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep + + public static int bar(int); + descriptor: (I)I + flags: (0x0009) ACC_PUBLIC, ACC_STATIC + Code: + stack=4, locals=1, args_size=1 + x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller + x: ldc #x // String bar + x: ldc #x // String (I)I + x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall + x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V + x: iload_0 + x: invokestatic #x // Method rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getArray:(I)[Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + x: iconst_0 + x: aaload + x: invokevirtual #x // Method rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getValue:()I + x: ireturn + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 11 10 0 value I + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep } SourceFile: "TinyFrameworkRenamedClassCaller.java" RuntimeVisibleAnnotations: @@ -4947,7 +4971,7 @@ public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFramew flags: (0x0021) ACC_PUBLIC, ACC_SUPER this_class: #x // rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed super_class: #x // java/lang/Object - interfaces: 0, fields: 1, methods: 3, attributes: 3 + interfaces: 0, fields: 1, methods: 4, attributes: 3 Constant pool: { private final int mValue; @@ -4962,8 +4986,8 @@ Constant pool: flags: (0x000a) ACC_PRIVATE, ACC_STATIC Code: stack=2, locals=0, args_size=0 - x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed - x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded + x: ldc #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed + x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V x: return @@ -4972,7 +4996,7 @@ Constant pool: flags: (0x0001) ACC_PUBLIC Code: stack=4, locals=2, args_size=2 - x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed + x: ldc #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed x: ldc #x // String <init> x: ldc #x // String (I)V x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall @@ -4986,7 +5010,7 @@ Constant pool: LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 11 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + 11 10 0 this Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; 11 10 1 value I RuntimeVisibleAnnotations: x: #x() @@ -4997,7 +5021,7 @@ Constant pool: flags: (0x0001) ACC_PUBLIC Code: stack=4, locals=1, args_size=1 - x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed + x: ldc #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed x: ldc #x // String getValue x: ldc #x // String ()I x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall @@ -5008,7 +5032,35 @@ Constant pool: LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + 11 5 0 this Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep + + public static rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed[] getArray(int); + descriptor: (I)[Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + flags: (0x0009) ACC_PUBLIC, ACC_STATIC + Code: + stack=6, locals=1, args_size=1 + x: ldc #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed + x: ldc #x // String getArray + x: ldc #x // String (I)[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall + x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V + x: iconst_1 + x: anewarray #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed + x: dup + x: iconst_0 + x: new #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed + x: dup + x: iload_0 + x: invokespecial #x // Method "<init>":(I)V + x: aastore + x: areturn + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 11 16 0 value I RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt index 78341d7afbb9..8f56f0e219a5 100644 --- a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt +++ b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt @@ -3219,7 +3219,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClas flags: (0x0021) ACC_PUBLIC, ACC_SUPER this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller super_class: #x // java/lang/Object - interfaces: 0, fields: 0, methods: 2, attributes: 2 + interfaces: 0, fields: 0, methods: 3, attributes: 2 Constant pool: { public com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller(); @@ -3250,6 +3250,22 @@ Constant pool: LocalVariableTable: Start Length Slot Name Signature 0 12 0 value I + + public static int bar(int); + descriptor: (I)I + flags: (0x0009) ACC_PUBLIC, ACC_STATIC + Code: + stack=2, locals=1, args_size=1 + x: iload_0 + x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getArray:(I)[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + x: iconst_0 + x: aaload + x: invokevirtual #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getValue:()I + x: ireturn + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 10 0 value I } SourceFile: "TinyFrameworkRenamedClassCaller.java" RuntimeInvisibleAnnotations: @@ -3263,7 +3279,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed flags: (0x0021) ACC_PUBLIC, ACC_SUPER this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed super_class: #x // java/lang/Object - interfaces: 0, fields: 1, methods: 2, attributes: 2 + interfaces: 0, fields: 1, methods: 3, attributes: 2 Constant pool: { private final int mValue; @@ -3299,6 +3315,26 @@ Constant pool: LocalVariableTable: Start Length Slot Name Signature 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + + public static com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed[] getArray(int); + descriptor: (I)[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + flags: (0x0009) ACC_PUBLIC, ACC_STATIC + Code: + stack=6, locals=1, args_size=1 + x: iconst_1 + x: anewarray #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed + x: dup + x: iconst_0 + x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed + x: dup + x: iload_0 + x: invokespecial #x // Method "<init>":(I)V + x: aastore + x: areturn + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 16 0 value I } SourceFile: "TinyFrameworkToBeRenamed.java" RuntimeInvisibleAnnotations: diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-dump.txt b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-dump.txt index 2e0b1820a696..c918bf86fa40 100644 --- a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-dump.txt +++ b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-dump.txt @@ -3422,7 +3422,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClas flags: (0x0021) ACC_PUBLIC, ACC_SUPER this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller super_class: #x // java/lang/Object - interfaces: 0, fields: 0, methods: 2, attributes: 3 + interfaces: 0, fields: 0, methods: 3, attributes: 3 Constant pool: { public com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller(); @@ -3459,6 +3459,25 @@ Constant pool: RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep + + public static int bar(int); + descriptor: (I)I + flags: (0x0009) ACC_PUBLIC, ACC_STATIC + Code: + stack=2, locals=1, args_size=1 + x: iload_0 + x: invokestatic #x // Method rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getArray:(I)[Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + x: iconst_0 + x: aaload + x: invokevirtual #x // Method rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getValue:()I + x: ireturn + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 10 0 value I + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep } SourceFile: "TinyFrameworkRenamedClassCaller.java" RuntimeVisibleAnnotations: @@ -3897,7 +3916,7 @@ public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFramew flags: (0x0021) ACC_PUBLIC, ACC_SUPER this_class: #x // rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed super_class: #x // java/lang/Object - interfaces: 0, fields: 1, methods: 2, attributes: 3 + interfaces: 0, fields: 1, methods: 3, attributes: 3 Constant pool: { private final int mValue; @@ -3921,7 +3940,7 @@ Constant pool: LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + 0 10 0 this Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; 0 10 1 value I RuntimeVisibleAnnotations: x: #x() @@ -3938,7 +3957,30 @@ Constant pool: LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + 0 5 0 this Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep + + public static rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed[] getArray(int); + descriptor: (I)[Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + flags: (0x0009) ACC_PUBLIC, ACC_STATIC + Code: + stack=6, locals=1, args_size=1 + x: iconst_1 + x: anewarray #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed + x: dup + x: iconst_0 + x: new #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed + x: dup + x: iload_0 + x: invokespecial #x // Method "<init>":(I)V + x: aastore + x: areturn + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 0 16 0 value I RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-dump.txt b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-dump.txt index 51f79258d53a..28065bf16d01 100644 --- a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-dump.txt +++ b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-dump.txt @@ -4271,7 +4271,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClas flags: (0x0021) ACC_PUBLIC, ACC_SUPER this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller super_class: #x // java/lang/Object - interfaces: 0, fields: 0, methods: 3, attributes: 3 + interfaces: 0, fields: 0, methods: 4, attributes: 3 Constant pool: { private static {}; @@ -4328,6 +4328,30 @@ Constant pool: RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep + + public static int bar(int); + descriptor: (I)I + flags: (0x0009) ACC_PUBLIC, ACC_STATIC + Code: + stack=4, locals=1, args_size=1 + x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller + x: ldc #x // String bar + x: ldc #x // String (I)I + x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall + x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V + x: iload_0 + x: invokestatic #x // Method rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getArray:(I)[Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + x: iconst_0 + x: aaload + x: invokevirtual #x // Method rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getValue:()I + x: ireturn + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 11 10 0 value I + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep } SourceFile: "TinyFrameworkRenamedClassCaller.java" RuntimeVisibleAnnotations: @@ -4977,7 +5001,7 @@ public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFramew flags: (0x0021) ACC_PUBLIC, ACC_SUPER this_class: #x // rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed super_class: #x // java/lang/Object - interfaces: 0, fields: 1, methods: 3, attributes: 3 + interfaces: 0, fields: 1, methods: 4, attributes: 3 Constant pool: { private final int mValue; @@ -4992,8 +5016,8 @@ Constant pool: flags: (0x000a) ACC_PRIVATE, ACC_STATIC Code: stack=2, locals=0, args_size=0 - x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed - x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded + x: ldc #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed + x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V x: return @@ -5002,7 +5026,7 @@ Constant pool: flags: (0x0001) ACC_PUBLIC Code: stack=4, locals=2, args_size=2 - x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed + x: ldc #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed x: ldc #x // String <init> x: ldc #x // String (I)V x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall @@ -5016,7 +5040,7 @@ Constant pool: LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 11 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + 11 10 0 this Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; 11 10 1 value I RuntimeVisibleAnnotations: x: #x() @@ -5027,7 +5051,7 @@ Constant pool: flags: (0x0001) ACC_PUBLIC Code: stack=4, locals=1, args_size=1 - x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed + x: ldc #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed x: ldc #x // String getValue x: ldc #x // String ()I x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall @@ -5038,7 +5062,35 @@ Constant pool: LineNumberTable: LocalVariableTable: Start Length Slot Name Signature - 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + 11 5 0 this Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + RuntimeVisibleAnnotations: + x: #x() + com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep + + public static rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed[] getArray(int); + descriptor: (I)[Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + flags: (0x0009) ACC_PUBLIC, ACC_STATIC + Code: + stack=6, locals=1, args_size=1 + x: ldc #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed + x: ldc #x // String getArray + x: ldc #x // String (I)[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed; + x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall + x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V + x: iconst_1 + x: anewarray #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed + x: dup + x: iconst_0 + x: new #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed + x: dup + x: iload_0 + x: invokespecial #x // Method "<init>":(I)V + x: aastore + x: areturn + LineNumberTable: + LocalVariableTable: + Start Length Slot Name Signature + 11 16 0 value I RuntimeVisibleAnnotations: x: #x() com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller.java b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller.java index 707bc0ebb4db..74e4610187c4 100644 --- a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller.java +++ b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller.java @@ -25,4 +25,9 @@ public class TinyFrameworkRenamedClassCaller { // so this code should work as-is. return new TinyFrameworkToBeRenamed(value).getValue(); } + + /** Calls the class that'll be renamed. */ + public static int bar(int value) { + return TinyFrameworkToBeRenamed.getArray(value)[0].getValue(); + } } diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.java b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.java index 8319ced6109a..7dcc83e79e26 100644 --- a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.java +++ b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.java @@ -31,4 +31,8 @@ public class TinyFrameworkToBeRenamed { public int getValue() { return mValue; } + + public static TinyFrameworkToBeRenamed[] getArray(int value) { + return new TinyFrameworkToBeRenamed[] { new TinyFrameworkToBeRenamed(value) }; + } } diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java index 68673dc2a5b8..b8d6be4265c9 100644 --- a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java +++ b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java @@ -308,6 +308,11 @@ public class TinyFrameworkClassTest { } @Test + public void testTypeRenameArray() { + assertThat(TinyFrameworkRenamedClassCaller.bar(2)).isEqualTo(2); + } + + @Test public void testMethodCallReplaceNonStatic() throws Exception { assertThat(TinyFrameworkMethodCallReplace.nonStaticMethodCallReplaceTester()) .isEqualTo(true); diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS index 62b89f3252e6..f98ec04f84d8 100644 --- a/services/core/java/com/android/server/pm/OWNERS +++ b/services/core/java/com/android/server/pm/OWNERS @@ -1,7 +1,6 @@ hackbod@android.com hackbod@google.com jsharkey@android.com -jsharkey@google.com narayan@google.com include /PACKAGE_MANAGER_OWNERS diff --git a/services/core/java/com/android/server/pm/dex/OWNERS b/services/core/java/com/android/server/pm/dex/OWNERS index 5ca8ddd1fe17..70af4e7d36b2 100644 --- a/services/core/java/com/android/server/pm/dex/OWNERS +++ b/services/core/java/com/android/server/pm/dex/OWNERS @@ -1,4 +1,3 @@ -alanstokes@google.com jiakaiz@google.com ngeoffray@google.com mast@google.com diff --git a/services/core/java/com/android/server/uri/OWNERS b/services/core/java/com/android/server/uri/OWNERS index cdc07ed7c67a..6599db7936c0 100644 --- a/services/core/java/com/android/server/uri/OWNERS +++ b/services/core/java/com/android/server/uri/OWNERS @@ -1,3 +1,2 @@ jsharkey@android.com -jsharkey@google.com varunshah@google.com diff --git a/services/core/java/com/android/server/wm/OWNERS b/services/core/java/com/android/server/wm/OWNERS index dede7676a4b6..243a5326b545 100644 --- a/services/core/java/com/android/server/wm/OWNERS +++ b/services/core/java/com/android/server/wm/OWNERS @@ -3,7 +3,6 @@ set noparent ogunwale@google.com jjaggi@google.com racarr@google.com -chaviw@google.com vishnun@google.com akulian@google.com roosa@google.com diff --git a/services/musicrecognition/OWNERS b/services/musicrecognition/OWNERS index 037b04831260..820be004efd5 100644 --- a/services/musicrecognition/OWNERS +++ b/services/musicrecognition/OWNERS @@ -1,5 +1,4 @@ # Bug component: 830636 oni@google.com -volnov@google.com diff --git a/telecomm/java/android/telecom/OWNERS b/telecomm/java/android/telecom/OWNERS index 6656a01403b8..0854c5d45603 100644 --- a/telecomm/java/android/telecom/OWNERS +++ b/telecomm/java/android/telecom/OWNERS @@ -3,4 +3,3 @@ rgreenwalt@google.com tgunn@google.com breadley@google.com -hallliu@google.com diff --git a/tests/EnforcePermission/OWNERS b/tests/EnforcePermission/OWNERS index 39550a394f33..160849e5616f 100644 --- a/tests/EnforcePermission/OWNERS +++ b/tests/EnforcePermission/OWNERS @@ -1,3 +1,2 @@ # Bug component: 315013 tweek@google.com -brufino@google.com diff --git a/tools/hiddenapi/OWNERS b/tools/hiddenapi/OWNERS index dc82aac9d41c..d1e36b953e7f 100644 --- a/tools/hiddenapi/OWNERS +++ b/tools/hiddenapi/OWNERS @@ -1,6 +1,5 @@ # compat-team@ for changes to hiddenapi files mathewi@google.com -satayev@google.com # soong-team@ as the files these tools protect are tightly coupled with Soong file:platform/build/soong:/OWNERS |