Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ plugins {
id("com.osfans.trime.opencc-data")
alias(libs.plugins.aboutlibraries)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.kotlin.parcelize)
alias(libs.plugins.ksp)
}

Expand Down Expand Up @@ -141,7 +141,6 @@ android.applicationVariants.all {
dependencies {
ksp(project(":codegen"))
implementation(libs.kotlinx.coroutines)
implementation(libs.kotlinx.serialization.json)
implementation(libs.androidx.activity)
implementation(libs.androidx.appcompat)
implementation(libs.androidx.autofill)
Expand All @@ -159,7 +158,9 @@ dependencies {
implementation(libs.androidx.work.runtime.ktx)
implementation(libs.flexbox)
implementation(libs.bravh)
implementation(libs.kaml)
implementation(libs.jackson.databind)
implementation(libs.jackson.module.kotlin)
implementation(libs.jackson.dataformat.yaml)
implementation(libs.timber)
implementation(libs.xxpermissions)
ksp(libs.kotlin.inject.compiler)
Expand Down
14 changes: 14 additions & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,20 @@
static void checkNotNullParameter(...);
}

# Proguard configuration for Jackson 2.x
-keep class com.fasterxml.jackson.databind.ObjectMapper {
public <methods>;
protected <methods>;
}
-keep class com.fasterxml.jackson.databind.ObjectWriter {
public ** writeValueAsString(**);
}
-keepclassmembers class * {
@com.fasterxml.jackson.annotation.* *;
}
-keepnames class com.fasterxml.jackson.** { *; }
-dontwarn com.fasterxml.jackson.databind.**

# Uncomment this to preserve the line number information for
# debugging stack traces.
-keepattributes SourceFile,LineNumberTable
Expand Down
3 changes: 0 additions & 3 deletions app/src/main/java/com/osfans/trime/data/base/DataChecksums.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@

package com.osfans.trime.data.base

import kotlinx.serialization.Serializable

@Serializable
data class DataChecksums(
val sha256: String,
val files: Map<String, String>,
Expand Down
7 changes: 4 additions & 3 deletions app/src/main/java/com/osfans/trime/data/base/DataManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ package com.osfans.trime.data.base
import android.content.res.AssetManager
import android.os.Build
import android.os.Environment
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import com.osfans.trime.data.prefs.AppPrefs
import com.osfans.trime.util.FileUtils
import com.osfans.trime.util.ResourceUtils
import com.osfans.trime.util.appContext
import kotlinx.serialization.json.Json
import timber.log.Timber
import java.io.File
import java.util.concurrent.locks.ReentrantLock
Expand All @@ -24,9 +25,9 @@ object DataManager {

private val lock = ReentrantLock()

private val json by lazy { Json }
private val json by lazy { jacksonObjectMapper() }

private fun deserializeDataChecksums(raw: String): DataChecksums = json.decodeFromString<DataChecksums>(raw)
private fun deserializeDataChecksums(raw: String): DataChecksums = json.readValue<DataChecksums>(raw)

// If Android version supports direct boot, we put the hierarchy in device encrypted storage
// instead of credential encrypted storage so that data can be accessed before user unlock
Expand Down
66 changes: 41 additions & 25 deletions app/src/main/java/com/osfans/trime/data/schema/Schema.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,58 @@

package com.osfans.trime.data.schema

import com.osfans.trime.util.config.Config
import timber.log.Timber
import com.fasterxml.jackson.annotation.JsonIgnore
import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonDeserializer
import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.annotation.JsonDeserialize

@JsonDeserialize(using = Schema.Deserializer::class)
data class Schema(
val switches: List<Switch>,
val symbols: Map<String, Config>,
val alphabet: String,
val switches: List<Switch> = emptyList(),
val symbols: Map<String, List<String>> = emptyMap(),
val alphabet: String = "",
) {
data class Switch(
val name: String = "",
val options: List<String> = listOf(),
val reset: Int = -1,
val states: List<String> = listOf(),
var enabled: Int = 0,
@field:JsonIgnore var enabled: Int = 0,
)

companion object {
fun open(schemaId: String): Schema {
val c = Config.openSchema(schemaId)
class Deserializer : JsonDeserializer<Schema>() {
override fun deserialize(
p: JsonParser,
ctxt: DeserializationContext,
): Schema {
val node = p.codec.readTree<JsonNode>(p)
val switches =
node["switches"].map {
Switch(
name = it["name"]?.asText() ?: "",
options = it["options"]?.map { o -> o.asText() } ?: emptyList(),
reset = it["reset"]?.intValue() ?: -1,
states = it["states"]?.map { o -> o.asText() } ?: emptyList(),
)
}
val symbols =
buildMap {
node.at("/punctuator/symbols").properties().forEach {
val value =
if (it.value.isArray) {
it.value?.map { v -> v.toString() } ?: emptyList()
} else {
listOf(it.value.toString())
}
put(it.key.toString(), value)
}
}
return Schema(
switches =
c.getList("switches").mapNotNull decode@{ e ->
try {
Switch(
name = e.getString("name"),
options = e.getStringList("options"),
reset = e.getInt("reset", -1),
states = e.getStringList("states"),
)
} catch (e: Exception) {
Timber.e(e, "Failed to decode switches of schema '$schemaId'")
null
}
},
symbols = c.getMap("punctuator/symbols"),
alphabet = c.getString("speller/alphabet"),
switches = switches,
symbols = symbols,
alphabet = node.at("/speller/alphabet").toString(),
)
}
}
Expand Down
16 changes: 12 additions & 4 deletions app/src/main/java/com/osfans/trime/data/schema/SchemaManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,33 @@

package com.osfans.trime.data.schema

import com.fasterxml.jackson.module.kotlin.readValue
import com.osfans.trime.core.Rime
import com.osfans.trime.data.base.DataManager
import com.osfans.trime.util.legacyYAMLMapper
import java.io.File

object SchemaManager {
private lateinit var currentSchema: Schema
var visibleSwitches: List<Schema.Switch> = listOf()

@JvmStatic
fun init(schemaId: String) {
currentSchema = Schema.open(schemaId)
val schemaFile = File(DataManager.resolveDeployedResourcePath("$schemaId.schema"))
currentSchema = legacyYAMLMapper().readValue<Schema>(schemaFile.inputStream())
visibleSwitches =
currentSchema.switches
.filter { it.states.isNotEmpty() } // 剔除没有 states 条目项的值,它们不作为开关使用
updateSwitchOptions()
}

val activeSchema: Schema
get() = currentSchema
get() =
try {
currentSchema
} catch (_: Exception) {
Schema()
}

@JvmStatic
fun updateSwitchOptions() {
if (visibleSwitches.isEmpty()) return // 無方案
visibleSwitches.forEach { s ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,29 @@
package com.osfans.trime.data.soundeffect

import android.view.KeyEvent
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import com.fasterxml.jackson.annotation.JsonIgnore

@Serializable
data class SoundEffect(
val name: String = "",
val sound: List<String>,
val folder: String,
val melody: List<String> = listOf(),
val keyset: List<Key>,
) {
@Serializable
data class Key(
val min: String = "UNKNOWN",
val max: String = "UNKNOWN",
val keys: List<String> = listOf(),
val inOrder: Boolean,
val sounds: List<Int>,
) {
@Transient
@JsonIgnore
private val sysKeyCodes = keys.map { KeyEvent.keyCodeFromString(it.uppercase()) }

@Transient
@JsonIgnore
private val minKeyCode = KeyEvent.keyCodeFromString(min.uppercase())

@Transient
@JsonIgnore
private val maxKeyCode = KeyEvent.keyCodeFromString(max.uppercase())

fun querySoundIndex(keyCode: Int): Int {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,16 @@

package com.osfans.trime.data.soundeffect

import com.charleskorn.kaml.Yaml
import com.charleskorn.kaml.YamlConfiguration
import com.fasterxml.jackson.module.kotlin.readValue
import com.osfans.trime.data.base.DataManager
import com.osfans.trime.data.prefs.AppPrefs
import com.osfans.trime.util.FileUtils
import com.osfans.trime.util.jacksonYAMLMapper
import timber.log.Timber
import java.io.File

object SoundEffectManager {
private val yaml =
Yaml(
configuration =
YamlConfiguration(
strictMode = false,
),
)
private val yaml by lazy { jacksonYAMLMapper() }

private val userDir: File
get() {
Expand All @@ -34,7 +28,7 @@ object SoundEffectManager {
?.mapNotNull decode@{ f ->
val effect =
runCatching {
val origin = yaml.decodeFromString(SoundEffect.serializer(), f.readText())
val origin = yaml.readValue<SoundEffect>(f.readText())
if (origin.name.isEmpty()) {
origin.copy(name = f.name.substringBefore('.'))
} else {
Expand Down
Loading
Loading