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

Commit 5d19c9b0 authored by Makoto Onuki's avatar Makoto Onuki
Browse files

[ravenwood] Make all classes and methods non-final

- Making them non-final allows mockito to use the traditional, subclass-based mock strategy, as opposed to "inline mocking", which is nice because inline mocking has some non-obvious gatchas.

- Other than that, this shouldn't affect any test behavior -- we still compile tests against the original jar, so tests still couldn't override final classes / methods.

(- It _could_ affect it if there were any tests that check class / method signatures, but I don't think we need to support such tests.)


Flag: EXEMPT host test change only
Bug: 292141694
Test: $ANDROID_BUILD_TOP/frameworks/base/ravenwood/scripts/run-ravenwood-tests.sh
Change-Id: Ia690cb4f50328e2ef0650513facad6f91835893f
parent f8490737
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -5,6 +5,8 @@
# Keep all classes / methods / fields, but make the methods throw.
--default-throw

--delete-finals

# Uncomment below lines to enable each feature.

#--default-method-call-hook
+2 −0
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@

--debug

--delete-finals

# Uncomment below lines to enable each feature.

#--default-method-call-hook
+2 −0
Original line number Diff line number Diff line
@@ -411,6 +411,8 @@ class HostStubGen(val options: HostStubGenOptions) {
            stats = stats,
            enablePreTrace = options.enablePreTrace.get,
            enablePostTrace = options.enablePostTrace.get,
            deleteClassFinals = options.deleteFinals.get,
            deleteMethodFinals = options.deleteFinals.get,
        )
        outVisitor = BaseAdapter.getVisitor(
            classInternalName, classes, outVisitor, filter,
+5 −0
Original line number Diff line number Diff line
@@ -106,6 +106,8 @@ class HostStubGenOptions(

        var cleanUpOnError: SetOnce<Boolean> = SetOnce(false),

        var deleteFinals: SetOnce<Boolean> = SetOnce(false),

        var enableClassChecker: SetOnce<Boolean> = SetOnce(false),
        var enablePreTrace: SetOnce<Boolean> = SetOnce(false),
        var enablePostTrace: SetOnce<Boolean> = SetOnce(false),
@@ -218,6 +220,8 @@ class HostStubGenOptions(
                        "--gen-keep-all-file" ->
                            ret.inputJarAsKeepAllFile.set(nextArg())

                        "--delete-finals" -> ret.deleteFinals.set(true)

                        // Following options are for debugging.
                        "--enable-class-checker" -> ret.enableClassChecker.set(true)
                        "--no-class-checker" -> ret.enableClassChecker.set(false)
@@ -293,6 +297,7 @@ class HostStubGenOptions(
              defaultMethodCallHook=$defaultMethodCallHook,
              policyOverrideFiles=${policyOverrideFiles.toTypedArray().contentToString()},
              defaultPolicy=$defaultPolicy,
              deleteFinals=$deleteFinals,
              cleanUpOnError=$cleanUpOnError,
              enableClassChecker=$enableClassChecker,
              enablePreTrace=$enablePreTrace,
+31 −4
Original line number Diff line number Diff line
@@ -50,7 +50,13 @@ abstract class BaseAdapter(
        val errors: HostStubGenErrors,
        val stats: HostStubGenStats?,
        val enablePreTrace: Boolean,
        val enablePostTrace: Boolean
        val enablePostTrace: Boolean,
        val deleteClassFinals: Boolean,
        val deleteMethodFinals: Boolean,
        // We don't remove finals from fields, because final fields have a stronger memory
        // guarantee than non-final fields, see:
        // https://docs.oracle.com/javase/specs/jls/se22/html/jls-17.html#jls-17.5
        // i.e. changing a final field to non-final _could_ result in different behavior.
    )

    protected lateinit var currentPackageName: String
@@ -58,14 +64,33 @@ abstract class BaseAdapter(
    protected var redirectionClass: String? = null
    protected lateinit var classPolicy: FilterPolicyWithReason

    private fun isEnum(access: Int): Boolean {
        return (access and Opcodes.ACC_ENUM) != 0
    }

    protected fun modifyClassAccess(access: Int): Int {
        if (options.deleteClassFinals && !isEnum(access)) {
            return access and Opcodes.ACC_FINAL.inv()
        }
        return access
    }

    protected fun modifyMethodAccess(access: Int): Int {
        if (options.deleteMethodFinals) {
            return access and Opcodes.ACC_FINAL.inv()
        }
        return access
    }

    override fun visit(
        version: Int,
        access: Int,
        origAccess: Int,
        name: String,
        signature: String?,
        superName: String?,
        interfaces: Array<String>,
    ) {
        val access = modifyClassAccess(origAccess)
        super.visit(version, access, name, signature, superName, interfaces)
        currentClassName = name
        currentPackageName = getPackageNameFromFullClassName(name)
@@ -130,13 +155,14 @@ abstract class BaseAdapter(
        }
    }

    override fun visitMethod(
        access: Int,
    final override fun visitMethod(
        origAccess: Int,
        name: String,
        descriptor: String,
        signature: String?,
        exceptions: Array<String>?,
    ): MethodVisitor? {
        val access = modifyMethodAccess(origAccess)
        if (skipMemberModificationNestCount > 0) {
            return super.visitMethod(access, name, descriptor, signature, exceptions)
        }
@@ -176,6 +202,7 @@ abstract class BaseAdapter(
                if (newAccess == NOT_COMPATIBLE) {
                    return null
                }
                newAccess = modifyMethodAccess(newAccess)

                log.v(
                    "Emitting %s.%s%s as %s %s", currentClassName, name, descriptor,
Loading