From 5a302fd488342c0da055caed16d700d833e896d1 Mon Sep 17 00:00:00 2001
From: Matthias Urhahn <matthias.urhahn@sap.com>
Date: Wed, 16 Jun 2021 15:46:00 +0200
Subject: [PATCH] Don't start ESL on app start in test build (EXPOSUREAPP-7946)
 (#3471)

* Enable ELS autologging in tester builds only if a specific package is installed.
This allows us to both disable it by default, but still have a way to log the initial app launch if necessary (or have it automatically enabled by just having the package installed).

* Fix tests, add more tests.

Co-authored-by: harambasicluka <64483219+harambasicluka@users.noreply.github.com>
Co-authored-by: BMItter <Berndus@gmx.de>
Co-authored-by: AlexanderAlferov <64849422+AlexanderAlferov@users.noreply.github.com>
---
 .../src/deviceForTesters/AndroidManifest.xml  |  9 +++
 .../bugreporting/debuglog/DebugLogger.kt      | 20 +++++-
 .../bugreporting/debuglog/DebugLoggerTest.kt  | 66 ++++++++++++++++++-
 3 files changed, 93 insertions(+), 2 deletions(-)
 create mode 100644 Corona-Warn-App/src/deviceForTesters/AndroidManifest.xml

diff --git a/Corona-Warn-App/src/deviceForTesters/AndroidManifest.xml b/Corona-Warn-App/src/deviceForTesters/AndroidManifest.xml
new file mode 100644
index 000000000..88a2064d0
--- /dev/null
+++ b/Corona-Warn-App/src/deviceForTesters/AndroidManifest.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <queries>
+        <!-- See DebugLogger.isAutoLoggingEnabled -->
+        <package android:name="de.rki.coronawarnapp.els.autologger" />
+    </queries>
+
+</manifest>
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/DebugLogger.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/DebugLogger.kt
index ab7f0f1f6..3860af4b3 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/DebugLogger.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/DebugLogger.kt
@@ -2,6 +2,7 @@ package de.rki.coronawarnapp.bugreporting.debuglog
 
 import android.annotation.SuppressLint
 import android.content.Context
+import android.content.pm.PackageManager
 import android.util.Log
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor
 import de.rki.coronawarnapp.bugreporting.debuglog.internal.DebugLogStorageCheck
@@ -62,13 +63,30 @@ class DebugLogger(
         )
     }
 
