diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 6ca59c4d9..aa2ae32ae 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -45,6 +45,14 @@ boolean ANDROID_DETECTED return true; } +#################################################################################################### +# Remove debug logs from release builds +#################################################################################################### +-assumenosideeffects class android.util.Log { + public static boolean isLoggable(java.lang.String, int); + public static int d(...); +} + #################################################################################################### # Mozilla Application Services #################################################################################################### diff --git a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt index 750a68d4c..086035b13 100644 --- a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt +++ b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt @@ -32,7 +32,6 @@ import mozilla.components.service.glean.config.Configuration import mozilla.components.service.glean.net.ConceptFetchHttpUploader import mozilla.components.support.base.log.Log import mozilla.components.support.base.log.logger.Logger -import mozilla.components.support.base.log.sink.AndroidLogSink import mozilla.components.support.ktx.android.content.isMainProcess import mozilla.components.support.ktx.android.content.runOnlyInMainProcess import mozilla.components.support.locale.LocaleAwareApplication @@ -42,7 +41,6 @@ import mozilla.components.support.utils.logElapsedTime import mozilla.components.support.webextensions.WebExtensionSupport import org.mozilla.fenix.components.Components import org.mozilla.fenix.components.metrics.MetricServiceType -import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.settings import org.mozilla.fenix.perf.StorageStatsMetrics import org.mozilla.fenix.perf.StartupTimeline @@ -114,7 +112,7 @@ open class FenixApplication : LocaleAwareApplication(), Provider { setupCrashReporting() // We want the log messages of all builds to go to Android logcat - Log.addSink(AndroidLogSink()) + Log.addSink(FenixLogSink(logsDebug = Config.channel.isDebug)) } @CallSuper diff --git a/app/src/main/java/org/mozilla/fenix/FenixLogSink.kt b/app/src/main/java/org/mozilla/fenix/FenixLogSink.kt new file mode 100644 index 000000000..b09b003af --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/FenixLogSink.kt @@ -0,0 +1,30 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix + +import mozilla.components.support.base.log.Log +import mozilla.components.support.base.log.sink.AndroidLogSink +import mozilla.components.support.base.log.sink.LogSink + +/** + * Fenix [LogSink] implementation that writes to Android's log, depending on settings. + * + * @param logsDebug If set to false, removes logging of debug logs. + */ +class FenixLogSink(private val logsDebug: Boolean = true) : LogSink { + + private val androidLogSink = AndroidLogSink() + + override fun log( + priority: Log.Priority, + tag: String?, + throwable: Throwable?, + message: String? + ) { + if (priority == Log.Priority.DEBUG && !logsDebug) + return + androidLogSink.log(priority, tag, throwable, message) + } +} diff --git a/app/src/test/java/org/mozilla/fenix/FenixLogSinkTest.kt b/app/src/test/java/org/mozilla/fenix/FenixLogSinkTest.kt new file mode 100644 index 000000000..b643e71e1 --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/FenixLogSinkTest.kt @@ -0,0 +1,77 @@ +package org.mozilla.fenix + +import android.util.Log +import io.mockk.mockkStatic +import io.mockk.unmockkStatic +import io.mockk.verify +import org.junit.After +import org.junit.Before +import org.junit.Test + +class FenixLogSinkTest { + + @Before + fun setup() { + mockkStatic(Log::class) + } + + @After + fun teardown() { + unmockkStatic(Log::class) + } + + @Test + fun `GIVEN we're in a release build WHEN we log debug statements THEN logs should not be forwarded`() { + val logSink = FenixLogSink(false) + logSink.log( + mozilla.components.support.base.log.Log.Priority.DEBUG, + "test", + message = "test" + ) + verify(exactly = 0) { Log.println(Log.DEBUG, "test", "test") } + } + + @Test + fun `GIVEN we're in a release build WHEN we log error statements THEN logs should be forwarded`() { + val logSink = FenixLogSink(false) + logSink.log( + mozilla.components.support.base.log.Log.Priority.ERROR, + "test", + message = "test" + ) + verify(exactly = 1) { Log.println(Log.ERROR, "test", "test") } + } + + @Test + fun `GIVEN we're in a release build WHEN we log warn statements THEN logs should be forwarded`() { + val logSink = FenixLogSink(false) + logSink.log( + mozilla.components.support.base.log.Log.Priority.WARN, + "test", + message = "test" + ) + verify(exactly = 1) { Log.println(Log.WARN, "test", "test") } + } + + @Test + fun `GIVEN we're in a release build WHEN we log info statements THEN logs should be forwarded`() { + val logSink = FenixLogSink(false) + logSink.log( + mozilla.components.support.base.log.Log.Priority.INFO, + "test", + message = "test" + ) + verify(exactly = 1) { Log.println(Log.INFO, "test", "test") } + } + + @Test + fun `GIVEN we're in a debug build WHEN we log debug statements THEN logs should be forwarded`() { + val logSink = FenixLogSink(true) + logSink.log( + mozilla.components.support.base.log.Log.Priority.DEBUG, + "test", + message = "test" + ) + verify(exactly = 1) { Log.println(Log.DEBUG, "test", "test") } + } +}