Skip to content

Commit 304a46c

Browse files
ADFA-4751: Rebrand remaining Sentry references to GlitchTip (#1548)
* ADFA-4751: Rebrand remaining Sentry references to GlitchTip The functional migration (ADFA-4397) kept the io.sentry SDK because GlitchTip is Sentry-protocol-compatible, and re-pointed only the DSN. This is the follow-up branding cleanup it left behind. User-facing / docs / naming: - privacy_disclosure_message onboarding string (English + Indonesian): now names GlitchTip instead of Sentry. - REVIEW.md / SECURITY.md prose -> GlitchTip (kept the Sentry.captureException code example, which is the real SDK API). - Renamed our own identifiers: SentryDiagnosticsContext -> GlitchTipDiagnosticsContext (file + test), SENTRY_ENV_* -> GLITCHTIP_ENV_*, shouldReportToSentry -> shouldReportToGlitchTip, sentryLogAppender -> glitchTipLogAppender. - Backend/product comments and log strings -> GlitchTip. Deliberately kept (would break crash reporting): all io.sentry.* imports and Sentry.* API calls, the manifest io.sentry.* meta-data keys and ${sentryDsn} placeholder, the io.sentry deps / plugin / sentry {} block, and the proguard -keep io.sentry.** rules. Each kept anchor now carries a one-line note that the Sentry SDK is our GlitchTip client. Historical "(Sentry APPDEVFORALL-####)" provenance notes are left as-is. Spotless (ratchet) retabbed a few touched files that were previously space-indented; those whitespace-only hunks bring them to the tab standard. Note: local.properties (gitignored) still uses old sentryDsn* keys pointing at sentry.io while the build now reads GLITCHTIP_DSN -- a per-developer config drift to fix separately, not part of this PR. * ADFA-4751: Use ASCII hyphen in touched WhitelistEngineTest comment Follow-up to code review: the retab re-touched this comment line, so swap its pre-existing em-dash for an ASCII '-' per CLAUDE.md code-style.
1 parent 1d161d7 commit 304a46c

21 files changed

Lines changed: 298 additions & 264 deletions

File tree

‎.github/workflows/analyze.yml‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@ jobs:
7575
7676
- name: Assemble V8 Debug
7777
env:
78-
# Build-time secrets consumed by the Gradle build (Sentry plugin,
79-
# Firebase config). Scoped to this step so SonarCloud and other
80-
# third-party actions never see them.
78+
# Build-time secrets consumed by the Gradle build (GlitchTip crash
79+
# reporting via the Sentry gradle plugin, Firebase config). Scoped to
80+
# this step so SonarCloud and other third-party actions never see them.
8181
FIREBASE_CONSOLE_URL: ${{ secrets.FIREBASE_CONSOLE_URL }}
8282
GLITCHTIP_DSN: ${{ secrets.GLITCHTIP_DSN }}
8383
run: |
@@ -101,7 +101,7 @@ jobs:
101101
env:
102102
GRADLE_OPTS: "-Xmx10g -XX:MaxMetaspaceSize=512m"
103103
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
104-
# The Gradle build also drives Sentry/Firebase configuration during
104+
# The Gradle build also drives GlitchTip/Firebase configuration during
105105
# the unit-test compile path.
106106
FIREBASE_CONSOLE_URL: ${{ secrets.FIREBASE_CONSOLE_URL }}
107107
GLITCHTIP_DSN: ${{ secrets.GLITCHTIP_DSN }}

‎REVIEW.md‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ A review isn't done because it *looks* fine; it's done when you can **show what
1616
| Area | Evidence to show |
1717
|---|---|
1818
| Ticket / feature completeness | Requirements list from ADFA-####, each mapped to code + test (or flagged missing) |
19-
| §1 Exceptions | Where new failure paths are caught; nothing new can reach the Sentry wrapper |
19+
| §1 Exceptions | Where new failure paths are caught; nothing new can reach the GlitchTip wrapper |
2020
| §2 Leaks | LeakCanary result for the touched flows (clean, or the leak addressed) |
2121
| §3 Threading/StrictMode | No new main-thread I/O or long compute; StrictMode run clean, no app-code whitelist |
2222
| §4 Security | Which untrusted inputs were validated; secrets checked |
@@ -31,7 +31,7 @@ Keep it proportional — a two-line change needs a two-line ledger.
3131
## The 60-second checklist
3232

3333
- [ ] **Feature complete:** does what the linked ticket asks — requirements implemented, intended flow covered by tests.
34-
- [ ] **Exceptions** are handled locally — nothing unexpected reaches the global Sentry crash handler.
34+
- [ ] **Exceptions** are handled locally — nothing unexpected reaches the global GlitchTip crash handler.
3535
- [ ] **No leaks** LeakCanary would catch later: every register/open/subscribe has a matching unregister/close in the right lifecycle callback.
3636
- [ ] **No main-thread disk/network I/O** — no new StrictMode violations, and no whitelisting of *our own* code.
3737
- [ ] **Security:** untrusted input (zip entries, URLs, file paths, web-server requests) is validated; no secrets in code, logs, or analytics.
@@ -46,9 +46,9 @@ Keep it proportional — a two-line change needs a two-line ledger.
4646

4747
---
4848

49-
## 1. Exception handling — stay out of the Sentry crash wrapper
49+
## 1. Exception handling — stay out of the GlitchTip crash wrapper
5050

51-
`IDEApplication` installs a global uncaught-exception handler (`handleUncaughtException`) that reports to **Sentry** and then runs the device/credential-protected loaders' handlers. An exception that escapes your code lands there and is recorded as a **crash**. That handler is a safety net, not a control-flow tool.
51+
`IDEApplication` installs a global uncaught-exception handler (`handleUncaughtException`) that reports to **GlitchTip** and then runs the device/credential-protected loaders' handlers. An exception that escapes your code lands there and is recorded as a **crash**. That handler is a safety net, not a control-flow tool.
5252

5353
- **Catch where you can recover.** Wrap I/O, parsing, IPC to the `tooling-api`, git, and plugin calls. Convert failures into a sealed error state (`…UiEffect.ShowError`, `Result`, `BuildState.Failed`) the UI can render.
5454
- **Never swallow silently.** A bare `catch (e: Exception) {}` hides bugs. At minimum log it; if it's notable-but-handled, report it explicitly with the established idiom:
@@ -89,7 +89,7 @@ This app extracts archives, runs a local web server, stores git credentials and
8989

9090
- **Injection / path traversal (Zip Slip):** template/project extraction (`ZipRecipeExecutor`) and any unzip must reject entries that resolve outside the target dir (`canonicalPath.startsWith(targetDir)`). Validate file paths built from user/project input.
9191
- **SQL:** use parameterized queries (`rawQuery(sql, args)` with `?` placeholders), never string-concatenated SQL. (Existing `WebServer`/tooltip queries already do this — match them.)
92-
- **Secrets & credential storage:** git tokens, keystore/signing passwords → `EncryptedSharedPreferences` / the Android Keystore, never plaintext files, never committed, **never logged or sent to analytics/Sentry**. Scrub secrets from breadcrumbs and exception messages.
92+
- **Secrets & credential storage:** git tokens, keystore/signing passwords → `EncryptedSharedPreferences` / the Android Keystore, never plaintext files, never committed, **never logged or sent to analytics/GlitchTip**. Scrub secrets from breadcrumbs and exception messages.
9393
- **Local web server (`WebServer`):** bind to loopback, scope what it serves, and don't reflect unsanitized input into responses. Treat every request as untrusted.
9494
- **Network:** HTTPS only; no disabled TLS/hostname verification; verify git remotes.
9595
- **Untrusted code/plugins:** respect the plugin manifest permission model (`plugin.permissions` in `AndroidManifest.xml`); don't widen plugin capabilities or load classes from untrusted sources without the manager's checks.
@@ -188,7 +188,7 @@ Hold the change to the patterns in [ARCHITECTURE.md](ARCHITECTURE.md). The key r
188188
CoGo is meant to work **without a network** — editing, building, and running an app on-device must not depend on connectivity. Hold new work to that:
189189

190190
- **Degrade gracefully offline.** A feature that needs the network must still launch, explain itself, and leave the rest of the app usable when there's no connection — never block a core flow (edit/build/run) on a request.
191-
- **Network calls are non-blocking and failure-tolerant.** Analytics, Sentry, and Gemini calls run off the main thread and must tolerate timeouts/failures silently (no crash, no hang, no lost user action). A dropped analytics event is acceptable; a dropped keystroke is not.
191+
- **Network calls are non-blocking and failure-tolerant.** Analytics, GlitchTip, and Gemini calls run off the main thread and must tolerate timeouts/failures silently (no crash, no hang, no lost user action). A dropped analytics event is acceptable; a dropped keystroke is not.
192192
- **No network on the critical path.** Don't introduce a connectivity dependency into startup, the editor, or the build pipeline.
193193
- **Verify it offline.** For a change to a network-touching flow, actually exercise it with the network off — `adb shell svc wifi disable && adb shell svc data disable` (re-enable after), or airplane mode — and confirm the core edit/build/run flow still works. Add an explicit offline test case for the path rather than trusting it by inspection.
194194

‎SECURITY.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ We render content in WebViews (tooltips, markdown preview, APK viewer) and run a
7878
### 6. Android component & data exposure
7979
- **Exported components** — `activity`/`service`/`receiver`/`provider` with `android:exported="true"` and no permission is a standard finding. Export only what must be, and protect it with a signature-level permission. Validate all incoming `Intent` extras (intent-redirection / spoofing).
8080
- **PendingIntent** — must be `FLAG_IMMUTABLE` unless mutability is genuinely required.
81-
- **Insecure storage** — no `MODE_WORLD_READABLE/WRITEABLE`; don't put sensitive data on external/shared storage; don't log file contents, tokens, or PII (scanners flag `Log`/print of tainted data, and it also leaks into Sentry/analytics).
81+
- **Insecure storage** — no `MODE_WORLD_READABLE/WRITEABLE`; don't put sensitive data on external/shared storage; don't log file contents, tokens, or PII (scanners flag `Log`/print of tainted data, and it also leaks into GlitchTip/analytics).
8282
- **Manifest hygiene** — `android:allowBackup` and `android:debuggable` are flagged for sensitive apps; set deliberately.
8383
- Request the minimum permissions; over-requesting is flagged.
8484

‎app/build.gradle.kts‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ plugins {
3232
id("kotlin-parcelize")
3333
id("androidx.navigation.safeargs.kotlin")
3434
id("com.itsaky.androidide.desugaring")
35+
// Sentry gradle plugin; the SDK it wires up reports to our GlitchTip backend.
3536
alias(libs.plugins.sentry)
3637
alias(libs.plugins.google.services)
3738
}
@@ -149,6 +150,7 @@ android {
149150
}
150151
}
151152

