diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index b3414460..ff09a750 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -101,6 +101,7 @@ dependencies {
debugImplementation(libs.thirdparty.leakcanary)
add("nonFreeImplementation", libs.thirdparty.nonfree.googlePlayAuthApiPhone)
add("nonFreeImplementation", libs.thirdparty.nonfree.sentry)
+ add("freeImplementation", projects.sentryStub)
androidTestImplementation(libs.bundles.testDependencies)
androidTestImplementation(libs.bundles.androidTestDependencies)
diff --git a/app/src/main/java/dev/msfjarvis/aps/Application.kt b/app/src/main/java/dev/msfjarvis/aps/Application.kt
index 1a72655b..0c7def1c 100644
--- a/app/src/main/java/dev/msfjarvis/aps/Application.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/Application.kt
@@ -15,11 +15,15 @@ import dagger.hilt.android.HiltAndroidApp
import dev.msfjarvis.aps.injection.context.FilesDirPath
import dev.msfjarvis.aps.injection.prefs.SettingsPreferences
import dev.msfjarvis.aps.util.extensions.getString
+import dev.msfjarvis.aps.util.features.Feature
+import dev.msfjarvis.aps.util.features.Features
import dev.msfjarvis.aps.util.git.sshj.setUpBouncyCastleForSshj
import dev.msfjarvis.aps.util.proxy.ProxyUtils
import dev.msfjarvis.aps.util.settings.GitSettings
import dev.msfjarvis.aps.util.settings.PreferenceKeys
import dev.msfjarvis.aps.util.settings.runMigrations
+import io.sentry.Sentry
+import io.sentry.protocol.User
import javax.inject.Inject
import logcat.AndroidLogcatLogger
import logcat.LogPriority.DEBUG
@@ -33,6 +37,7 @@ class Application : android.app.Application(), SharedPreferences.OnSharedPrefere
@Inject @FilesDirPath lateinit var filesDirPath: String
@Inject lateinit var proxyUtils: ProxyUtils
@Inject lateinit var gitSettings: GitSettings
+ @Inject lateinit var features: Features
override fun onCreate() {
super.onCreate()
@@ -48,6 +53,14 @@ class Application : android.app.Application(), SharedPreferences.OnSharedPrefere
runMigrations(filesDirPath, prefs, gitSettings)
proxyUtils.setDefaultProxy()
DynamicColors.applyToActivitiesIfAvailable(this)
+ Sentry.configureScope { scope ->
+ val user = User()
+ user.others =
+ Feature.VALUES.associate { feature ->
+ "features.${feature.configKey}" to features.isEnabled(feature).toString()
+ }
+ scope.user = user
+ }
}
override fun onTerminate() {
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/features/Feature.kt b/app/src/main/java/dev/msfjarvis/aps/util/features/Feature.kt
index 7ae2e642..4eef003d 100644
--- a/app/src/main/java/dev/msfjarvis/aps/util/features/Feature.kt
+++ b/app/src/main/java/dev/msfjarvis/aps/util/features/Feature.kt
@@ -15,4 +15,9 @@ enum class Feature(
/** Opt into the new PGP backend powered by the PGPainless library. */
EnablePGPainlessBackend(false, "enable_pgp_v2_backend"),
+ ;
+
+ companion object {
+ @JvmField val VALUES = values()
+ }
}
diff --git a/app/src/nonFree/AndroidManifest.xml b/app/src/nonFree/AndroidManifest.xml
index 2f8d2746..83103b18 100644
--- a/app/src/nonFree/AndroidManifest.xml
+++ b/app/src/nonFree/AndroidManifest.xml
@@ -6,6 +6,6 @@
-
+
diff --git a/build-logic/android-plugins/build.gradle.kts b/build-logic/android-plugins/build.gradle.kts
index cdc7c315..dfe77e89 100644
--- a/build-logic/android-plugins/build.gradle.kts
+++ b/build-logic/android-plugins/build.gradle.kts
@@ -35,4 +35,5 @@ dependencies {
implementation(libs.build.dokka)
implementation(libs.build.mavenpublish)
implementation(libs.build.semver)
+ implementation(libs.build.sentry)
}
diff --git a/build-logic/android-plugins/src/main/kotlin/com.github.android-password-store.sentry.gradle.kts b/build-logic/android-plugins/src/main/kotlin/com.github.android-password-store.sentry.gradle.kts
index 4c22e8c8..0407d808 100644
--- a/build-logic/android-plugins/src/main/kotlin/com.github.android-password-store.sentry.gradle.kts
+++ b/build-logic/android-plugins/src/main/kotlin/com.github.android-password-store.sentry.gradle.kts
@@ -2,11 +2,14 @@
import flavors.FlavorDimensions
import flavors.ProductFlavors
+import io.sentry.android.gradle.InstrumentationFeature
-plugins { id("com.android.application") }
+plugins {
+ id("com.android.application")
+ id("io.sentry.android.gradle")
+}
val SENTRY_DSN_PROPERTY = "SENTRY_DSN"
-val INVOKED_FROM_IDE_PROPERTY = "android.injected.invoked.from.ide"
android {
androidComponents {
@@ -14,12 +17,17 @@ android {
val sentryDsn = project.providers.environmentVariable(SENTRY_DSN_PROPERTY)
if (sentryDsn.isPresent) {
variant.manifestPlaceholders.put("sentryDsn", sentryDsn.get())
- } else if (project.providers.gradleProperty(INVOKED_FROM_IDE_PROPERTY).orNull != "true") {
- // Checking for 'INVOKED_FROM_IDE_PROPERTY' prevents failures during Gradle sync by the IDE
- throw GradleException(
- "The '${SENTRY_DSN_PROPERTY}' environment variable must be set when building the ${ProductFlavors.NON_FREE} flavor"
- )
}
}
}
}
+
+sentry {
+ autoUploadProguardMapping.set(true)
+ ignoredBuildTypes.set(setOf("debug"))
+ ignoredFlavors.set(setOf(ProductFlavors.FREE))
+ tracingInstrumentation {
+ enabled.set(true)
+ features.set(setOf(InstrumentationFeature.FILE_IO))
+ }
+}
diff --git a/build-logic/kotlin-plugins/src/main/kotlin/com.github.android-password-store.binary-compatibility.gradle.kts b/build-logic/kotlin-plugins/src/main/kotlin/com.github.android-password-store.binary-compatibility.gradle.kts
index ad6080e0..2723c8dc 100644
--- a/build-logic/kotlin-plugins/src/main/kotlin/com.github.android-password-store.binary-compatibility.gradle.kts
+++ b/build-logic/kotlin-plugins/src/main/kotlin/com.github.android-password-store.binary-compatibility.gradle.kts
@@ -16,6 +16,7 @@ apiValidation {
"format-common",
"diceware",
"random",
+ "sentry-stub",
"ui-compose",
)
}
diff --git a/build-logic/settings.gradle.kts b/build-logic/settings.gradle.kts
index dc8e13b2..144cd7f7 100644
--- a/build-logic/settings.gradle.kts
+++ b/build-logic/settings.gradle.kts
@@ -2,6 +2,7 @@
* Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved.
* SPDX-License-Identifier: GPL-3.0-only
*/
+@file:Suppress("UnstableApiUsage")
rootProject.name = "build-logic"
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 256b2797..b2c1a09c 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -50,6 +50,7 @@ build-mavenpublish = "com.vanniktech:gradle-maven-publish-plugin:0.19.0"
build-okhttp = "com.squareup.okhttp3:okhttp:4.9.3"
build-r8 = "com.android.tools:r8:3.3.15-dev"
build-semver = "com.vdurmont:semver4j:3.1.0"
+build-sentry = "io.sentry.android.gradle:io.sentry.android.gradle.gradle.plugin:3.0.0-rc.3"
build-spotless = "com.diffplug.spotless:spotless-plugin-gradle:6.3.0"
dagger-hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" }
diff --git a/sentry-stub/build.gradle.kts b/sentry-stub/build.gradle.kts
new file mode 100644
index 00000000..f91458dd
--- /dev/null
+++ b/sentry-stub/build.gradle.kts
@@ -0,0 +1,4 @@
+plugins {
+ kotlin("jvm")
+ id("com.github.android-password-store.kotlin-library")
+}
diff --git a/sentry-stub/src/main/kotlin/io/sentry/Scope.kt b/sentry-stub/src/main/kotlin/io/sentry/Scope.kt
new file mode 100644
index 00000000..34557a84
--- /dev/null
+++ b/sentry-stub/src/main/kotlin/io/sentry/Scope.kt
@@ -0,0 +1,10 @@
+@file:Suppress("Unused", "UNUSED_PARAMETER")
+
+package io.sentry
+
+import io.sentry.protocol.User
+
+public class Scope {
+ public var user: User? = null
+ public fun setTag(tag: String, value: String) {}
+}
diff --git a/sentry-stub/src/main/kotlin/io/sentry/Sentry.kt b/sentry-stub/src/main/kotlin/io/sentry/Sentry.kt
new file mode 100644
index 00000000..e64f176e
--- /dev/null
+++ b/sentry-stub/src/main/kotlin/io/sentry/Sentry.kt
@@ -0,0 +1,8 @@
+@file:Suppress("Unused", "UNUSED_PARAMETER")
+
+package io.sentry
+
+/** Stubs for the Sentry SDK */
+public object Sentry {
+ public fun configureScope(callback: (Scope) -> Unit) {}
+}
diff --git a/sentry-stub/src/main/kotlin/io/sentry/protocol/User.kt b/sentry-stub/src/main/kotlin/io/sentry/protocol/User.kt
new file mode 100644
index 00000000..5b60ba72
--- /dev/null
+++ b/sentry-stub/src/main/kotlin/io/sentry/protocol/User.kt
@@ -0,0 +1,12 @@
+@file:Suppress("Unused", "UNUSED_PARAMETER")
+
+package io.sentry.protocol
+
+public data class User(
+ public var email: String? = null,
+ public var id: String? = null,
+ public var username: String? = null,
+ public var ipAddress: String? = null,
+ public var others: Map? = null,
+ public var unknown: Map? = null,
+)
diff --git a/settings.gradle.kts b/settings.gradle.kts
index e0ab512d..1840ee1c 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -2,6 +2,7 @@
* Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved.
* SPDX-License-Identifier: GPL-3.0-only
*/
+@file:Suppress("UnstableApiUsage")
rootProject.name = "APS"
@@ -54,4 +55,6 @@ include("passgen:diceware")
include("passgen:random")
+include("sentry-stub")
+
include("ui-compose")