diff --git a/telemetry/src/firebase/kotlin/mihon/telemetry/PackageInfo.kt b/telemetry/src/firebase/kotlin/mihon/telemetry/PackageInfo.kt new file mode 100644 index 000000000..eb81ca842 --- /dev/null +++ b/telemetry/src/firebase/kotlin/mihon/telemetry/PackageInfo.kt @@ -0,0 +1,46 @@ +package mihon.telemetry + +import android.content.pm.PackageInfo +import android.content.pm.PackageManager +import android.content.pm.Signature +import android.os.Build +import java.security.MessageDigest + +internal fun PackageInfo.getCertificateFingerprints(): List { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + val signingInfo = signingInfo!! + if (signingInfo.hasMultipleSigners()) { + signingInfo.apkContentsSigners + } else { + signingInfo.signingCertificateHistory + } + } else { + @Suppress("DEPRECATION") + signatures + } + ?.map(Signature::getCertificateFingerprint) + ?.toList() + ?: emptyList() +} + +internal val SignatureFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + PackageManager.GET_SIGNING_CERTIFICATES +} else { + @Suppress("DEPRECATION") + PackageManager.GET_SIGNATURES +} + +@OptIn(ExperimentalStdlibApi::class) +private val CertificateFingerprintHexFormat = HexFormat { + upperCase = true + bytes { + byteSeparator = ":" + } +} + +@OptIn(ExperimentalStdlibApi::class) +private fun Signature.getCertificateFingerprint(): String { + return MessageDigest.getInstance("SHA-256") + .digest(toByteArray()) + .toHexString(CertificateFingerprintHexFormat) +} diff --git a/telemetry/src/firebase/kotlin/mihon/telemetry/TelemetryConfig.kt b/telemetry/src/firebase/kotlin/mihon/telemetry/TelemetryConfig.kt index 613e5e48b..c1d55ce0b 100644 --- a/telemetry/src/firebase/kotlin/mihon/telemetry/TelemetryConfig.kt +++ b/telemetry/src/firebase/kotlin/mihon/telemetry/TelemetryConfig.kt @@ -6,25 +6,40 @@ import com.google.firebase.analytics.FirebaseAnalytics import com.google.firebase.crashlytics.FirebaseCrashlytics object TelemetryConfig { - private lateinit var analytics: FirebaseAnalytics - private lateinit var crashlytics: FirebaseCrashlytics + private var analytics: FirebaseAnalytics? = null + private var crashlytics: FirebaseCrashlytics? = null fun init(context: Context, isPreviewBuildType: Boolean, commitCount: String) { + // To stop forks/test builds from polluting our data + if (!context.isMihonProductionApp()) return + analytics = FirebaseAnalytics.getInstance(context) FirebaseApp.initializeApp(context) crashlytics = FirebaseCrashlytics.getInstance() // KMK --> if (isPreviewBuildType) { - analytics.setUserProperty("preview_version", commitCount) + analytics?.setUserProperty("preview_version", commitCount) } // KMK <-- } fun setAnalyticsEnabled(enabled: Boolean) { - analytics.setAnalyticsCollectionEnabled(enabled) + analytics?.setAnalyticsCollectionEnabled(enabled) } fun setCrashlyticsEnabled(enabled: Boolean) { - crashlytics.isCrashlyticsCollectionEnabled = enabled + crashlytics?.isCrashlyticsCollectionEnabled = enabled + } + + private fun Context.isMihonProductionApp(): Boolean { + if (packageName !in MIHON_PACKAGES) return false + + return packageManager.getPackageInfo(packageName, SignatureFlags) + .getCertificateFingerprints() + .any { it == MIHON_CERTIFICATE_FINGERPRINT } } } + +private val MIHON_PACKAGES = hashSetOf("app.komikku", "app.komikku.beta") +private const val MIHON_CERTIFICATE_FINGERPRINT = + "CB:EC:12:1A:A8:2E:BB:02:AA:A7:38:06:99:2E:03:68:A9:7D:47:B5:45:1E:D6:52:48:16:D0:30:84:C4:59:05" diff --git a/telemetry/src/main/AndroidManifest.xml b/telemetry/src/main/AndroidManifest.xml index 9d0be9170..65e3e4a52 100644 --- a/telemetry/src/main/AndroidManifest.xml +++ b/telemetry/src/main/AndroidManifest.xml @@ -2,6 +2,10 @@ + + + +