Commit 84590c6e authored by Roger Yang's avatar Roger Yang
Browse files

Closes #4666: Dynamically support JSON extra file from GeckoView

parent 3ffdc64b
......@@ -11,10 +11,13 @@ import android.os.Build
import androidx.annotation.VisibleForTesting
import mozilla.components.lib.crash.Crash
import mozilla.components.support.base.log.logger.Logger
import org.json.JSONException
import org.json.JSONObject
import org.mozilla.geckoview.BuildConfig
import java.io.BufferedReader
import java.io.File
import java.io.FileInputStream
import java.io.FileNotFoundException
import java.io.FileReader
import java.io.IOException
import java.io.InputStreamReader
......@@ -26,6 +29,7 @@ import java.net.URL
import java.nio.channels.Channels
import java.util.concurrent.TimeUnit
import java.util.zip.GZIPOutputStream
import kotlin.collections.HashMap
import kotlin.random.Random
private const val DEFAULT_SERVER_URL = "https://crash-reports.mozilla.com/submit?" +
......@@ -244,7 +248,12 @@ class MozillaSocorroService(
}
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
internal fun readExtrasFromFile(file: File): HashMap<String, String> {
internal fun jsonUnescape(string: String): String {
return string.replace("""\\\\""", "\\").replace("""\n""", "\n").replace("""\t""", "\t")
}
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
internal fun readExtrasFromLegacyFile(file: File): HashMap<String, String> {
var fileReader: FileReader? = null
var bufReader: BufferedReader? = null
var line: String?
......@@ -277,6 +286,37 @@ class MozillaSocorroService(
return map
}
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
internal fun readExtrasFromFile(file: File): HashMap<String, String> {
var resultMap = HashMap<String, String>()
var notJson = false
try {
FileReader(file).use { fileReader ->
val input = fileReader.readLines().firstOrNull()
?: throw JSONException("failed to read json file")
val jsonObject = JSONObject(input)
for (key in jsonObject.keys()) {
resultMap[key] = jsonUnescape(jsonObject.getString(key))
}
}
} catch (e: FileNotFoundException) {
Logger.error("failed to find extra file", e)
} catch (e: IOException) {
Logger.error("failed read the extra file", e)
} catch (e: JSONException) {
Logger.info("extras file JSON syntax error, trying legacy format")
notJson = true
}
if (notJson) {
resultMap = readExtrasFromLegacyFile(file)
}
return resultMap
}
private fun getExceptionStackTrace(throwable: Throwable, isCaughtException: Boolean): String {
val stringWriter = StringWriter()
val printWriter = PrintWriter(stringWriter)
......
......@@ -11,6 +11,7 @@ import mozilla.components.support.test.any
import mozilla.components.support.test.robolectric.testContext
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyBoolean
......@@ -189,16 +190,83 @@ class MozillaSocorroServiceTest {
val file = File(getResource("TestExtrasFile").file)
val extrasMap = service.readExtrasFromFile(file)
assert(extrasMap.size == 9)
assert(extrasMap["InstallTime"] == "1569440259")
assert(extrasMap["ProductName"] == "Test Product")
assert(extrasMap["StartupCrash"] == "0")
assert(extrasMap["StartupTime"] == "1569642043")
assert(extrasMap["useragent_locale"] == "en-US")
assert(extrasMap["CrashTime"] == "1569642098")
assert(extrasMap["UptimeTS"] == "56.3663876")
assert(extrasMap["SecondsSinceLastCrash"] == "104")
assert(extrasMap["TextureUsage"] == "12345678")
assertEquals(extrasMap.size, 27)
assertEquals(extrasMap["ContentSandboxLevel"], "2")
assertEquals(extrasMap["TelemetryEnvironment"], "{\"EscapedField\":\"EscapedData\n\nfoo\"}")
assertEquals(extrasMap["EMCheckCompatibility"], "true")
assertEquals(extrasMap["ProductName"], "Firefox")
assertEquals(extrasMap["ContentSandboxCapabilities"], "119")
assertEquals(extrasMap["TelemetryClientId"], "")
assertEquals(extrasMap["Vendor"], "Mozilla")
assertEquals(extrasMap["InstallTime"], "1000000000")
assertEquals(extrasMap["Theme"], "classic/1.0")
assertEquals(extrasMap["ReleaseChannel"], "default")
assertEquals(extrasMap["ServerURL"], "https://crash-reports.mozilla.com")
assertEquals(extrasMap["SafeMode"], "0")
assertEquals(extrasMap["ContentSandboxCapable"], "1")
assertEquals(extrasMap["useragent_locale"], "en-US")
assertEquals(extrasMap["Version"], "55.0a1")
assertEquals(extrasMap["BuildID"], "20170512114708")
assertEquals(extrasMap["ProductID"], "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}")
assertEquals(extrasMap["TelemetryServerURL"], "")
assertEquals(extrasMap["DOMIPCEnabled"], "1")
assertEquals(extrasMap["Add-ons"], "")
assertEquals(extrasMap["CrashTime"], "1494582646")
assertEquals(extrasMap["UptimeTS"], "14.9179586")
assertEquals(extrasMap["ThreadIdNameMapping"], "")
assertEquals(extrasMap["ContentSandboxEnabled"], "1")
assertEquals(extrasMap["StartupTime"], "1000000000")
assertEquals(extrasMap["URL"], "about:home")
}
@Test
fun `MozillaSocorroService parses legacyExtraFile correctly`() {
val service = spy(MozillaSocorroService(
testContext,
"Test App"
))
val file = File(getResource("TestLegacyExtrasFile").file)
val extrasMap = service.readExtrasFromFile(file)
assertEquals(extrasMap.size, 27)
assertEquals(extrasMap["ContentSandboxLevel"], "2")
assertEquals(extrasMap["TelemetryEnvironment"], "{\"EscapedField\":\"EscapedData\n\nfoo\"}")
assertEquals(extrasMap["EMCheckCompatibility"], "true")
assertEquals(extrasMap["ProductName"], "Firefox")
assertEquals(extrasMap["ContentSandboxCapabilities"], "119")
assertEquals(extrasMap["TelemetryClientId"], "")
assertEquals(extrasMap["Vendor"], "Mozilla")
assertEquals(extrasMap["InstallTime"], "1000000000")
assertEquals(extrasMap["Theme"], "classic/1.0")
assertEquals(extrasMap["ReleaseChannel"], "default")
assertEquals(extrasMap["ServerURL"], "https://crash-reports.mozilla.com")
assertEquals(extrasMap["SafeMode"], "0")
assertEquals(extrasMap["ContentSandboxCapable"], "1")
assertEquals(extrasMap["useragent_locale"], "en-US")
assertEquals(extrasMap["Version"], "55.0a1")
assertEquals(extrasMap["BuildID"], "20170512114708")
assertEquals(extrasMap["ProductID"], "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}")
assertEquals(extrasMap["TelemetryServerURL"], "")
assertEquals(extrasMap["DOMIPCEnabled"], "1")
assertEquals(extrasMap["Add-ons"], "")
assertEquals(extrasMap["CrashTime"], "1494582646")
assertEquals(extrasMap["UptimeTS"], "14.9179586")
assertEquals(extrasMap["ThreadIdNameMapping"], "")
assertEquals(extrasMap["ContentSandboxEnabled"], "1")
assertEquals(extrasMap["StartupTime"], "1000000000")
assertEquals(extrasMap["URL"], "about:home")
}
@Test
fun `MozillaSocorroService handles bad extrasFile correctly`() {
val service = spy(MozillaSocorroService(
testContext,
"Test App"
))
val file = File(getResource("BadTestExtrasFile").file)
val extrasMap = service.readExtrasFromFile(file)
assertEquals(extrasMap.size, 0)
}
@Test
......
{"ContentSandboxLevel":"2","TelemetryEnvironment":"{"EscapedField":"EscapedData\\n\\nfoo"}","EMCheckCompatibility":"true","ProductName":"Firefox","ContentSandboxCapabilities":"119","TelemetryClientId":"","Vendor":"Mozilla","InstallTime":"1000000000","Theme":"classic/1.0","ReleaseChannel":"default","ServerURL":"https://crash-reports.mozilla.com","SafeMode":"0","ContentSandboxCapable":"1","useragent_locale":"en-US","Version":"55.0a1","BuildID":"20170512114708","ProductID":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","TelemetryServerURL":"","DOMIPCEnabled":"1","Add-ons":"","CrashTime":"1494582646","UptimeTS":"14.9179586","ThreadIdNameMapping":"","ContentSandboxEnabled":"1","ProcessType":"content","StartupTime":"1000000000","URL":"about:home"}
InstallTime=1569440259
ProductName=Test Product
StartupCrash=0
StartupTime=1569642043
useragent_locale=en-US
CrashTime=1569642098
UptimeTS=56.3663876
SecondsSinceLastCrash=104
TextureUsage=12345678
{"ContentSandboxLevel":"2","TelemetryEnvironment":"{\"EscapedField\":\"EscapedData\\n\\nfoo\"}","EMCheckCompatibility":"true","ProductName":"Firefox","ContentSandboxCapabilities":"119","TelemetryClientId":"","Vendor":"Mozilla","InstallTime":"1000000000","Theme":"classic/1.0","ReleaseChannel":"default","ServerURL":"https://crash-reports.mozilla.com","SafeMode":"0","ContentSandboxCapable":"1","useragent_locale":"en-US","Version":"55.0a1","BuildID":"20170512114708","ProductID":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","TelemetryServerURL":"","DOMIPCEnabled":"1","Add-ons":"","CrashTime":"1494582646","UptimeTS":"14.9179586","ThreadIdNameMapping":"","ContentSandboxEnabled":"1","ProcessType":"content","StartupTime":"1000000000","URL":"about:home"}
ContentSandboxLevel=2
TelemetryEnvironment={"EscapedField":"EscapedData\\n\\nfoo"}
EMCheckCompatibility=true
ProductName=Firefox
ContentSandboxCapabilities=119
TelemetryClientId=
Vendor=Mozilla
InstallTime=1000000000
Theme=classic/1.0
ReleaseChannel=default
ServerURL=https://crash-reports.mozilla.com
SafeMode=0
ContentSandboxCapable=1
useragent_locale=en-US
Version=55.0a1
BuildID=20170512114708
ProductID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
TelemetryServerURL=
DOMIPCEnabled=1
Add-ons=
CrashTime=1494582646
UptimeTS=14.9179586
ThreadIdNameMapping=
ContentSandboxLevel=2
ContentSandboxEnabled=1
ProcessType=content
DOMIPCEnabled=1
StartupTime=1000000000
URL=about:home
ContentSandboxCapabilities=119
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment