diff --git a/features/login/impl/build.gradle.kts b/features/login/impl/build.gradle.kts
index e6381c9162..f36cda49f6 100644
--- a/features/login/impl/build.gradle.kts
+++ b/features/login/impl/build.gradle.kts
@@ -1,3 +1,4 @@
+import extension.buildConfigFieldStr
import extension.setupDependencyInjection
import extension.testCommonDependencies
@@ -23,6 +24,29 @@ android {
isIncludeAndroidResources = true
}
}
+
+ buildFeatures {
+ buildConfig = true
+ }
+
+ buildTypes {
+ val elementClassicPackageKey = "elementClassicPackage"
+ val elementClassicPackage = "im.vector.app"
+ val elementClassicPackageDebug = "$elementClassicPackage.debug"
+ val elementClassicPackageNightly = "$elementClassicPackage.nightly"
+ getByName("release") {
+ manifestPlaceholders[elementClassicPackageKey] = elementClassicPackage
+ buildConfigFieldStr(elementClassicPackageKey, elementClassicPackage)
+ }
+ getByName("debug") {
+ manifestPlaceholders[elementClassicPackageKey] = elementClassicPackageDebug
+ buildConfigFieldStr(elementClassicPackageKey, elementClassicPackageDebug)
+ }
+ register("nightly") {
+ manifestPlaceholders[elementClassicPackageKey] = elementClassicPackageNightly
+ buildConfigFieldStr(elementClassicPackageKey, elementClassicPackageNightly)
+ }
+ }
}
setupDependencyInjection()
diff --git a/features/login/impl/src/main/AndroidManifest.xml b/features/login/impl/src/main/AndroidManifest.xml
index f2d84131a7..295658f6d4 100644
--- a/features/login/impl/src/main/AndroidManifest.xml
+++ b/features/login/impl/src/main/AndroidManifest.xml
@@ -13,8 +13,9 @@
+
+
+
-
-
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/classic/ElementClassicConnection.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/classic/ElementClassicConnection.kt
index c983ea04ba..f895dd781e 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/classic/ElementClassicConnection.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/classic/ElementClassicConnection.kt
@@ -20,9 +20,8 @@ import android.os.Messenger
import android.os.RemoteException
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding
+import io.element.android.features.login.impl.BuildConfig
import io.element.android.libraries.core.log.logger.LoggerTag
-import io.element.android.libraries.core.meta.BuildMeta
-import io.element.android.libraries.core.meta.BuildType
import io.element.android.libraries.di.annotations.AppCoroutineScope
import io.element.android.libraries.di.annotations.ApplicationContext
import io.element.android.libraries.matrix.api.core.UserId
@@ -44,7 +43,11 @@ sealed interface ElementClassicConnectionState {
object Idle : ElementClassicConnectionState
object ElementClassicNotFound : ElementClassicConnectionState
object ElementClassicReadyNoSession : ElementClassicConnectionState
- data class ElementClassicReady(val userId: UserId) : ElementClassicConnectionState
+ data class ElementClassicReady(
+ val userId: UserId,
+ val secrets: String,
+ ) : ElementClassicConnectionState
+
data class Error(val error: String) : ElementClassicConnectionState
}
@@ -56,7 +59,6 @@ class DefaultElementClassicConnection(
private val context: Context,
@AppCoroutineScope
private val coroutineScope: CoroutineScope,
- private val buildMeta: BuildMeta,
) : ElementClassicConnection {
// Messenger for communicating with the service.
private var messenger: Messenger? = null
@@ -101,7 +103,7 @@ class DefaultElementClassicConnection(
// applications replace our component.
try {
val intentService = Intent()
- intentService.setComponent(getElementClassicComponent(buildMeta))
+ intentService.setComponent(getElementClassicComponent())
if (context.bindService(intentService, serviceConnection, BIND_AUTO_CREATE)) {
Timber.tag(loggerTag.value).d("Binding returned true")
} else {
@@ -198,17 +200,8 @@ class DefaultElementClassicConnection(
}
}
- private fun getElementClassicComponent(buildMeta: BuildMeta) = ComponentName(
- buildString {
- append(ELEMENT_CLASSIC_APP_ID)
- append(
- when (buildMeta.buildType) {
- BuildType.DEBUG -> ELEMENT_CLASSIC_APP_ID_DEBUG_SUFFIX
- BuildType.NIGHTLY -> ELEMENT_CLASSIC_APP_ID_NIGHTLY_SUFFIX
- BuildType.RELEASE -> ELEMENT_CLASSIC_APP_ID_RELEASE_SUFFIX
- }
- )
- },
+ private fun getElementClassicComponent() = ComponentName(
+ BuildConfig.elementClassicPackage,
ELEMENT_CLASSIC_SERVICE_FULL_CLASS_NAME,
)
@@ -220,9 +213,14 @@ class DefaultElementClassicConnection(
if (error != null) {
ElementClassicConnectionState.Error(error)
} else {
- val userId = getString(KEY_USER_ID_STR)?.let(::UserId)
+ val userId = getString(KEY_USER_ID_STR)?.takeIf { it.isNotEmpty() }?.let(::UserId)
if (userId != null) {
- ElementClassicConnectionState.ElementClassicReady(userId)
+ val secrets = getString(KEY_SECRETS_STR)?.takeIf { it.isNotEmpty() }
+ if (secrets == null) {
+ ElementClassicConnectionState.Error("No secrets received from Element Classic")
+ } else {
+ ElementClassicConnectionState.ElementClassicReady(userId, secrets)
+ }
} else {
ElementClassicConnectionState.ElementClassicReadyNoSession
}
@@ -232,18 +230,31 @@ class DefaultElementClassicConnection(
// Everything in this companion object must match what is defined in Element Classic
private companion object {
+ const val ELEMENT_CLASSIC_SERVICE_FULL_CLASS_NAME = "im.vector.app.features.importer.ImporterService"
+
// Command to the service to get the data.
const val MSG_GET_DATA = 1
- const val ELEMENT_CLASSIC_APP_ID = "im.vector.app"
- const val ELEMENT_CLASSIC_APP_ID_DEBUG_SUFFIX = ".debug"
- const val ELEMENT_CLASSIC_APP_ID_NIGHTLY_SUFFIX = ".nightly"
- const val ELEMENT_CLASSIC_APP_ID_RELEASE_SUFFIX = ""
-
- const val ELEMENT_CLASSIC_SERVICE_FULL_CLASS_NAME = "im.vector.app.features.importer.ImporterService"
-
// Keys for the bundle returned from the service
const val KEY_ERROR_STR = "error"
const val KEY_USER_ID_STR = "userId"
+
+ /**
+ * Key to extract the secrets from the bundle, as a Json string.
+ * Json will have this format:
+ * {
+ * "cross_signing" : {
+ * "master_key" : "z8RUxnaAGu___REDACTED___k+BQL9o",
+ * "user_signing_key" : "baJHzA___REDACTED___xMLbSUAXw9QUzqms",
+ * "self_signing_key" : "DU0CvLtR2G/___REDACTED___dV/MONNq4nsQhM"
+ * },
+ * "backup" : {
+ * "algorithm" : "m.megolm_backup.v1.curve25519-aes-sha2",
+ * "key" : "VzncmQ+UOV___REDACTED___patxDz7m0Nc",
+ * "backup_version" : "1"
+ * }
+ * }
+ */
+ const val KEY_SECRETS_STR = "secrets"
}
}