diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b7c7b3f206e..e18a38b34d4 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -49,7 +49,7 @@ repositories { google() } -val nonFreeFlavors = setOf("prod", "internal", "staging", "beta", "dev") +val nonFreeFlavors = setOf("prod", "internal", "staging", "beta", "dev", "enterprise") val fossFlavors = setOf("fdroid") val internalFlavors = setOf("internal", "staging", "beta", "dev") val allFlavors = nonFreeFlavors + fossFlavors @@ -199,6 +199,8 @@ dependencies { implementationWithCoverage(projects.features.meetings) implementationWithCoverage(projects.features.sync) + enterpriseImplementation(projects.core.nomad) + // Anonymous Analytics val flavors = getFlavorsSettings() val isCustomBuild = isCustomizationEnabled() diff --git a/app/src/enterprise/AndroidManifest.xml b/app/src/enterprise/AndroidManifest.xml new file mode 100644 index 00000000000..9994a4c9b58 --- /dev/null +++ b/app/src/enterprise/AndroidManifest.xml @@ -0,0 +1,17 @@ + + + + + + + + + + diff --git a/app/src/enterprise/res/drawable/ic_launcher_background.xml b/app/src/enterprise/res/drawable/ic_launcher_background.xml new file mode 100644 index 00000000000..58a11edd910 --- /dev/null +++ b/app/src/enterprise/res/drawable/ic_launcher_background.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/enterprise/res/drawable/ic_launcher_foreground.xml b/app/src/enterprise/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 00000000000..e63fed2e550 --- /dev/null +++ b/app/src/enterprise/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/enterprise/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/enterprise/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 00000000000..b0444ebeab6 --- /dev/null +++ b/app/src/enterprise/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,23 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/enterprise/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/enterprise/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 00000000000..b0444ebeab6 --- /dev/null +++ b/app/src/enterprise/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,23 @@ + + + + + + + \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/flavor/ProductFlavors.kt b/buildSrc/src/main/kotlin/flavor/ProductFlavors.kt index a6dc13fdd58..61c507a7a91 100644 --- a/buildSrc/src/main/kotlin/flavor/ProductFlavors.kt +++ b/buildSrc/src/main/kotlin/flavor/ProductFlavors.kt @@ -35,6 +35,7 @@ sealed class ProductFlavors( object Beta : ProductFlavors("beta", "Wire Beta") object Internal : ProductFlavors("internal", "Wire Internal") + object Enterprise : ProductFlavors("enterprise", "Wire Enterprise") object Production : ProductFlavors("prod", "Wire", shareduserId = "com.waz.userid") object Fdroid : ProductFlavors( buildName = "fdroid", @@ -49,6 +50,7 @@ sealed class ProductFlavors( Staging, Beta, Internal, + Enterprise, Production, Fdroid, ) diff --git a/core/nomad/build.gradle.kts b/core/nomad/build.gradle.kts new file mode 100644 index 00000000000..8760da1e77a --- /dev/null +++ b/core/nomad/build.gradle.kts @@ -0,0 +1,16 @@ +plugins { + id(libs.plugins.wire.android.library.get().pluginId) + id(libs.plugins.wire.kover.get().pluginId) + id(libs.plugins.wire.hilt.get().pluginId) + alias(libs.plugins.compose.compiler) +} + +dependencies { + implementation(projects.core.di) + implementation("com.wire.kalium:kalium-logic") + implementation("com.wire.kalium:kalium-nomaddevice") + implementation("com.wire.kalium:kalium-userstorage") + implementation("com.wire.kalium:kalium-hooks") + implementation(libs.androidx.startup) + implementation(libs.androidx.compose.runtime) +} diff --git a/core/nomad/src/main/kotlin/com/wire/android/nomad/NomadHookRegistrar.kt b/core/nomad/src/main/kotlin/com/wire/android/nomad/NomadHookRegistrar.kt new file mode 100644 index 00000000000..b1330cd0209 --- /dev/null +++ b/core/nomad/src/main/kotlin/com/wire/android/nomad/NomadHookRegistrar.kt @@ -0,0 +1,37 @@ +/* + * Wire + * Copyright (C) 2026 Wire Swiss GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +package com.wire.android.nomad + +import com.wire.kalium.logic.CoreLogic +import com.wire.kalium.nomaddevice.NomadRemoteBackupChangeLogHookNotifier +import com.wire.kalium.userstorage.di.PlatformUserStorageProvider +import dagger.Lazy + +public object NomadHookRegistrar { + /** + * Registers Nomad's persisted-message hook into CoreLogic during app startup. + */ + public fun register(coreLogic: Lazy) { + coreLogic.get().registerPersistenceEventHook( + NomadRemoteBackupChangeLogHookNotifier( + userStorageProvider = PlatformUserStorageProvider() + ) + ) + } +} diff --git a/core/nomad/src/main/kotlin/com/wire/android/nomad/di/NomadInitializerEntryPoint.kt b/core/nomad/src/main/kotlin/com/wire/android/nomad/di/NomadInitializerEntryPoint.kt new file mode 100644 index 00000000000..330bb736734 --- /dev/null +++ b/core/nomad/src/main/kotlin/com/wire/android/nomad/di/NomadInitializerEntryPoint.kt @@ -0,0 +1,43 @@ +/* + * Wire + * Copyright (C) 2026 Wire Swiss GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +package com.wire.android.nomad.di + +import android.content.Context +import com.wire.android.di.KaliumCoreLogic +import com.wire.kalium.logic.CoreLogic +import dagger.Lazy +import dagger.hilt.EntryPoint +import dagger.hilt.InstallIn +import dagger.hilt.android.EntryPointAccessors +import dagger.hilt.components.SingletonComponent + +@EntryPoint +@InstallIn(SingletonComponent::class) +interface NomadInitializerEntryPoint { + + @KaliumCoreLogic + fun coreLogic(): Lazy + + companion object { + fun resolve(context: Context): NomadInitializerEntryPoint { + val appContext = context.applicationContext ?: throw IllegalStateException() + return EntryPointAccessors.fromApplication(appContext, NomadInitializerEntryPoint::class.java) + } + } +} diff --git a/core/nomad/src/main/kotlin/com/wire/android/nomad/initializer/NomadInitializer.kt b/core/nomad/src/main/kotlin/com/wire/android/nomad/initializer/NomadInitializer.kt new file mode 100644 index 00000000000..621c973cf00 --- /dev/null +++ b/core/nomad/src/main/kotlin/com/wire/android/nomad/initializer/NomadInitializer.kt @@ -0,0 +1,34 @@ +/* + * Wire + * Copyright (C) 2026 Wire Swiss GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +package com.wire.android.nomad.initializer + +import android.content.Context +import androidx.startup.Initializer +import com.wire.android.nomad.NomadHookRegistrar +import com.wire.android.nomad.di.NomadInitializerEntryPoint + +class NomadInitializer : Initializer { + + override fun create(context: Context) { + val entryPoint = NomadInitializerEntryPoint.resolve(context) + NomadHookRegistrar.register(coreLogic = entryPoint.coreLogic()) + } + + override fun dependencies(): List>> = emptyList() +} diff --git a/default.json b/default.json index a4ea456c220..688c510a162 100644 --- a/default.json +++ b/default.json @@ -71,7 +71,7 @@ "analytics_app_key": "8ffae535f1836ed5f58fd5c8a11c00eca07c5438", "analytics_server_url": "https://wire.count.ly/", "enable_new_registration": true, - "use_async_flush_logging": true, + "use_async_flush_logging": true }, "internal": { "application_id": "com.wire.internal", @@ -86,7 +86,18 @@ "use_strict_mls_filter": false, "use_async_flush_logging": true, "conversation_feeder_enabled": true, - "db_invalidation_control_enabled": false, + "db_invalidation_control_enabled": false + }, + "enterprise": { + "application_id": "com.wire.team", + "developer_features_enabled": false, + "logging_enabled": false, + "application_is_private_build": false, + "development_api_enabled": false, + "analytics_enabled": true, + "analytics_app_key": "4483f7a58ae3e70b3780319c4ccb5c88a037be49", + "analytics_server_url": "https://wire.count.ly/", + "enable_new_registration": true }, "fdroid": { "application_id": "com.wire", diff --git a/include_builds.gradle.kts b/include_builds.gradle.kts index 56f021dd41a..99c3bd549cb 100644 --- a/include_builds.gradle.kts +++ b/include_builds.gradle.kts @@ -23,6 +23,9 @@ includeBuild("kalium") { substitute(module("com.wire.kalium:kalium-data")).using(project(":core:data")) substitute(module("com.wire.kalium:kalium-common")).using(project(":core:common")) substitute(module("com.wire.kalium:kalium-cells")).using(project(":domain:cells")) + substitute(module("com.wire.kalium:kalium-nomaddevice")).using(project(":domain:nomaddevice")) + substitute(module("com.wire.kalium:kalium-userstorage")).using(project(":domain:userstorage")) + substitute(module("com.wire.kalium:kalium-hooks")).using(project(":domain:messaging:hooks")) // test modules substitute(module("com.wire.kalium:kalium-mocks")).using(project(":test:mocks")) substitute(module("com.wire.kalium:kalium-network")).using(project(":data:network")) diff --git a/kalium b/kalium index 83e3c7cbf31..9a9620e35e1 160000 --- a/kalium +++ b/kalium @@ -1 +1 @@ -Subproject commit 83e3c7cbf31e7996c03f91d9740b50e480acee35 +Subproject commit 9a9620e35e190a957ccf2d3e1229019a9b3471a1