| /* | |
| * Copyright (C) 2023 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. | |
| */ | |
| @file:JvmName("R8ResourceShrinker") | |
| package com.android.build.shrinker.usages | |
| import com.android.tools.r8.ProgramResource | |
| import com.android.tools.r8.ProgramResourceProvider | |
| import com.android.tools.r8.ResourceShrinker | |
| import com.android.tools.r8.origin.PathOrigin | |
| import com.android.tools.r8.references.MethodReference | |
| import java.nio.file.Path | |
| fun runResourceShrinkerAnalysis(bytes: ByteArray, file: Path, callback: AnalysisCallback) { | |
| val resource = | |
| ProgramResource.fromBytes(PathOrigin(file), ProgramResource.Kind.DEX, bytes, null) | |
| val provider = ProgramResourceProvider { listOf(resource) } | |
| val command = ResourceShrinker.Builder().addProgramResourceProvider(provider).build() | |
| ResourceShrinker.run(command, AnalysisAdapter(callback)) | |
| } | |
| /** An adapter so R8 API classes do not leak into other modules. */ | |
| class AnalysisAdapter(val impl: AnalysisCallback) : ResourceShrinker.ReferenceChecker { | |
| override fun shouldProcess(internalName: String): Boolean = impl.shouldProcess(internalName) | |
| override fun referencedStaticField(internalName: String, fieldName: String) = | |
| impl.referencedStaticField(internalName, fieldName) | |
| override fun referencedInt(value: Int) = impl.referencedInt(value) | |
| override fun referencedString(value: String) = impl.referencedString(value) | |
| override fun referencedMethod( | |
| internalName: String, methodName: String, methodDescriptor: String | |
| ) = impl.referencedMethod(internalName, methodName, methodDescriptor) | |
| override fun startMethodVisit(methodReference: MethodReference | |
| ) = impl.startMethodVisit(methodReference) | |
| override fun endMethodVisit(methodReference: MethodReference | |
| ) = impl.endMethodVisit(methodReference) | |
| } | |
| interface AnalysisCallback { | |
| fun shouldProcess(internalName: String): Boolean | |
| fun referencedInt(value: Int) | |
| fun referencedString(value: String) | |
| fun referencedStaticField(internalName: String, fieldName: String) | |
| fun referencedMethod(internalName: String, methodName: String, methodDescriptor: String) | |
| fun startMethodVisit(methodReference: MethodReference) | |
| fun endMethodVisit(methodReference: MethodReference) | |
| } | |
| class MethodVisitingStatus(var isVisiting: Boolean = false, var methodName: String? = null) |