Add preferences for AirPods Identity and Encryption Keys

This commit introduces settings for users to input their AirPods' Identity Resolving Key (IRK) and Encryption Key. These keys, obtainable via a MacBook, allow CAPod to reliably identify the AirPods and decrypt detailed status information.

Key changes:
- Added new preferences in General Settings for IRK and Encryption Key.
- Implemented a custom dialog for key input, including validation and a link to a guide.
- Added a Moshi adapter for serializing/deserializing `ByteArray` to/from Base64 for storing the keys.
- Included new string resources for labels, descriptions, and explanations related to the keys.
- Added new icons for the key preferences.
This commit is contained in:
darken
2025-06-06 06:03:41 +02:00
committed by Matthias Urhahn
parent eb8a9b3b46
commit e8481cc8cd
11 changed files with 169 additions and 5 deletions
@@ -2,7 +2,7 @@ package eu.darken.capod.common
import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.core.net.toUri
import dagger.Reusable
import dagger.hilt.android.qualifiers.ApplicationContext
import eu.darken.capod.common.debug.logging.Logging.Priority.ERROR
@@ -15,7 +15,7 @@ class WebpageTool @Inject constructor(
) {
fun open(address: String) {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(address)).apply {
val intent = Intent(Intent.ACTION_VIEW, address.toUri()).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
try {
@@ -0,0 +1,15 @@
package eu.darken.capod.common.serialization
import com.squareup.moshi.FromJson
import com.squareup.moshi.ToJson
import kotlin.io.encoding.Base64
import kotlin.io.encoding.ExperimentalEncodingApi
@OptIn(ExperimentalEncodingApi::class)
class ByteArrayAdapter {
@ToJson
fun toJson(obj: ByteArray): String = Base64.encode(obj)
@FromJson
fun fromJson(base64: String): ByteArray? = Base64.decode(base64)
}
@@ -15,6 +15,7 @@ class SerializationModule {
@Singleton
fun moshi(): Moshi = Moshi.Builder()
.add(JavaInstantAdapter())
.add(ByteArrayAdapter())
.build()
}
@@ -35,6 +35,9 @@ class GeneralSettings @Inject constructor(
val mainDeviceAddress = preferences.createFlowPreference<String?>("core.maindevice.address", null)
val mainDeviceModel = preferences.createFlowPreference("core.maindevice.model", PodDevice.Model.UNKNOWN, moshi)
val mainDeviceIdentityKey = preferences.createFlowPreference<ByteArray?>("core.maindevice.identitykey", null, moshi)
val mainDeviceEncryptionKey =
preferences.createFlowPreference<ByteArray?>("core.maindevice.encryptionkey", null, moshi)
val isOffloadedFilteringDisabled = preferences.createFlowPreference(
"core.compat.offloaded.filtering.disabled",