NTP-75213 | bbps transsion db crash fix experiment (#16755)
This commit is contained in:
@@ -56,6 +56,13 @@ class NaviBbpsAnalytics private constructor() {
|
||||
eventValues = mapOf("errorConfig" to errorConfig.toString()),
|
||||
)
|
||||
}
|
||||
|
||||
fun onTranssionDeviceData(eventValues: Map<String, String>) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
eventName = "Dev_NaviBBPS_TranssionCrashFixExperiment",
|
||||
eventValues = eventValues,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
inner class BillCategories {
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright © 2024-2025 by Navi Technologies Limited
|
||||
* * All rights reserved. Strictly confidential
|
||||
*
|
||||
*/
|
||||
|
||||
package com.navi.bbps.db
|
||||
|
||||
import android.os.Build
|
||||
import androidx.room.RoomDatabase
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import com.navi.analytics.firebase.FcmAnalyticsUtil
|
||||
import com.navi.bbps.common.NaviBbpsAnalytics
|
||||
import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper
|
||||
import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper.NAVI_BBPS_TRANSSION_DB_CRASH_FIX_ENABLED
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
/**
|
||||
* A/B Test configuration for Transsion phone database compatibility fixes
|
||||
*
|
||||
* This experiment tests enhanced SQLite settings specifically for Transsion devices to resolve
|
||||
* SQLiteCantOpenDatabaseException crashes.
|
||||
*
|
||||
* Test Groups:
|
||||
* - CONTROL: Current default Room database settings
|
||||
* - EXPERIMENT: Enhanced compatibility with PRAGMA settings and TRUNCATE journal mode
|
||||
*/
|
||||
class TranssionDbExperiment {
|
||||
|
||||
private val analytics = NaviBbpsAnalytics.INSTANCE.GenericDev()
|
||||
|
||||
/**
|
||||
* Applies database configuration based on A/B test group
|
||||
*
|
||||
* @param builder Room database builder to configure
|
||||
*/
|
||||
fun applyDbFixes(builder: RoomDatabase.Builder<*>) {
|
||||
if (!isTranssionDevice()) {
|
||||
// Non-Transsion devices: no changes
|
||||
return
|
||||
}
|
||||
|
||||
val isExperimentEnabled =
|
||||
FirebaseRemoteConfigHelper.getBoolean(NAVI_BBPS_TRANSSION_DB_CRASH_FIX_ENABLED)
|
||||
|
||||
FcmAnalyticsUtil.analytics.trackEvent(
|
||||
eventName = "TranssionDbExperiment init",
|
||||
eventValues =
|
||||
mapOf("isTranssionDbFixExperimentEnabled" to isExperimentEnabled.toString()),
|
||||
)
|
||||
if (isExperimentEnabled) {
|
||||
applyExperimentalFixes(builder)
|
||||
} else {
|
||||
applyControlGroupLogging(builder)
|
||||
}
|
||||
}
|
||||
|
||||
private fun applyExperimentalFixes(builder: RoomDatabase.Builder<*>) {
|
||||
logExperimentMetrics(
|
||||
group = "EXPERIMENT",
|
||||
event = "configuration_started",
|
||||
success = true,
|
||||
errorMessage = "Applying Transsion DB fixes",
|
||||
)
|
||||
|
||||
builder.apply {
|
||||
setJournalMode(RoomDatabase.JournalMode.TRUNCATE)
|
||||
|
||||
addCallback(
|
||||
object : RoomDatabase.Callback() {
|
||||
override fun onCreate(db: SupportSQLiteDatabase) {
|
||||
super.onCreate(db)
|
||||
logExperimentMetrics(
|
||||
group = "EXPERIMENT",
|
||||
event = "database_created",
|
||||
success = true,
|
||||
errorMessage = "Database onCreate for ${Build.MODEL}",
|
||||
)
|
||||
|
||||
try {
|
||||
db.execSQL("PRAGMA journal_mode=DELETE")
|
||||
db.execSQL("PRAGMA synchronous=NORMAL")
|
||||
logExperimentMetrics(
|
||||
group = "EXPERIMENT",
|
||||
event = "pragma_applied",
|
||||
success = true,
|
||||
errorMessage = "PRAGMA settings applied successfully",
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
logExperimentMetrics(
|
||||
group = "EXPERIMENT",
|
||||
event = "pragma_failed",
|
||||
success = false,
|
||||
errorMessage = e.message,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onOpen(db: SupportSQLiteDatabase) {
|
||||
super.onOpen(db)
|
||||
logExperimentMetrics(
|
||||
group = "EXPERIMENT",
|
||||
event = "database_opened",
|
||||
success = true,
|
||||
errorMessage = "Database onOpen for ${Build.MODEL}",
|
||||
)
|
||||
|
||||
try {
|
||||
db.execSQL("PRAGMA integrity_check")
|
||||
logExperimentMetrics(
|
||||
group = "EXPERIMENT",
|
||||
event = "integrity_check_passed",
|
||||
success = true,
|
||||
errorMessage = "Database integrity check passed",
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
logExperimentMetrics(
|
||||
group = "EXPERIMENT",
|
||||
event = "integrity_check_failed",
|
||||
success = false,
|
||||
errorMessage = e.message,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun applyControlGroupLogging(builder: RoomDatabase.Builder<*>) {
|
||||
logExperimentMetrics(
|
||||
group = "CONTROL",
|
||||
event = "configuration_started",
|
||||
success = true,
|
||||
errorMessage = "Using default DB settings",
|
||||
)
|
||||
|
||||
builder.apply {
|
||||
setQueryCallback(
|
||||
{ sqlQuery, bindArgs ->
|
||||
logExperimentMetrics(
|
||||
group = "CONTROL",
|
||||
event = "query_executed",
|
||||
success = true,
|
||||
errorMessage = "Query: $sqlQuery, args: ${bindArgs.joinToString()}",
|
||||
)
|
||||
},
|
||||
Executors.newSingleThreadExecutor(),
|
||||
)
|
||||
|
||||
addCallback(
|
||||
object : RoomDatabase.Callback() {
|
||||
override fun onCreate(db: SupportSQLiteDatabase) {
|
||||
super.onCreate(db)
|
||||
logExperimentMetrics(
|
||||
group = "CONTROL",
|
||||
event = "database_created",
|
||||
success = true,
|
||||
errorMessage = "Database onCreate for ${Build.MODEL}",
|
||||
)
|
||||
}
|
||||
|
||||
override fun onOpen(db: SupportSQLiteDatabase) {
|
||||
super.onOpen(db)
|
||||
logExperimentMetrics(
|
||||
group = "CONTROL",
|
||||
event = "database_opened",
|
||||
success = true,
|
||||
errorMessage = "Database onOpen for ${Build.MODEL}",
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun logExperimentMetrics(
|
||||
group: String,
|
||||
event: String,
|
||||
success: Boolean,
|
||||
errorMessage: String? = null,
|
||||
) {
|
||||
val deviceDetails =
|
||||
"Model: ${Build.MODEL}, Manufacturer: ${Build.MANUFACTURER}, Brand: ${Build.BRAND}, SDK: ${Build.VERSION.SDK_INT}"
|
||||
|
||||
analytics.onTranssionDeviceData(
|
||||
eventValues =
|
||||
mapOf(
|
||||
"device_details" to deviceDetails,
|
||||
"group" to group,
|
||||
"event" to event,
|
||||
"success" to success.toString(),
|
||||
"error_message" to errorMessage.orEmpty(),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun isTranssionDevice(): Boolean =
|
||||
Build.MANUFACTURER.equals("TRANSSION", ignoreCase = true) ||
|
||||
Build.BRAND.equals("TRANSSION", ignoreCase = true)
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import com.navi.bbps.db.NAVI_BBPS_DATABASE_MIGRATION_7_8
|
||||
import com.navi.bbps.db.NAVI_BBPS_DATABASE_MIGRATION_8_9
|
||||
import com.navi.bbps.db.NAVI_BBPS_DATABASE_MIGRATION_9_10
|
||||
import com.navi.bbps.db.NaviBbpsAppDatabase
|
||||
import com.navi.bbps.db.TranssionDbExperiment
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
@@ -34,15 +35,21 @@ import javax.inject.Singleton
|
||||
object NaviBbpsDbModule {
|
||||
@Singleton @Provides fun providesSharedPreferences() = BbpsSharedPreferences()
|
||||
|
||||
@Singleton @Provides fun providesTranssionDbExperiment() = TranssionDbExperiment()
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun providesNaviBbpsAppDatabase(@ApplicationContext context: Context) =
|
||||
fun providesNaviBbpsAppDatabase(
|
||||
@ApplicationContext context: Context,
|
||||
transsionDbExperiment: TranssionDbExperiment,
|
||||
) =
|
||||
Room.databaseBuilder(
|
||||
context,
|
||||
NaviBbpsAppDatabase::class.java,
|
||||
NaviBbpsAppDatabase.NAVI_BBPS_DATABASE_NAME,
|
||||
)
|
||||
.enableMultiInstanceInvalidation()
|
||||
.apply { transsionDbExperiment.applyDbFixes(this) }
|
||||
.addMigrations(
|
||||
NAVI_BBPS_DATABASE_MIGRATION_1_2,
|
||||
NAVI_BBPS_DATABASE_MIGRATION_2_3,
|
||||
@@ -56,7 +63,7 @@ object NaviBbpsDbModule {
|
||||
NAVI_BBPS_DATABASE_MIGRATION_10_11,
|
||||
NAVI_BBPS_DATABASE_MIGRATION_11_12,
|
||||
)
|
||||
.fallbackToDestructiveMigration()
|
||||
.fallbackToDestructiveMigration(dropAllTables = false)
|
||||
.build()
|
||||
|
||||
@Singleton
|
||||
|
||||
Reference in New Issue
Block a user