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

Commit 623cffb0 authored by Makoto Onuki's avatar Makoto Onuki
Browse files

HostStubGen: Write verbose/debug log to a file

See below for the log filename.

Also disable an unimplemented flag.

Bug: 311174191
Test: ./scripts/run-all-tests.sh
Test: m framework-minus-apex.ravenwood
    and examine console output and
    out/soong/.intermediates/frameworks/base/framework-minus-apex.ravenwood-base/android_common/gen/hoststubgen_framework-minus-apex.log
Change-Id: I9997370c93e2fe90276d5f3e657d45d440ca0a59
parent a29375a5
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@ java_genrule {
    cmd: "$(location hoststubgen) " +
        "@$(location ravenwood/ravenwood-standard-options.txt) " +

        "--debug-log $(location hoststubgen_framework-minus-apex.log) " +

        "--out-impl-jar $(location ravenwood.jar) " +

        "--gen-keep-all-file $(location hoststubgen_keep_all.txt) " +
@@ -52,6 +54,8 @@ java_genrule {
        // Following files are created just as FYI.
        "hoststubgen_keep_all.txt",
        "hoststubgen_dump.txt",

        "hoststubgen_framework-minus-apex.log",
    ],
    visibility: ["//visibility:private"],
}
+1 −1
Original line number Diff line number Diff line
# File containing standard options to HostStubGen for Ravenwood

--debug
# --debug # To enable debug log on consone

# Keep all classes / methods / fields, but make the methods throw.
--default-throw
+0 −4
Original line number Diff line number Diff line
@@ -235,10 +235,6 @@ EXTRA_ARGS="--in-jar abc" run_hoststubgen_for_failure "Duplicate arg" \
    "Duplicate or conflicting argument found: --in-jar" \
    ""

EXTRA_ARGS="--quiet" run_hoststubgen_for_failure "Conflicting arg" \
    "Duplicate or conflicting argument found: --quiet" \
    ""


echo "All tests passed"
exit 0
 No newline at end of file
