@@ -22,6 +22,7 @@ import androidx.compose.foundation.layout.padding
2222import androidx.compose.foundation.layout.size
2323import androidx.compose.foundation.layout.statusBarsPadding
2424import androidx.compose.foundation.rememberScrollState
25+ import androidx.compose.foundation.shape.RoundedCornerShape
2526import androidx.compose.foundation.verticalScroll
2627import androidx.compose.material.icons.Icons
2728import androidx.compose.material.icons.outlined.HelpOutline
@@ -45,6 +46,7 @@ import androidx.compose.material3.Text
4546import androidx.compose.material3.TooltipBox
4647import androidx.compose.material3.TooltipDefaults
4748import androidx.compose.material3.rememberTooltipState
49+ import androidx.compose.runtime.Composable
4850import androidx.compose.runtime.LaunchedEffect
4951import androidx.compose.runtime.getValue
5052import androidx.compose.runtime.mutableStateOf
@@ -70,6 +72,7 @@ import io.sentry.SpanStatus
7072import io.sentry.TransactionContext
7173import io.sentry.TransactionOptions
7274import io.sentry.protocol.SentryId
75+ import io.sentry.samples.android.BuildConfig
7376import kotlinx.coroutines.Dispatchers
7477import kotlinx.coroutines.delay
7578import kotlinx.coroutines.launch
@@ -93,33 +96,45 @@ private val CONTROL_SECTION_GAP = TOGGLE_SECTION_GAP * 2
9396
9497private val SECTION_HEADER_HEIGHT = 28 .dp
9598
99+ private const val SAGP_DIRECT_DRIVER_MESSAGE =
100+ " SAGP doesn't auto-instrument SQLiteDriver for direct use"
101+
96102/* * Which sentry-android-sqlite integration the demo currently targets. */
97103private enum class IntegrationMode (
98104 val color : Color ,
99105 val segmentLabel : String ,
100106 val apiName : String ,
101- val subtitle : String ,
102107) {
103- DRIVER (
104- SentryPurple ,
105- " SQLiteDriver" ,
106- " SQLiteDriver" ,
107- " SentrySQLiteDriver.create(BundledSQLiteDriver)" ,
108- ),
109- OPEN_HELPER (
110- SentryPink ,
111- " OpenHelper" ,
112- " SupportSQLiteOpenHelper" ,
113- " SentrySupportSQLiteOpenHelper.create(...)" ,
114- ),
108+
109+ DRIVER (SentryPurple , " SQLiteDriver" , " SQLiteDriver" ),
110+ OPEN_HELPER (SentryPink , " OpenHelper" , " SupportSQLiteOpenHelper" ),
115111 // Not directly-supported, but lets us verify behavior when both the DRIVER and OPEN_HELPER
116112 // integrations are used together via the SupportSQLiteDriver bridge.
117- BRIDGE (
118- SentryOrange ,
119- " Bridge" ,
120- " SupportSQLiteDriver bridge" ,
121- " SentrySQLiteDriver.create(SupportSQLiteDriver(Sentry helper))" ,
122- ),
113+ BRIDGE (SentryOrange , " Bridge" , " SupportSQLiteDriver bridge" );
114+
115+ fun subtitle (): String =
116+ when (this ) {
117+ DRIVER ->
118+ if (BuildConfig .USE_SAGP ) {
119+ " BundledSQLiteDriver (SAGP auto-wrap)"
120+ } else {
121+ " SentrySQLiteDriver.create(BundledSQLiteDriver)"
122+ }
123+
124+ OPEN_HELPER ->
125+ if (BuildConfig .USE_SAGP ) {
126+ " FrameworkSQLiteOpenHelperFactory (SAGP auto-wrap)"
127+ } else {
128+ " SentrySupportSQLiteOpenHelper.create(...)"
129+ }
130+
131+ BRIDGE ->
132+ if (BuildConfig .USE_SAGP ) {
133+ " SupportSQLiteDriver(open helper) (SAGP auto-wrap)"
134+ } else {
135+ " SentrySQLiteDriver.create(SupportSQLiteDriver(Sentry helper))"
136+ }
137+ }
123138}
124139
125140/* *
@@ -318,6 +333,7 @@ class SQLiteActivity : ComponentActivity() {
318333 lerp(MaterialTheme .colorScheme.outline, integration.color, shimmer.value)
319334
320335 Text (text = " SQLite Instrumentation" , style = MaterialTheme .typography.headlineSmall)
336+ SagpBuildPill ()
321337
322338 Spacer (Modifier .height(titleGap))
323339
@@ -364,6 +380,7 @@ class SQLiteActivity : ComponentActivity() {
364380 label = row.label,
365381 color = integration.color,
366382 variant = variant,
383+ sagpDisabledReason = sagpDisabledReason(integration, row),
367384 disabledReason = " ${row.label} doesn't support the ${integration.apiName} stack" ,
368385 )
369386 }
@@ -447,7 +464,7 @@ class SQLiteActivity : ComponentActivity() {
447464 }
448465
449466 @OptIn(ExperimentalMaterial3Api ::class )
450- @androidx.compose.runtime. Composable
467+ @Composable
451468 private fun IntegrationModeSelector (
452469 selected : IntegrationMode ,
453470 onSelected : (IntegrationMode ) -> Unit ,
@@ -471,18 +488,36 @@ class SQLiteActivity : ComponentActivity() {
471488 }
472489
473490 Text (
474- text = selected.subtitle,
491+ text = selected.subtitle() ,
475492 style = MaterialTheme .typography.bodySmall,
476493 color = Color .Gray ,
477494 modifier = Modifier .padding(top = 6 .dp),
478495 )
479496 }
480497
498+ @Composable
499+ private fun SagpBuildPill () {
500+ val useSagp = BuildConfig .USE_SAGP
501+
502+ Surface (
503+ shape = RoundedCornerShape (percent = 50 ),
504+ color = if (useSagp) SentryPurple .copy(alpha = 0.15f ) else Color .Gray .copy(alpha = 0.2f ),
505+ modifier = Modifier .padding(top = 6 .dp),
506+ ) {
507+ Text (
508+ text = if (useSagp) " Built with SAGP" else " Built without SAGP" ,
509+ style = MaterialTheme .typography.labelSmall,
510+ color = if (useSagp) SentryPurple else Color .DarkGray ,
511+ modifier = Modifier .padding(horizontal = 10 .dp, vertical = 4 .dp),
512+ )
513+ }
514+ }
515+
481516 /* *
482517 * A compact, left-justified labeled switch. [labelColor] defaults to [Color.Unspecified] so the
483518 * label inherits the default text color.
484519 */
485- @androidx.compose.runtime. Composable
520+ @Composable
486521 private fun ToggleRow (
487522 label : String ,
488523 checked : Boolean ,
@@ -509,11 +544,11 @@ class SQLiteActivity : ComponentActivity() {
509544 }
510545 }
511546
512- @androidx.compose.runtime. Composable
547+ @Composable
513548 private fun SectionHeader (
514549 title : String ,
515550 topPadding : Dp = 8.dp,
516- trailing : (@androidx.compose.runtime. Composable () -> Unit )? = null,
551+ trailing : (@Composable () -> Unit )? = null,
517552 ) {
518553 Column (modifier = Modifier .fillMaxWidth().padding(top = topPadding)) {
519554 Row (verticalAlignment = Alignment .CenterVertically ) {
@@ -529,7 +564,7 @@ class SQLiteActivity : ComponentActivity() {
529564 * tooltip that auto-dismisses after a few seconds.
530565 */
531566 @OptIn(ExperimentalMaterial3Api ::class )
532- @androidx.compose.runtime. Composable
567+ @Composable
533568 private fun HelpTooltip () {
534569 val tooltipState = rememberTooltipState(isPersistent = true )
535570 val scope = rememberCoroutineScope()
@@ -565,16 +600,19 @@ class SQLiteActivity : ComponentActivity() {
565600 * dimmed and, when clicked, explains why via a toast ([disabledReason]) instead of running.
566601 */
567602 @OptIn(ExperimentalFoundationApi ::class )
568- @androidx.compose.runtime. Composable
603+ @Composable
569604 private fun DemoRowButton (
570605 label : String ,
571606 color : Color ,
572607 variant : DemoVariant ? ,
608+ sagpDisabledReason : String? ,
573609 disabledReason : String ,
574610 ) {
575611 val context = LocalContext .current
576- val enabled = variant != null
577- val explain = { Toast .makeText(context, disabledReason, Toast .LENGTH_SHORT ).show() }
612+ val enabled = variant != null && sagpDisabledReason == null
613+ val explain = {
614+ Toast .makeText(context, sagpDisabledReason ? : disabledReason, Toast .LENGTH_SHORT ).show()
615+ }
578616
579617 Surface (
580618 modifier = Modifier .fillMaxWidth(),
@@ -585,8 +623,8 @@ class SQLiteActivity : ComponentActivity() {
585623 Box (
586624 modifier =
587625 Modifier .combinedClickable(
588- onClick = { if (variant != null ) onTap(variant) else explain() },
589- onLongClick = { if (variant != null ) onLongPress(variant) else explain() },
626+ onClick = { if (enabled ) onTap(variant) else explain() },
627+ onLongClick = { if (enabled ) onLongPress(variant) else explain() },
590628 )
591629 .fillMaxWidth()
592630 .heightIn(min = 44 .dp)
@@ -598,7 +636,7 @@ class SQLiteActivity : ComponentActivity() {
598636 }
599637 }
600638
601- @androidx.compose.runtime. Composable
639+ @Composable
602640 private fun ResetButton (dbOperationInFlight : Boolean , resetInProgress : Boolean ) {
603641 // Debounce demo-driven disablement so fast taps don't flicker the button; reset disables
604642 // immediately via [resetInProgress]. [dbOperationInFlight] still guards [onClick] either way.
@@ -642,7 +680,7 @@ class SQLiteActivity : ComponentActivity() {
642680 }
643681 }
644682
645- @androidx.compose.runtime. Composable
683+ @Composable
646684 private fun DetailField (label : String , value : String , borderColor : Color ) {
647685 OutlinedTextField (
648686 value = value,
@@ -699,6 +737,15 @@ class SQLiteActivity : ComponentActivity() {
699737 }
700738 }
701739
740+ private fun sagpDisabledReason (mode : IntegrationMode , row : DemoRow ): String? {
741+ if (! BuildConfig .USE_SAGP ) return null
742+ val demo = row.variantFor(mode)?.demo ? : return null
743+ return when (demo) {
744+ SqlDemo .DRIVER_DIRECT -> SAGP_DIRECT_DRIVER_MESSAGE
745+ else -> null
746+ }
747+ }
748+
702749 /* * Closes + deletes every demo database file (via [SampleDatabases]), then re-warms them. */
703750 private suspend fun resetDatabases (): String {
704751 val cleared = SampleDatabases .reset(applicationContext)
0 commit comments