diff --git a/changelog.d/6406.misc b/changelog.d/6406.misc
new file mode 100644
index 0000000000..27cf3c6493
--- /dev/null
+++ b/changelog.d/6406.misc
@@ -0,0 +1 @@
+[Modularization] Provides abstraction to avoids direct usages of BuildConfig
diff --git a/vector-config/src/main/java/im/vector/app/config/Analytics.kt b/vector-config/src/main/java/im/vector/app/config/Analytics.kt
new file mode 100644
index 0000000000..7fdc78dc8a
--- /dev/null
+++ b/vector-config/src/main/java/im/vector/app/config/Analytics.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.config
+
+/**
+ * The types of analytics Element currently supports.
+ */
+sealed interface Analytics {
+
+    /**
+     * Disables the analytics integrations.
+     */
+    object Disabled : Analytics
+
+    /**
+     * Analytics integration via PostHog.
+     */
+    data class PostHog(
+            /**
+             * The PostHog instance url.
+             */
+            val postHogHost: String,
+
+            /**
+             * The PostHog instance API key.
+             */
+            val postHogApiKey: String,
+
+            /**
+             * A URL to more information about the analytics collection.
+             */
+            val policyLink: String,
+    ) : Analytics
+}
diff --git a/vector-config/src/main/java/im/vector/app/config/Config.kt b/vector-config/src/main/java/im/vector/app/config/Config.kt
index 7577e6dba5..f660799d06 100644
--- a/vector-config/src/main/java/im/vector/app/config/Config.kt
+++ b/vector-config/src/main/java/im/vector/app/config/Config.kt
@@ -36,4 +36,57 @@ object Config {
      * - Changing the value from `true` to `false` will force the app to return to the background sync / Firebase Push.
      */
     const val ALLOW_EXTERNAL_UNIFIED_PUSH_DISTRIBUTORS = true
+
+    const val ENABLE_LOCATION_SHARING = true
+    const val LOCATION_MAP_TILER_KEY = "fU3vlMsMn4Jb6dnEIFsx"
+
+    /**
+     * The maximum length of voice messages in milliseconds.
+     */
+    const val VOICE_MESSAGE_LIMIT_MS = 120_000L
+
+    /**
+     * The strategy for sharing device keys.
+     */
+    val KEY_SHARING_STRATEGY = KeySharingStrategy.WhenTyping
+
+    /**
+     * The onboarding flow.
+     */
+    val ONBOARDING_VARIANT = OnboardingVariant.FTUE_AUTH
+
+    /**
+     * If set, MSC3086 asserted identity messages sent on VoIP calls will cause the call to appear in the room corresponding to the asserted identity.
+     * This *must* only be set in trusted environments.
+     */
+    const val HANDLE_CALL_ASSERTED_IDENTITY_EVENTS = false
+
+    const val LOW_PRIVACY_LOG_ENABLE = false
+    const val ENABLE_STRICT_MODE_LOGS = false
+
+    /**
+     * The analytics configuration to use for the Debug build type.
+     * Can be disabled by providing Analytics.Disabled
+     */
+    val DEBUG_ANALYTICS_CONFIG = Analytics.PostHog(
+            postHogHost = "https://posthog.element.dev",
+            postHogApiKey = "phc_VtA1L35nw3aeAtHIx1ayrGdzGkss7k1xINeXcoIQzXN",
+            policyLink = "https://element.io/cookie-policy",
+    )
+
+    /**
+     * The analytics configuration to use for the Release build type.
+     * Can be disabled by providing Analytics.Disabled
+     */
+    val RELEASE_ANALYTICS_CONFIG = Analytics.PostHog(
+            postHogHost = "https://posthog.hss.element.io",
+            postHogApiKey = "phc_Jzsm6DTm6V2705zeU5dcNvQDlonOR68XvX2sh1sEOHO",
+            policyLink = "https://element.io/cookie-policy",
+    )
+
+    /**
+     * The analytics configuration to use for the Nightly build type.
+     * Can be disabled by providing Analytics.Disabled
+     */
+    val NIGHTLY_ANALYTICS_CONFIG = RELEASE_ANALYTICS_CONFIG
 }
diff --git a/vector/src/debug/java/im/vector/app/config/AnalyticsConfig.kt b/vector-config/src/main/java/im/vector/app/config/KeySharingStrategy.kt
similarity index 55%
rename from vector/src/debug/java/im/vector/app/config/AnalyticsConfig.kt
rename to vector-config/src/main/java/im/vector/app/config/KeySharingStrategy.kt
index 63f14f72f6..51f3d81151 100644
--- a/vector/src/debug/java/im/vector/app/config/AnalyticsConfig.kt
+++ b/vector-config/src/main/java/im/vector/app/config/KeySharingStrategy.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 New Vector Ltd
+ * Copyright (c) 2022 New Vector Ltd
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,12 +16,20 @@
 
 package im.vector.app.config
 
