Fix DebugInfoExporter hanging
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user