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

Commit 787bff4e authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes I344d60df,Idf954e45 into main

* changes:
  [HostStubGen] Support method call redirection
  [HostStubGen] clean-up remapper support
parents ef615889 0fa7e444
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
    }

    /**
+10 −2
Original line number Diff line number Diff line
@@ -117,6 +117,14 @@ fun resolveClassNameWithDefaultPackage(className: String, defaultPackageName: St
    return "$defaultPackageName.$className"
}

fun splitWithLastPeriod(name: String): Pair<String, String>? {
    val pos = name.lastIndexOf('.')
    if (pos < 0) {
        return null
    }
    return Pair(name.substring(0, pos), name.substring(pos + 1))
}

fun String.toJvmClassName(): String {
    return this.replace('.', '/')
}
@@ -198,11 +206,11 @@ fun writeByteCodeToReturn(methodDescriptor: String, writer: MethodVisitor) {
/**
 * Given a method descriptor, insert an [argType] as the first argument to it.
 */
fun prependArgTypeToMethodDescriptor(methodDescriptor: String, argType: Type): String {
fun prependArgTypeToMethodDescriptor(methodDescriptor: String, classInternalName: String): String {
    val returnType = Type.getReturnType(methodDescriptor)
    val argTypes = Type.getArgumentTypes(methodDescriptor).toMutableList()

    argTypes.add(0, argType)
    argTypes.add(0, Type.getType("L" + classInternalName + ";"))

    return Type.getMethodDescriptor(returnType, *argTypes.toTypedArray())
}
+19 −0
Original line number Diff line number Diff line
@@ -87,4 +87,23 @@ abstract class DelegatingFilter(
    ): List<String> {
        return fallback.getMethodCallHooks(className, methodName, descriptor)
    }

    override fun remapType(className: String): String? {
        return fallback.remapType(className)
    }

    override fun hasAnyMethodCallReplace(): Boolean {
        return fallback.hasAnyMethodCallReplace()
    }

    override fun getMethodCallReplaceTo(
        callerClassName: String,
        callerMethodName: String,
        className: String,
        methodName: String,
        descriptor: String,
    ): MethodReplaceTarget? {
        return fallback.getMethodCallReplaceTo(
            callerClassName, callerMethodName, className, methodName, descriptor)
    }
}
+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
+32 −1
Original line number Diff line number Diff line
@@ -89,4 +89,35 @@ 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
    }

    data class MethodReplaceTarget(val className: String, val methodName: String)

    /**
     * Return if this filter may return non-null from [getMethodCallReplaceTo].
     * (Used for a small optimization)
     */
    open fun hasAnyMethodCallReplace(): Boolean {
        return false
    }

    /**
     * If a method call should be forwarded to another method, return the target's class / method.
     */
    open fun getMethodCallReplaceTo(
        callerClassName: String,
        callerMethodName: String,
        className: String,
        methodName: String,
        descriptor: String,
    ): MethodReplaceTarget? {
        return null
    }
}
Loading