-import im.vector.app.BuildConfig
-import im.vector.app.features.analytics.AnalyticsConfig
+enum class KeySharingStrategy {
+    /**
+     * Keys will be sent for the first time when the first message is sent.
+     * This is handled by the Matrix SDK so there's no need to do it in Vector.
+     */
+    WhenSendingEvent,
 
-val analyticsConfig: AnalyticsConfig = object : AnalyticsConfig {
-    override val isEnabled = BuildConfig.APPLICATION_ID == "im.vector.app.debug"
-    override val postHogHost = "https://posthog.element.dev"
-    override val postHogApiKey = "phc_VtA1L35nw3aeAtHIx1ayrGdzGkss7k1xINeXcoIQzXN"
-    override val policyLink = "https://element.io/cookie-policy"
+    /**
+     * Keys will be sent for the first time when the timeline displayed.
+     */
+    WhenEnteringRoom,
+
+    /**
+     * Keys will be sent for the first time when a typing started.
+     */
+    WhenTyping
 }
diff --git a/vector/src/release/java/im/vector/app/config/AnalyticsConfig.kt b/vector-config/src/main/java/im/vector/app/config/OnboardingVariant.kt
similarity index 50%
rename from vector/src/release/java/im/vector/app/config/AnalyticsConfig.kt
rename to vector-config/src/main/java/im/vector/app/config/OnboardingVariant.kt
index e1427338b2..ae8cfd1172 100644
--- a/vector/src/release/java/im/vector/app/config/AnalyticsConfig.kt
+++ b/vector-config/src/main/java/im/vector/app/config/OnboardingVariant.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 New Vector Ltd
+ * Copyright (c) 2022 New Vector Ltd
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,17 +16,8 @@
 
 package im.vector.app.config
 
-import im.vector.app.BuildConfig
-import im.vector.app.features.analytics.AnalyticsConfig
-
-private val allowedPackageList = listOf(
-        "im.vector.app",
-        "im.vector.app.nightly",
-)
-
-val analyticsConfig: AnalyticsConfig = object : AnalyticsConfig {
-    override val isEnabled = BuildConfig.APPLICATION_ID in allowedPackageList
-    override val postHogHost = "https://posthog.hss.element.io"
-    override val postHogApiKey = "phc_Jzsm6DTm6V2705zeU5dcNvQDlonOR68XvX2sh1sEOHO"
-    override val policyLink = "https://element.io/cookie-policy"
+enum class OnboardingVariant {
+    LEGACY,
+    LOGIN_2,
+    FTUE_AUTH
 }
diff --git a/vector/build.gradle b/vector/build.gradle
index 0b7973a148..56a3f0eb80 100644
--- a/vector/build.gradle
+++ b/vector/build.gradle
@@ -156,19 +156,6 @@ android {
         buildConfigField "String", "GIT_BRANCH_NAME", "\"${gitBranchName()}\""
         buildConfigField "String", "BUILD_NUMBER", "\"${buildNumber}\""
 
-        buildConfigField "im.vector.app.features.VectorFeatures.OnboardingVariant", "ONBOARDING_VARIANT", "im.vector.app.features.VectorFeatures.OnboardingVariant.FTUE_AUTH"
-
-        buildConfigField "im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy", "outboundSessionKeySharingStrategy", "im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy.WhenTyping"
-
-        buildConfigField "Long", "VOICE_MESSAGE_DURATION_LIMIT_MS", "120_000L"
-
-        //  If set, MSC3086 asserted identity messages sent on VoIP calls will cause the call to appear in the room corresponding to the asserted identity.
-        //  This *must* only be set in trusted environments.
-        buildConfigField "Boolean", "handleCallAssertedIdentityEvents", "false"
-
-        buildConfigField "Boolean", "enableLocationSharing", "true"
-        buildConfigField "String", "mapTilerKey", "\"fU3vlMsMn4Jb6dnEIFsx\""
-
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
 
         // Keep abiFilter for the universalApk
@@ -250,10 +237,6 @@ android {
             resValue "string", "app_name", "Element dbg"
             resValue "color", "launcher_background", "#0DBD8B"
 
-            buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false"
-            // Set to true if you want to enable strict mode in debug
-            buildConfigField "boolean", "ENABLE_STRICT_MODE_LOGS", "false"
-
             signingConfig signingConfigs.debug
 
             if (project.hasProperty("coverage")) {
@@ -265,10 +248,6 @@ android {
             resValue "string", "app_name", "Element"
             resValue "color", "launcher_background", "#0DBD8B"
 
-            buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false"
-            buildConfigField "boolean", "ENABLE_STRICT_MODE_LOGS", "false"
-
-            // When updating this block, please also update the same block in the `nightly` buildType below
             postprocessing {
                 removeUnusedCode true
                 removeUnusedResources true
@@ -329,7 +308,6 @@ android {
             versionName "${versionMajor}.${versionMinor}.${versionPatch}${getGplayVersionSuffix()}"
 
             resValue "bool", "isGplay", "true"
-            buildConfigField "boolean", "ALLOW_FCM_USE", "true"
             buildConfigField "String", "SHORT_FLAVOR_DESCRIPTION", "\"G\""
             buildConfigField "String", "FLAVOR_DESCRIPTION", "\"GooglePlay\""
         }
@@ -340,7 +318,6 @@ android {
             versionName "${versionMajor}.${versionMinor}.${versionPatch}${getFdroidVersionSuffix()}"
 
             resValue "bool", "isGplay", "false"
-            buildConfigField "boolean", "ALLOW_FCM_USE", "false"
             buildConfigField "String", "SHORT_FLAVOR_DESCRIPTION", "\"F\""
             buildConfigField "String", "FLAVOR_DESCRIPTION", "\"FDroid\""
         }
diff --git a/vector/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt b/vector/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt
index 8fe65bd387..d7e402c4dc 100644
--- a/vector/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt
+++ b/vector/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt
@@ -70,6 +70,11 @@ class DebugFeaturesStateFactory @Inject constructor(
                                 key = DebugFeatureKeys.allowExternalUnifiedPushDistributors,
                                 factory = VectorFeatures::allowExternalUnifiedPushDistributors
                         ),
+                        createBooleanFeature(
+                                label = "Enable Live Location Sharing",
+                                key = DebugFeatureKeys.liveLocationSharing,
+                                factory = VectorFeatures::isLocationSharingEnabled
+                        ),
                         createBooleanFeature(
                                 label = "Force usage of OpusEncoder library",
                                 key = DebugFeatureKeys.forceUsageOfOpusEncoder,
diff --git a/vector/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt b/vector/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt
index 23aad65653..031ff11d59 100644
--- a/vector/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt
+++ b/vector/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt
@@ -24,6 +24,7 @@ import androidx.datastore.preferences.core.booleanPreferencesKey
 import androidx.datastore.preferences.core.edit
 import androidx.datastore.preferences.core.stringPreferencesKey
 import androidx.datastore.preferences.preferencesDataStore
+import im.vector.app.config.OnboardingVariant
 import im.vector.app.features.DefaultVectorFeatures
 import im.vector.app.features.VectorFeatures
 import kotlinx.coroutines.flow.first
@@ -39,8 +40,8 @@ class DebugVectorFeatures(
 
     private val dataStore = context.dataStore
 
-    override fun onboardingVariant(): VectorFeatures.OnboardingVariant {
-        return readPreferences().getEnum<VectorFeatures.OnboardingVariant>() ?: vectorFeatures.onboardingVariant()
+    override fun onboardingVariant(): OnboardingVariant {
+        return readPreferences().getEnum<OnboardingVariant>() ?: vectorFeatures.onboardingVariant()
     }
 
     override fun isOnboardingAlreadyHaveAccountSplashEnabled(): Boolean = read(DebugFeatureKeys.onboardingAlreadyHaveAnAccount)
@@ -66,6 +67,9 @@ class DebugVectorFeatures(
     override fun isScreenSharingEnabled(): Boolean = read(DebugFeatureKeys.screenSharing)
             ?: vectorFeatures.isScreenSharingEnabled()
 
+    override fun isLocationSharingEnabled(): Boolean = read(DebugFeatureKeys.liveLocationSharing)
+            ?: vectorFeatures.isLocationSharingEnabled()
+
     override fun forceUsageOfOpusEncoder(): Boolean = read(DebugFeatureKeys.forceUsageOfOpusEncoder)
             ?: vectorFeatures.forceUsageOfOpusEncoder()
 
diff --git a/vector/src/main/java/im/vector/app/VectorApplication.kt b/vector/src/main/java/im/vector/app/VectorApplication.kt
index d3dfbf8c4f..b1bd0fc308 100644
--- a/vector/src/main/java/im/vector/app/VectorApplication.kt
+++ b/vector/src/main/java/im/vector/app/VectorApplication.kt
@@ -40,7 +40,9 @@ import com.mapbox.mapboxsdk.Mapbox
 import com.vanniktech.emoji.EmojiManager
 import com.vanniktech.emoji.google.GoogleEmojiProvider
 import dagger.hilt.android.HiltAndroidApp
+import im.vector.app.config.Config
 import im.vector.app.core.di.ActiveSessionHolder
+import im.vector.app.core.resources.BuildMeta
 import im.vector.app.features.analytics.VectorAnalytics
 import im.vector.app.features.call.webrtc.WebRtcCallManager
 import im.vector.app.features.configuration.VectorConfiguration
@@ -99,6 +101,7 @@ class VectorApplication :
     @Inject lateinit var flipperProxy: FlipperProxy
     @Inject lateinit var matrix: Matrix
     @Inject lateinit var fcmHelper: FcmHelper
+    @Inject lateinit var buildMeta: BuildMeta
 
     // font thread handler
     private var fontThreadHandler: Handler? = null
@@ -127,12 +130,12 @@ class VectorApplication :
                 .filterIsInstance(JitsiMeetDefaultLogHandler::class.java)
                 .forEach { Timber.uproot(it) }
 
-        if (BuildConfig.DEBUG) {
+        if (buildMeta.isDebug) {
             Timber.plant(Timber.DebugTree())
         }
         Timber.plant(vectorFileLogger)
 
-        if (BuildConfig.DEBUG) {
+        if (buildMeta.isDebug) {
             Stetho.initializeWithDefaults(this)
         }
         logInfo()
@@ -148,7 +151,7 @@ class VectorApplication :
                 R.array.com_google_android_gms_fonts_certs
         )
         FontsContractCompat.requestFont(this, fontRequest, emojiCompatFontProvider, getFontThreadHandler())
-        VectorLocale.init(this)
+        VectorLocale.init(this, buildMeta)
         ThemeUtils.init(this)
         vectorConfiguration.applyToApplicationContext()
 
@@ -196,7 +199,7 @@ class VectorApplication :
     }
 
     private fun enableStrictModeIfNeeded() {
-        if (BuildConfig.ENABLE_STRICT_MODE_LOGS) {
+        if (Config.ENABLE_STRICT_MODE_LOGS) {
             StrictMode.setThreadPolicy(
                     StrictMode.ThreadPolicy.Builder()
                             .detectAll()
diff --git a/vector/src/main/java/im/vector/app/core/di/ConfigurationModule.kt b/vector/src/main/java/im/vector/app/core/di/ConfigurationModule.kt
new file mode 100644
index 0000000000..a75b3fa46b
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/core/di/ConfigurationModule.kt
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.core.di
+
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import im.vector.app.BuildConfig
+import im.vector.app.config.Analytics
+import im.vector.app.config.Config
+import im.vector.app.config.KeySharingStrategy
+import im.vector.app.features.analytics.AnalyticsConfig
+import im.vector.app.features.call.webrtc.VoipConfig
+import im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy
+import im.vector.app.features.home.room.detail.composer.voice.VoiceMessageConfig
+import im.vector.app.features.location.LocationSharingConfig
+import im.vector.app.features.raw.wellknown.CryptoConfig
+
+@InstallIn(SingletonComponent::class)
+@Module
+object ConfigurationModule {
+
+    @Provides
+    fun providesAnalyticsConfig(): AnalyticsConfig {
+        val config: Analytics = when (BuildConfig.BUILD_TYPE) {
+            "debug" -> Config.DEBUG_ANALYTICS_CONFIG
+            "nightly" -> Config.NIGHTLY_ANALYTICS_CONFIG
+            "release" -> Config.RELEASE_ANALYTICS_CONFIG
+            else -> throw IllegalStateException("Unhandled build type: ${BuildConfig.BUILD_TYPE}")
+        }
+        return when (config) {
+            Analytics.Disabled -> AnalyticsConfig(isEnabled = false, "", "", "")
+            is Analytics.PostHog -> AnalyticsConfig(
+                    isEnabled = true,
+                    postHogHost = config.postHogHost,
+                    postHogApiKey = config.postHogApiKey,
+                    policyLink = config.policyLink
+            )
+        }
+    }
+
+    @Provides
+    fun providesVoiceMessageConfig() = VoiceMessageConfig(
+            lengthLimitMs = Config.VOICE_MESSAGE_LIMIT_MS
+    )
+
+    @Provides
+    fun providesCryptoConfig() = CryptoConfig(
+            fallbackKeySharingStrategy = when (Config.KEY_SHARING_STRATEGY) {
+                KeySharingStrategy.WhenSendingEvent -> OutboundSessionKeySharingStrategy.WhenSendingEvent
+                KeySharingStrategy.WhenEnteringRoom -> OutboundSessionKeySharingStrategy.WhenSendingEvent
+                KeySharingStrategy.WhenTyping -> OutboundSessionKeySharingStrategy.WhenSendingEvent
+            }
+    )
+
+    @Provides
+    fun providesLocationSharingConfig() = LocationSharingConfig(
+            mapTilerKey = Config.LOCATION_MAP_TILER_KEY,
+    )
+
+    @Provides
+    fun providesVoipConfig() = VoipConfig(
+            handleCallAssertedIdentityEvents = Config.HANDLE_CALL_ASSERTED_IDENTITY_EVENTS
+    )
+}
diff --git a/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt
index c969df74e4..6959f17586 100644
--- a/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt
+++ b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt
@@ -33,7 +33,7 @@ import im.vector.app.EmojiCompatWrapper
 import im.vector.app.EmojiSpanify
 import im.vector.app.SpaceStateHandler
 import im.vector.app.SpaceStateHandlerImpl
-import im.vector.app.config.analyticsConfig
+import im.vector.app.config.Config
 import im.vector.app.core.dispatchers.CoroutineDispatchers
 import im.vector.app.core.error.DefaultErrorFormatter
 import im.vector.app.core.error.ErrorFormatter
@@ -42,7 +42,6 @@ import im.vector.app.core.time.Clock
 import im.vector.app.core.time.DefaultClock
 import im.vector.app.core.utils.AndroidSystemSettingsProvider
 import im.vector.app.core.utils.SystemSettingsProvider
-import im.vector.app.features.analytics.AnalyticsConfig
 import im.vector.app.features.analytics.AnalyticsTracker
 import im.vector.app.features.analytics.VectorAnalytics
 import im.vector.app.features.analytics.impl.DefaultVectorAnalytics
@@ -205,17 +204,23 @@ object VectorStaticModule {
         return GlobalScope
     }
 
-    @Provides
-    fun providesAnalyticsConfig(): AnalyticsConfig {
-        return analyticsConfig
-    }
-
     @Provides
     fun providesPhoneNumberUtil(): PhoneNumberUtil = PhoneNumberUtil.getInstance()
 
     @Provides
     @Singleton
-    fun providesBuildMeta() = BuildMeta()
+    fun providesBuildMeta() = BuildMeta(
+            isDebug = BuildConfig.DEBUG,
+            applicationId = BuildConfig.APPLICATION_ID,
+            lowPrivacyLoggingEnabled = Config.LOW_PRIVACY_LOG_ENABLE,
+            versionName = BuildConfig.VERSION_NAME,
+            gitRevision = BuildConfig.GIT_REVISION,
+            gitRevisionDate = BuildConfig.GIT_REVISION_DATE,
+            gitBranchName = BuildConfig.GIT_BRANCH_NAME,
+            buildNumber = BuildConfig.BUILD_NUMBER,
+            flavorDescription = BuildConfig.FLAVOR_DESCRIPTION,
+            flavorShortDescription = BuildConfig.SHORT_FLAVOR_DESCRIPTION,
+    )
 
     @Provides
     @Singleton
diff --git a/vector/src/main/java/im/vector/app/core/extensions/Context.kt b/vector/src/main/java/im/vector/app/core/extensions/Context.kt
index 509dd6a862..14e639bf32 100644
--- a/vector/src/main/java/im/vector/app/core/extensions/Context.kt
+++ b/vector/src/main/java/im/vector/app/core/extensions/Context.kt
@@ -37,7 +37,7 @@ import androidx.datastore.preferences.core.Preferences
 import dagger.hilt.EntryPoints
 import im.vector.app.core.datastore.dataStoreProvider
 import im.vector.app.core.di.SingletonEntryPoint
-import im.vector.app.core.resources.BuildMeta
+import org.matrix.android.sdk.api.util.BuildVersionSdkIntProvider
 import java.io.OutputStream
 import kotlin.math.roundToInt
 
@@ -93,9 +93,9 @@ fun Context.safeOpenOutputStream(uri: Uri): OutputStream? {
  */
 @Suppress("deprecation")
 @SuppressLint("NewApi") // false positive
-fun Context.inferNoConnectivity(buildMeta: BuildMeta): Boolean {
+fun Context.inferNoConnectivity(sdkIntProvider: BuildVersionSdkIntProvider): Boolean {
     val connectivityManager = getSystemService<ConnectivityManager>()!!
-    return if (buildMeta.sdkInt > Build.VERSION_CODES.M) {
+    return if (sdkIntProvider.get() > Build.VERSION_CODES.M) {
         val networkCapabilities = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
         when {
             networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == true -> false
diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt
index e7d130a6d5..8a09b6bd46 100644
--- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt
+++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt
@@ -54,7 +54,6 @@ import com.google.android.material.color.MaterialColors
 import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import com.google.android.material.snackbar.Snackbar
 import dagger.hilt.android.EntryPointAccessors
-import im.vector.app.BuildConfig
 import im.vector.app.R
 import im.vector.app.core.di.ActiveSessionHolder
 import im.vector.app.core.di.ActivityEntryPoint
@@ -68,6 +67,7 @@ import im.vector.app.core.extensions.restart
 import im.vector.app.core.extensions.setTextOrHide
 import im.vector.app.core.extensions.singletonEntryPoint
 import im.vector.app.core.extensions.toMvRxBundle
+import im.vector.app.core.resources.BuildMeta
 import im.vector.app.core.utils.AndroidSystemSettingsProvider
 import im.vector.app.core.utils.ToolbarConfig
 import im.vector.app.core.utils.toast
@@ -157,11 +157,9 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), Maver
     protected lateinit var bugReporter: BugReporter
     private lateinit var pinLocker: PinLocker
 
-    @Inject
-    lateinit var rageShake: RageShake
-
-    @Inject
-    lateinit var fontScalePreferences: FontScalePreferences
+    @Inject lateinit var rageShake: RageShake
+    @Inject lateinit var buildMeta: BuildMeta
+    @Inject lateinit var fontScalePreferences: FontScalePreferences
 
     @Inject
     lateinit var vectorFeatures: VectorFeatures
@@ -422,7 +420,7 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), Maver
         }
         DebugReceiver
                 .getIntentFilter(this)
-                .takeIf { BuildConfig.DEBUG }
+                .takeIf { buildMeta.isDebug }
                 ?.let {
                     debugReceiver = DebugReceiver()
                     registerReceiver(debugReceiver, it)
diff --git a/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt b/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt
index 0d6828f569..8e88e44627 100644
--- a/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt
+++ b/vector/src/main/java/im/vector/app/core/pushers/VectorMessagingReceiver.kt
@@ -25,14 +25,14 @@ import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.ProcessLifecycleOwner
 import androidx.localbroadcastmanager.content.LocalBroadcastManager
 import dagger.hilt.android.AndroidEntryPoint
-import im.vector.app.BuildConfig
 import im.vector.app.core.di.ActiveSessionHolder
 import im.vector.app.core.network.WifiDetector
 import im.vector.app.core.pushers.model.PushData
+import im.vector.app.core.resources.BuildMeta
 import im.vector.app.core.services.GuardServiceStarter
 import im.vector.app.features.notifications.NotifiableEventResolver
+import im.vector.app.features.notifications.NotificationActionIds
 import im.vector.app.features.notifications.NotificationDrawerManager
-import im.vector.app.features.notifications.NotificationUtils
 import im.vector.app.features.settings.BackgroundSyncMode
 import im.vector.app.features.settings.VectorDataStore
 import im.vector.app.features.settings.VectorPreferences
@@ -68,6 +68,8 @@ class VectorMessagingReceiver : MessagingReceiver() {
     @Inject lateinit var unifiedPushHelper: UnifiedPushHelper
     @Inject lateinit var unifiedPushStore: UnifiedPushStore
     @Inject lateinit var pushParser: PushParser
+    @Inject lateinit var actionIds: NotificationActionIds
+    @Inject lateinit var buildMeta: BuildMeta
 
     private val coroutineScope = CoroutineScope(SupervisorJob())
 
@@ -87,7 +89,7 @@ class VectorMessagingReceiver : MessagingReceiver() {
         Timber.tag(loggerTag.value).d("## onMessage() received")
 
         val sMessage = String(message)
-        if (BuildConfig.LOW_PRIVACY_LOG_ENABLE) {
+        if (buildMeta.lowPrivacyLoggingEnabled) {
             Timber.tag(loggerTag.value).d("## onMessage() $sMessage")
         }
 
@@ -100,7 +102,7 @@ class VectorMessagingReceiver : MessagingReceiver() {
 
         // Diagnostic Push
         if (pushData.eventId == PushersManager.TEST_EVENT_ID) {
-            val intent = Intent(NotificationUtils.PUSH_ACTION)
+            val intent = Intent(actionIds.push)
             LocalBroadcastManager.getInstance(context).sendBroadcast(intent)
             return
         }
@@ -171,7 +173,7 @@ class VectorMessagingReceiver : MessagingReceiver() {
      */
     private suspend fun onMessageReceivedInternal(pushData: PushData) {
         try {
-            if (BuildConfig.LOW_PRIVACY_LOG_ENABLE) {
+            if (buildMeta.lowPrivacyLoggingEnabled) {
                 Timber.tag(loggerTag.value).d("## onMessageReceivedInternal() : $pushData")
             } else {
                 Timber.tag(loggerTag.value).d("## onMessageReceivedInternal()")
diff --git a/vector/src/main/java/im/vector/app/core/resources/BuildMeta.kt b/vector/src/main/java/im/vector/app/core/resources/BuildMeta.kt
index 14d97e4c8f..6c25348ea1 100644
--- a/vector/src/main/java/im/vector/app/core/resources/BuildMeta.kt
+++ b/vector/src/main/java/im/vector/app/core/resources/BuildMeta.kt
@@ -16,8 +16,15 @@
 
 package im.vector.app.core.resources
 
-import android.os.Build
-
 data class BuildMeta(
-        val sdkInt: Int = Build.VERSION.SDK_INT
+        val isDebug: Boolean,
+        val applicationId: String,
+        val lowPrivacyLoggingEnabled: Boolean,
+        val versionName: String,
+        val gitRevision: String,
+        val gitRevisionDate: String,
+        val gitBranchName: String,
+        val buildNumber: String,
+        val flavorDescription: String,
+        val flavorShortDescription: String,
 )
diff --git a/vector/src/main/java/im/vector/app/core/utils/ExternalApplicationsUtil.kt b/vector/src/main/java/im/vector/app/core/utils/ExternalApplicationsUtil.kt
index 3a8ffac543..d52b7088ff 100644
--- a/vector/src/main/java/im/vector/app/core/utils/ExternalApplicationsUtil.kt
+++ b/vector/src/main/java/im/vector/app/core/utils/ExternalApplicationsUtil.kt
@@ -39,7 +39,6 @@ import androidx.browser.customtabs.CustomTabsSession
 import androidx.core.app.ShareCompat
 import androidx.core.content.FileProvider
 import androidx.core.content.getSystemService
-import im.vector.app.BuildConfig
 import im.vector.app.R
 import im.vector.app.features.notifications.NotificationUtils
 import im.vector.app.features.themes.ThemeUtils
@@ -182,7 +181,7 @@ fun openUri(activity: Activity, uri: String) {
  */
 fun openMedia(activity: Activity, savedMediaPath: String, mimeType: String) {
     val file = File(savedMediaPath)
-    val uri = FileProvider.getUriForFile(activity, BuildConfig.APPLICATION_ID + ".fileProvider", file)
+    val uri = FileProvider.getUriForFile(activity, activity.packageName + ".fileProvider", file)
 
     val intent = Intent(Intent.ACTION_VIEW).apply {
         setDataAndType(uri, mimeType)
@@ -214,7 +213,7 @@ fun openLocation(activity: Activity, latitude: Double, longitude: Double) {
 
 fun shareMedia(context: Context, file: File, mediaMimeType: String?) {
     val mediaUri = try {
-        FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".fileProvider", file)
+        FileProvider.getUriForFile(context, context.packageName + ".fileProvider", file)
     } catch (e: Exception) {
         Timber.e(e, "onMediaAction Selected File cannot be shared")
         return
@@ -376,7 +375,7 @@ private fun addToGallery(savedFile: File, mediaMimeType: String?, context: Conte
 /**
  * Open the play store to the provided application Id, default to this app.
  */
-fun openPlayStore(activity: Activity, appId: String = BuildConfig.APPLICATION_ID) {
+fun openPlayStore(activity: Activity, appId: String) {
     try {
         activity.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=$appId")))
     } catch (activityNotFoundException: ActivityNotFoundException) {
diff --git a/vector/src/main/java/im/vector/app/features/VectorFeatures.kt b/vector/src/main/java/im/vector/app/features/VectorFeatures.kt
index 3a56f31b72..290d21879d 100644
--- a/vector/src/main/java/im/vector/app/features/VectorFeatures.kt
+++ b/vector/src/main/java/im/vector/app/features/VectorFeatures.kt
@@ -16,8 +16,8 @@
 
 package im.vector.app.features
 
-import im.vector.app.BuildConfig
 import im.vector.app.config.Config
+import im.vector.app.config.OnboardingVariant
 
 interface VectorFeatures {
 
@@ -30,19 +30,14 @@ interface VectorFeatures {
     fun isOnboardingCombinedLoginEnabled(): Boolean
     fun allowExternalUnifiedPushDistributors(): Boolean
     fun isScreenSharingEnabled(): Boolean
+    fun isLocationSharingEnabled(): Boolean
     fun forceUsageOfOpusEncoder(): Boolean
     fun shouldStartDmOnFirstMessage(): Boolean
     fun isNewAppLayoutEnabled(): Boolean
-
-    enum class OnboardingVariant {
-        LEGACY,
-        LOGIN_2,
-        FTUE_AUTH
-    }
 }
 
 class DefaultVectorFeatures : VectorFeatures {
-    override fun onboardingVariant(): VectorFeatures.OnboardingVariant = BuildConfig.ONBOARDING_VARIANT
+    override fun onboardingVariant() = Config.ONBOARDING_VARIANT
     override fun isOnboardingAlreadyHaveAccountSplashEnabled() = true
     override fun isOnboardingSplashCarouselEnabled() = true
     override fun isOnboardingUseCaseEnabled() = true
@@ -51,6 +46,7 @@ class DefaultVectorFeatures : VectorFeatures {
     override fun isOnboardingCombinedLoginEnabled() = true
     override fun allowExternalUnifiedPushDistributors(): Boolean = Config.ALLOW_EXTERNAL_UNIFIED_PUSH_DISTRIBUTORS
     override fun isScreenSharingEnabled(): Boolean = true
+    override fun isLocationSharingEnabled() = Config.ENABLE_LOCATION_SHARING
     override fun forceUsageOfOpusEncoder(): Boolean = false
     override fun shouldStartDmOnFirstMessage(): Boolean = false
     override fun isNewAppLayoutEnabled(): Boolean = false
diff --git a/vector/src/main/java/im/vector/app/features/analytics/AnalyticsConfig.kt b/vector/src/main/java/im/vector/app/features/analytics/AnalyticsConfig.kt
index 46119f5563..bffba6fa9c 100644
--- a/vector/src/main/java/im/vector/app/features/analytics/AnalyticsConfig.kt
+++ b/vector/src/main/java/im/vector/app/features/analytics/AnalyticsConfig.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 New Vector Ltd
+ * Copyright (c) 2022 New Vector Ltd
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,9 +16,9 @@
 
 package im.vector.app.features.analytics
 
-interface AnalyticsConfig {
-    val isEnabled: Boolean
-    val postHogHost: String
-    val postHogApiKey: String
-    val policyLink: String
-}
+data class AnalyticsConfig(
+        val isEnabled: Boolean,
+        val postHogHost: String,
+        val postHogApiKey: String,
+        val policyLink: String,
+)
diff --git a/vector/src/main/java/im/vector/app/features/analytics/impl/PostHogFactory.kt b/vector/src/main/java/im/vector/app/features/analytics/impl/PostHogFactory.kt
index 029732f76c..7442989352 100644
--- a/vector/src/main/java/im/vector/app/features/analytics/impl/PostHogFactory.kt
+++ b/vector/src/main/java/im/vector/app/features/analytics/impl/PostHogFactory.kt
@@ -18,11 +18,15 @@ package im.vector.app.features.analytics.impl
 
 import android.content.Context
 import com.posthog.android.PostHog
-import im.vector.app.BuildConfig
-import im.vector.app.config.analyticsConfig
+import im.vector.app.core.resources.BuildMeta
+import im.vector.app.features.analytics.AnalyticsConfig
 import javax.inject.Inject
 
-class PostHogFactory @Inject constructor(private val context: Context) {
+class PostHogFactory @Inject constructor(
+        private val context: Context,
+        private val analyticsConfig: AnalyticsConfig,
+        private val buildMeta: BuildMeta,
+) {
 
     fun createPosthog(): PostHog {
         return PostHog.Builder(context, analyticsConfig.postHogApiKey, analyticsConfig.postHogHost)
@@ -43,7 +47,7 @@ class PostHogFactory @Inject constructor(private val context: Context) {
     }
 
     private fun getLogLevel(): PostHog.LogLevel {
-        return if (BuildConfig.DEBUG) {
+        return if (buildMeta.isDebug) {
             PostHog.LogLevel.DEBUG
         } else {
             PostHog.LogLevel.INFO
diff --git a/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInFragment.kt b/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInFragment.kt
index 320386aebd..a5bafa2ee6 100644
--- a/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/analytics/ui/consent/AnalyticsOptInFragment.kt
@@ -22,17 +22,17 @@ import android.view.View
 import android.view.ViewGroup
 import com.airbnb.mvrx.activityViewModel
 import im.vector.app.R
-import im.vector.app.config.analyticsConfig
 import im.vector.app.core.extensions.setTextWithColoredPart
 import im.vector.app.core.platform.OnBackPressed
 import im.vector.app.core.platform.VectorBaseFragment
 import im.vector.app.core.utils.openUrlInChromeCustomTab
 import im.vector.app.databinding.FragmentAnalyticsOptinBinding
+import im.vector.app.features.analytics.AnalyticsConfig
 import javax.inject.Inject
 
-class AnalyticsOptInFragment @Inject constructor() :
-        VectorBaseFragment<FragmentAnalyticsOptinBinding>(),
-        OnBackPressed {
+class AnalyticsOptInFragment @Inject constructor(
+        private val analyticsConfig: AnalyticsConfig,
+) : VectorBaseFragment<FragmentAnalyticsOptinBinding>(), OnBackPressed {
 
     // Share the view model with the Activity so that the Activity
     // can decide what to do when the data has been saved
diff --git a/vector/src/main/java/im/vector/app/features/attachments/AttachmentsHelper.kt b/vector/src/main/java/im/vector/app/features/attachments/AttachmentsHelper.kt
index d0843b3b64..f8aa22f418 100644
--- a/vector/src/main/java/im/vector/app/features/attachments/AttachmentsHelper.kt
+++ b/vector/src/main/java/im/vector/app/features/attachments/AttachmentsHelper.kt
@@ -23,9 +23,9 @@ import android.os.Bundle
 import androidx.activity.result.ActivityResultLauncher
 import im.vector.app.core.dialogs.PhotoOrVideoDialog
 import im.vector.app.core.platform.Restorable
+import im.vector.app.core.resources.BuildMeta
 import im.vector.app.features.settings.VectorPreferences
 import im.vector.lib.multipicker.MultiPicker
-import org.matrix.android.sdk.BuildConfig
 import org.matrix.android.sdk.api.session.content.ContentAttachmentData
 import timber.log.Timber
 
@@ -35,15 +35,14 @@ private const val PENDING_TYPE_KEY = "PENDING_TYPE_KEY"
 /**
  * This class helps to handle attachments by providing simple methods.
  */
-class AttachmentsHelper(val context: Context, val callback: Callback) : Restorable {
+class AttachmentsHelper(
+        val context: Context,
+        val callback: Callback,
+        private val buildMeta: BuildMeta,
+) : Restorable {
 
     interface Callback {
-        fun onContactAttachmentReady(contactAttachment: ContactAttachment) {
-            if (BuildConfig.LOG_PRIVATE_DATA) {
-                Timber.v("On contact attachment ready: $contactAttachment")
-            }
-        }
-
+        fun onContactAttachmentReady(contactAttachment: ContactAttachment)
         fun onContentAttachmentsReady(attachments: List<ContentAttachmentData>)
     }
 
@@ -144,6 +143,9 @@ class AttachmentsHelper(val context: Context, val callback: Callback) : Restorab
                 .firstOrNull()
                 ?.toContactAttachment()
                 ?.let {
+                    if (buildMeta.lowPrivacyLoggingEnabled) {
+                        Timber.v("On contact attachment ready: $it")
+                    }
                     callback.onContactAttachmentReady(it)
                 }
     }
diff --git a/vector/src/main/java/im/vector/app/features/call/webrtc/VoipConfig.kt b/vector/src/main/java/im/vector/app/features/call/webrtc/VoipConfig.kt
new file mode 100644
index 0000000000..03a9312999
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/call/webrtc/VoipConfig.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.call.webrtc
+
+data class VoipConfig(
+      val handleCallAssertedIdentityEvents: Boolean
+)
diff --git a/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCallManager.kt b/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCallManager.kt
index b35ab774be..074779c6cc 100644
--- a/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCallManager.kt
+++ b/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCallManager.kt
@@ -20,7 +20,6 @@ import android.content.Context
 import androidx.lifecycle.DefaultLifecycleObserver
 import androidx.lifecycle.LifecycleOwner
 import im.vector.app.ActiveSessionDataSource
-import im.vector.app.BuildConfig
 import im.vector.app.core.pushers.UnifiedPushHelper
 import im.vector.app.core.services.CallAndroidService
 import im.vector.app.features.analytics.AnalyticsTracker
@@ -74,6 +73,7 @@ class WebRtcCallManager @Inject constructor(
         private val activeSessionDataSource: ActiveSessionDataSource,
         private val analyticsTracker: AnalyticsTracker,
         private val unifiedPushHelper: UnifiedPushHelper,
+        private val voipConfig: VoipConfig,
 ) : CallListener,
         DefaultLifecycleObserver {
 
@@ -444,7 +444,7 @@ class WebRtcCallManager @Inject constructor(
     }
 
     override fun onCallAssertedIdentityReceived(callAssertedIdentityContent: CallAssertedIdentityContent) {
-        if (!BuildConfig.handleCallAssertedIdentityEvents) {
+        if (!voipConfig.handleCallAssertedIdentityEvents) {
             return
         }
         val call = callsByCallId[callAssertedIdentityContent.callId]
diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt
index eb24a1ba86..cfe76706a5 100644
--- a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt
@@ -22,11 +22,11 @@ import com.airbnb.mvrx.ViewModelContext
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
-import im.vector.app.config.analyticsConfig
 import im.vector.app.core.di.ActiveSessionHolder
 import im.vector.app.core.di.MavericksAssistedViewModelFactory
 import im.vector.app.core.di.hiltMavericksViewModelFactory
 import im.vector.app.core.platform.VectorViewModel
+import im.vector.app.features.analytics.AnalyticsConfig
 import im.vector.app.features.analytics.AnalyticsTracker
 import im.vector.app.features.analytics.extensions.toAnalyticsType
 import im.vector.app.features.analytics.plan.Signup
@@ -80,7 +80,8 @@ class HomeActivityViewModel @AssistedInject constructor(
         private val analyticsStore: AnalyticsStore,
         private val lightweightSettingsStorage: LightweightSettingsStorage,
         private val vectorPreferences: VectorPreferences,
-        private val analyticsTracker: AnalyticsTracker
+        private val analyticsTracker: AnalyticsTracker,
+        private val analyticsConfig: AnalyticsConfig,
 ) : VectorViewModel<HomeActivityViewState, HomeActivityViewActions, HomeActivityViewEvents>(initialState) {
 
     @AssistedFactory
diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDrawerFragment.kt b/vector/src/main/java/im/vector/app/features/home/HomeDrawerFragment.kt
index e79387c66d..535f38e68e 100644
--- a/vector/src/main/java/im/vector/app/features/home/HomeDrawerFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/home/HomeDrawerFragment.kt
@@ -23,11 +23,11 @@ import android.view.ViewGroup
 import androidx.core.app.ActivityOptionsCompat
 import androidx.core.view.ViewCompat
 import androidx.core.view.isVisible
-import im.vector.app.BuildConfig
 import im.vector.app.R
 import im.vector.app.core.extensions.observeK
 import im.vector.app.core.extensions.replaceChildFragment
 import im.vector.app.core.platform.VectorBaseFragment
+import im.vector.app.core.resources.BuildMeta
 import im.vector.app.core.utils.startSharePlainTextIntent
 import im.vector.app.databinding.FragmentHomeDrawerBinding
 import im.vector.app.features.analytics.plan.MobileScreen
@@ -43,7 +43,8 @@ import javax.inject.Inject
 class HomeDrawerFragment @Inject constructor(
         private val session: Session,
         private val vectorPreferences: VectorPreferences,
-        private val avatarRenderer: AvatarRenderer
+        private val avatarRenderer: AvatarRenderer,
+        private val buildMeta: BuildMeta,
 ) : VectorBaseFragment<FragmentHomeDrawerBinding>() {
 
     private lateinit var sharedActionViewModel: HomeSharedActionViewModel
@@ -112,7 +113,7 @@ class HomeDrawerFragment @Inject constructor(
         }
 
         // Debug menu
-        views.homeDrawerHeaderDebugView.isVisible = BuildConfig.DEBUG && vectorPreferences.developerMode()
+        views.homeDrawerHeaderDebugView.isVisible = buildMeta.isDebug && vectorPreferences.developerMode()
         views.homeDrawerHeaderDebugView.debouncedClicks {
             sharedActionViewModel.post(HomeActivitySharedAction.CloseDrawer)
             navigator.openDebug(requireActivity())
diff --git a/vector/src/main/java/im/vector/app/features/home/ShortcutCreator.kt b/vector/src/main/java/im/vector/app/features/home/ShortcutCreator.kt
index a51b8eff63..861fdc64b2 100644
--- a/vector/src/main/java/im/vector/app/features/home/ShortcutCreator.kt
+++ b/vector/src/main/java/im/vector/app/features/home/ShortcutCreator.kt
@@ -24,8 +24,8 @@ import androidx.annotation.WorkerThread
 import androidx.core.content.pm.ShortcutInfoCompat
 import androidx.core.content.pm.ShortcutManagerCompat
 import androidx.core.graphics.drawable.IconCompat
-import im.vector.app.BuildConfig
 import im.vector.app.core.glide.GlideApp
+import im.vector.app.core.resources.BuildMeta
 import im.vector.app.core.utils.DimensionConverter
 import im.vector.app.features.MainActivity
 import org.matrix.android.sdk.api.session.room.model.RoomSummary
@@ -35,13 +35,15 @@ import javax.inject.Inject
 private val useAdaptiveIcon = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
 private const val adaptiveIconSizeDp = 108
 private const val adaptiveIconOuterSidesDp = 18
-private const val directShareCategory = BuildConfig.APPLICATION_ID + ".SHORTCUT_SHARE"
 
 class ShortcutCreator @Inject constructor(
         private val context: Context,
         private val avatarRenderer: AvatarRenderer,
-        private val dimensionConverter: DimensionConverter
+        private val dimensionConverter: DimensionConverter,
+        buildMeta: BuildMeta,
 ) {
+
+    private val directShareCategory = buildMeta.applicationId + ".SHORTCUT_SHARE"
     private val adaptiveIconSize = dimensionConverter.dpToPx(adaptiveIconSizeDp)
     private val adaptiveIconOuterSides = dimensionConverter.dpToPx(adaptiveIconOuterSidesDp)
     private val iconSize by lazy {
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt
index 7acc77a686..8f9564789a 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt
@@ -67,7 +67,6 @@ import com.airbnb.mvrx.fragmentViewModel
 import com.airbnb.mvrx.withState
 import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import com.vanniktech.emoji.EmojiPopup
-import im.vector.app.BuildConfig
 import im.vector.app.R
 import im.vector.app.core.animations.play
 import im.vector.app.core.dialogs.ConfirmationDialogBuilder
@@ -92,6 +91,7 @@ import im.vector.app.core.platform.VectorBaseFragment
 import im.vector.app.core.platform.VectorMenuProvider
 import im.vector.app.core.platform.lifecycleAwareLazy
 import im.vector.app.core.platform.showOptimizedSnackbar
+import im.vector.app.core.resources.BuildMeta
 import im.vector.app.core.resources.ColorProvider
 import im.vector.app.core.resources.UserPreferencesProvider
 import im.vector.app.core.time.Clock
@@ -125,6 +125,7 @@ import im.vector.app.core.utils.startInstallFromSourceIntent
 import im.vector.app.core.utils.toast
 import im.vector.app.databinding.DialogReportContentBinding
 import im.vector.app.databinding.FragmentTimelineBinding
+import im.vector.app.features.VectorFeatures
 import im.vector.app.features.analytics.extensions.toAnalyticsInteraction
 import im.vector.app.features.analytics.plan.Interaction
 import im.vector.app.features.analytics.plan.MobileScreen
@@ -275,7 +276,9 @@ class TimelineFragment @Inject constructor(
         private val callManager: WebRtcCallManager,
         private val audioMessagePlaybackTracker: AudioMessagePlaybackTracker,
         private val shareIntentHandler: ShareIntentHandler,
-        private val clock: Clock
+        private val clock: Clock,
+        private val vectorFeatures: VectorFeatures,
+        private val buildMeta: BuildMeta,
 ) :
         VectorBaseFragment<FragmentTimelineBinding>(),
         TimelineEventController.Callback,
@@ -372,7 +375,7 @@ class TimelineFragment @Inject constructor(
         sharedActionViewModel = activityViewModelProvider.get(MessageSharedActionViewModel::class.java)
         sharedActivityActionViewModel = activityViewModelProvider.get(RoomDetailSharedActionViewModel::class.java)
         knownCallsViewModel = activityViewModelProvider.get(SharedKnownCallsViewModel::class.java)
-        attachmentsHelper = AttachmentsHelper(requireContext(), this).register()
+        attachmentsHelper = AttachmentsHelper(requireContext(), this, buildMeta).register()
         callActionsHandler = StartCallActionsHandler(
                 roomId = timelineArgs.roomId,
                 fragment = this,
@@ -1559,7 +1562,7 @@ class TimelineFragment @Inject constructor(
                     attachmentTypeSelector = AttachmentTypeSelectorView(vectorBaseActivity, vectorBaseActivity.layoutInflater, this@TimelineFragment)
                     attachmentTypeSelector.setAttachmentVisibility(
                             AttachmentTypeSelectorView.Type.LOCATION,
-                            BuildConfig.enableLocationSharing
+                            vectorFeatures.isLocationSharingEnabled(),
                     )
                     attachmentTypeSelector.setAttachmentVisibility(
                             AttachmentTypeSelectorView.Type.POLL, !isThreadTimeLine()
@@ -2646,7 +2649,6 @@ class TimelineFragment @Inject constructor(
     }
 
     override fun onContactAttachmentReady(contactAttachment: ContactAttachment) {
-        super.onContactAttachmentReady(contactAttachment)
         val formattedContact = contactAttachment.toHumanReadable()
         messageComposerViewModel.handle(MessageComposerAction.SendMessage(formattedContact, false))
     }
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt
index 9e31c737bf..c0f90aba7a 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt
@@ -33,6 +33,7 @@ import im.vector.app.core.di.MavericksAssistedViewModelFactory
 import im.vector.app.core.di.hiltMavericksViewModelFactory
 import im.vector.app.core.mvrx.runCatchingToAsync
 import im.vector.app.core.platform.VectorViewModel
+import im.vector.app.core.resources.BuildMeta
 import im.vector.app.core.resources.StringProvider
 import im.vector.app.core.utils.BehaviorDataSource
 import im.vector.app.features.analytics.AnalyticsTracker
@@ -56,6 +57,7 @@ import im.vector.app.features.location.live.StopLiveLocationShareUseCase
 import im.vector.app.features.location.live.tracking.LocationSharingServiceConnection
 import im.vector.app.features.notifications.NotificationDrawerManager
 import im.vector.app.features.powerlevel.PowerLevelsFlowFactory
+import im.vector.app.features.raw.wellknown.CryptoConfig
 import im.vector.app.features.raw.wellknown.getOutboundSessionKeySharingStrategyOrDefault
 import im.vector.app.features.raw.wellknown.withElementWellKnown
 import im.vector.app.features.session.coroutineScope
@@ -137,6 +139,8 @@ class TimelineViewModel @AssistedInject constructor(
         private val locationSharingServiceConnection: LocationSharingServiceConnection,
         private val stopLiveLocationShareUseCase: StopLiveLocationShareUseCase,
         private val redactLiveLocationShareEventUseCase: RedactLiveLocationShareEventUseCase,
+        private val cryptoConfig: CryptoConfig,
+        buildMeta: BuildMeta,
         timelineFactory: TimelineFactory,
         spaceStateHandler: SpaceStateHandler,
 ) : VectorViewModel<RoomDetailViewState, RoomDetailAction, RoomDetailViewEvents>(initialState),
@@ -150,7 +154,7 @@ class TimelineViewModel @AssistedInject constructor(
     val timeline = timelineFactory.createTimeline(viewModelScope, room, eventId, initialState.rootThreadEventId)
 
     // Same lifecycle than the ViewModel (survive to screen rotation)
-    val previewUrlRetriever = PreviewUrlRetriever(session, viewModelScope)
+    val previewUrlRetriever = PreviewUrlRetriever(session, viewModelScope, buildMeta)
 
     // Slot to keep a pending action during permission request
     var pendingAction: RoomDetailAction? = null
@@ -205,7 +209,7 @@ class TimelineViewModel @AssistedInject constructor(
         // Ensure to share the outbound session keys with all members
         if (room.roomCryptoService().isEncrypted()) {
             rawService.withElementWellKnown(viewModelScope, session.sessionParams) {
-                val strategy = it.getOutboundSessionKeySharingStrategyOrDefault()
+                val strategy = it.getOutboundSessionKeySharingStrategyOrDefault(cryptoConfig.fallbackKeySharingStrategy)
                 if (strategy == OutboundSessionKeySharingStrategy.WhenEnteringRoom) {
                     prepareForEncryption()
                 }
@@ -688,7 +692,7 @@ class TimelineViewModel @AssistedInject constructor(
         // Ensure outbound session keys
         if (room.roomCryptoService().isEncrypted()) {
             rawService.withElementWellKnown(viewModelScope, session.sessionParams) {
-                val strategy = it.getOutboundSessionKeySharingStrategyOrDefault()
+                val strategy = it.getOutboundSessionKeySharingStrategyOrDefault(cryptoConfig.fallbackKeySharingStrategy)
                 if (strategy == OutboundSessionKeySharingStrategy.WhenTyping && action.focused) {
                     // Should we add some rate limit here, or do it only once per model lifecycle?
                     prepareForEncryption()
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/AudioMessageHelper.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/AudioMessageHelper.kt
index 9374d51228..2e150daee6 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/AudioMessageHelper.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/AudioMessageHelper.kt
@@ -20,7 +20,7 @@ import android.content.Context
 import android.media.AudioAttributes
 import android.media.MediaPlayer
 import androidx.core.content.FileProvider
-import im.vector.app.BuildConfig
+import im.vector.app.core.resources.BuildMeta
 import im.vector.app.features.home.room.detail.timeline.helper.AudioMessagePlaybackTracker
 import im.vector.app.features.voice.VoiceFailure
 import im.vector.app.features.voice.VoiceRecorder
@@ -43,6 +43,7 @@ import javax.inject.Inject
 class AudioMessageHelper @Inject constructor(
         private val context: Context,
         private val playbackTracker: AudioMessagePlaybackTracker,
+        private val buildMeta: BuildMeta,
         voiceRecorderProvider: VoiceRecorderProvider
 ) {
     private var mediaPlayer: MediaPlayer? = null
@@ -88,7 +89,7 @@ class AudioMessageHelper @Inject constructor(
 
         try {
             voiceMessageFile?.let {
-                val outputFileUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".fileProvider", it, "Voice message.${it.extension}")
+                val outputFileUri = FileProvider.getUriForFile(context, buildMeta.applicationId + ".fileProvider", it, "Voice message.${it.extension}")
                 return outputFileUri
                         .toMultiPickerAudioType(context)
                         ?.apply {
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/voice/VoiceMessageConfig.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/voice/VoiceMessageConfig.kt
new file mode 100644
index 0000000000..5ba5e40ca8
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/voice/VoiceMessageConfig.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.home.room.detail.composer.voice
+
+data class VoiceMessageConfig(
+        val lengthLimitMs: Long
+)
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/voice/VoiceMessageRecorderView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/voice/VoiceMessageRecorderView.kt
index 536a582ec1..13e0477ab6 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/voice/VoiceMessageRecorderView.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/voice/VoiceMessageRecorderView.kt
@@ -21,7 +21,6 @@ import android.util.AttributeSet
 import android.view.View
 import androidx.constraintlayout.widget.ConstraintLayout
 import dagger.hilt.android.AndroidEntryPoint
-import im.vector.app.BuildConfig
 import im.vector.app.R
 import im.vector.app.core.hardware.vibrate
 import im.vector.app.core.time.Clock
@@ -57,6 +56,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
     }
 
     @Inject lateinit var clock: Clock
+    @Inject lateinit var voiceMessageConfig: VoiceMessageConfig
 
     // We need to define views as lateinit var to be able to check if initialized for the bug fix on api 21 and 22.
     @Suppress("UNNECESSARY_LATEINIT")
@@ -202,7 +202,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
 
     private fun onRecordingTick(isLocked: Boolean, milliseconds: Long) {
         voiceMessageViews.renderRecordingTimer(isLocked, milliseconds / 1_000)
-        val timeDiffToRecordingLimit = BuildConfig.VOICE_MESSAGE_DURATION_LIMIT_MS - milliseconds
+        val timeDiffToRecordingLimit = voiceMessageConfig.lengthLimitMs - milliseconds
         if (timeDiffToRecordingLimit <= 0) {
             post {
                 callback.onRecordingLimitReached()
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlRetriever.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlRetriever.kt
index eef649dbc0..1c5cdd2562 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlRetriever.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlRetriever.kt
@@ -16,7 +16,7 @@
 
 package im.vector.app.features.home.room.detail.timeline.url
 
-import im.vector.app.BuildConfig
+import im.vector.app.core.resources.BuildMeta
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
@@ -27,7 +27,8 @@ import org.matrix.android.sdk.api.session.room.timeline.getLatestEventId
 
 class PreviewUrlRetriever(
         session: Session,
-        private val coroutineScope: CoroutineScope
+        private val coroutineScope: CoroutineScope,
+        private val buildMeta: BuildMeta,
 ) {
     private val mediaService = session.mediaService()
 
@@ -77,7 +78,7 @@ class PreviewUrlRetriever(
                     mediaService.getPreviewUrl(
                             url = urlToRetrieve,
                             timestamp = null,
-                            cacheStrategy = if (BuildConfig.DEBUG) CacheStrategy.NoCache else CacheStrategy.TtlCache(CACHE_VALIDITY, false)
+                            cacheStrategy = if (buildMeta.isDebug) CacheStrategy.NoCache else CacheStrategy.TtlCache(CACHE_VALIDITY, false)
                     )
                 }.fold(
                         {
diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingConfig.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingConfig.kt
new file mode 100644
index 0000000000..4615564e41
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingConfig.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.location
+
+data class LocationSharingConfig(
+        val mapTilerKey: String,
+)
diff --git a/vector/src/main/java/im/vector/app/features/location/LocationTracker.kt b/vector/src/main/java/im/vector/app/features/location/LocationTracker.kt
index aa05fe764b..a416cd90f5 100644
--- a/vector/src/main/java/im/vector/app/features/location/LocationTracker.kt
+++ b/vector/src/main/java/im/vector/app/features/location/LocationTracker.kt
@@ -24,8 +24,8 @@ import androidx.annotation.RequiresPermission
 import androidx.annotation.VisibleForTesting
 import androidx.core.content.getSystemService
 import androidx.core.location.LocationListenerCompat
-import im.vector.app.BuildConfig
 import im.vector.app.core.di.ActiveSessionHolder
+import im.vector.app.core.resources.BuildMeta
 import im.vector.app.features.session.coroutineScope
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.asSharedFlow
@@ -40,7 +40,8 @@ import javax.inject.Singleton
 @Singleton
 class LocationTracker @Inject constructor(
         context: Context,
-        private val activeSessionHolder: ActiveSessionHolder
+        private val activeSessionHolder: ActiveSessionHolder,
+        private val buildMeta: BuildMeta,
 ) : LocationListenerCompat {
 
     private val locationManager = context.getSystemService<LocationManager>()
@@ -104,7 +105,7 @@ class LocationTracker @Inject constructor(
                     }
                     .maxByOrNull { location -> location.time }
                     ?.let { latestKnownLocation ->
-                        if (BuildConfig.LOW_PRIVACY_LOG_ENABLE) {
+                        if (buildMeta.lowPrivacyLoggingEnabled) {
                             Timber.d("lastKnownLocation: $latestKnownLocation")
                         } else {
                             Timber.d("lastKnownLocation: ${latestKnownLocation.provider}")
@@ -162,7 +163,7 @@ class LocationTracker @Inject constructor(
     }
 
     override fun onLocationChanged(location: Location) {
-        if (BuildConfig.LOW_PRIVACY_LOG_ENABLE) {
+        if (buildMeta.lowPrivacyLoggingEnabled) {
             Timber.d("onLocationChanged: $location")
         } else {
             Timber.d("onLocationChanged: ${location.provider}")
@@ -196,7 +197,7 @@ class LocationTracker @Inject constructor(
 
     private fun notifyLocation(location: Location) {
         activeSessionHolder.getSafeActiveSession()?.coroutineScope?.launch {
-            if (BuildConfig.LOW_PRIVACY_LOG_ENABLE) {
+            if (buildMeta.lowPrivacyLoggingEnabled) {
                 Timber.d("notify location: $location")
             } else {
                 Timber.d("notify location: ${location.provider}")
diff --git a/vector/src/main/java/im/vector/app/features/location/UrlMapProvider.kt b/vector/src/main/java/im/vector/app/features/location/UrlMapProvider.kt
index f043006d70..3748b1b19e 100644
--- a/vector/src/main/java/im/vector/app/features/location/UrlMapProvider.kt
+++ b/vector/src/main/java/im/vector/app/features/location/UrlMapProvider.kt
@@ -16,7 +16,6 @@
 
 package im.vector.app.features.location
 
-import im.vector.app.BuildConfig
 import im.vector.app.features.raw.wellknown.getElementWellknown
 import org.matrix.android.sdk.api.extensions.tryOrNull
 import org.matrix.android.sdk.api.raw.RawService
@@ -25,9 +24,10 @@ import javax.inject.Inject
 
 class UrlMapProvider @Inject constructor(
         private val session: Session,
-        private val rawService: RawService
+        private val rawService: RawService,
+        locationSharingConfig: LocationSharingConfig,
 ) {
-    private val keyParam = "?key=${BuildConfig.mapTilerKey}"
+    private val keyParam = "?key=${locationSharingConfig.mapTilerKey}"
 
     private val fallbackMapUrl = buildString {
         append(MAP_BASE_URL)
diff --git a/vector/src/main/java/im/vector/app/features/location/live/tracking/LiveLocationNotificationBuilder.kt b/vector/src/main/java/im/vector/app/features/location/live/tracking/LiveLocationNotificationBuilder.kt
index b8dd17e8fd..5bc730f3d7 100644
--- a/vector/src/main/java/im/vector/app/features/location/live/tracking/LiveLocationNotificationBuilder.kt
+++ b/vector/src/main/java/im/vector/app/features/location/live/tracking/LiveLocationNotificationBuilder.kt
@@ -31,6 +31,7 @@ import im.vector.app.features.home.room.detail.RoomDetailActivity
 import im.vector.app.features.home.room.detail.arguments.TimelineArgs
 import im.vector.app.features.location.live.map.LiveLocationMapViewActivity
 import im.vector.app.features.location.live.map.LiveLocationMapViewArgs
+import im.vector.app.features.notifications.NotificationActionIds
 import im.vector.app.features.notifications.NotificationUtils
 import im.vector.app.features.themes.ThemeUtils
 import javax.inject.Inject
@@ -41,6 +42,7 @@ class LiveLocationNotificationBuilder @Inject constructor(
         private val context: Context,
         private val stringProvider: StringProvider,
         private val clock: Clock,
+        private val actionIds: NotificationActionIds,
 ) {
 
     /**
@@ -66,7 +68,7 @@ class LiveLocationNotificationBuilder @Inject constructor(
                 liveLocationMapViewArgs = LiveLocationMapViewArgs(roomId = roomId),
                 firstStartMainActivity = true
         )
-        mapIntent.action = NotificationUtils.TAP_TO_VIEW_ACTION
+        mapIntent.action = actionIds.tapToView
         // pending intent get reused by system, this will mess up the extra params, so put unique info to avoid that
         mapIntent.data = createIgnoredUri("openLiveLocationMap?$roomId")
 
diff --git a/vector/src/main/java/im/vector/app/features/login/LoginServerUrlFormFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginServerUrlFormFragment.kt
index b0adeff04b..937e1bdf55 100644
--- a/vector/src/main/java/im/vector/app/features/login/LoginServerUrlFormFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/login/LoginServerUrlFormFragment.kt
@@ -27,9 +27,9 @@ import androidx.core.view.isInvisible
 import androidx.core.view.isVisible
 import androidx.lifecycle.lifecycleScope
 import com.google.android.material.textfield.TextInputLayout
-import im.vector.app.BuildConfig
 import im.vector.app.R
 import im.vector.app.core.extensions.hideKeyboard
+import im.vector.app.core.resources.BuildMeta
 import im.vector.app.core.utils.ensureProtocol
 import im.vector.app.core.utils.openUrlInChromeCustomTab
 import im.vector.app.databinding.FragmentLoginServerUrlFormBinding
@@ -43,7 +43,9 @@ import javax.inject.Inject
 /**
  * In this screen, the user is prompted to enter a homeserver url.
  */
-class LoginServerUrlFormFragment @Inject constructor() : AbstractLoginFragment<FragmentLoginServerUrlFormBinding>() {
+class LoginServerUrlFormFragment @Inject constructor(
+        private val buildMeta: BuildMeta,
+) : AbstractLoginFragment<FragmentLoginServerUrlFormBinding>() {
 
     override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginServerUrlFormBinding {
         return FragmentLoginServerUrlFormBinding.inflate(inflater, container, false)
@@ -99,7 +101,7 @@ class LoginServerUrlFormFragment @Inject constructor() : AbstractLoginFragment<F
                 views.loginServerUrlFormNotice.text = getString(R.string.login_server_url_form_common_notice)
             }
         }
-        val completions = state.knownCustomHomeServersUrls + if (BuildConfig.DEBUG) listOf("http://10.0.2.2:8080") else emptyList()
+        val completions = state.knownCustomHomeServersUrls + if (buildMeta.isDebug) listOf("http://10.0.2.2:8080") else emptyList()
         views.loginServerUrlFormHomeServerUrl.setAdapter(
                 ArrayAdapter(
                         requireContext(),
diff --git a/vector/src/main/java/im/vector/app/features/login/LoginSplashFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginSplashFragment.kt
index f3287ae333..7f5e87967b 100644
--- a/vector/src/main/java/im/vector/app/features/login/LoginSplashFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/login/LoginSplashFragment.kt
@@ -23,8 +23,8 @@ import android.view.View
 import android.view.ViewGroup
 import androidx.core.view.isVisible
 import com.google.android.material.dialog.MaterialAlertDialogBuilder
-import im.vector.app.BuildConfig
 import im.vector.app.R
+import im.vector.app.core.resources.BuildMeta
 import im.vector.app.databinding.FragmentLoginSplashBinding
 import im.vector.app.features.analytics.plan.MobileScreen
 import im.vector.app.features.settings.VectorPreferences
@@ -36,7 +36,8 @@ import javax.inject.Inject
  * In this screen, the user is viewing an introduction to what he can do with this application.
  */
 class LoginSplashFragment @Inject constructor(
-        private val vectorPreferences: VectorPreferences
+        private val vectorPreferences: VectorPreferences,
+        private val buildMeta: BuildMeta,
 ) : AbstractLoginFragment<FragmentLoginSplashBinding>() {
 
     override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginSplashBinding {
@@ -57,12 +58,12 @@ class LoginSplashFragment @Inject constructor(
     private fun setupViews() {
         views.loginSplashSubmit.debouncedClicks { getStarted() }
 
-        if (BuildConfig.DEBUG || vectorPreferences.developerMode()) {
+        if (buildMeta.isDebug || vectorPreferences.developerMode()) {
             views.loginSplashVersion.isVisible = true
             @SuppressLint("SetTextI18n")
-            views.loginSplashVersion.text = "Version : ${BuildConfig.VERSION_NAME}\n" +
-                    "Branch: ${BuildConfig.GIT_BRANCH_NAME}\n" +
-                    "Build: ${BuildConfig.BUILD_NUMBER}"
+            views.loginSplashVersion.text = "Version : ${buildMeta.versionName}\n" +
+                    "Branch: ${buildMeta.gitBranchName}\n" +
+                    "Build: ${buildMeta.buildNumber}"
             views.loginSplashVersion.debouncedClicks { navigator.openDebug(requireContext()) }
         }
     }
diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginServerUrlFormFragment2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginServerUrlFormFragment2.kt
index bcd2d84346..50f8f38634 100644
--- a/vector/src/main/java/im/vector/app/features/login2/LoginServerUrlFormFragment2.kt
+++ b/vector/src/main/java/im/vector/app/features/login2/LoginServerUrlFormFragment2.kt
@@ -26,9 +26,9 @@ import android.widget.ArrayAdapter
 import androidx.core.view.isInvisible
 import androidx.lifecycle.lifecycleScope
 import com.google.android.material.textfield.TextInputLayout
-import im.vector.app.BuildConfig
 import im.vector.app.R
 import im.vector.app.core.extensions.hideKeyboard
+import im.vector.app.core.resources.BuildMeta
 import im.vector.app.core.utils.ensureProtocol
 import im.vector.app.databinding.FragmentLoginServerUrlForm2Binding
 import kotlinx.coroutines.flow.launchIn
@@ -43,7 +43,9 @@ import javax.net.ssl.HttpsURLConnection
 /**
  * In this screen, the user is prompted to enter a homeserver url.
  */
-class LoginServerUrlFormFragment2 @Inject constructor() : AbstractLoginFragment2<FragmentLoginServerUrlForm2Binding>() {
+class LoginServerUrlFormFragment2 @Inject constructor(
+        private val buildMeta: BuildMeta,
+) : AbstractLoginFragment2<FragmentLoginServerUrlForm2Binding>() {
 
     override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginServerUrlForm2Binding {
         return FragmentLoginServerUrlForm2Binding.inflate(inflater, container, false)
@@ -80,7 +82,7 @@ class LoginServerUrlFormFragment2 @Inject constructor() : AbstractLoginFragment2
     }
 
     private fun setupUi(state: LoginViewState2) {
-        val completions = state.knownCustomHomeServersUrls + if (BuildConfig.DEBUG) listOf("http://10.0.2.2:8080") else emptyList()
+        val completions = state.knownCustomHomeServersUrls + if (buildMeta.isDebug) listOf("http://10.0.2.2:8080") else emptyList()
         views.loginServerUrlFormHomeServerUrl.setAdapter(
                 ArrayAdapter(
                         requireContext(),
diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginSplashSignUpSignInSelectionFragment2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginSplashSignUpSignInSelectionFragment2.kt
index 611b5f4cd2..84af28f75e 100644
--- a/vector/src/main/java/im/vector/app/features/login2/LoginSplashSignUpSignInSelectionFragment2.kt
+++ b/vector/src/main/java/im/vector/app/features/login2/LoginSplashSignUpSignInSelectionFragment2.kt
@@ -22,7 +22,7 @@ import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import androidx.core.view.isVisible
-import im.vector.app.BuildConfig
+import im.vector.app.core.resources.BuildMeta
 import im.vector.app.databinding.FragmentLoginSplash2Binding
 import im.vector.app.features.settings.VectorPreferences
 import javax.inject.Inject
@@ -32,7 +32,8 @@ import javax.inject.Inject
  * This is the new splash screen.
  */
 class LoginSplashSignUpSignInSelectionFragment2 @Inject constructor(
-        private val vectorPreferences: VectorPreferences
+        private val vectorPreferences: VectorPreferences,
+        private val buildMeta: BuildMeta,
 ) : AbstractLoginFragment2<FragmentLoginSplash2Binding>() {
 
     override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginSplash2Binding {
@@ -49,12 +50,12 @@ class LoginSplashSignUpSignInSelectionFragment2 @Inject constructor(
         views.loginSignupSigninSignUp.setOnClickListener { signUp() }
         views.loginSignupSigninSignIn.setOnClickListener { signIn() }
 
-        if (BuildConfig.DEBUG || vectorPreferences.developerMode()) {
+        if (buildMeta.isDebug || vectorPreferences.developerMode()) {
             views.loginSplashVersion.isVisible = true
             @SuppressLint("SetTextI18n")
-            views.loginSplashVersion.text = "Version : ${BuildConfig.VERSION_NAME}\n" +
-                    "Branch: ${BuildConfig.GIT_BRANCH_NAME}\n" +
-                    "Build: ${BuildConfig.BUILD_NUMBER}"
+            views.loginSplashVersion.text = "Version : ${buildMeta.versionName}\n" +
+                    "Branch: ${buildMeta.gitBranchName}\n" +
+                    "Build: ${buildMeta.buildNumber}"
             views.loginSplashVersion.debouncedClicks { navigator.openDebug(requireContext()) }
         }
     }
diff --git a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt
index d2404b5bb8..38db642287 100644
--- a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt
+++ b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt
@@ -33,10 +33,10 @@ import androidx.core.view.ViewCompat
 import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import im.vector.app.R
 import im.vector.app.SpaceStateHandler
+import im.vector.app.config.OnboardingVariant
 import im.vector.app.core.di.ActiveSessionHolder
 import im.vector.app.core.error.fatalError
 import im.vector.app.features.VectorFeatures
-import im.vector.app.features.VectorFeatures.OnboardingVariant
 import im.vector.app.features.analytics.AnalyticsTracker
 import im.vector.app.features.analytics.extensions.toAnalyticsViewRoom
 import im.vector.app.features.analytics.plan.ViewRoom
diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt
index 1ca72b8399..1cf80de4ee 100644
--- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt
+++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt
@@ -16,9 +16,9 @@
 package im.vector.app.features.notifications
 
 import android.net.Uri
-import im.vector.app.BuildConfig
 import im.vector.app.R
 import im.vector.app.core.extensions.takeAs
+import im.vector.app.core.resources.BuildMeta
 import im.vector.app.core.resources.StringProvider
 import im.vector.app.core.time.Clock
 import im.vector.app.features.displayname.getBestName
@@ -62,6 +62,7 @@ class NotifiableEventResolver @Inject constructor(
         private val noticeEventFormatter: NoticeEventFormatter,
         private val displayableEventFormatter: DisplayableEventFormatter,
         private val clock: Clock,
+        private val buildMeta: BuildMeta,
 ) {
 
     // private val eventDisplay = RiotEventDisplay(context)
@@ -264,7 +265,7 @@ class NotifiableEventResolver @Inject constructor(
             )
         } else {
             Timber.e("## unsupported notifiable event for eventId [${event.eventId}]")
-            if (BuildConfig.LOW_PRIVACY_LOG_ENABLE) {
+            if (buildMeta.lowPrivacyLoggingEnabled) {
                 Timber.e("## unsupported notifiable event for event [$event]")
             }
             // TODO generic handling?
diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationActionIds.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationActionIds.kt
new file mode 100644
index 0000000000..3bd7a635ae
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationActionIds.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.notifications
+
+import im.vector.app.core.resources.BuildMeta
+import javax.inject.Inject
+
+/**
+ * Util class for creating notifications.
+ * Note: Cannot inject ColorProvider in the constructor, because it requires an Activity
+ */
+
+data class NotificationActionIds @Inject constructor(
+        private val buildMeta: BuildMeta,
+) {
+
+    val join = "${buildMeta.applicationId}.NotificationActions.JOIN_ACTION"
+    val reject = "${buildMeta.applicationId}.NotificationActions.REJECT_ACTION"
+    val quickLaunch = "${buildMeta.applicationId}.NotificationActions.QUICK_LAUNCH_ACTION"
+    val markRoomRead = "${buildMeta.applicationId}.NotificationActions.MARK_ROOM_READ_ACTION"
+    val smartReply = "${buildMeta.applicationId}.NotificationActions.SMART_REPLY_ACTION"
+    val dismissSummary = "${buildMeta.applicationId}.NotificationActions.DISMISS_SUMMARY_ACTION"
+    val dismissRoom = "${buildMeta.applicationId}.NotificationActions.DISMISS_ROOM_NOTIF_ACTION"
+    val tapToView = "${buildMeta.applicationId}.NotificationActions.TAP_TO_VIEW_ACTION"
+    val diagnostic = "${buildMeta.applicationId}.NotificationActions.DIAGNOSTIC"
+    val push = "${buildMeta.applicationId}.PUSH"
+}
diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt
index c01be9a44f..3fe0898eb4 100644
--- a/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt
+++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt
@@ -48,31 +48,32 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
     @Inject lateinit var activeSessionHolder: ActiveSessionHolder
     @Inject lateinit var analyticsTracker: AnalyticsTracker
     @Inject lateinit var clock: Clock
+    @Inject lateinit var actionIds: NotificationActionIds
 
     override fun onReceive(context: Context?, intent: Intent?) {
         if (intent == null || context == null) return
         Timber.v("NotificationBroadcastReceiver received : $intent")
         when (intent.action) {
-            NotificationUtils.SMART_REPLY_ACTION ->
+            actionIds.smartReply ->
                 handleSmartReply(intent, context)
-            NotificationUtils.DISMISS_ROOM_NOTIF_ACTION ->
+            actionIds.dismissRoom ->
                 intent.getStringExtra(KEY_ROOM_ID)?.let { roomId ->
                     notificationDrawerManager.updateEvents { it.clearMessagesForRoom(roomId) }
                 }
-            NotificationUtils.DISMISS_SUMMARY_ACTION ->
+            actionIds.dismissSummary ->
                 notificationDrawerManager.clearAllEvents()
-            NotificationUtils.MARK_ROOM_READ_ACTION ->
+            actionIds.markRoomRead ->
                 intent.getStringExtra(KEY_ROOM_ID)?.let { roomId ->
                     notificationDrawerManager.updateEvents { it.clearMessagesForRoom(roomId) }
                     handleMarkAsRead(roomId)
                 }
-            NotificationUtils.JOIN_ACTION -> {
+            actionIds.join -> {
                 intent.getStringExtra(KEY_ROOM_ID)?.let { roomId ->
                     notificationDrawerManager.updateEvents { it.clearMemberShipNotificationForRoom(roomId) }
                     handleJoinRoom(roomId)
                 }
             }
-            NotificationUtils.REJECT_ACTION -> {
+            actionIds.reject -> {
                 intent.getStringExtra(KEY_ROOM_ID)?.let { roomId ->
                     notificationDrawerManager.updateEvents { it.clearMemberShipNotificationForRoom(roomId) }
                     handleRejectRoom(roomId)
diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt
index 686ed324dc..5f43ff6b90 100644
--- a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt
+++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt
@@ -20,8 +20,8 @@ import android.os.Handler
 import android.os.HandlerThread
 import androidx.annotation.WorkerThread
 import im.vector.app.ActiveSessionDataSource
-import im.vector.app.BuildConfig
 import im.vector.app.R
+import im.vector.app.core.resources.BuildMeta
 import im.vector.app.core.utils.FirstThrottler
 import im.vector.app.features.displayname.getBestName
 import im.vector.app.features.settings.VectorPreferences
@@ -46,7 +46,8 @@ class NotificationDrawerManager @Inject constructor(
         private val activeSessionDataSource: ActiveSessionDataSource,
         private val notifiableEventProcessor: NotifiableEventProcessor,
         private val notificationRenderer: NotificationRenderer,
-        private val notificationEventPersistence: NotificationEventPersistence
+        private val notificationEventPersistence: NotificationEventPersistence,
+        private val buildMeta: BuildMeta,
 ) {
 
     private val handlerThread: HandlerThread = HandlerThread("NotificationDrawerManager", Thread.MIN_PRIORITY)
@@ -92,7 +93,7 @@ class NotificationDrawerManager @Inject constructor(
         }
         // If we support multi session, event list should be per userId
         // Currently only manage single session
-        if (BuildConfig.LOW_PRIVACY_LOG_ENABLE) {
+        if (buildMeta.lowPrivacyLoggingEnabled) {
             Timber.d("onNotifiableEventReceived(): $notifiableEvent")
         } else {
             Timber.d("onNotifiableEventReceived(): is push: ${notifiableEvent.canBeReplaced}")
diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt
index b5bd02b9d5..8f05819fc4 100755
--- a/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt
+++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt
@@ -45,7 +45,6 @@ import androidx.core.content.getSystemService
 import androidx.core.content.res.ResourcesCompat
 import androidx.core.graphics.drawable.IconCompat
 import androidx.fragment.app.Fragment
-import im.vector.app.BuildConfig
 import im.vector.app.R
 import im.vector.app.core.extensions.createIgnoredUri
 import im.vector.app.core.platform.PendingIntentCompat
@@ -69,16 +68,13 @@ import javax.inject.Inject
 import javax.inject.Singleton
 import kotlin.random.Random
 
-/**
- * Util class for creating notifications.
- * Note: Cannot inject ColorProvider in the constructor, because it requires an Activity
- */
 @Singleton
 class NotificationUtils @Inject constructor(
         private val context: Context,
         private val stringProvider: StringProvider,
         private val vectorPreferences: VectorPreferences,
         private val clock: Clock,
+        private val actionIds: NotificationActionIds,
 ) {
 
     companion object {
@@ -94,21 +90,6 @@ class NotificationUtils @Inject constructor(
          */
         const val NOTIFICATION_ID_FOREGROUND_SERVICE = 61
 
-        /* ==========================================================================================
-         * IDs for actions
-         * ========================================================================================== */
-
-        const val JOIN_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.JOIN_ACTION"
-        const val REJECT_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.REJECT_ACTION"
-        private const val QUICK_LAUNCH_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.QUICK_LAUNCH_ACTION"
-        const val MARK_ROOM_READ_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.MARK_ROOM_READ_ACTION"
-        const val SMART_REPLY_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.SMART_REPLY_ACTION"
-        const val DISMISS_SUMMARY_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.DISMISS_SUMMARY_ACTION"
-        const val DISMISS_ROOM_NOTIF_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.DISMISS_ROOM_NOTIF_ACTION"
-        const val TAP_TO_VIEW_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.TAP_TO_VIEW_ACTION"
-        const val DIAGNOSTIC_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.DIAGNOSTIC"
-        const val PUSH_ACTION = "${BuildConfig.APPLICATION_ID}.PUSH"
-
         /* ==========================================================================================
          * IDs for channels
          * ========================================================================================== */
@@ -651,7 +632,7 @@ class NotificationUtils @Inject constructor(
                     // Add actions and notification intents
                     // Mark room as read
                     val markRoomReadIntent = Intent(context, NotificationBroadcastReceiver::class.java)
-                    markRoomReadIntent.action = MARK_ROOM_READ_ACTION
+                    markRoomReadIntent.action = actionIds.markRoomRead
                     markRoomReadIntent.data = createIgnoredUri(roomInfo.roomId)
                     markRoomReadIntent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomInfo.roomId)
                     val markRoomReadPendingIntent = PendingIntent.getBroadcast(
@@ -698,7 +679,7 @@ class NotificationUtils @Inject constructor(
 
                     val intent = Intent(context, NotificationBroadcastReceiver::class.java)
                     intent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomInfo.roomId)
-                    intent.action = DISMISS_ROOM_NOTIF_ACTION
+                    intent.action = actionIds.dismissRoom
                     val pendingIntent = PendingIntent.getBroadcast(
                             context.applicationContext,
                             clock.epochMillis().toInt(),
@@ -733,7 +714,7 @@ class NotificationUtils @Inject constructor(
                     val roomId = inviteNotifiableEvent.roomId
                     // offer to type a quick reject button
                     val rejectIntent = Intent(context, NotificationBroadcastReceiver::class.java)
-                    rejectIntent.action = REJECT_ACTION
+                    rejectIntent.action = actionIds.reject
                     rejectIntent.data = createIgnoredUri("$roomId&$matrixId")
                     rejectIntent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomId)
                     val rejectIntentPendingIntent = PendingIntent.getBroadcast(
@@ -751,7 +732,7 @@ class NotificationUtils @Inject constructor(
 
                     // offer to type a quick accept button
                     val joinIntent = Intent(context, NotificationBroadcastReceiver::class.java)
-                    joinIntent.action = JOIN_ACTION
+                    joinIntent.action = actionIds.join
                     joinIntent.data = createIgnoredUri("$roomId&$matrixId")
                     joinIntent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomId)
                     val joinIntentPendingIntent = PendingIntent.getBroadcast(
@@ -834,7 +815,7 @@ class NotificationUtils @Inject constructor(
 
     private fun buildOpenRoomIntent(roomId: String): PendingIntent? {
         val roomIntentTap = RoomDetailActivity.newIntent(context, TimelineArgs(roomId = roomId, switchToParentSpace = true), true)
-        roomIntentTap.action = TAP_TO_VIEW_ACTION
+        roomIntentTap.action = actionIds.tapToView
         // pending intent get reused by system, this will mess up the extra params, so put unique info to avoid that
         roomIntentTap.data = createIgnoredUri("openRoom?$roomId")
 
@@ -872,7 +853,7 @@ class NotificationUtils @Inject constructor(
         val intent: Intent
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
             intent = Intent(context, NotificationBroadcastReceiver::class.java)
-            intent.action = SMART_REPLY_ACTION
+            intent.action = actionIds.smartReply
             intent.data = createIgnoredUri(roomId)
             intent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomId)
             return PendingIntent.getBroadcast(
@@ -948,7 +929,7 @@ class NotificationUtils @Inject constructor(
 
     private fun getDismissSummaryPendingIntent(): PendingIntent {
         val intent = Intent(context, NotificationBroadcastReceiver::class.java)
-        intent.action = DISMISS_SUMMARY_ACTION
+        intent.action = actionIds.dismissSummary
         intent.data = createIgnoredUri("deleteSummary")
         return PendingIntent.getBroadcast(
                 context.applicationContext,
@@ -987,7 +968,7 @@ class NotificationUtils @Inject constructor(
 
     fun displayDiagnosticNotification() {
         val testActionIntent = Intent(context, TestNotificationReceiver::class.java)
-        testActionIntent.action = DIAGNOSTIC_ACTION
+        testActionIntent.action = actionIds.diagnostic
         val testPendingIntent = PendingIntent.getBroadcast(
                 context,
                 0,
diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingVariantFactory.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingVariantFactory.kt
index 8d9f372bdd..9837db8e91 100644
--- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingVariantFactory.kt
+++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingVariantFactory.kt
@@ -16,6 +16,7 @@
 
 package im.vector.app.features.onboarding
 
+import im.vector.app.config.OnboardingVariant
 import im.vector.app.core.platform.ScreenOrientationLocker
 import im.vector.app.databinding.ActivityLoginBinding
 import im.vector.app.features.VectorFeatures
@@ -34,8 +35,8 @@ class OnboardingVariantFactory @Inject constructor(
             onboardingViewModel: Lazy<OnboardingViewModel>,
             loginViewModel2: Lazy<LoginViewModel2>
     ) = when (vectorFeatures.onboardingVariant()) {
-        VectorFeatures.OnboardingVariant.LEGACY -> error("Legacy is not supported by the FTUE")
-        VectorFeatures.OnboardingVariant.FTUE_AUTH -> FtueAuthVariant(
+        OnboardingVariant.LEGACY -> error("Legacy is not supported by the FTUE")
+        OnboardingVariant.FTUE_AUTH -> FtueAuthVariant(
                 views = views,
                 onboardingViewModel = onboardingViewModel.value,
                 activity = activity,
@@ -43,7 +44,7 @@ class OnboardingVariantFactory @Inject constructor(
                 vectorFeatures = vectorFeatures,
                 orientationLocker = orientationLocker
         )
-        VectorFeatures.OnboardingVariant.LOGIN_2 -> Login2Variant(
+        OnboardingVariant.LOGIN_2 -> Login2Variant(
                 views = views,
                 loginViewModel = loginViewModel2.value,
                 activity = activity,
diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt
index 6cadb4308a..8136dc379b 100644
--- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt
@@ -32,7 +32,6 @@ import im.vector.app.core.extensions.isMatrixId
 import im.vector.app.core.extensions.toReducedUrl
 import im.vector.app.core.extensions.vectorStore
 import im.vector.app.core.platform.VectorViewModel
-import im.vector.app.core.resources.BuildMeta
 import im.vector.app.core.resources.StringProvider
 import im.vector.app.core.utils.ensureProtocol
 import im.vector.app.core.utils.ensureTrailingSlash
@@ -63,6 +62,7 @@ import org.matrix.android.sdk.api.auth.registration.RegistrationAvailability
 import org.matrix.android.sdk.api.auth.registration.RegistrationWizard
 import org.matrix.android.sdk.api.failure.isHomeserverUnavailable
 import org.matrix.android.sdk.api.session.Session
+import org.matrix.android.sdk.api.util.BuildVersionSdkIntProvider
 import timber.log.Timber
 import java.util.UUID
 import java.util.concurrent.CancellationException
@@ -86,7 +86,7 @@ class OnboardingViewModel @AssistedInject constructor(
         private val startAuthenticationFlowUseCase: StartAuthenticationFlowUseCase,
         private val vectorOverrides: VectorOverrides,
         private val registrationActionHandler: RegistrationActionHandler,
-        private val buildMeta: BuildMeta,
+        private val sdkIntProvider: BuildVersionSdkIntProvider,
 ) : VectorViewModel<OnboardingViewState, OnboardingAction, OnboardingViewEvents>(initialState) {
 
     @AssistedFactory
@@ -708,7 +708,7 @@ class OnboardingViewModel @AssistedInject constructor(
 
     private fun onAuthenticationStartError(error: Throwable, trigger: OnboardingAction.HomeServerChange) {
         when {
-            error.isHomeserverUnavailable() && applicationContext.inferNoConnectivity(buildMeta) -> _viewEvents.post(
+            error.isHomeserverUnavailable() && applicationContext.inferNoConnectivity(sdkIntProvider) -> _viewEvents.post(
                     OnboardingViewEvents.Failure(error)
             )
             deeplinkUrlIsUnavailable(error, trigger) -> _viewEvents.post(
diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthServerUrlFormFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthServerUrlFormFragment.kt
index b2a99ffb7e..b16ad3ee93 100644
--- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthServerUrlFormFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthServerUrlFormFragment.kt
@@ -27,9 +27,9 @@ import androidx.core.view.isInvisible
 import androidx.core.view.isVisible
 import androidx.lifecycle.lifecycleScope
 import com.google.android.material.textfield.TextInputLayout
-import im.vector.app.BuildConfig
 import im.vector.app.R
 import im.vector.app.core.extensions.hideKeyboard
+import im.vector.app.core.resources.BuildMeta
 import im.vector.app.core.utils.ensureProtocol
 import im.vector.app.core.utils.openUrlInChromeCustomTab
 import im.vector.app.databinding.FragmentLoginServerUrlFormBinding
@@ -47,7 +47,9 @@ import javax.inject.Inject
 /**
  * In this screen, the user is prompted to enter a homeserver url.
  */
-class FtueAuthServerUrlFormFragment @Inject constructor() : AbstractFtueAuthFragment<FragmentLoginServerUrlFormBinding>() {
+class FtueAuthServerUrlFormFragment @Inject constructor(
+        private val buildMeta: BuildMeta,
+) : AbstractFtueAuthFragment<FragmentLoginServerUrlFormBinding>() {
 
     override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginServerUrlFormBinding {
         return FragmentLoginServerUrlFormBinding.inflate(inflater, container, false)
@@ -103,7 +105,7 @@ class FtueAuthServerUrlFormFragment @Inject constructor() : AbstractFtueAuthFrag
                 views.loginServerUrlFormNotice.text = getString(R.string.login_server_url_form_common_notice)
             }
         }
-        val completions = state.knownCustomHomeServersUrls + if (BuildConfig.DEBUG) listOf("http://10.0.2.2:8080") else emptyList()
+        val completions = state.knownCustomHomeServersUrls + if (buildMeta.isDebug) listOf("http://10.0.2.2:8080") else emptyList()
         views.loginServerUrlFormHomeServerUrl.setAdapter(
                 ArrayAdapter(
                         requireContext(),
diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthSplashCarouselFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthSplashCarouselFragment.kt
index 0d86c4cd24..6ad5df3fef 100644
--- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthSplashCarouselFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthSplashCarouselFragment.kt
@@ -27,10 +27,10 @@ import androidx.lifecycle.LifecycleOwner
 import androidx.lifecycle.lifecycleScope
 import androidx.viewpager2.widget.ViewPager2
 import com.google.android.material.tabs.TabLayoutMediator
-import im.vector.app.BuildConfig
 import im.vector.app.R
 import im.vector.app.core.extensions.incrementByOneAndWrap
 import im.vector.app.core.extensions.setCurrentItem
+import im.vector.app.core.resources.BuildMeta
 import im.vector.app.databinding.FragmentFtueSplashCarouselBinding
 import im.vector.app.features.VectorFeatures
 import im.vector.app.features.onboarding.OnboardingAction
@@ -48,7 +48,8 @@ class FtueAuthSplashCarouselFragment @Inject constructor(
         private val vectorPreferences: VectorPreferences,
         private val vectorFeatures: VectorFeatures,
         private val carouselController: SplashCarouselController,
-        private val carouselStateFactory: SplashCarouselStateFactory
+        private val carouselStateFactory: SplashCarouselStateFactory,
+        private val buildMeta: BuildMeta,
 ) : AbstractFtueAuthFragment<FragmentFtueSplashCarouselBinding>() {
 
     override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtueSplashCarouselBinding {
@@ -76,11 +77,11 @@ class FtueAuthSplashCarouselFragment @Inject constructor(
             debouncedClicks { alreadyHaveAnAccount() }
         }
 
-        if (BuildConfig.DEBUG || vectorPreferences.developerMode()) {
+        if (buildMeta.isDebug || vectorPreferences.developerMode()) {
             views.loginSplashVersion.isVisible = true
             @SuppressLint("SetTextI18n")
-            views.loginSplashVersion.text = "Version : ${BuildConfig.VERSION_NAME}#${BuildConfig.BUILD_NUMBER}\n" +
-                    "Branch: ${BuildConfig.GIT_BRANCH_NAME}"
+            views.loginSplashVersion.text = "Version : ${buildMeta.versionName}#${buildMeta.buildNumber}\n" +
+                    "Branch: ${buildMeta.gitBranchName}"
             views.loginSplashVersion.debouncedClicks { navigator.openDebug(requireContext()) }
         }
         views.splashCarousel.registerAutomaticUntilInteractionTransitions()
diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthSplashFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthSplashFragment.kt
index cd1e4b2714..a04e8a5c01 100644
--- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthSplashFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthSplashFragment.kt
@@ -22,8 +22,8 @@ import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import androidx.core.view.isVisible
-import im.vector.app.BuildConfig
 import im.vector.app.R
+import im.vector.app.core.resources.BuildMeta
 import im.vector.app.databinding.FragmentFtueAuthSplashBinding
 import im.vector.app.features.VectorFeatures
 import im.vector.app.features.onboarding.OnboardingAction
@@ -36,7 +36,8 @@ import javax.inject.Inject
  */
 class FtueAuthSplashFragment @Inject constructor(
         private val vectorPreferences: VectorPreferences,
-        private val vectorFeatures: VectorFeatures
+        private val vectorFeatures: VectorFeatures,
+        private val buildMeta: BuildMeta,
 ) : AbstractFtueAuthFragment<FragmentFtueAuthSplashBinding>() {
 
     override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtueAuthSplashBinding {
@@ -59,12 +60,12 @@ class FtueAuthSplashFragment @Inject constructor(
             debouncedClicks { alreadyHaveAnAccount() }
         }
 
-        if (BuildConfig.DEBUG || vectorPreferences.developerMode()) {
+        if (buildMeta.isDebug || vectorPreferences.developerMode()) {
             views.loginSplashVersion.isVisible = true
             @SuppressLint("SetTextI18n")
-            views.loginSplashVersion.text = "Version : ${BuildConfig.VERSION_NAME}\n" +
-                    "Branch: ${BuildConfig.GIT_BRANCH_NAME}\n" +
-                    "Build: ${BuildConfig.BUILD_NUMBER}"
+            views.loginSplashVersion.text = "Version : ${buildMeta.versionName}\n" +
+                    "Branch: ${buildMeta.gitBranchName}\n" +
+                    "Build: ${buildMeta.buildNumber}"
             views.loginSplashVersion.debouncedClicks { navigator.openDebug(requireContext()) }
         }
     }
diff --git a/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt b/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt
index e2e5ee2c6e..ad09593ebd 100755
--- a/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt
+++ b/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt
@@ -30,6 +30,7 @@ import im.vector.app.R
 import im.vector.app.core.di.ActiveSessionHolder
 import im.vector.app.core.extensions.getAllChildFragments
 import im.vector.app.core.extensions.toOnOff
+import im.vector.app.core.resources.BuildMeta
 import im.vector.app.features.settings.VectorLocale
 import im.vector.app.features.settings.VectorPreferences
 import im.vector.app.features.settings.devtools.GossipingEventsSerializer
@@ -50,6 +51,7 @@ import okhttp3.Response
 import org.json.JSONException
 import org.json.JSONObject
 import org.matrix.android.sdk.api.Matrix
+import org.matrix.android.sdk.api.util.BuildVersionSdkIntProvider
 import org.matrix.android.sdk.api.util.JsonDict
 import org.matrix.android.sdk.api.util.MatrixJsonParser
 import org.matrix.android.sdk.api.util.MimeTypes
@@ -74,7 +76,9 @@ class BugReporter @Inject constructor(
         private val vectorPreferences: VectorPreferences,
         private val vectorFileLogger: VectorFileLogger,
         private val systemLocaleProvider: SystemLocaleProvider,
-        private val matrix: Matrix
+        private val matrix: Matrix,
+        private val buildMeta: BuildMeta,
+        private val sdkIntProvider: BuildVersionSdkIntProvider,
 ) {
     var inMultiWindowMode = false
 
@@ -278,14 +282,14 @@ class BugReporter @Inject constructor(
                             .addFormDataPart("can_contact", canContact.toString())
                             .addFormDataPart("device_id", deviceId)
                             .addFormDataPart("version", versionProvider.getVersion(longFormat = true, useBuildNumber = false))
-                            .addFormDataPart("branch_name", BuildConfig.GIT_BRANCH_NAME)
+                            .addFormDataPart("branch_name", buildMeta.gitBranchName)
                             .addFormDataPart("matrix_sdk_version", Matrix.getSdkVersion())
                             .addFormDataPart("olm_version", olmVersion)
                             .addFormDataPart("device", Build.MODEL.trim())
                             .addFormDataPart("verbose_log", vectorPreferences.labAllowedExtendedLogging().toOnOff())
                             .addFormDataPart("multi_window", inMultiWindowMode.toOnOff())
                             .addFormDataPart(
-                                    "os", Build.VERSION.RELEASE + " (API " + Build.VERSION.SDK_INT + ") " +
+                                    "os", Build.VERSION.RELEASE + " (API " + sdkIntProvider.get() + ") " +
                                     Build.VERSION.INCREMENTAL + "-" + Build.VERSION.CODENAME
                             )
                             .addFormDataPart("locale", Locale.getDefault().toString())
@@ -299,7 +303,7 @@ class BugReporter @Inject constructor(
                                 }
                             }
 
-                    val buildNumber = BuildConfig.BUILD_NUMBER
+                    val buildNumber = buildMeta.buildNumber
                     if (buildNumber.isNotEmpty() && buildNumber != "0") {
                         builder.addFormDataPart("build_number", buildNumber)
                     }
@@ -339,9 +343,9 @@ class BugReporter @Inject constructor(
                     screenshot = null
 
                     // add some github labels
-                    builder.addFormDataPart("label", BuildConfig.VERSION_NAME)
-                    builder.addFormDataPart("label", BuildConfig.FLAVOR_DESCRIPTION)
-                    builder.addFormDataPart("label", BuildConfig.GIT_BRANCH_NAME)
+                    builder.addFormDataPart("label", buildMeta.versionName)
+                    builder.addFormDataPart("label", buildMeta.flavorDescription)
+                    builder.addFormDataPart("label", buildMeta.gitBranchName)
 
                     // Special for Element
                     builder.addFormDataPart("label", "[Element]")
diff --git a/vector/src/main/java/im/vector/app/features/raw/wellknown/CryptoConfig.kt b/vector/src/main/java/im/vector/app/features/raw/wellknown/CryptoConfig.kt
new file mode 100644
index 0000000000..130fa0078a
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/raw/wellknown/CryptoConfig.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.raw.wellknown
+
+import im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy
+
+data class CryptoConfig(
+        val fallbackKeySharingStrategy: OutboundSessionKeySharingStrategy
+)
diff --git a/vector/src/main/java/im/vector/app/features/raw/wellknown/ElementWellKnown.kt b/vector/src/main/java/im/vector/app/features/raw/wellknown/ElementWellKnown.kt
index 0df5f0e9cf..78329350d3 100644
--- a/vector/src/main/java/im/vector/app/features/raw/wellknown/ElementWellKnown.kt
+++ b/vector/src/main/java/im/vector/app/features/raw/wellknown/ElementWellKnown.kt
@@ -68,7 +68,7 @@ data class E2EWellKnownConfig(
         val secureBackupSetupMethods: List<String>? = null,
 
         /**
-         * Configuration for sharing keys strategy which should be used instead of [im.vector.app.BuildConfig.outboundSessionKeySharingStrategy].
+         * Configuration for sharing keys strategy which should be used instead of [im.vector.app.config.Config.KEY_SHARING_STRATEGY].
          * One of on_room_opening, on_typing or disabled.
          */
         @Json(name = "outbound_keys_pre_sharing_mode")
diff --git a/vector/src/main/java/im/vector/app/features/raw/wellknown/ElementWellKnownExt.kt b/vector/src/main/java/im/vector/app/features/raw/wellknown/ElementWellKnownExt.kt
index 73662613f7..28c7fecf0b 100644
--- a/vector/src/main/java/im/vector/app/features/raw/wellknown/ElementWellKnownExt.kt
+++ b/vector/src/main/java/im/vector/app/features/raw/wellknown/ElementWellKnownExt.kt
@@ -16,7 +16,6 @@
 
 package im.vector.app.features.raw.wellknown
 
-import im.vector.app.BuildConfig
 import im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
@@ -35,12 +34,12 @@ suspend fun RawService.getElementWellknown(sessionParams: SessionParams): Elemen
 
 fun ElementWellKnown.isE2EByDefault() = elementE2E?.e2eDefault ?: riotE2E?.e2eDefault ?: true
 
-fun ElementWellKnown?.getOutboundSessionKeySharingStrategyOrDefault(): OutboundSessionKeySharingStrategy {
+fun ElementWellKnown?.getOutboundSessionKeySharingStrategyOrDefault(fallback: OutboundSessionKeySharingStrategy): OutboundSessionKeySharingStrategy {
     return when (this?.elementE2E?.outboundsKeyPreSharingMode) {
         "on_room_opening" -> OutboundSessionKeySharingStrategy.WhenEnteringRoom
         "on_typing" -> OutboundSessionKeySharingStrategy.WhenTyping
         "disabled" -> OutboundSessionKeySharingStrategy.WhenSendingEvent
-        else -> BuildConfig.outboundSessionKeySharingStrategy
+        else -> fallback
     }
 }
 
diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorLocale.kt b/vector/src/main/java/im/vector/app/features/settings/VectorLocale.kt
index 326f20845f..4666d586d3 100644
--- a/vector/src/main/java/im/vector/app/features/settings/VectorLocale.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/VectorLocale.kt
@@ -19,9 +19,9 @@ package im.vector.app.features.settings
 import android.content.Context
 import android.content.res.Configuration
 import androidx.core.content.edit
-import im.vector.app.BuildConfig
 import im.vector.app.R
 import im.vector.app.core.di.DefaultSharedPreferences
+import im.vector.app.core.resources.BuildMeta
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.withContext
 import timber.log.Timber
@@ -53,12 +53,14 @@ object VectorLocale {
         private set
 
     private lateinit var context: Context
+    private lateinit var buildMeta: BuildMeta
 
     /**
      * Init this object.
      */
-    fun init(context: Context) {
+    fun init(context: Context, buildMeta: BuildMeta) {
         this.context = context
+        this.buildMeta = buildMeta
         val preferences = DefaultSharedPreferences.getInstance(context)
 
         if (preferences.contains(APPLICATION_LOCALE_LANGUAGE_KEY)) {
@@ -174,7 +176,7 @@ object VectorLocale {
                         .setScript(script)
                         .build()
             } catch (exception: IllformedLocaleException) {
-                if (BuildConfig.DEBUG) {
+                if (buildMeta.isDebug) {
                     throw exception
                 }
                 // Ignore this locale in production
diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt
index 3b202969e5..ac14bfc3c7 100755
--- a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt
@@ -23,9 +23,9 @@ import android.provider.MediaStore
 import androidx.annotation.BoolRes
 import androidx.core.content.edit
 import com.squareup.seismic.ShakeDetector
-import im.vector.app.BuildConfig
 import im.vector.app.R
 import im.vector.app.core.di.DefaultSharedPreferences
+import im.vector.app.core.resources.BuildMeta
 import im.vector.app.core.time.Clock
 import im.vector.app.features.disclaimer.SHARED_PREF_KEY
 import im.vector.app.features.home.ShortcutsHandler
@@ -38,6 +38,7 @@ import javax.inject.Inject
 class VectorPreferences @Inject constructor(
         private val context: Context,
         private val clock: Clock,
+        private val buildMeta: BuildMeta,
 ) {
 
     companion object {
@@ -364,7 +365,7 @@ class VectorPreferences @Inject constructor(
     }
 
     fun failFast(): Boolean {
-        return BuildConfig.DEBUG || (developerMode() && defaultPrefs.getBoolean(SETTINGS_DEVELOPER_MODE_FAIL_FAST_PREFERENCE_KEY, false))
+        return buildMeta.isDebug || (developerMode() && defaultPrefs.getBoolean(SETTINGS_DEVELOPER_MODE_FAIL_FAST_PREFERENCE_KEY, false))
     }
 
     fun didAskUserToEnableSessionPush(): Boolean {
diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsHelpAboutFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsHelpAboutFragment.kt
index 5844467a1f..df7baa7397 100644
--- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsHelpAboutFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsHelpAboutFragment.kt
@@ -18,10 +18,10 @@ package im.vector.app.features.settings
 
 import android.os.Bundle
 import androidx.preference.Preference
-import im.vector.app.BuildConfig
 import im.vector.app.R
 import im.vector.app.core.extensions.orEmpty
 import im.vector.app.core.preference.VectorPreference
+import im.vector.app.core.resources.BuildMeta
 import im.vector.app.core.utils.FirstThrottler
 import im.vector.app.core.utils.copyToClipboard
 import im.vector.app.core.utils.openAppSettingsPage
@@ -32,7 +32,8 @@ import org.matrix.android.sdk.api.Matrix
 import javax.inject.Inject
 
 class VectorSettingsHelpAboutFragment @Inject constructor(
-        private val versionProvider: VersionProvider
+        private val versionProvider: VersionProvider,
+        private val buildMeta: BuildMeta,
 ) : VectorSettingsBaseFragment() {
 
     override var titleRes = R.string.preference_root_help_about
@@ -66,9 +67,9 @@ class VectorSettingsHelpAboutFragment @Inject constructor(
         findPreference<VectorPreference>(VectorPreferences.SETTINGS_VERSION_PREFERENCE_KEY)!!.let {
             it.summary = buildString {
                 append(versionProvider.getVersion(longFormat = false, useBuildNumber = true))
-                if (BuildConfig.DEBUG) {
+                if (buildMeta.isDebug) {
                     append(" ")
-                    append(BuildConfig.GIT_BRANCH_NAME)
+                    append(buildMeta.gitBranchName)
                 }
             }
 
diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt
index f25ad0661a..ac8a47b81e 100644
--- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt
@@ -35,7 +35,6 @@ import androidx.recyclerview.widget.RecyclerView
 import com.airbnb.mvrx.fragmentViewModel
 import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import im.vector.app.R
-import im.vector.app.config.analyticsConfig
 import im.vector.app.core.di.ActiveSessionHolder
 import im.vector.app.core.dialogs.ExportKeysDialog
 import im.vector.app.core.extensions.queryExportKeys
@@ -51,6 +50,7 @@ import im.vector.app.core.utils.copyToClipboard
 import im.vector.app.core.utils.openFileSelection
 import im.vector.app.core.utils.toast
 import im.vector.app.databinding.DialogImportE2eKeysBinding
+import im.vector.app.features.analytics.AnalyticsConfig
 import im.vector.app.features.analytics.plan.MobileScreen
 import im.vector.app.features.analytics.ui.consent.AnalyticsConsentViewActions
 import im.vector.app.features.analytics.ui.consent.AnalyticsConsentViewModel
@@ -84,7 +84,8 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
         private val keysExporter: KeysExporter,
         private val keysImporter: KeysImporter,
         private val rawService: RawService,
-        private val navigator: Navigator
+        private val navigator: Navigator,
+        private val analyticsConfig: AnalyticsConfig,
 ) : VectorSettingsBaseFragment() {
 
     override var titleRes = R.string.settings_security_and_privacy
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationsTroubleshootFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationsTroubleshootFragment.kt
index 0eb22bf24d..8a3407b428 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationsTroubleshootFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationsTroubleshootFragment.kt
@@ -34,7 +34,7 @@ import im.vector.app.core.extensions.cleanup
 import im.vector.app.core.extensions.registerStartForActivityResult
 import im.vector.app.core.platform.VectorBaseFragment
 import im.vector.app.databinding.FragmentSettingsNotificationsTroubleshootBinding
-import im.vector.app.features.notifications.NotificationUtils
+import im.vector.app.features.notifications.NotificationActionIds
 import im.vector.app.features.rageshake.BugReporter
 import im.vector.app.features.settings.VectorSettingsFragmentInteractionListener
 import im.vector.app.features.settings.troubleshoot.NotificationTroubleshootTestManager
@@ -46,7 +46,8 @@ import javax.inject.Inject
 
 class VectorSettingsNotificationsTroubleshootFragment @Inject constructor(
         private val bugReporter: BugReporter,
-        private val testManagerFactory: NotificationTroubleshootTestManagerFactory
+        private val testManagerFactory: NotificationTroubleshootTestManagerFactory,
+        private val actionIds: NotificationActionIds,
 ) : VectorBaseFragment<FragmentSettingsNotificationsTroubleshootBinding>() {
 
     private var testManager: NotificationTroubleshootTestManager? = null
@@ -151,11 +152,11 @@ class VectorSettingsNotificationsTroubleshootFragment @Inject constructor(
 
         tryOrNull("Unable to register the receiver") {
             LocalBroadcastManager.getInstance(requireContext())
-                    .registerReceiver(broadcastReceiverPush, IntentFilter(NotificationUtils.PUSH_ACTION))
+                    .registerReceiver(broadcastReceiverPush, IntentFilter(actionIds.push))
         }
         tryOrNull("Unable to register the receiver") {
             LocalBroadcastManager.getInstance(requireContext())
-                    .registerReceiver(broadcastReceiverNotification, IntentFilter(NotificationUtils.DIAGNOSTIC_ACTION))
+                    .registerReceiver(broadcastReceiverNotification, IntentFilter(actionIds.diagnostic))
         }
     }
 
diff --git a/vector/src/main/java/im/vector/app/features/version/VersionProvider.kt b/vector/src/main/java/im/vector/app/features/version/VersionProvider.kt
index 96a7d917e5..4c8188dc8b 100644
--- a/vector/src/main/java/im/vector/app/features/version/VersionProvider.kt
+++ b/vector/src/main/java/im/vector/app/features/version/VersionProvider.kt
@@ -16,24 +16,27 @@
 
 package im.vector.app.features.version
 
-import im.vector.app.BuildConfig
+import im.vector.app.core.resources.BuildMeta
 import im.vector.app.core.resources.VersionCodeProvider
 import javax.inject.Inject
 
-class VersionProvider @Inject constructor(private val versionCodeProvider: VersionCodeProvider) {
+class VersionProvider @Inject constructor(
+        private val versionCodeProvider: VersionCodeProvider,
+        private val buildMeta: BuildMeta,
+) {
 
     fun getVersion(longFormat: Boolean, useBuildNumber: Boolean): String {
-        var result = "${BuildConfig.VERSION_NAME} [${versionCodeProvider.getVersionCode()}]"
+        var result = "${buildMeta.versionName} [${versionCodeProvider.getVersionCode()}]"
 
-        var flavor = BuildConfig.SHORT_FLAVOR_DESCRIPTION
+        var flavor = buildMeta.flavorShortDescription
 
         if (flavor.isNotBlank()) {
             flavor += "-"
         }
 
-        var gitVersion = BuildConfig.GIT_REVISION
-        val gitRevisionDate = BuildConfig.GIT_REVISION_DATE
-        val buildNumber = BuildConfig.BUILD_NUMBER
+        var gitVersion = buildMeta.gitRevision
+        val gitRevisionDate = buildMeta.gitRevisionDate
+        val buildNumber = buildMeta.buildNumber
 
         var useLongFormat = longFormat
 
diff --git a/vector/src/test/java/im/vector/app/features/location/LocationTrackerTest.kt b/vector/src/test/java/im/vector/app/features/location/LocationTrackerTest.kt
index 454a73cd70..54f7412238 100644
--- a/vector/src/test/java/im/vector/app/features/location/LocationTrackerTest.kt
+++ b/vector/src/test/java/im/vector/app/features/location/LocationTrackerTest.kt
@@ -23,6 +23,7 @@ import im.vector.app.features.session.coroutineScope
 import im.vector.app.test.fakes.FakeActiveSessionHolder
 import im.vector.app.test.fakes.FakeContext
 import im.vector.app.test.fakes.FakeLocationManager
+import im.vector.app.test.fixtures.aBuildMeta
 import im.vector.app.test.test
 import io.mockk.every
 import io.mockk.just
@@ -56,7 +57,7 @@ class LocationTrackerTest {
     @Before
     fun setUp() {
         mockkStatic("im.vector.app.features.session.SessionCoroutineScopesKt")
-        locationTracker = LocationTracker(fakeContext.instance, fakeActiveSessionHolder.instance)
+        locationTracker = LocationTracker(fakeContext.instance, fakeActiveSessionHolder.instance, aBuildMeta())
         fakeLocationManager.givenRemoveUpdates(locationTracker)
     }
 
diff --git a/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt b/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt
index a9bbb3eb07..61d3101b64 100644
--- a/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt
+++ b/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt
@@ -17,6 +17,7 @@
 package im.vector.app.features.onboarding
 
 import android.net.Uri
+import android.os.Build
 import com.airbnb.mvrx.test.MvRxTestRule
 import im.vector.app.R
 import im.vector.app.features.login.LoginConfig
@@ -24,6 +25,7 @@ import im.vector.app.features.login.LoginMode
 import im.vector.app.features.login.ReAuthHelper
 import im.vector.app.features.login.SignMode
 import im.vector.app.features.onboarding.StartAuthenticationFlowUseCase.StartAuthenticationResult
+import im.vector.app.test.TestBuildVersionSdkIntProvider
 import im.vector.app.test.fakes.FakeActiveSessionHolder
 import im.vector.app.test.fakes.FakeAnalyticsTracker
 import im.vector.app.test.fakes.FakeAuthenticationService
@@ -43,7 +45,6 @@ import im.vector.app.test.fakes.FakeVectorFeatures
 import im.vector.app.test.fakes.FakeVectorOverrides
 import im.vector.app.test.fakes.toTestString
 import im.vector.app.test.fixtures.a401ServerError
-import im.vector.app.test.fixtures.aBuildMeta
 import im.vector.app.test.fixtures.aHomeServerCapabilities
 import im.vector.app.test.test
 import kotlinx.coroutines.test.runTest
@@ -720,7 +721,7 @@ class OnboardingViewModelTest {
                 fakeStartAuthenticationFlowUseCase.instance,
                 FakeVectorOverrides(),
                 fakeRegistrationActionHandler.instance,
-                aBuildMeta(),
+                TestBuildVersionSdkIntProvider().also { it.value = Build.VERSION_CODES.O },
         ).also {
             viewModel = it
             initialState = state
diff --git a/vector/src/test/java/im/vector/app/test/fixtures/AnalyticsConfigFixture.kt b/vector/src/test/java/im/vector/app/test/fixtures/AnalyticsConfigFixture.kt
index 5fbcdd98d1..ea1769ecb2 100644
--- a/vector/src/test/java/im/vector/app/test/fixtures/AnalyticsConfigFixture.kt
+++ b/vector/src/test/java/im/vector/app/test/fixtures/AnalyticsConfigFixture.kt
@@ -24,10 +24,5 @@ object AnalyticsConfigFixture {
             postHogHost: String = "http://posthog.url",
             postHogApiKey: String = "api-key",
             policyLink: String = "http://policy.link"
-    ) = object : AnalyticsConfig {
-        override val isEnabled: Boolean = isEnabled
-        override val postHogHost = postHogHost
-        override val postHogApiKey = postHogApiKey
-        override val policyLink = policyLink
-    }
+    ) = AnalyticsConfig(isEnabled, postHogHost, postHogApiKey, policyLink)
 }
diff --git a/vector/src/test/java/im/vector/app/test/fixtures/BuildMetaFixture.kt b/vector/src/test/java/im/vector/app/test/fixtures/BuildMetaFixture.kt
index b0e6b1dd51..4f4649106d 100644
--- a/vector/src/test/java/im/vector/app/test/fixtures/BuildMetaFixture.kt
+++ b/vector/src/test/java/im/vector/app/test/fixtures/BuildMetaFixture.kt
@@ -16,7 +16,17 @@
 
 package im.vector.app.test.fixtures
 
-import android.os.Build
 import im.vector.app.core.resources.BuildMeta
 
-fun aBuildMeta() = BuildMeta(Build.VERSION_CODES.O)
+fun aBuildMeta() = BuildMeta(
+        isDebug = false,
+        applicationId = "im.vector",
+        lowPrivacyLoggingEnabled = false,
+        versionName = "app-version-name",
+        gitRevision = "abcdef",
+        gitRevisionDate = "01-01-01",
+        gitBranchName = "a-branch-name",
+        buildNumber = "100",
+        flavorDescription = "Gplay",
+        flavorShortDescription = "",
+)