kopia lustrzana https://github.com/ryukoposting/Signal-Android
Change spinner to lazily read database stuff.
Otherwise you get into situations where Spinner will force DB accesses super early during Application#onCreate on the main thread, which can be bad when testing large DB migrations.main
rodzic
3ce5a7da67
commit
10f78d5daa
|
@ -51,25 +51,25 @@ class SpinnerApplicationContext : ApplicationContext() {
|
||||||
Spinner.init(
|
Spinner.init(
|
||||||
this,
|
this,
|
||||||
mapOf(
|
mapOf(
|
||||||
"Device" to "${Build.MODEL} (Android ${Build.VERSION.RELEASE}, API ${Build.VERSION.SDK_INT})",
|
"Device" to { "${Build.MODEL} (Android ${Build.VERSION.RELEASE}, API ${Build.VERSION.SDK_INT})" },
|
||||||
"Package" to "$packageName (${AppSignatureUtil.getAppSignature(this)})",
|
"Package" to { "$packageName (${AppSignatureUtil.getAppSignature(this)})" },
|
||||||
"App Version" to "${BuildConfig.VERSION_NAME} (${BuildConfig.CANONICAL_VERSION_CODE}, ${BuildConfig.GIT_HASH})",
|
"App Version" to { "${BuildConfig.VERSION_NAME} (${BuildConfig.CANONICAL_VERSION_CODE}, ${BuildConfig.GIT_HASH})" },
|
||||||
"Profile Name" to (if (SignalStore.account().isRegistered) Recipient.self().profileName.toString() else "none"),
|
"Profile Name" to { (if (SignalStore.account().isRegistered) Recipient.self().profileName.toString() else "none") },
|
||||||
"E164" to (SignalStore.account().e164 ?: "none"),
|
"E164" to { SignalStore.account().e164 ?: "none" },
|
||||||
"ACI" to (SignalStore.account().aci?.toString() ?: "none"),
|
"ACI" to { SignalStore.account().aci?.toString() ?: "none" },
|
||||||
"PNI" to (SignalStore.account().pni?.toString() ?: "none"),
|
"PNI" to { SignalStore.account().pni?.toString() ?: "none" },
|
||||||
Spinner.KEY_ENVIRONMENT to BuildConfig.FLAVOR_environment.uppercase(Locale.US)
|
Spinner.KEY_ENVIRONMENT to { BuildConfig.FLAVOR_environment.uppercase(Locale.US) }
|
||||||
),
|
),
|
||||||
linkedMapOf(
|
linkedMapOf(
|
||||||
"signal" to DatabaseConfig(
|
"signal" to DatabaseConfig(
|
||||||
db = SignalDatabase.rawDatabase,
|
db = { SignalDatabase.rawDatabase },
|
||||||
columnTransformers = listOf(MessageBitmaskColumnTransformer, GV2Transformer, GV2UpdateTransformer, IsStoryTransformer, TimestampTransformer, ProfileKeyCredentialTransformer)
|
columnTransformers = listOf(MessageBitmaskColumnTransformer, GV2Transformer, GV2UpdateTransformer, IsStoryTransformer, TimestampTransformer, ProfileKeyCredentialTransformer)
|
||||||
),
|
),
|
||||||
"jobmanager" to DatabaseConfig(db = JobDatabase.getInstance(this).sqlCipherDatabase),
|
"jobmanager" to DatabaseConfig(db = { JobDatabase.getInstance(this).sqlCipherDatabase }),
|
||||||
"keyvalue" to DatabaseConfig(db = KeyValueDatabase.getInstance(this).sqlCipherDatabase),
|
"keyvalue" to DatabaseConfig(db = { KeyValueDatabase.getInstance(this).sqlCipherDatabase }),
|
||||||
"megaphones" to DatabaseConfig(db = MegaphoneDatabase.getInstance(this).sqlCipherDatabase),
|
"megaphones" to DatabaseConfig(db = { MegaphoneDatabase.getInstance(this).sqlCipherDatabase }),
|
||||||
"localmetrics" to DatabaseConfig(db = LocalMetricsDatabase.getInstance(this).sqlCipherDatabase),
|
"localmetrics" to DatabaseConfig(db = { LocalMetricsDatabase.getInstance(this).sqlCipherDatabase }),
|
||||||
"logs" to DatabaseConfig(db = LogDatabase.getInstance(this).sqlCipherDatabase),
|
"logs" to DatabaseConfig(db = { LogDatabase.getInstance(this).sqlCipherDatabase }),
|
||||||
),
|
),
|
||||||
linkedMapOf(
|
linkedMapOf(
|
||||||
StorageServicePlugin.PATH to StorageServicePlugin()
|
StorageServicePlugin.PATH to StorageServicePlugin()
|
||||||
|
|
|
@ -20,10 +20,10 @@ class MainActivity : AppCompatActivity() {
|
||||||
Spinner.init(
|
Spinner.init(
|
||||||
application,
|
application,
|
||||||
mapOf(
|
mapOf(
|
||||||
"Name" to "${Build.MODEL} (API ${Build.VERSION.SDK_INT})",
|
"Name" to { "${Build.MODEL} (API ${Build.VERSION.SDK_INT})" },
|
||||||
"Package" to packageName
|
"Package" to { packageName }
|
||||||
),
|
),
|
||||||
mapOf("main" to Spinner.DatabaseConfig(db = db)),
|
mapOf("main" to Spinner.DatabaseConfig(db = { db })),
|
||||||
emptyMap()
|
emptyMap()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ object Spinner {
|
||||||
|
|
||||||
private lateinit var server: SpinnerServer
|
private lateinit var server: SpinnerServer
|
||||||
|
|
||||||
fun init(application: Application, deviceInfo: Map<String, String>, databases: Map<String, DatabaseConfig>, plugins: Map<String, Plugin>) {
|
fun init(application: Application, deviceInfo: Map<String, () -> String>, databases: Map<String, DatabaseConfig>, plugins: Map<String, Plugin>) {
|
||||||
try {
|
try {
|
||||||
server = SpinnerServer(application, deviceInfo, databases, plugins)
|
server = SpinnerServer(application, deviceInfo, databases, plugins)
|
||||||
server.start()
|
server.start()
|
||||||
|
@ -91,7 +91,7 @@ object Spinner {
|
||||||
}
|
}
|
||||||
|
|
||||||
data class DatabaseConfig(
|
data class DatabaseConfig(
|
||||||
val db: SupportSQLiteDatabase,
|
val db: () -> SupportSQLiteDatabase,
|
||||||
val columnTransformers: List<ColumnTransformer> = emptyList()
|
val columnTransformers: List<ColumnTransformer> = emptyList()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ import kotlin.math.min
|
||||||
*/
|
*/
|
||||||
internal class SpinnerServer(
|
internal class SpinnerServer(
|
||||||
private val application: Application,
|
private val application: Application,
|
||||||
deviceInfo: Map<String, String>,
|
deviceInfo: Map<String, () -> String>,
|
||||||
private val databases: Map<String, DatabaseConfig>,
|
private val databases: Map<String, DatabaseConfig>,
|
||||||
private val plugins: Map<String, Plugin>
|
private val plugins: Map<String, Plugin>
|
||||||
) : NanoHTTPD(5000) {
|
) : NanoHTTPD(5000) {
|
||||||
|
@ -37,8 +37,8 @@ internal class SpinnerServer(
|
||||||
private val TAG = Log.tag(SpinnerServer::class.java)
|
private val TAG = Log.tag(SpinnerServer::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val deviceInfo: Map<String, String> = deviceInfo.filterKeys { !it.startsWith(Spinner.KEY_PREFIX) }
|
private val deviceInfo: Map<String, () -> String> = deviceInfo.filterKeys { !it.startsWith(Spinner.KEY_PREFIX) }
|
||||||
private val environment: String = deviceInfo[Spinner.KEY_ENVIRONMENT] ?: "UNKNOWN"
|
private val environment: String = deviceInfo[Spinner.KEY_ENVIRONMENT]?.let { it() } ?: "UNKNOWN"
|
||||||
|
|
||||||
private val handlebars: Handlebars = Handlebars(AssetTemplateLoader(application)).apply {
|
private val handlebars: Handlebars = Handlebars(AssetTemplateLoader(application)).apply {
|
||||||
registerHelper("eq", ConditionalHelpers.eq)
|
registerHelper("eq", ConditionalHelpers.eq)
|
||||||
|
@ -61,8 +61,8 @@ internal class SpinnerServer(
|
||||||
return when {
|
return when {
|
||||||
session.method == Method.GET && session.uri == "/css/main.css" -> newFileResponse("css/main.css", "text/css")
|
session.method == Method.GET && session.uri == "/css/main.css" -> newFileResponse("css/main.css", "text/css")
|
||||||
session.method == Method.GET && session.uri == "/js/main.js" -> newFileResponse("js/main.js", "text/javascript")
|
session.method == Method.GET && session.uri == "/js/main.js" -> newFileResponse("js/main.js", "text/javascript")
|
||||||
session.method == Method.GET && session.uri == "/" -> getIndex(dbParam, dbConfig.db)
|
session.method == Method.GET && session.uri == "/" -> getIndex(dbParam, dbConfig.db())
|
||||||
session.method == Method.GET && session.uri == "/browse" -> getBrowse(dbParam, dbConfig.db)
|
session.method == Method.GET && session.uri == "/browse" -> getBrowse(dbParam, dbConfig.db())
|
||||||
session.method == Method.POST && session.uri == "/browse" -> postBrowse(dbParam, dbConfig, session)
|
session.method == Method.POST && session.uri == "/browse" -> postBrowse(dbParam, dbConfig, session)
|
||||||
session.method == Method.GET && session.uri == "/query" -> getQuery(dbParam)
|
session.method == Method.GET && session.uri == "/query" -> getQuery(dbParam)
|
||||||
session.method == Method.POST && session.uri == "/query" -> postQuery(dbParam, dbConfig, session)
|
session.method == Method.POST && session.uri == "/query" -> postQuery(dbParam, dbConfig, session)
|
||||||
|
@ -98,7 +98,7 @@ internal class SpinnerServer(
|
||||||
"overview",
|
"overview",
|
||||||
OverviewPageModel(
|
OverviewPageModel(
|
||||||
environment = environment,
|
environment = environment,
|
||||||
deviceInfo = deviceInfo,
|
deviceInfo = deviceInfo.resolve(),
|
||||||
database = dbName,
|
database = dbName,
|
||||||
databases = databases.keys.toList(),
|
databases = databases.keys.toList(),
|
||||||
plugins = plugins.values.toList(),
|
plugins = plugins.values.toList(),
|
||||||
|
@ -115,7 +115,7 @@ internal class SpinnerServer(
|
||||||
"browse",
|
"browse",
|
||||||
BrowsePageModel(
|
BrowsePageModel(
|
||||||
environment = environment,
|
environment = environment,
|
||||||
deviceInfo = deviceInfo,
|
deviceInfo = deviceInfo.resolve(),
|
||||||
database = dbName,
|
database = dbName,
|
||||||
databases = databases.keys.toList(),
|
databases = databases.keys.toList(),
|
||||||
plugins = plugins.values.toList(),
|
plugins = plugins.values.toList(),
|
||||||
|
@ -130,7 +130,7 @@ internal class SpinnerServer(
|
||||||
var pageIndex: Int = session.parameters["pageIndex"]?.get(0)?.toInt() ?: 0
|
var pageIndex: Int = session.parameters["pageIndex"]?.get(0)?.toInt() ?: 0
|
||||||
val action: String? = session.parameters["action"]?.get(0)
|
val action: String? = session.parameters["action"]?.get(0)
|
||||||
|
|
||||||
val rowCount = dbConfig.db.getTableRowCount(table)
|
val rowCount = dbConfig.db().getTableRowCount(table)
|
||||||
val pageCount = ceil(rowCount.toFloat() / pageSize.toFloat()).toInt()
|
val pageCount = ceil(rowCount.toFloat() / pageSize.toFloat()).toInt()
|
||||||
|
|
||||||
when (action) {
|
when (action) {
|
||||||
|
@ -141,17 +141,17 @@ internal class SpinnerServer(
|
||||||
}
|
}
|
||||||
|
|
||||||
val query = "select * from $table limit $pageSize offset ${pageSize * pageIndex}"
|
val query = "select * from $table limit $pageSize offset ${pageSize * pageIndex}"
|
||||||
val queryResult = dbConfig.db.query(query).use { it.toQueryResult(columnTransformers = dbConfig.columnTransformers) }
|
val queryResult = dbConfig.db().query(query).use { it.toQueryResult(columnTransformers = dbConfig.columnTransformers) }
|
||||||
|
|
||||||
return renderTemplate(
|
return renderTemplate(
|
||||||
"browse",
|
"browse",
|
||||||
BrowsePageModel(
|
BrowsePageModel(
|
||||||
environment = environment,
|
environment = environment,
|
||||||
deviceInfo = deviceInfo,
|
deviceInfo = deviceInfo.resolve(),
|
||||||
database = dbName,
|
database = dbName,
|
||||||
databases = databases.keys.toList(),
|
databases = databases.keys.toList(),
|
||||||
plugins = plugins.values.toList(),
|
plugins = plugins.values.toList(),
|
||||||
tableNames = dbConfig.db.getTableNames(),
|
tableNames = dbConfig.db().getTableNames(),
|
||||||
table = table,
|
table = table,
|
||||||
queryResult = queryResult,
|
queryResult = queryResult,
|
||||||
pagingData = PagingData(
|
pagingData = PagingData(
|
||||||
|
@ -171,7 +171,7 @@ internal class SpinnerServer(
|
||||||
"query",
|
"query",
|
||||||
QueryPageModel(
|
QueryPageModel(
|
||||||
environment = environment,
|
environment = environment,
|
||||||
deviceInfo = deviceInfo,
|
deviceInfo = deviceInfo.resolve(),
|
||||||
database = dbName,
|
database = dbName,
|
||||||
databases = databases.keys.toList(),
|
databases = databases.keys.toList(),
|
||||||
plugins = plugins.values.toList(),
|
plugins = plugins.values.toList(),
|
||||||
|
@ -193,7 +193,7 @@ internal class SpinnerServer(
|
||||||
"recent",
|
"recent",
|
||||||
RecentPageModel(
|
RecentPageModel(
|
||||||
environment = environment,
|
environment = environment,
|
||||||
deviceInfo = deviceInfo,
|
deviceInfo = deviceInfo.resolve(),
|
||||||
database = dbName,
|
database = dbName,
|
||||||
databases = databases.keys.toList(),
|
databases = databases.keys.toList(),
|
||||||
plugins = plugins.values.toList(),
|
plugins = plugins.values.toList(),
|
||||||
|
@ -212,12 +212,12 @@ internal class SpinnerServer(
|
||||||
"query",
|
"query",
|
||||||
QueryPageModel(
|
QueryPageModel(
|
||||||
environment = environment,
|
environment = environment,
|
||||||
deviceInfo = deviceInfo,
|
deviceInfo = deviceInfo.resolve(),
|
||||||
database = dbName,
|
database = dbName,
|
||||||
databases = databases.keys.toList(),
|
databases = databases.keys.toList(),
|
||||||
plugins = plugins.values.toList(),
|
plugins = plugins.values.toList(),
|
||||||
query = rawQuery,
|
query = rawQuery,
|
||||||
queryResult = dbConfig.db.query(query).use { it.toQueryResult(queryStartTimeNanos = startTimeNanos, columnTransformers = dbConfig.columnTransformers) }
|
queryResult = dbConfig.db().query(query).use { it.toQueryResult(queryStartTimeNanos = startTimeNanos, columnTransformers = dbConfig.columnTransformers) }
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -227,7 +227,7 @@ internal class SpinnerServer(
|
||||||
"plugin",
|
"plugin",
|
||||||
PluginPageModel(
|
PluginPageModel(
|
||||||
environment = environment,
|
environment = environment,
|
||||||
deviceInfo = deviceInfo,
|
deviceInfo = deviceInfo.resolve(),
|
||||||
database = dbName,
|
database = dbName,
|
||||||
databases = databases.keys.toList(),
|
databases = databases.keys.toList(),
|
||||||
plugins = plugins.values.toList(),
|
plugins = plugins.values.toList(),
|
||||||
|
@ -389,6 +389,10 @@ internal class SpinnerServer(
|
||||||
return params[name]
|
return params[name]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Map<String, () -> String>.resolve(): Map<String, String> {
|
||||||
|
return this.mapValues { entry -> entry.value() }.toMap()
|
||||||
|
}
|
||||||
|
|
||||||
interface PrefixPageData {
|
interface PrefixPageData {
|
||||||
val environment: String
|
val environment: String
|
||||||
val deviceInfo: Map<String, String>
|
val deviceInfo: Map<String, String>
|
||||||
|
|
Ładowanie…
Reference in New Issue