+2 −2
Original line number Diff line number Diff line
@@ -239,7 +239,7 @@ class HostStubGen(val options: HostStubGenOptions) {
            errors: HostStubGenErrors,
            ) {
        log.i("Converting %s into [stub: %s, impl: %s] ...", inJar, outStubJar, outImplJar)
        log.i("Checker is %s", if (enableChecker) "enabled" else "disabled")
        log.i("ASM CheckClassAdapter is %s", if (enableChecker) "enabled" else "disabled")

        val start = System.currentTimeMillis()

@@ -264,7 +264,7 @@ class HostStubGen(val options: HostStubGenOptions) {
            }
        }
        val end = System.currentTimeMillis()
        log.v("Done transforming the jar in %.1f second(s).", (end - start) / 1000.0)
        log.i("Done transforming the jar in %.1f second(s).", (end - start) / 1000.0)
    }

    private fun <T> maybeWithZipOutputStream(filename: String?, block: (ZipOutputStream?) -> T): T {
+141 −78
Original line number Diff line number Diff line
@@ -15,10 +15,12 @@
 */
package com.android.hoststubgen

import java.io.OutputStream
import java.io.PrintStream
import java.io.BufferedOutputStream
import java.io.FileOutputStream
import java.io.PrintWriter
import java.io.Writer

val log: HostStubGenLogger = HostStubGenLogger()
val log: HostStubGenLogger = HostStubGenLogger().setConsoleLogLevel(LogLevel.Info)

/** Logging level */
enum class LogLevel {
@@ -30,15 +32,13 @@ enum class LogLevel {
    Debug,
}

/** Simple logging class. */
class HostStubGenLogger(
        private var out: PrintStream = System.out!!,
        var level: LogLevel = LogLevel.Info,
) {
    companion object {
        private val sNullPrintStream: PrintStream = PrintStream(OutputStream.nullOutputStream())
    }

/**
 * Simple logging class.
 *
 * By default, it has no printers set. Use [setConsoleLogLevel] or [addFilePrinter] to actually
 * write log.
 */
class HostStubGenLogger {
    private var indentLevel: Int = 0
        get() = field
        set(value) {
@@ -47,6 +47,56 @@ class HostStubGenLogger(
        }
    private var indent: String = ""

    private val printers: MutableList<LogPrinter> = mutableListOf()

    private var consolePrinter: LogPrinter? = null

    private var maxLogLevel = LogLevel.None

    private fun updateMaxLogLevel() {
        maxLogLevel = LogLevel.None

        printers.forEach {
            if (maxLogLevel < it.logLevel) {
                maxLogLevel = it.logLevel
            }
        }
    }

    private fun addPrinter(printer: LogPrinter) {
        printers.add(printer)
        updateMaxLogLevel()
    }

    private fun removePrinter(printer: LogPrinter) {
        printers.remove(printer)
        updateMaxLogLevel()
    }

    fun setConsoleLogLevel(level: LogLevel): HostStubGenLogger {
        // If there's already a console log printer set, remove it, and then add a new one
        consolePrinter?.let {
            removePrinter(it)
        }
        val cp = StreamPrinter(level, PrintWriter(System.out))
        addPrinter(cp)
        consolePrinter = cp

        return this
    }

    fun addFilePrinter(level: LogLevel, logFilename: String): HostStubGenLogger {
        addPrinter(StreamPrinter(level, PrintWriter(BufferedOutputStream(
            FileOutputStream(logFilename)))))

        return this
    }

    /** Flush all the printers */
    fun flush() {
        printers.forEach { it.flush() }
    }

    fun indent() {
        indentLevel++
    }
@@ -68,92 +118,71 @@ class HostStubGenLogger(
    }

    fun isEnabled(level: LogLevel): Boolean {
        return level.ordinal <= this.level.ordinal
        return level.ordinal <= maxLogLevel.ordinal
    }

    private fun println(message: String) {
        out.print(indent)
        out.println(message)
    private fun println(level: LogLevel, message: String) {
        printers.forEach {
            if (it.logLevel.ordinal >= level.ordinal) {
                it.println(level, indent, message)
            }
        }
    }

    private fun println(level: LogLevel, format: String, vararg args: Any?) {
        if (isEnabled(level)) {
            println(level, String.format(format, *args))
        }
    }

    /** Log an error. */
    fun e(message: String) {
        if (level.ordinal < LogLevel.Error.ordinal) {
            return
        }
        println(message)
        println(LogLevel.Error, message)
    }

    /** Log an error. */
    fun e(format: String, vararg args: Any?) {
        if (level.ordinal < LogLevel.Error.ordinal) {
            return
        }
        e(String.format(format, *args))
        println(LogLevel.Error, format, *args)
    }

    /** Log a warning. */
    fun w(message: String) {
        if (level.ordinal < LogLevel.Warn.ordinal) {
            return
        }
        println(message)
        println(LogLevel.Warn, message)
    }

    /** Log a warning. */
    fun w(format: String, vararg args: Any?) {
        if (level.ordinal < LogLevel.Warn.ordinal) {
            return
        }
        w(String.format(format, *args))
        println(LogLevel.Warn, format, *args)
    }

    /** Log an info message. */
    fun i(message: String) {
        if (level.ordinal < LogLevel.Info.ordinal) {
            return
        }
        println(message)
        println(LogLevel.Info, message)
    }

    /** Log a debug message. */
    /** Log an info message. */
    fun i(format: String, vararg args: Any?) {
        if (level.ordinal < LogLevel.Warn.ordinal) {
            return
        }
        i(String.format(format, *args))
        println(LogLevel.Info, format, *args)
    }

    /** Log a verbose message. */
    fun v(message: String) {
        if (level.ordinal < LogLevel.Verbose.ordinal) {
            return
        }
        println(message)
        println(LogLevel.Verbose, message)
    }

    /** Log a verbose message. */
    fun v(format: String, vararg args: Any?) {
        if (level.ordinal < LogLevel.Verbose.ordinal) {
            return
        }
        v(String.format(format, *args))
        println(LogLevel.Verbose, format, *args)
    }

    /** Log a debug message. */
    fun d(message: String) {
        if (level.ordinal < LogLevel.Debug.ordinal) {
            return
        }
        println(message)
        println(LogLevel.Debug, message)
    }

    /** Log a debug message. */
    fun d(format: String, vararg args: Any?) {
        if (level.ordinal < LogLevel.Warn.ordinal) {
            return
        }
        d(String.format(format, *args))
        println(LogLevel.Debug, format, *args)
    }

    inline fun forVerbose(block: () -> Unit) {
@@ -168,31 +197,65 @@ class HostStubGenLogger(
        }
    }

    /** Return a stream for error. */
    fun getErrorPrintStream(): PrintStream {
        if (level.ordinal < LogLevel.Error.ordinal) {
            return sNullPrintStream
    /** Return a Writer for a given log level. */
    fun getWriter(level: LogLevel): Writer {
        return MultiplexingWriter(level)
    }

        // TODO Apply indent
        return PrintStream(out)
    private inner class MultiplexingWriter(val level: LogLevel) : Writer() {
        private inline fun forPrinters(callback: (LogPrinter) -> Unit) {
            printers.forEach {
                if (it.logLevel.ordinal >= level.ordinal) {
                    callback(it)
                }
            }
        }

        override fun close() {
            flush()
        }

    /** Return a stream for verbose messages. */
    fun getVerbosePrintStream(): PrintStream {
        if (level.ordinal < LogLevel.Verbose.ordinal) {
            return sNullPrintStream
        override fun flush() {
            forPrinters {
                it.flush()
            }
        }

        override fun write(cbuf: CharArray, off: Int, len: Int) {
            // TODO Apply indent
        return PrintStream(out)
            forPrinters {
                it.write(cbuf, off, len)
            }
        }
    }
}

private interface LogPrinter {
    val logLevel: LogLevel

    fun println(logLevel: LogLevel, indent: String, message: String)

    // TODO: This should be removed once MultiplexingWriter starts applying indent, at which point
    // println() should be used instead.
    fun write(cbuf: CharArray, off: Int, len: Int)

    fun flush()
}

private class StreamPrinter(
    override val logLevel: LogLevel,
    val out: PrintWriter,
) : LogPrinter {
    override fun println(logLevel: LogLevel, indent: String, message: String) {
        out.print(indent)
        out.println(message)
    }

    /** Return a stream for debug messages. */
    fun getInfoPrintStream(): PrintStream {
        if (level.ordinal < LogLevel.Info.ordinal) {
            return sNullPrintStream
    override fun write(cbuf: CharArray, off: Int, len: Int) {
        out.write(cbuf, off, len)
    }
        // TODO Apply indent
        return PrintStream(out)

    override fun flush() {
        out.flush()
    }
}
Loading