153+
// Sentry gradle plugin config (crash reporting to GlitchTip).
152154
sentry {
153155
includeProguardMapping = false
154156
}
@@ -324,7 +326,7 @@ dependencies {
324326
implementation(libs.koin.android)
325327
implementation(libs.androidx.security.crypto)
326328

327-
// Sentry Android SDK (core + replay for quality configuration)
329+
// Sentry Android SDK (core + replay for quality configuration); our GlitchTip client.
328330
implementation(libs.sentry.core)
329331
implementation(libs.sentry.android.core)
330332
implementation(libs.sentry.logback)

‎app/proguard-rules.pro‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@
128128
*;
129129
}
130130

131-
## Sentry
131+
## GlitchTip crash reporting (via the Sentry SDK; GlitchTip speaks the Sentry protocol)
132132
-keepattributes SourceFile,LineNumberTable
133133
-keep class io.sentry.** { *; }
134134
-dontwarn io.sentry.**

‎app/src/androidTest/kotlin/com/itsaky/androidide/app/strictmode/WhitelistEngineTest.kt‎

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -85,19 +85,17 @@ class WhitelistEngineTest {
8585
fun evaluateReturnsAllowForOplusUIFirstDiskReadViolation() {
8686
val violatingFrames =
8787
listOf(
88-
// Minimal "realistic" prelude (as in Sentry)
89-
stackTraceElement("android.os.StrictMode\$AndroidBlockGuardPolicy", "onReadFromDisk", "StrictMode.java", 1772,),
90-
stackTraceElement("libcore.io.BlockGuardOs", "access", "BlockGuardOs.java", 74,),
91-
stackTraceElement("java.io.UnixFileSystem", "checkAccess", "UnixFileSystem.java", 337,),
92-
88+
// Minimal "realistic" prelude (as in GlitchTip)
89+
stackTraceElement("android.os.StrictMode\$AndroidBlockGuardPolicy", "onReadFromDisk", "StrictMode.java", 1772),
90+
stackTraceElement("libcore.io.BlockGuardOs", "access", "BlockGuardOs.java", 74),
91+
stackTraceElement("java.io.UnixFileSystem", "checkAccess", "UnixFileSystem.java", 337),
9392
// Whitelisted sequence (adjacent, in-order)
9493
stackTraceElement("java.io.File", "exists", "File.java", 829),
9594
stackTraceElement("com.oplus.uifirst.Utils", "writeProcNode", "Utils.java", 139),
96-
stackTraceElement("com.oplus.uifirst.OplusUIFirstManager", "writeProcNode", "OplusUIFirstManager.java", 382,),
97-
stackTraceElement("com.oplus.uifirst.OplusUIFirstManager", "setBinderThreadUxFlag", "OplusUIFirstManager.java", 877,),
98-
99-
// Minimal tail (system server / wm — optional but matches Sentry shape)
100-
stackTraceElement("com.android.server.wm.ActivityRecordExtImpl", "hookSetBinderUxFlag", "ActivityRecordExtImpl.java", 3008,),
95+
stackTraceElement("com.oplus.uifirst.OplusUIFirstManager", "writeProcNode", "OplusUIFirstManager.java", 382),
96+
stackTraceElement("com.oplus.uifirst.OplusUIFirstManager", "setBinderThreadUxFlag", "OplusUIFirstManager.java", 877),
97+
// Minimal tail (system server / wm - optional but matches GlitchTip shape)
98+
stackTraceElement("com.android.server.wm.ActivityRecordExtImpl", "hookSetBinderUxFlag", "ActivityRecordExtImpl.java", 3008),
10199
)
102100

103101
val violation = createViolation<DiskReadViolation>(violatingFrames)

‎app/src/main/AndroidManifest.xml‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,10 @@
128128
android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize"
129129
android:windowSoftInputMode="adjustResize" />
130130

131-
<!-- Required: set your sentry.io project identifier (DSN) -->
131+
<!-- Crash/log reporting. These io.sentry.* keys configure the Sentry SDK,
132+
which reports to our GlitchTip backend (GlitchTip speaks the Sentry
133+
protocol); ${sentryDsn} carries the GlitchTip DSN. -->
134+
<!-- Required: the GlitchTip project identifier (DSN) -->
132135
<meta-data
133136
android:name="io.sentry.dsn"
134137
android:value="${sentryDsn}" />
@@ -151,7 +154,7 @@
151154
<meta-data
152155
android:name="io.sentry.send-default-pii"
153156
android:value="true" />
154-
<!-- Enable logs to be sent to Sentry -->
157+
<!-- Enable logs to be sent to GlitchTip -->
155158
<meta-data
156159
android:name="io.sentry.logs.enabled"
157160
android:value="true" />

‎app/src/main/java/com/itsaky/androidide/app/DeviceProtectedApplicationLoader.kt‎

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
package com.itsaky.androidide.app
22

3+
import android.os.Build
4+
import android.provider.Settings
35
import androidx.lifecycle.DefaultLifecycleObserver
46
import androidx.lifecycle.LifecycleOwner
57
import androidx.lifecycle.ProcessLifecycleOwner
8+
import ch.qos.logback.classic.Level
9+
import ch.qos.logback.classic.Logger
10+
import ch.qos.logback.classic.LoggerContext
611
import com.itsaky.androidide.BuildConfig
712
import com.itsaky.androidide.analytics.IAnalyticsManager
813
import com.itsaky.androidide.app.strictmode.StrictModeConfig
@@ -13,7 +18,7 @@ import com.itsaky.androidide.events.LspApiEventsIndex
1318
import com.itsaky.androidide.events.LspJavaEventsIndex
1419
import com.itsaky.androidide.events.ProjectsApiEventsIndex
1520
import com.itsaky.androidide.handlers.CrashEventSubscriber
16-
import com.itsaky.androidide.handlers.SentryDiagnosticsContext
21+
import com.itsaky.androidide.handlers.GlitchTipDiagnosticsContext
1722
import com.itsaky.androidide.syntax.colorschemes.SchemeAndroidIDE
1823
import com.itsaky.androidide.ui.themes.IThemeManager
1924
import com.itsaky.androidide.utils.Environment
@@ -22,6 +27,8 @@ import com.termux.shared.reflection.ReflectionUtils
2227
import io.github.rosemoe.sora.widget.schemes.EditorColorScheme
2328
import io.sentry.Sentry
2429
import io.sentry.android.core.SentryAndroid
30+
import io.sentry.logback.SentryAppender
31+
import io.sentry.protocol.User
2532
import kotlinx.coroutines.Dispatchers
2633
import kotlinx.coroutines.launch
2734
import kotlinx.coroutines.withContext
@@ -31,13 +38,6 @@ import org.koin.core.component.KoinComponent
3138
import org.koin.core.component.inject
3239
import org.slf4j.LoggerFactory
3340
import kotlin.system.exitProcess
34-
import ch.qos.logback.classic.Level
35-
import ch.qos.logback.classic.Logger
36-
import ch.qos.logback.classic.LoggerContext
37-
import io.sentry.logback.SentryAppender
38-
import io.sentry.protocol.User
39-
import android.os.Build
40-
import android.provider.Settings
4141

4242
/**
4343
* @author Akash Yadav
@@ -74,24 +74,26 @@ internal object DeviceProtectedApplicationLoader :
7474
)
7575

7676
runCatching {
77+
// Initialize the Sentry SDK; it reports to our GlitchTip backend
78+
// (GlitchTip is Sentry-protocol-compatible), so the SDK types stay io.sentry.
7779
SentryAndroid.init(app) { options ->
7880
options.environment =
79-
if (BuildConfig.DEBUG) IDEApplication.SENTRY_ENV_DEV else IDEApplication.SENTRY_ENV_PROD
81+
if (BuildConfig.DEBUG) IDEApplication.GLITCHTIP_ENV_DEV else IDEApplication.GLITCHTIP_ENV_PROD
8082

81-
// Enrich every Sentry event with app-specific diagnostic context.
82-
SentryDiagnosticsContext.install(options)
83+
// Enrich every GlitchTip event with app-specific diagnostic context.
84+
GlitchTipDiagnosticsContext.install(options)
8385
}
8486

8587
val loggerContext = LoggerFactory.getILoggerFactory() as LoggerContext
86-
val sentryLogAppender =
88+
val glitchTipLogAppender =
8789
SentryAppender().apply {
8890
context = loggerContext
8991
setMinimumEventLevel(Level.OFF)
9092
setMinimumBreadcrumbLevel(Level.INFO)
9193
setMinimumLevel(Level.WARN)
9294
start()
9395
}
94-
loggerContext.getLogger(Logger.ROOT_LOGGER_NAME).addAppender(sentryLogAppender)
96+
loggerContext.getLogger(Logger.ROOT_LOGGER_NAME).addAppender(glitchTipLogAppender)
9597

9698
Sentry.setUser(
9799
User().apply {
@@ -145,7 +147,7 @@ internal object DeviceProtectedApplicationLoader :
145147
exception: Throwable,
146148
) {
147149
// we can't write logs to files, nor we can show the crash handler
148-
// activity to the user. Just report to Sentry and exit.
150+
// activity to the user. Just report to GlitchTip and exit.
149151

150152
Sentry.captureException(exception)
151153
IDEApplication.instance.uncaughtExceptionHandler?.uncaughtException(thread, exception)

‎app/src/main/java/com/itsaky/androidide/app/IDEApplication.kt‎

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import androidx.work.Configuration
2929
import com.itsaky.androidide.BuildConfig
3030
import com.itsaky.androidide.di.coreModule
3131
import com.itsaky.androidide.di.pluginModule
32-
import com.itsaky.androidide.handlers.SentryDiagnosticsContext
32+
import com.itsaky.androidide.handlers.GlitchTipDiagnosticsContext
3333
import com.itsaky.androidide.plugins.manager.core.PluginManager
3434
import com.itsaky.androidide.treesitter.TreeSitter
3535
import com.itsaky.androidide.utils.RecyclableObjectPool
@@ -85,9 +85,9 @@ class IDEApplication :
8585
) {
8686
if (intent?.action == Intent.ACTION_USER_UNLOCKED) {
8787
runCatching { unregisterReceiver(this) }
88-
// Stamp the unlock time so Sentry's boot_mode context reflects the
88+
// Stamp the unlock time so GlitchTip's boot_mode context reflects the
8989
// live state and can report the direct-boot locked duration.
90-
SentryDiagnosticsContext.onUserUnlocked()
90+
GlitchTipDiagnosticsContext.onUserUnlocked()
9191
coroutineScope.launch(Dispatchers.Default) {
9292
logger.info("Device unlocked! Loading all components...")
9393
CredentialProtectedApplicationLoader.load(this@IDEApplication)
@@ -99,8 +99,8 @@ class IDEApplication :
9999
companion object {
100100
private val logger = LoggerFactory.getLogger(IDEApplication::class.java)
101101

102-
const val SENTRY_ENV_DEV = "development"
103-
const val SENTRY_ENV_PROD = "production"
102+
const val GLITCHTIP_ENV_DEV = "development"
103+
const val GLITCHTIP_ENV_PROD = "production"
104104

105105
@JvmStatic
106106
@SuppressLint("StaticFieldLeak")
@@ -202,7 +202,7 @@ class IDEApplication :
202202
}
203203

204204
override val workManagerConfiguration: Configuration
205-
get() = Configuration.Builder().build()
205+
get() = Configuration.Builder().build()
206206

207207
private fun ensureKoinStarted() {
208208
runCatching { GlobalContext.get() }.getOrNull()?.let { return }
@@ -243,7 +243,10 @@ class IDEApplication :
243243
}
244244
}
245245

246-
private fun isFinalizerWatchdogTimeout(thread: Thread, exception: Throwable): Boolean {
246+
private fun isFinalizerWatchdogTimeout(
247+
thread: Thread,
248+
exception: Throwable,
249+
): Boolean {
247250
if (exception !is java.util.concurrent.TimeoutException) return false
248251
return thread.name.contains("FinalizerWatchdogDaemon") ||
249252
exception.stackTrace.any { it.className.contains("Daemons\$FinalizerWatchdogDaemon") }

0 commit comments

Comments
 (0)