diff --git a/android/app/build.gradle b/android/app/build.gradle index 92dece2414..3537df033d 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -28,7 +28,7 @@ android { '-DSTABLE_BUILD=' + STABLE_BUILD, '-DDISABLE_QML=OFF', '-DDISABLE_KTX_CACHE=OFF', - '-DUSE_BREAKPAD=' + (project.hasProperty("BACKTRACE_URL") && project.hasProperty("BACKTRACE_TOKEN") ? 'ON' : 'OFF'); + '-DUSE_BREAKPAD=' + (System.getenv("CMAKE_BACKTRACE_URL") && System.getenv("CMAKE_BACKTRACE_TOKEN") ? 'ON' : 'OFF'); } } signingConfigs { @@ -48,8 +48,8 @@ android { buildTypes { debug { - buildConfigField "String", "BACKTRACE_URL", "\"" + (project.hasProperty("BACKTRACE_URL") ? BACKTRACE_URL : '') + "\"" - buildConfigField "String", "BACKTRACE_TOKEN", "\"" + (project.hasProperty("BACKTRACE_TOKEN") ? BACKTRACE_TOKEN : '') + "\"" + buildConfigField "String", "BACKTRACE_URL", "\"" + (System.getenv("CMAKE_BACKTRACE_URL") ? System.getenv("CMAKE_BACKTRACE_URL") : '') + "\"" + buildConfigField "String", "BACKTRACE_TOKEN", "\"" + (System.getenv("CMAKE_BACKTRACE_TOKEN") ? System.getenv("CMAKE_BACKTRACE_TOKEN") : '') + "\"" } release { minifyEnabled false @@ -58,8 +58,8 @@ android { project.hasProperty("HIFI_ANDROID_KEYSTORE_PASSWORD") && project.hasProperty("HIFI_ANDROID_KEY_ALIAS") && project.hasProperty("HIFI_ANDROID_KEY_PASSWORD")? signingConfigs.release : null - buildConfigField "String", "BACKTRACE_URL", "\"" + (project.hasProperty("BACKTRACE_URL") ? BACKTRACE_URL : '') + "\"" - buildConfigField "String", "BACKTRACE_TOKEN", "\"" + (project.hasProperty("BACKTRACE_TOKEN") ? BACKTRACE_TOKEN : '') + "\"" + buildConfigField "String", "BACKTRACE_URL", "\"" + (System.getenv("CMAKE_BACKTRACE_URL") ? System.getenv("CMAKE_BACKTRACE_URL") : '') + "\"" + buildConfigField "String", "BACKTRACE_TOKEN", "\"" + (System.getenv("CMAKE_BACKTRACE_TOKEN") ? System.getenv("CMAKE_BACKTRACE_TOKEN") : '') + "\"" } } @@ -74,6 +74,10 @@ android { // so our merge has to depend on the external native build variant.externalNativeBuildTasks.each { task -> variant.mergeResources.dependsOn(task) + def uploadDumpSymsTask = rootProject.getTasksByName("uploadBreakpadDumpSyms${variant.name.capitalize()}", false).first() + def runDumpSymsTask = rootProject.getTasksByName("runBreakpadDumpSyms${variant.name.capitalize()}", false).first() + runDumpSymsTask.dependsOn(task) + variant.assemble.dependsOn(uploadDumpSymsTask) } variant.mergeAssets.doLast { diff --git a/android/build.gradle b/android/build.gradle index e2d92fe2f6..373569ca77 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -21,6 +21,7 @@ buildscript { plugins { id 'de.undercouch.download' version '3.3.0' id "cz.malohlava" version "1.0.3" + id "io.github.http-builder-ng.http-plugin" version "0.1.1" } allprojects { @@ -67,6 +68,7 @@ def baseFolder = new File(HIFI_ANDROID_PRECOMPILED) def appDir = new File(projectDir, 'app') def jniFolder = new File(appDir, 'src/main/jniLibs/arm64-v8a') def baseUrl = 'https://hifi-public.s3.amazonaws.com/dependencies/android/' +def breakpadDumpSymsDir = new File("${appDir}/build/tmp/breakpadDumpSyms") def qtFile='qt-5.9.3_linux_armv8-libcpp_openssl.tgz' def qtChecksum='04599670ccca84bd2b15f6915568eb2d' @@ -151,11 +153,11 @@ def packages = [ checksum: '14b02795d774457a33bbc60e00a786bc' ], breakpad: [ - file: 'breakpad.zip', - versionId: '2OwvCCZrF171wnte5T44AnjTYFhhJsGJ', - checksum: 'a46062a3167dfedd4fb4916136e204d2', + file: 'breakpad.tgz', + versionId: '8VrYXz7oyc.QBxNia0BVJOUBvrFO61jI', + checksum: 'ddcb23df336b08017042ba4786db1d9e', sharedLibFolder: 'lib', - includeLibs: ['libbreakpad_client.a','libbreakpad.a'] + includeLibs: ['libbreakpad_client.a'] ] ] @@ -549,7 +551,93 @@ task cleanDependencies(type: Delete) { delete 'app/src/main/res/values/libs.xml' } +def runBreakpadDumpSyms = { buildType -> + gradle.startParameter.showStacktrace = ShowStacktrace.ALWAYS + def objDir = new File("${appDir}/build/intermediates/cmake/${buildType}/obj/arm64-v8a") + def stripDebugSymbol = "${appDir}/build/intermediates/transforms/stripDebugSymbol/${buildType}/0/lib/arm64-v8a/" + def outputDir = new File(breakpadDumpSymsDir, buildType) + if (!outputDir.exists()) { + outputDir.mkdirs() + } + + objDir.eachFileRecurse (FileType.FILES) { file -> + if (file.name.endsWith('.so')) { + def output = file.name + ".sym" + def cmdArgs = [ + file.toString(), + stripDebugSymbol + ] + def result = exec { + workingDir HIFI_ANDROID_PRECOMPILED + '/breakpad/bin' + commandLine './dump_syms' + args cmdArgs + ignoreExitValue true + standardOutput = new BufferedOutputStream(new FileOutputStream(new File(outputDir, output))) + } + } + } +} + +task runBreakpadDumpSymsDebug() { + doLast { + runBreakpadDumpSyms("debug"); + } +} + +task runBreakpadDumpSymsRelease() { + doLast { + runBreakpadDumpSyms("release"); + } +} + +task zipDumpSymsDebug(type: Zip, dependsOn: runBreakpadDumpSymsDebug) { + from (new File(breakpadDumpSymsDir, "debug").absolutePath) + archiveName "symbols-${RELEASE_NUMBER}-debug.zip" + destinationDir(new File("${appDir}/build/tmp/")) +} + +task zipDumpSymsRelease(type: Zip, dependsOn: runBreakpadDumpSymsRelease) { + from (new File(breakpadDumpSymsDir, "release").absolutePath) + archiveName "symbols-${RELEASE_NUMBER}-release.zip" + destinationDir(new File("${appDir}/build/tmp/")) +} + +task uploadBreakpadDumpSymsDebug(type:io.github.httpbuilderng.http.HttpTask, dependsOn: zipDumpSymsDebug) { + onlyIf { + System.getenv("CMAKE_BACKTRACE_URL") && System.getenv("CMAKE_BACKTRACE_SYMBOLS_TOKEN") + } + config { + request.uri = System.getenv("CMAKE_BACKTRACE_URL") + } + post { + request.uri.path = '/post' + request.uri.query = [format: 'symbols', token: System.getenv("CMAKE_BACKTRACE_SYMBOLS_TOKEN")] + request.body = new File("${appDir}/build/tmp/", "symbols-${RELEASE_NUMBER}-debug.zip").bytes + request.contentType = 'application/octet-stream' + response.success { + println ("${appDir}/build/tmp/symbols-${RELEASE_NUMBER}-debug.zip uploaded") + } + } +} + +task uploadBreakpadDumpSymsRelease(type:io.github.httpbuilderng.http.HttpTask, dependsOn: zipDumpSymsRelease) { + onlyIf { + System.getenv("CMAKE_BACKTRACE_URL") && System.getenv("CMAKE_BACKTRACE_SYMBOLS_TOKEN") + } + config { + request.uri = System.getenv("CMAKE_BACKTRACE_URL") + } + post { + request.uri.path = '/post' + request.uri.query = [format: 'symbols', token: System.getenv("CMAKE_BACKTRACE_SYMBOLS_TOKEN")] + request.body = new File("${appDir}/build/tmp/", "symbols-${RELEASE_NUMBER}-release.zip").bytes + request.contentType = 'application/octet-stream' + response.success { + println ("${appDir}/build/tmp/symbols-${RELEASE_NUMBER}-release.zip uploaded") + } + } +} // FIXME this code is prototyping the desired functionality for doing build time binary dependency resolution. // See the comment on the qtBundle task above diff --git a/interface/src/CrashHandler_Breakpad.cpp b/interface/src/CrashHandler_Breakpad.cpp index fe4979853e..f2a174b6ea 100644 --- a/interface/src/CrashHandler_Breakpad.cpp +++ b/interface/src/CrashHandler_Breakpad.cpp @@ -24,6 +24,7 @@ #include #include +#include google_breakpad::ExceptionHandler* gBreakpadHandler; @@ -43,7 +44,23 @@ QString obbDir() { return dataAbsPath; } +void flushAnnotations() { + QSettings settings(obbDir() + "/annotations.json", JSON_FORMAT); + settings.clear(); + settings.beginGroup("Annotations"); + for (auto k : annotations.keys()) { + settings.setValue(k, annotations.value(k)); + } + settings.endGroup(); + settings.sync(); +} + bool startCrashHandler() { + annotations["version"] = BuildInfo::VERSION; + annotations["build_number"] = BuildInfo::BUILD_NUMBER; + annotations["build_type"] = BuildInfo::BUILD_TYPE_STRING; + + flushAnnotations(); gBreakpadHandler = new google_breakpad::ExceptionHandler( google_breakpad::MinidumpDescriptor(obbDir().toStdString()), @@ -56,15 +73,7 @@ void setCrashAnnotation(std::string name, std::string value) { QString qName = QString::fromStdString(name); QString qValue = QString::fromStdString(value); annotations[qName] = qValue; - - QSettings settings(obbDir() + "/annotations.json", JSON_FORMAT); - settings.clear(); - settings.beginGroup("Annotations"); - for (auto k : annotations.keys()) { - settings.setValue(k, annotations.value(k)); - } - settings.endGroup(); - settings.sync(); + flushAnnotations(); } #endif diff --git a/scripts/system/+android/audio.js b/scripts/system/+android/audio.js index 50919ed5d1..34dd52604a 100644 --- a/scripts/system/+android/audio.js +++ b/scripts/system/+android/audio.js @@ -46,7 +46,6 @@ function init() { function onMuteClicked() { Audio.muted = !Audio.muted; - Menu.triggerOption("Out of Bounds Vector Access"); } function onMutePressed() {