+    private fun isAutoLoggingEnabled(): Boolean {
+        if (!CWADebug.isDeviceForTestersBuild) return false
+
+        return try {
+            val autoLoggerPkg = "de.rki.coronawarnapp.els.autologger"
+            context.packageManager.getPackageInfo(autoLoggerPkg, 0)
+            Timber.tag(TAG).i("Autologger package is installed (%s).", autoLoggerPkg)
+            true
+        } catch (e: PackageManager.NameNotFoundException) {
+            Timber.tag(TAG).i("DeviceForTester build, but no autologger package installed.")
+            false
+        } catch (e: Exception) {
+            Timber.tag(TAG).e(e, "Failed to determiner if autologger package is installed.")
+            false
+        }
+    }
+
     fun init() = try {
         val startLogger = when {
             triggerFile.exists() -> {
                 Timber.tag(TAG).i("Trigger file exists, starting debug log.")
                 true
             }
-            CWADebug.isDeviceForTestersBuild -> {
+            isAutoLoggingEnabled() -> {
                 Timber.tag(TAG).i("Trigger file does not exist, but it's a tester build, starting debug log.")
                 true
             }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/debuglog/DebugLoggerTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/debuglog/DebugLoggerTest.kt
index 329aed6fb..20309b770 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/debuglog/DebugLoggerTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/debuglog/DebugLoggerTest.kt
@@ -1,6 +1,7 @@
 package de.rki.coronawarnapp.bugreporting.debuglog
 
 import android.app.Application
+import android.content.pm.PackageManager
 import dagger.Lazy
 import de.rki.coronawarnapp.bugreporting.censors.BugCensor
 import de.rki.coronawarnapp.bugreporting.debuglog.internal.DebugLogTree
@@ -10,11 +11,14 @@ import io.kotest.matchers.shouldBe
 import io.kotest.matchers.shouldNotBe
 import io.kotest.matchers.string.shouldEndWith
 import io.kotest.matchers.string.shouldStartWith
+import io.mockk.Called
 import io.mockk.MockKAnnotations
 import io.mockk.coEvery
 import io.mockk.every
 import io.mockk.impl.annotations.MockK
+import io.mockk.mockk
 import io.mockk.mockkObject
+import io.mockk.verify
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.test.runBlockingTest
@@ -31,6 +35,7 @@ import java.io.File
 class DebugLoggerTest : BaseIOTest() {
 
     @MockK lateinit var application: Application
+    @MockK lateinit var packageManager: PackageManager
     @MockK lateinit var component: ApplicationComponent
     @MockK lateinit var coronaTestCensor1: BugCensor
     @MockK lateinit var coronaTestCensor2: BugCensor
@@ -51,6 +56,8 @@ class DebugLoggerTest : BaseIOTest() {
         testDir.exists() shouldBe true
 
         every { application.cacheDir } returns cacheDir
+        every { application.packageManager } returns packageManager
+
         every { component.inject(any<DebugLogger>()) } answers {
             val logger = arg<DebugLogger>(0)
             logger.bugCensors = Lazy { setOf(coronaTestCensor1, coronaTestCensor2) }
@@ -102,9 +109,13 @@ class DebugLoggerTest : BaseIOTest() {
     }
 
     @Test
-    fun `init calls start if it is a tester build`() = runBlockingTest {
+    fun `init calls start if it is a tester build and autologger pkg is installed`() = runBlockingTest {
         every { CWADebug.isDeviceForTestersBuild } returns true
 
+        every {
+            packageManager.getPackageInfo("de.rki.coronawarnapp.els.autologger", 0)
+        } returns mockk()
+
         val instance = createInstance(scope = this).apply {
             init()
             setInjectionIsReady(component)
@@ -116,6 +127,59 @@ class DebugLoggerTest : BaseIOTest() {
         instance.stop()
     }
 
+    @Test
+    fun `init does not call start on tester builds without the autologger pkg`() = runBlockingTest {
+        every { CWADebug.isDeviceForTestersBuild } returns true
+
+        every { application.packageManager } returns mockk<PackageManager>().apply {
+            every { getPackageInfo(any<String>(), any()) } throws PackageManager.NameNotFoundException()
+        }
+
+        val instance = createInstance(scope = this).apply {
+            init()
+            setInjectionIsReady(component)
+            isLogging.value shouldBe false
+        }
+
+        runningLog.exists() shouldBe false
+
+        instance.stop()
+    }
+
+    @Test
+    fun `init does not call start on tester builds with ROM issues`() = runBlockingTest {
+        every { CWADebug.isDeviceForTestersBuild } returns true
+
+        every { application.packageManager } throws SecurityException()
+
+        val instance = createInstance(scope = this).apply {
+            init()
+            setInjectionIsReady(component)
+            isLogging.value shouldBe false
+        }
+
+        runningLog.exists() shouldBe false
+
+        instance.stop()
+    }
+
+    @Test
+    fun `package check is not executed in PROD`() = runBlockingTest {
+        every { CWADebug.isDeviceForTestersBuild } returns false
+
+        val instance = createInstance(scope = this).apply {
+            init()
+            setInjectionIsReady(component)
+            isLogging.value shouldBe false
+        }
+
+        runningLog.exists() shouldBe false
+
+        instance.stop()
+
+        verify { packageManager wasNot Called }
+    }
+
     @Test
     fun `start plants a tree and starts a logging coroutine`() = runBlockingTest {
         val instance = createInstance(scope = this).apply {
-- 
GitLab