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

Commit d3c056bb authored by Makoto Onuki's avatar Makoto Onuki
Browse files

[HostStubGen] clean-up remapper support

Using "Pair" was too ad-hoc. Let's blend the feature into OutputFilter.

This will allow more flexible remapping in the future too.

Flag: EXEMPT host side test change only
Bug: 358155729

Test: $ANDROID_BUILD_TOP/frameworks/base/ravenwood/scripts/run-ravenwood-tests.sh
Change-Id: Idf954e4536ef1332571ae22fd0217ef760427b87
parent 56220168
Loading
Loading
Loading
Loading
+8 −9
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import com.android.hoststubgen.filters.ClassWidePolicyPropagatingFilter
import com.android.hoststubgen.filters.ConstantFilter
import com.android.hoststubgen.filters.DefaultHookInjectingFilter
import com.android.hoststubgen.filters.FilterPolicy
import com.android.hoststubgen.filters.FilterRemapper
import com.android.hoststubgen.filters.ImplicitOutputFilter
import com.android.hoststubgen.filters.OutputFilter
import com.android.hoststubgen.filters.StubIntersectingFilter
@@ -75,7 +76,9 @@ class HostStubGen(val options: HostStubGenOptions) {
        }

        // Build the filters.
        val (filter, policyFileRemapper) = buildFilter(errors, allClasses, options)
        val filter = buildFilter(errors, allClasses, options)

        val filterRemapper = FilterRemapper(filter)

        // Transform the jar.
        convert(
@@ -87,7 +90,7 @@ class HostStubGen(val options: HostStubGenOptions) {
                allClasses,
                errors,
                stats,
                policyFileRemapper,
                filterRemapper,
                options.numShards.get,
                options.shard.get,
        )
@@ -117,7 +120,7 @@ class HostStubGen(val options: HostStubGenOptions) {
            errors: HostStubGenErrors,
            allClasses: ClassNodes,
            options: HostStubGenOptions,
            ): Pair<OutputFilter, Remapper?> {
            ): OutputFilter {
        // We build a "chain" of multiple filters here.
        //
        // The filters are build in from "inside", meaning the first filter created here is
@@ -170,14 +173,10 @@ class HostStubGen(val options: HostStubGenOptions) {
            filter,
        )

        var policyFileRemapper: Remapper? = null

        // Next, "text based" filter, which allows to override polices without touching
        // the target code.
        options.policyOverrideFile.ifSet {
            val (f, p) = createFilterFromTextPolicyFile(it, allClasses, filter)
            filter = f
            policyFileRemapper = p
            filter = createFilterFromTextPolicyFile(it, allClasses, filter)
        }

        // If `--intersect-stub-jar` is provided, load from these jar files too.
@@ -192,7 +191,7 @@ class HostStubGen(val options: HostStubGenOptions) {
        // Apply the implicit filter.
        filter = ImplicitOutputFilter(errors, allClasses, filter)

        return Pair(filter, policyFileRemapper)
        return filter
    }

    /**
+4 −0
Original line number Diff line number Diff line
@@ -87,4 +87,8 @@ abstract class DelegatingFilter(
    ): List<String> {
        return fallback.getMethodCallHooks(className, methodName, descriptor)
    }

    override fun remapType(className: String): String? {
        return fallback.remapType(className)
    }
}
+41 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.hoststubgen.filters

import org.objectweb.asm.commons.Remapper

/**
 * A [Remapper] that uses [OutputFilter.remapType]
 */
class FilterRemapper(val filter: OutputFilter) : Remapper() {
    private val cache = mutableMapOf<String, String>()

    override fun mapType(typeInternalName: String?): String? {
        if (typeInternalName == null) {
            return null
        }

        cache[typeInternalName]?.let {
            return it
        }

        var mapped = filter.remapType(typeInternalName) ?: typeInternalName
        cache[typeInternalName] = mapped
        return mapped
    }

    // TODO Do we need to implement mapPackage(), etc too?
}
 No newline at end of file
+8 −0
Original line number Diff line number Diff line
@@ -89,4 +89,12 @@ abstract class OutputFilter {
            List<String> {
        return emptyList()
    }

    /**
     * Take a class (internal) name. If the class needs to be renamed, return the new name.
     * This is used by [FilterRemapper].
     */
    open fun remapType(className: String): String? {
        return null
    }
}
 No newline at end of file
+8 −10
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ import com.android.hoststubgen.log
import com.android.hoststubgen.normalizeTextLine
import com.android.hoststubgen.whitespaceRegex
import org.objectweb.asm.Opcodes
import org.objectweb.asm.commons.Remapper
import org.objectweb.asm.tree.ClassNode
import java.io.BufferedReader
import java.io.FileReader
@@ -62,7 +61,7 @@ fun createFilterFromTextPolicyFile(
        filename: String,
        classes: ClassNodes,
        fallback: OutputFilter,
        ): Pair<OutputFilter, Remapper?> {
        ): OutputFilter {
    log.i("Loading offloaded annotations from $filename ...")
    log.withIndent {
        val subclassFilter = SubclassFilter(classes, fallback)
@@ -75,7 +74,7 @@ fun createFilterFromTextPolicyFile(
        var featureFlagsPolicy: FilterPolicyWithReason? = null
        var syspropsPolicy: FilterPolicyWithReason? = null
        var rFilePolicy: FilterPolicyWithReason? = null
        val typeRenameSpec = mutableListOf<TextFilePolicyRemapper.TypeRenameSpec>()
        val typeRenameSpec = mutableListOf<TextFilePolicyRemapperFilter.TypeRenameSpec>()

        try {
            BufferedReader(FileReader(filename)).use { reader ->
@@ -267,7 +266,7 @@ fun createFilterFromTextPolicyFile(
                            // applied. (Which is needed for services.jar)
                            val prefix = fields[2].trimStart('/')

                            typeRenameSpec += TextFilePolicyRemapper.TypeRenameSpec(
                            typeRenameSpec += TextFilePolicyRemapperFilter.TypeRenameSpec(
                                pattern, prefix)
                        }

@@ -281,16 +280,15 @@ fun createFilterFromTextPolicyFile(
            throw e.withSourceInfo(filename, lineNo)
        }

        var remapper: TextFilePolicyRemapper? = null
        var ret: OutputFilter = imf
        if (typeRenameSpec.isNotEmpty()) {
            remapper = TextFilePolicyRemapper(typeRenameSpec)
            ret = TextFilePolicyRemapperFilter(typeRenameSpec, ret)
        }

        // Wrap the in-memory-filter with AHF.
        return Pair(
            AndroidHeuristicsFilter(
                classes, aidlPolicy, featureFlagsPolicy, syspropsPolicy, rFilePolicy, imf),
            remapper)
        ret = AndroidHeuristicsFilter(
                classes, aidlPolicy, featureFlagsPolicy, syspropsPolicy, rFilePolicy, ret)
        return ret
    }
}

Loading