Fix DebugInfoExporter hanging

This commit is contained in:
世界
2026-03-12 22:34:43 +08:00
parent d64e3b4235
commit c2f1fd8e67
2 changed files with 30 additions and 37 deletions

View File

@@ -13,11 +13,13 @@ import java.io.StringWriter
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
import java.util.zip.Deflater
import java.util.zip.ZipEntry import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream import java.util.zip.ZipOutputStream
object DebugInfoExporter { object DebugInfoExporter {
private const val TAG = "DebugInfoExporter" private const val TAG = "DebugInfoExporter"
private const val BUFFER_SIZE = 128 * 1024
fun export(context: Context, outputPath: String, packageName: String): String { fun export(context: Context, outputPath: String, packageName: String): String {
Log.i(TAG, "export start: output=$outputPath, package=$packageName") Log.i(TAG, "export start: output=$outputPath, package=$packageName")
@@ -94,43 +96,27 @@ object DebugInfoExporter {
private fun addFrameworkEntries(zip: ZipOutputStream, warnings: MutableList<String>): Int { private fun addFrameworkEntries(zip: ZipOutputStream, warnings: MutableList<String>): Int {
var count = 0 var count = 0
val roots = val root = File("/system/framework")
listOf( if (!root.isDirectory) return 0
File("/system/framework"),
File("/system_ext/framework"),
File("/product/framework"),
File("/vendor/framework"),
)
val targetFiles = setOf("framework.jar", "services.jar") val targetFiles = setOf("framework.jar", "services.jar")
for (root in roots) {
if (!root.isDirectory) continue
val destPrefix = "framework/${root.name}"
val files = root.listFiles() ?: emptyArray() val files = root.listFiles() ?: emptyArray()
for (file in files) { for (file in files) {
if (!file.isFile) continue if (!file.isFile) continue
if (file.name !in targetFiles) continue if (file.name !in targetFiles) continue
if (addFileEntry(zip, file, "$destPrefix/${file.name}", warnings)) { if (addFileEntry(zip, file, "framework/${file.name}", warnings, noCompression = true)) {
count++ count++
} }
} }
}
return count return count
} }
private fun addApexEntries(zip: ZipOutputStream, warnings: MutableList<String>): Int { private fun addApexEntries(zip: ZipOutputStream, warnings: MutableList<String>): Int {
var count = 0 val file = File("/apex/com.android.tethering/javalib/service-connectivity.jar")
val tetheringApex = File("/apex/com.android.tethering/javalib") if (!file.isFile) {
if (!tetheringApex.isDirectory) return 0 warnings.add("missing file: ${file.path}")
val destPrefix = "framework/apex_com.android.tethering" return 0
val files = tetheringApex.listFiles() ?: emptyArray()
for (file in files) {
if (!file.isFile) continue
if (!file.name.lowercase(Locale.US).endsWith(".jar")) continue
if (addFileEntry(zip, file, "$destPrefix/${file.name}", warnings)) {
count++
} }
} return if (addFileEntry(zip, file, "framework/apex_com.android.tethering/service-connectivity.jar", warnings, noCompression = true)) 1 else 0
return count
} }
private fun addLogEntries(zip: ZipOutputStream, warnings: MutableList<String>, context: Context): Int { private fun addLogEntries(zip: ZipOutputStream, warnings: MutableList<String>, context: Context): Int {
@@ -222,16 +208,22 @@ object DebugInfoExporter {
return count return count
} }
private fun addFileEntry(zip: ZipOutputStream, file: File, entryName: String, warnings: MutableList<String>): Boolean { private fun addFileEntry(
zip: ZipOutputStream,
file: File,
entryName: String,
warnings: MutableList<String>,
noCompression: Boolean = false,
): Boolean {
if (!file.isFile) { if (!file.isFile) {
warnings.add("missing file: ${file.path}") warnings.add("missing file: ${file.path}")
return false return false
} }
try { try {
val entry = ZipEntry(entryName) if (noCompression) zip.setLevel(Deflater.NO_COMPRESSION)
zip.putNextEntry(entry) zip.putNextEntry(ZipEntry(entryName))
BufferedInputStream(FileInputStream(file)).use { input -> BufferedInputStream(FileInputStream(file)).use { input ->
val buffer = ByteArray(16 * 1024) val buffer = ByteArray(BUFFER_SIZE)
while (true) { while (true) {
val read = input.read(buffer) val read = input.read(buffer)
if (read <= 0) break if (read <= 0) break
@@ -239,9 +231,11 @@ object DebugInfoExporter {
} }
} }
zip.closeEntry() zip.closeEntry()
if (noCompression) zip.setLevel(Deflater.DEFAULT_COMPRESSION)
return true return true
} catch (e: Throwable) { } catch (e: Throwable) {
warnings.add("zip failed ${file.path}: ${e.message}") warnings.add("zip failed ${file.path}: ${e.message}")
if (noCompression) zip.setLevel(Deflater.DEFAULT_COMPRESSION)
return false return false
} }
} }
@@ -263,11 +257,10 @@ object DebugInfoExporter {
command: List<String>, command: List<String>,
): CommandResult? = try { ): CommandResult? = try {
val process = ProcessBuilder(command).redirectErrorStream(true).start() val process = ProcessBuilder(command).redirectErrorStream(true).start()
val entry = ZipEntry(entryName) zip.putNextEntry(ZipEntry(entryName))
zip.putNextEntry(entry)
var bytes = 0L var bytes = 0L
process.inputStream.use { input -> process.inputStream.use { input ->
val buffer = ByteArray(16 * 1024) val buffer = ByteArray(BUFFER_SIZE)
while (true) { while (true) {
val read = input.read(buffer) val read = input.read(buffer)
if (read <= 0) break if (read <= 0) break

View File

@@ -95,7 +95,7 @@ object RootClient {
shell.execTask(task) shell.execTask(task)
} else { } else {
continuation.resumeWithException( continuation.resumeWithException(
IOException("permission denied") IOException("permission denied"),
) )
} }
} catch (e: Exception) { } catch (e: Exception) {