|  | /* | 
|  | * 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) |