Skip to content

Commit

Permalink
#1274 WIP: add assistant trigger key
Browse files Browse the repository at this point in the history
  • Loading branch information
sds100 committed Oct 5, 2024
1 parent 0dbd022 commit bafb15b
Show file tree
Hide file tree
Showing 23 changed files with 389 additions and 306 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,5 @@ class AccessibilityServiceController(
devicesAdapter,
suAdapter,
inputMethodAdapter,
settingsRepository
)
settingsRepository,
)

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package io.github.sds100.keymapper.data.entities

import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize
import java.util.UUID

@Parcelize
data class AssistantTriggerKeyEntity(
/**
* The type of assistant that triggers this key. The voice assistant
* is the assistant that handles voice commands and the device assistant
* is the one selected in the settings as the default for reading on-screen
* content.
*/
@SerializedName(NAME_ASSISTANT_TYPE)
val type: String = ASSISTANT_TYPE_ANY,

@SerializedName(NAME_CLICK_TYPE)
override val clickType: Int = SHORT_PRESS,

@SerializedName(NAME_UID)
override val uid: String = UUID.randomUUID().toString(),
) : TriggerKeyEntity(),
Parcelable {

companion object {
// DON'T CHANGE THESE. Used for JSON serialization and parsing.
const val NAME_ASSISTANT_TYPE = "assistantType"

// IDS! DON'T CHANGE
const val ASSISTANT_TYPE_ANY = "any"
const val ASSISTANT_TYPE_VOICE = "voice"
const val ASSISTANT_TYPE_DEVICE = "device"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package io.github.sds100.keymapper.data.entities

import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize
import java.util.UUID

@Parcelize
data class KeyCodeTriggerKeyEntity(
@SerializedName(NAME_KEYCODE)
val keyCode: Int,

@SerializedName(NAME_DEVICE_ID)
val deviceId: String = DEVICE_ID_THIS_DEVICE,

@SerializedName(NAME_DEVICE_NAME)
val deviceName: String? = null,

@SerializedName(NAME_CLICK_TYPE)
override val clickType: Int = SHORT_PRESS,

@SerializedName(NAME_FLAGS)
val flags: Int = 0,

@SerializedName(NAME_UID)
override val uid: String = UUID.randomUUID().toString(),
) : TriggerKeyEntity(),
Parcelable {

companion object {
// DON'T CHANGE THESE. Used for JSON serialization and parsing.
const val NAME_KEYCODE = "keyCode"
const val NAME_DEVICE_ID = "deviceId"
const val NAME_DEVICE_NAME = "deviceName"
const val NAME_FLAGS = "flags"

// IDS! DON'T CHANGE
const val DEVICE_ID_THIS_DEVICE = "io.github.sds100.keymapper.THIS_DEVICE"
const val DEVICE_ID_ANY_DEVICE = "io.github.sds100.keymapper.ANY_DEVICE"

const val FLAG_DO_NOT_CONSUME_KEY_EVENT = 1
}
}
Original file line number Diff line number Diff line change
@@ -1,78 +1,72 @@
package io.github.sds100.keymapper.data.entities

import android.os.Parcelable
import androidx.annotation.IntDef
import com.github.salomonbrys.kotson.byInt
import com.github.salomonbrys.kotson.byNullableInt
import com.github.salomonbrys.kotson.byNullableString
import com.github.salomonbrys.kotson.byString
import com.github.salomonbrys.kotson.jsonDeserializer
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize
import com.github.salomonbrys.kotson.obj
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import java.util.UUID

@Parcelize
data class TriggerKeyEntity(
@SerializedName(NAME_KEYCODE)
val keyCode: Int,
@SerializedName(NAME_DEVICE_ID)
val deviceId: String = DEVICE_ID_THIS_DEVICE,

@SerializedName(NAME_DEVICE_NAME)
val deviceName: String? = null,

@ClickType
@SerializedName(NAME_CLICK_TYPE)
val clickType: Int = SHORT_PRESS,

@SerializedName(NAME_FLAGS)
val flags: Int = 0,

@SerializedName(NAME_UID)
val uid: String = UUID.randomUUID().toString(),
) : Parcelable {
sealed class TriggerKeyEntity : Parcelable {
abstract val clickType: Int
abstract val uid: String

companion object {
// DON'T CHANGE THESE. Used for JSON serialization and parsing.
const val NAME_KEYCODE = "keyCode"
const val NAME_DEVICE_ID = "deviceId"
const val NAME_DEVICE_NAME = "deviceName"
const val NAME_CLICK_TYPE = "clickType"
const val NAME_FLAGS = "flags"
const val NAME_UID = "uid"

// IDS! DON'T CHANGE
const val DEVICE_ID_THIS_DEVICE = "io.github.sds100.keymapper.THIS_DEVICE"
const val DEVICE_ID_ANY_DEVICE = "io.github.sds100.keymapper.ANY_DEVICE"

const val FLAG_DO_NOT_CONSUME_KEY_EVENT = 1

// Click types
const val UNDETERMINED = -1
const val SHORT_PRESS = 0
const val LONG_PRESS = 1
const val DOUBLE_PRESS = 2

val DESERIALIZER = jsonDeserializer {
val keycode by it.json.byInt(NAME_KEYCODE)
val deviceId by it.json.byString(NAME_DEVICE_ID)
val deviceName by it.json.byNullableString(NAME_DEVICE_NAME)
val clickType by it.json.byInt(NAME_CLICK_TYPE)
val DESERIALIZER: JsonDeserializer<TriggerKeyEntity> =
jsonDeserializer { (json, _, _) ->
// nullable because this property was added after backup and restore was released.
var uid: String? by json.byNullableString(key = NAME_UID)
uid = uid ?: UUID.randomUUID().toString()

// nullable because this property was added after backup and restore was released.
val flags by it.json.byNullableInt(NAME_FLAGS)
val uid by it.json.byNullableString(NAME_UID)
if (json.obj.has(AssistantTriggerKeyEntity.NAME_ASSISTANT_TYPE)) {
return@jsonDeserializer deserializeAssistantTriggerKey(json, uid!!)
} else {
return@jsonDeserializer deserializeKeyCodeTriggerKey(json, uid!!)
}
}

TriggerKeyEntity(
keycode,
private fun deserializeAssistantTriggerKey(
json: JsonElement,
uid: String,
): AssistantTriggerKeyEntity {
val type by json.byString(AssistantTriggerKeyEntity.NAME_ASSISTANT_TYPE)
val clickType by json.byInt(NAME_CLICK_TYPE)

return AssistantTriggerKeyEntity(type, clickType, uid)
}

private fun deserializeKeyCodeTriggerKey(
json: JsonElement,
uid: String,
): KeyCodeTriggerKeyEntity {
val keyCode by json.byInt(KeyCodeTriggerKeyEntity.NAME_KEYCODE)
val deviceId by json.byString(KeyCodeTriggerKeyEntity.NAME_DEVICE_ID)
val deviceName by json.byNullableString(KeyCodeTriggerKeyEntity.NAME_DEVICE_NAME)
val clickType by json.byInt(NAME_CLICK_TYPE)
val flags by json.byNullableInt(KeyCodeTriggerKeyEntity.NAME_FLAGS)

return KeyCodeTriggerKeyEntity(
keyCode,
deviceId,
deviceName,
clickType,
flags ?: 0,
uid ?: UUID.randomUUID().toString(),
uid,
)
}
}

@IntDef(value = [UNDETERMINED, SHORT_PRESS, LONG_PRESS, DOUBLE_PRESS])
annotation class ClickType
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import com.google.gson.JsonArray
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import io.github.sds100.keymapper.data.entities.ActionEntity
import io.github.sds100.keymapper.data.entities.TriggerKeyEntity
import io.github.sds100.keymapper.data.entities.KeyCodeTriggerKeyEntity
import splitties.bitflags.hasFlag
import timber.log.Timber

Expand Down Expand Up @@ -107,7 +107,7 @@ object Migration1To2 {

createTriggerKey2(
it.asInt,
TriggerKeyEntity.DEVICE_ID_ANY_DEVICE,
KeyCodeTriggerKeyEntity.DEVICE_ID_ANY_DEVICE,
clickType,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.github.salomonbrys.kotson.fromJson
import com.github.salomonbrys.kotson.registerTypeAdapter
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import io.github.sds100.keymapper.data.entities.KeyCodeTriggerKeyEntity
import io.github.sds100.keymapper.data.entities.TriggerEntity
import io.github.sds100.keymapper.data.entities.TriggerKeyEntity
import splitties.bitflags.hasFlag
Expand All @@ -29,7 +30,10 @@ object Migration6To7 {
.create()

query(query).apply {
val gson = GsonBuilder().registerTypeAdapter(TriggerEntity.DESERIALIZER).create()
val gson = GsonBuilder()
.registerTypeAdapter(TriggerEntity.DESERIALIZER)
.registerTypeAdapter(TriggerKeyEntity.DESERIALIZER)
.create()

while (moveToNext()) {
val idColumnIndex = getColumnIndex("id")
Expand All @@ -39,13 +43,15 @@ object Migration6To7 {

val trigger = gson.fromJson<TriggerEntity>(getString(triggerColumnIndex))

val newTriggerKeys = trigger.keys.map {
if (trigger.flags.hasFlag(TRIGGER_FLAG_DONT_OVERRIDE_DEFAULT_ACTION)) {
it.copy(flags = it.flags.withFlag(TriggerKeyEntity.FLAG_DO_NOT_CONSUME_KEY_EVENT))
} else {
it
val newTriggerKeys = trigger.keys
.mapNotNull { it as? KeyCodeTriggerKeyEntity }
.map { key ->
if (trigger.flags.hasFlag(TRIGGER_FLAG_DONT_OVERRIDE_DEFAULT_ACTION)) {
key.copy(flags = key.flags.withFlag(KeyCodeTriggerKeyEntity.FLAG_DO_NOT_CONSUME_KEY_EVENT))
} else {
key
}
}
}

val newTriggerFlags = trigger.flags.minusFlag(
TRIGGER_FLAG_DONT_OVERRIDE_DEFAULT_ACTION,
Expand Down
Loading

0 comments on commit bafb15b

Please sign in to comment.