Merge pull request #6517 from vector-im/feature/adm/build-config
Avoiding direct `BuildConfig` usage
This commit is contained in:
commit
8aaf185a8e
1
changelog.d/6406.misc
Normal file
1
changelog.d/6406.misc
Normal file
@ -0,0 +1 @@
|
|||||||
|
[Modularization] Provides abstraction to avoids direct usages of BuildConfig
|
@ -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
|
||||||
|
}
|
@ -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.
|
* - 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 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
|
||||||
}
|
}
|
||||||
|
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -16,12 +16,20 @@
|
|||||||
|
|
||||||
package im.vector.app.config
|
package im.vector.app.config
|
||||||
|
|
||||||
import im.vector.app.BuildConfig
|
enum class KeySharingStrategy {
|
||||||
import im.vector.app.features.analytics.AnalyticsConfig
|
/**
|
||||||
|
* 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"
|
* Keys will be sent for the first time when the timeline displayed.
|
||||||
override val postHogHost = "https://posthog.element.dev"
|
*/
|
||||||
override val postHogApiKey = "phc_VtA1L35nw3aeAtHIx1ayrGdzGkss7k1xINeXcoIQzXN"
|
WhenEnteringRoom,
|
||||||
override val policyLink = "https://element.io/cookie-policy"
|
|
||||||
|
/**
|
||||||
|
* Keys will be sent for the first time when a typing started.
|
||||||
|
*/
|
||||||
|
WhenTyping
|
||||||
}
|
}
|
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -16,17 +16,8 @@
|
|||||||
|
|
||||||
package im.vector.app.config
|
package im.vector.app.config
|
||||||
|
|
||||||
import im.vector.app.BuildConfig
|
enum class OnboardingVariant {
|
||||||
import im.vector.app.features.analytics.AnalyticsConfig
|
LEGACY,
|
||||||
|
LOGIN_2,
|
||||||
private val allowedPackageList = listOf(
|
FTUE_AUTH
|
||||||
"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"
|
|
||||||
}
|
}
|
@ -156,19 +156,6 @@ android {
|
|||||||
buildConfigField "String", "GIT_BRANCH_NAME", "\"${gitBranchName()}\""
|
buildConfigField "String", "GIT_BRANCH_NAME", "\"${gitBranchName()}\""
|
||||||
buildConfigField "String", "BUILD_NUMBER", "\"${buildNumber}\""
|
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"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
// Keep abiFilter for the universalApk
|
// Keep abiFilter for the universalApk
|
||||||
@ -250,10 +237,6 @@ android {
|
|||||||
resValue "string", "app_name", "Element dbg"
|
resValue "string", "app_name", "Element dbg"
|
||||||
resValue "color", "launcher_background", "#0DBD8B"
|
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
|
signingConfig signingConfigs.debug
|
||||||
|
|
||||||
if (project.hasProperty("coverage")) {
|
if (project.hasProperty("coverage")) {
|
||||||
@ -265,10 +248,6 @@ android {
|
|||||||
resValue "string", "app_name", "Element"
|
resValue "string", "app_name", "Element"
|
||||||
resValue "color", "launcher_background", "#0DBD8B"
|
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 {
|
postprocessing {
|
||||||
removeUnusedCode true
|
removeUnusedCode true
|
||||||
removeUnusedResources true
|
removeUnusedResources true
|
||||||
@ -329,7 +308,6 @@ android {
|
|||||||
versionName "${versionMajor}.${versionMinor}.${versionPatch}${getGplayVersionSuffix()}"
|
versionName "${versionMajor}.${versionMinor}.${versionPatch}${getGplayVersionSuffix()}"
|
||||||
|
|
||||||
resValue "bool", "isGplay", "true"
|
resValue "bool", "isGplay", "true"
|
||||||
buildConfigField "boolean", "ALLOW_FCM_USE", "true"
|
|
||||||
buildConfigField "String", "SHORT_FLAVOR_DESCRIPTION", "\"G\""
|
buildConfigField "String", "SHORT_FLAVOR_DESCRIPTION", "\"G\""
|
||||||
buildConfigField "String", "FLAVOR_DESCRIPTION", "\"GooglePlay\""
|
buildConfigField "String", "FLAVOR_DESCRIPTION", "\"GooglePlay\""
|
||||||
}
|
}
|
||||||
@ -340,7 +318,6 @@ android {
|
|||||||
versionName "${versionMajor}.${versionMinor}.${versionPatch}${getFdroidVersionSuffix()}"
|
versionName "${versionMajor}.${versionMinor}.${versionPatch}${getFdroidVersionSuffix()}"
|
||||||
|
|
||||||
resValue "bool", "isGplay", "false"
|
resValue "bool", "isGplay", "false"
|
||||||
buildConfigField "boolean", "ALLOW_FCM_USE", "false"
|
|
||||||
buildConfigField "String", "SHORT_FLAVOR_DESCRIPTION", "\"F\""
|
buildConfigField "String", "SHORT_FLAVOR_DESCRIPTION", "\"F\""
|
||||||
buildConfigField "String", "FLAVOR_DESCRIPTION", "\"FDroid\""
|
buildConfigField "String", "FLAVOR_DESCRIPTION", "\"FDroid\""
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,11 @@ class DebugFeaturesStateFactory @Inject constructor(
|
|||||||
key = DebugFeatureKeys.allowExternalUnifiedPushDistributors,
|
key = DebugFeatureKeys.allowExternalUnifiedPushDistributors,
|
||||||
factory = VectorFeatures::allowExternalUnifiedPushDistributors
|
factory = VectorFeatures::allowExternalUnifiedPushDistributors
|
||||||
),
|
),
|
||||||
|
createBooleanFeature(
|
||||||
|
label = "Enable Live Location Sharing",
|
||||||
|
key = DebugFeatureKeys.liveLocationSharing,
|
||||||
|
factory = VectorFeatures::isLocationSharingEnabled
|
||||||
|
),
|
||||||
createBooleanFeature(
|
createBooleanFeature(
|
||||||
label = "Force usage of OpusEncoder library",
|
label = "Force usage of OpusEncoder library",
|
||||||
key = DebugFeatureKeys.forceUsageOfOpusEncoder,
|
key = DebugFeatureKeys.forceUsageOfOpusEncoder,
|
||||||
|
@ -24,6 +24,7 @@ import androidx.datastore.preferences.core.booleanPreferencesKey
|
|||||||
import androidx.datastore.preferences.core.edit
|
import androidx.datastore.preferences.core.edit
|
||||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||||
import androidx.datastore.preferences.preferencesDataStore
|
import androidx.datastore.preferences.preferencesDataStore
|
||||||
|
import im.vector.app.config.OnboardingVariant
|
||||||
import im.vector.app.features.DefaultVectorFeatures
|
import im.vector.app.features.DefaultVectorFeatures
|
||||||
import im.vector.app.features.VectorFeatures
|
import im.vector.app.features.VectorFeatures
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
@ -39,8 +40,8 @@ class DebugVectorFeatures(
|
|||||||
|
|
||||||
private val dataStore = context.dataStore
|
private val dataStore = context.dataStore
|
||||||
|
|
||||||
override fun onboardingVariant(): VectorFeatures.OnboardingVariant {
|
override fun onboardingVariant(): OnboardingVariant {
|
||||||
return readPreferences().getEnum<VectorFeatures.OnboardingVariant>() ?: vectorFeatures.onboardingVariant()
|
return readPreferences().getEnum<OnboardingVariant>() ?: vectorFeatures.onboardingVariant()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isOnboardingAlreadyHaveAccountSplashEnabled(): Boolean = read(DebugFeatureKeys.onboardingAlreadyHaveAnAccount)
|
override fun isOnboardingAlreadyHaveAccountSplashEnabled(): Boolean = read(DebugFeatureKeys.onboardingAlreadyHaveAnAccount)
|
||||||
@ -66,6 +67,9 @@ class DebugVectorFeatures(
|
|||||||
override fun isScreenSharingEnabled(): Boolean = read(DebugFeatureKeys.screenSharing)
|
override fun isScreenSharingEnabled(): Boolean = read(DebugFeatureKeys.screenSharing)
|
||||||
?: vectorFeatures.isScreenSharingEnabled()
|
?: vectorFeatures.isScreenSharingEnabled()
|
||||||
|
|
||||||
|
override fun isLocationSharingEnabled(): Boolean = read(DebugFeatureKeys.liveLocationSharing)
|
||||||
|
?: vectorFeatures.isLocationSharingEnabled()
|
||||||
|
|
||||||
override fun forceUsageOfOpusEncoder(): Boolean = read(DebugFeatureKeys.forceUsageOfOpusEncoder)
|
override fun forceUsageOfOpusEncoder(): Boolean = read(DebugFeatureKeys.forceUsageOfOpusEncoder)
|
||||||
?: vectorFeatures.forceUsageOfOpusEncoder()
|
?: vectorFeatures.forceUsageOfOpusEncoder()
|
||||||
|
|
||||||
|
@ -40,7 +40,9 @@ import com.mapbox.mapboxsdk.Mapbox
|
|||||||
import com.vanniktech.emoji.EmojiManager
|
import com.vanniktech.emoji.EmojiManager
|
||||||
import com.vanniktech.emoji.google.GoogleEmojiProvider
|
import com.vanniktech.emoji.google.GoogleEmojiProvider
|
||||||
import dagger.hilt.android.HiltAndroidApp
|
import dagger.hilt.android.HiltAndroidApp
|
||||||
|
import im.vector.app.config.Config
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
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.analytics.VectorAnalytics
|
||||||
import im.vector.app.features.call.webrtc.WebRtcCallManager
|
import im.vector.app.features.call.webrtc.WebRtcCallManager
|
||||||
import im.vector.app.features.configuration.VectorConfiguration
|
import im.vector.app.features.configuration.VectorConfiguration
|
||||||
@ -99,6 +101,7 @@ class VectorApplication :
|
|||||||
@Inject lateinit var flipperProxy: FlipperProxy
|
@Inject lateinit var flipperProxy: FlipperProxy
|
||||||
@Inject lateinit var matrix: Matrix
|
@Inject lateinit var matrix: Matrix
|
||||||
@Inject lateinit var fcmHelper: FcmHelper
|
@Inject lateinit var fcmHelper: FcmHelper
|
||||||
|
@Inject lateinit var buildMeta: BuildMeta
|
||||||
|
|
||||||
// font thread handler
|
// font thread handler
|
||||||
private var fontThreadHandler: Handler? = null
|
private var fontThreadHandler: Handler? = null
|
||||||
@ -127,12 +130,12 @@ class VectorApplication :
|
|||||||
.filterIsInstance(JitsiMeetDefaultLogHandler::class.java)
|
.filterIsInstance(JitsiMeetDefaultLogHandler::class.java)
|
||||||
.forEach { Timber.uproot(it) }
|
.forEach { Timber.uproot(it) }
|
||||||
|
|
||||||
if (BuildConfig.DEBUG) {
|
if (buildMeta.isDebug) {
|
||||||
Timber.plant(Timber.DebugTree())
|
Timber.plant(Timber.DebugTree())
|
||||||
}
|
}
|
||||||
Timber.plant(vectorFileLogger)
|
Timber.plant(vectorFileLogger)
|
||||||
|
|
||||||
if (BuildConfig.DEBUG) {
|
if (buildMeta.isDebug) {
|
||||||
Stetho.initializeWithDefaults(this)
|
Stetho.initializeWithDefaults(this)
|
||||||
}
|
}
|
||||||
logInfo()
|
logInfo()
|
||||||
@ -148,7 +151,7 @@ class VectorApplication :
|
|||||||
R.array.com_google_android_gms_fonts_certs
|
R.array.com_google_android_gms_fonts_certs
|
||||||
)
|
)
|
||||||
FontsContractCompat.requestFont(this, fontRequest, emojiCompatFontProvider, getFontThreadHandler())
|
FontsContractCompat.requestFont(this, fontRequest, emojiCompatFontProvider, getFontThreadHandler())
|
||||||
VectorLocale.init(this)
|
VectorLocale.init(this, buildMeta)
|
||||||
ThemeUtils.init(this)
|
ThemeUtils.init(this)
|
||||||
vectorConfiguration.applyToApplicationContext()
|
vectorConfiguration.applyToApplicationContext()
|
||||||
|
|
||||||
@ -196,7 +199,7 @@ class VectorApplication :
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun enableStrictModeIfNeeded() {
|
private fun enableStrictModeIfNeeded() {
|
||||||
if (BuildConfig.ENABLE_STRICT_MODE_LOGS) {
|
if (Config.ENABLE_STRICT_MODE_LOGS) {
|
||||||
StrictMode.setThreadPolicy(
|
StrictMode.setThreadPolicy(
|
||||||
StrictMode.ThreadPolicy.Builder()
|
StrictMode.ThreadPolicy.Builder()
|
||||||
.detectAll()
|
.detectAll()
|
||||||
|
@ -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
|
||||||
|
)
|
||||||
|
}
|
@ -33,7 +33,7 @@ import im.vector.app.EmojiCompatWrapper
|
|||||||
import im.vector.app.EmojiSpanify
|
import im.vector.app.EmojiSpanify
|
||||||
import im.vector.app.SpaceStateHandler
|
import im.vector.app.SpaceStateHandler
|
||||||
import im.vector.app.SpaceStateHandlerImpl
|
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.dispatchers.CoroutineDispatchers
|
||||||
import im.vector.app.core.error.DefaultErrorFormatter
|
import im.vector.app.core.error.DefaultErrorFormatter
|
||||||
import im.vector.app.core.error.ErrorFormatter
|
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.time.DefaultClock
|
||||||
import im.vector.app.core.utils.AndroidSystemSettingsProvider
|
import im.vector.app.core.utils.AndroidSystemSettingsProvider
|
||||||
import im.vector.app.core.utils.SystemSettingsProvider
|
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.AnalyticsTracker
|
||||||
import im.vector.app.features.analytics.VectorAnalytics
|
import im.vector.app.features.analytics.VectorAnalytics
|
||||||
import im.vector.app.features.analytics.impl.DefaultVectorAnalytics
|
import im.vector.app.features.analytics.impl.DefaultVectorAnalytics
|
||||||
@ -205,17 +204,23 @@ object VectorStaticModule {
|
|||||||
return GlobalScope
|
return GlobalScope
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
fun providesAnalyticsConfig(): AnalyticsConfig {
|
|
||||||
return analyticsConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
fun providesPhoneNumberUtil(): PhoneNumberUtil = PhoneNumberUtil.getInstance()
|
fun providesPhoneNumberUtil(): PhoneNumberUtil = PhoneNumberUtil.getInstance()
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@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
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
|
@ -37,7 +37,7 @@ import androidx.datastore.preferences.core.Preferences
|
|||||||
import dagger.hilt.EntryPoints
|
import dagger.hilt.EntryPoints
|
||||||
import im.vector.app.core.datastore.dataStoreProvider
|
import im.vector.app.core.datastore.dataStoreProvider
|
||||||
import im.vector.app.core.di.SingletonEntryPoint
|
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 java.io.OutputStream
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
@ -93,9 +93,9 @@ fun Context.safeOpenOutputStream(uri: Uri): OutputStream? {
|
|||||||
*/
|
*/
|
||||||
@Suppress("deprecation")
|
@Suppress("deprecation")
|
||||||
@SuppressLint("NewApi") // false positive
|
@SuppressLint("NewApi") // false positive
|
||||||
fun Context.inferNoConnectivity(buildMeta: BuildMeta): Boolean {
|
fun Context.inferNoConnectivity(sdkIntProvider: BuildVersionSdkIntProvider): Boolean {
|
||||||
val connectivityManager = getSystemService<ConnectivityManager>()!!
|
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)
|
val networkCapabilities = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
|
||||||
when {
|
when {
|
||||||
networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == true -> false
|
networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == true -> false
|
||||||
|
@ -54,7 +54,6 @@ import com.google.android.material.color.MaterialColors
|
|||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import dagger.hilt.android.EntryPointAccessors
|
import dagger.hilt.android.EntryPointAccessors
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
import im.vector.app.core.di.ActivityEntryPoint
|
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.setTextOrHide
|
||||||
import im.vector.app.core.extensions.singletonEntryPoint
|
import im.vector.app.core.extensions.singletonEntryPoint
|
||||||
import im.vector.app.core.extensions.toMvRxBundle
|
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.AndroidSystemSettingsProvider
|
||||||
import im.vector.app.core.utils.ToolbarConfig
|
import im.vector.app.core.utils.ToolbarConfig
|
||||||
import im.vector.app.core.utils.toast
|
import im.vector.app.core.utils.toast
|
||||||
@ -157,11 +157,9 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), Maver
|
|||||||
protected lateinit var bugReporter: BugReporter
|
protected lateinit var bugReporter: BugReporter
|
||||||
private lateinit var pinLocker: PinLocker
|
private lateinit var pinLocker: PinLocker
|
||||||
|
|
||||||
@Inject
|
@Inject lateinit var rageShake: RageShake
|
||||||
lateinit var rageShake: RageShake
|
@Inject lateinit var buildMeta: BuildMeta
|
||||||
|
@Inject lateinit var fontScalePreferences: FontScalePreferences
|
||||||
@Inject
|
|
||||||
lateinit var fontScalePreferences: FontScalePreferences
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var vectorFeatures: VectorFeatures
|
lateinit var vectorFeatures: VectorFeatures
|
||||||
@ -422,7 +420,7 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), Maver
|
|||||||
}
|
}
|
||||||
DebugReceiver
|
DebugReceiver
|
||||||
.getIntentFilter(this)
|
.getIntentFilter(this)
|
||||||
.takeIf { BuildConfig.DEBUG }
|
.takeIf { buildMeta.isDebug }
|
||||||
?.let {
|
?.let {
|
||||||
debugReceiver = DebugReceiver()
|
debugReceiver = DebugReceiver()
|
||||||
registerReceiver(debugReceiver, it)
|
registerReceiver(debugReceiver, it)
|
||||||
|
@ -25,14 +25,14 @@ import androidx.lifecycle.Lifecycle
|
|||||||
import androidx.lifecycle.ProcessLifecycleOwner
|
import androidx.lifecycle.ProcessLifecycleOwner
|
||||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
import im.vector.app.core.network.WifiDetector
|
import im.vector.app.core.network.WifiDetector
|
||||||
import im.vector.app.core.pushers.model.PushData
|
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.core.services.GuardServiceStarter
|
||||||
import im.vector.app.features.notifications.NotifiableEventResolver
|
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.NotificationDrawerManager
|
||||||
import im.vector.app.features.notifications.NotificationUtils
|
|
||||||
import im.vector.app.features.settings.BackgroundSyncMode
|
import im.vector.app.features.settings.BackgroundSyncMode
|
||||||
import im.vector.app.features.settings.VectorDataStore
|
import im.vector.app.features.settings.VectorDataStore
|
||||||
import im.vector.app.features.settings.VectorPreferences
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
@ -68,6 +68,8 @@ class VectorMessagingReceiver : MessagingReceiver() {
|
|||||||
@Inject lateinit var unifiedPushHelper: UnifiedPushHelper
|
@Inject lateinit var unifiedPushHelper: UnifiedPushHelper
|
||||||
@Inject lateinit var unifiedPushStore: UnifiedPushStore
|
@Inject lateinit var unifiedPushStore: UnifiedPushStore
|
||||||
@Inject lateinit var pushParser: PushParser
|
@Inject lateinit var pushParser: PushParser
|
||||||
|
@Inject lateinit var actionIds: NotificationActionIds
|
||||||
|
@Inject lateinit var buildMeta: BuildMeta
|
||||||
|
|
||||||
private val coroutineScope = CoroutineScope(SupervisorJob())
|
private val coroutineScope = CoroutineScope(SupervisorJob())
|
||||||
|
|
||||||
@ -87,7 +89,7 @@ class VectorMessagingReceiver : MessagingReceiver() {
|
|||||||
Timber.tag(loggerTag.value).d("## onMessage() received")
|
Timber.tag(loggerTag.value).d("## onMessage() received")
|
||||||
|
|
||||||
val sMessage = String(message)
|
val sMessage = String(message)
|
||||||
if (BuildConfig.LOW_PRIVACY_LOG_ENABLE) {
|
if (buildMeta.lowPrivacyLoggingEnabled) {
|
||||||
Timber.tag(loggerTag.value).d("## onMessage() $sMessage")
|
Timber.tag(loggerTag.value).d("## onMessage() $sMessage")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +102,7 @@ class VectorMessagingReceiver : MessagingReceiver() {
|
|||||||
|
|
||||||
// Diagnostic Push
|
// Diagnostic Push
|
||||||
if (pushData.eventId == PushersManager.TEST_EVENT_ID) {
|
if (pushData.eventId == PushersManager.TEST_EVENT_ID) {
|
||||||
val intent = Intent(NotificationUtils.PUSH_ACTION)
|
val intent = Intent(actionIds.push)
|
||||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent)
|
LocalBroadcastManager.getInstance(context).sendBroadcast(intent)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -171,7 +173,7 @@ class VectorMessagingReceiver : MessagingReceiver() {
|
|||||||
*/
|
*/
|
||||||
private suspend fun onMessageReceivedInternal(pushData: PushData) {
|
private suspend fun onMessageReceivedInternal(pushData: PushData) {
|
||||||
try {
|
try {
|
||||||
if (BuildConfig.LOW_PRIVACY_LOG_ENABLE) {
|
if (buildMeta.lowPrivacyLoggingEnabled) {
|
||||||
Timber.tag(loggerTag.value).d("## onMessageReceivedInternal() : $pushData")
|
Timber.tag(loggerTag.value).d("## onMessageReceivedInternal() : $pushData")
|
||||||
} else {
|
} else {
|
||||||
Timber.tag(loggerTag.value).d("## onMessageReceivedInternal()")
|
Timber.tag(loggerTag.value).d("## onMessageReceivedInternal()")
|
||||||
|
@ -16,8 +16,15 @@
|
|||||||
|
|
||||||
package im.vector.app.core.resources
|
package im.vector.app.core.resources
|
||||||
|
|
||||||
import android.os.Build
|
|
||||||
|
|
||||||
data class BuildMeta(
|
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,
|
||||||
)
|
)
|
||||||
|
@ -39,7 +39,6 @@ import androidx.browser.customtabs.CustomTabsSession
|
|||||||
import androidx.core.app.ShareCompat
|
import androidx.core.app.ShareCompat
|
||||||
import androidx.core.content.FileProvider
|
import androidx.core.content.FileProvider
|
||||||
import androidx.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.features.notifications.NotificationUtils
|
import im.vector.app.features.notifications.NotificationUtils
|
||||||
import im.vector.app.features.themes.ThemeUtils
|
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) {
|
fun openMedia(activity: Activity, savedMediaPath: String, mimeType: String) {
|
||||||
val file = File(savedMediaPath)
|
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 {
|
val intent = Intent(Intent.ACTION_VIEW).apply {
|
||||||
setDataAndType(uri, mimeType)
|
setDataAndType(uri, mimeType)
|
||||||
@ -214,7 +213,7 @@ fun openLocation(activity: Activity, latitude: Double, longitude: Double) {
|
|||||||
|
|
||||||
fun shareMedia(context: Context, file: File, mediaMimeType: String?) {
|
fun shareMedia(context: Context, file: File, mediaMimeType: String?) {
|
||||||
val mediaUri = try {
|
val mediaUri = try {
|
||||||
FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".fileProvider", file)
|
FileProvider.getUriForFile(context, context.packageName + ".fileProvider", file)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Timber.e(e, "onMediaAction Selected File cannot be shared")
|
Timber.e(e, "onMediaAction Selected File cannot be shared")
|
||||||
return
|
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.
|
* 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 {
|
try {
|
||||||
activity.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=$appId")))
|
activity.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=$appId")))
|
||||||
} catch (activityNotFoundException: ActivityNotFoundException) {
|
} catch (activityNotFoundException: ActivityNotFoundException) {
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
package im.vector.app.features
|
package im.vector.app.features
|
||||||
|
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.config.Config
|
import im.vector.app.config.Config
|
||||||
|
import im.vector.app.config.OnboardingVariant
|
||||||
|
|
||||||
interface VectorFeatures {
|
interface VectorFeatures {
|
||||||
|
|
||||||
@ -30,19 +30,14 @@ interface VectorFeatures {
|
|||||||
fun isOnboardingCombinedLoginEnabled(): Boolean
|
fun isOnboardingCombinedLoginEnabled(): Boolean
|
||||||
fun allowExternalUnifiedPushDistributors(): Boolean
|
fun allowExternalUnifiedPushDistributors(): Boolean
|
||||||
fun isScreenSharingEnabled(): Boolean
|
fun isScreenSharingEnabled(): Boolean
|
||||||
|
fun isLocationSharingEnabled(): Boolean
|
||||||
fun forceUsageOfOpusEncoder(): Boolean
|
fun forceUsageOfOpusEncoder(): Boolean
|
||||||
fun shouldStartDmOnFirstMessage(): Boolean
|
fun shouldStartDmOnFirstMessage(): Boolean
|
||||||
fun isNewAppLayoutEnabled(): Boolean
|
fun isNewAppLayoutEnabled(): Boolean
|
||||||
|
|
||||||
enum class OnboardingVariant {
|
|
||||||
LEGACY,
|
|
||||||
LOGIN_2,
|
|
||||||
FTUE_AUTH
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class DefaultVectorFeatures : VectorFeatures {
|
class DefaultVectorFeatures : VectorFeatures {
|
||||||
override fun onboardingVariant(): VectorFeatures.OnboardingVariant = BuildConfig.ONBOARDING_VARIANT
|
override fun onboardingVariant() = Config.ONBOARDING_VARIANT
|
||||||
override fun isOnboardingAlreadyHaveAccountSplashEnabled() = true
|
override fun isOnboardingAlreadyHaveAccountSplashEnabled() = true
|
||||||
override fun isOnboardingSplashCarouselEnabled() = true
|
override fun isOnboardingSplashCarouselEnabled() = true
|
||||||
override fun isOnboardingUseCaseEnabled() = true
|
override fun isOnboardingUseCaseEnabled() = true
|
||||||
@ -51,6 +46,7 @@ class DefaultVectorFeatures : VectorFeatures {
|
|||||||
override fun isOnboardingCombinedLoginEnabled() = true
|
override fun isOnboardingCombinedLoginEnabled() = true
|
||||||
override fun allowExternalUnifiedPushDistributors(): Boolean = Config.ALLOW_EXTERNAL_UNIFIED_PUSH_DISTRIBUTORS
|
override fun allowExternalUnifiedPushDistributors(): Boolean = Config.ALLOW_EXTERNAL_UNIFIED_PUSH_DISTRIBUTORS
|
||||||
override fun isScreenSharingEnabled(): Boolean = true
|
override fun isScreenSharingEnabled(): Boolean = true
|
||||||
|
override fun isLocationSharingEnabled() = Config.ENABLE_LOCATION_SHARING
|
||||||
override fun forceUsageOfOpusEncoder(): Boolean = false
|
override fun forceUsageOfOpusEncoder(): Boolean = false
|
||||||
override fun shouldStartDmOnFirstMessage(): Boolean = false
|
override fun shouldStartDmOnFirstMessage(): Boolean = false
|
||||||
override fun isNewAppLayoutEnabled(): Boolean = false
|
override fun isNewAppLayoutEnabled(): Boolean = false
|
||||||
|
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -16,9 +16,9 @@
|
|||||||
|
|
||||||
package im.vector.app.features.analytics
|
package im.vector.app.features.analytics
|
||||||
|
|
||||||
interface AnalyticsConfig {
|
data class AnalyticsConfig(
|
||||||
val isEnabled: Boolean
|
val isEnabled: Boolean,
|
||||||
val postHogHost: String
|
val postHogHost: String,
|
||||||
val postHogApiKey: String
|
val postHogApiKey: String,
|
||||||
val policyLink: String
|
val policyLink: String,
|
||||||
}
|
)
|
||||||
|
@ -18,11 +18,15 @@ package im.vector.app.features.analytics.impl
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.posthog.android.PostHog
|
import com.posthog.android.PostHog
|
||||||
import im.vector.app.BuildConfig
|
import im.vector.app.core.resources.BuildMeta
|
||||||
import im.vector.app.config.analyticsConfig
|
import im.vector.app.features.analytics.AnalyticsConfig
|
||||||
import javax.inject.Inject
|
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 {
|
fun createPosthog(): PostHog {
|
||||||
return PostHog.Builder(context, analyticsConfig.postHogApiKey, analyticsConfig.postHogHost)
|
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 {
|
private fun getLogLevel(): PostHog.LogLevel {
|
||||||
return if (BuildConfig.DEBUG) {
|
return if (buildMeta.isDebug) {
|
||||||
PostHog.LogLevel.DEBUG
|
PostHog.LogLevel.DEBUG
|
||||||
} else {
|
} else {
|
||||||
PostHog.LogLevel.INFO
|
PostHog.LogLevel.INFO
|
||||||
|
@ -22,17 +22,17 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import com.airbnb.mvrx.activityViewModel
|
import com.airbnb.mvrx.activityViewModel
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.config.analyticsConfig
|
|
||||||
import im.vector.app.core.extensions.setTextWithColoredPart
|
import im.vector.app.core.extensions.setTextWithColoredPart
|
||||||
import im.vector.app.core.platform.OnBackPressed
|
import im.vector.app.core.platform.OnBackPressed
|
||||||
import im.vector.app.core.platform.VectorBaseFragment
|
import im.vector.app.core.platform.VectorBaseFragment
|
||||||
import im.vector.app.core.utils.openUrlInChromeCustomTab
|
import im.vector.app.core.utils.openUrlInChromeCustomTab
|
||||||
import im.vector.app.databinding.FragmentAnalyticsOptinBinding
|
import im.vector.app.databinding.FragmentAnalyticsOptinBinding
|
||||||
|
import im.vector.app.features.analytics.AnalyticsConfig
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class AnalyticsOptInFragment @Inject constructor() :
|
class AnalyticsOptInFragment @Inject constructor(
|
||||||
VectorBaseFragment<FragmentAnalyticsOptinBinding>(),
|
private val analyticsConfig: AnalyticsConfig,
|
||||||
OnBackPressed {
|
) : VectorBaseFragment<FragmentAnalyticsOptinBinding>(), OnBackPressed {
|
||||||
|
|
||||||
// Share the view model with the Activity so that the Activity
|
// Share the view model with the Activity so that the Activity
|
||||||
// can decide what to do when the data has been saved
|
// can decide what to do when the data has been saved
|
||||||
|
@ -23,9 +23,9 @@ import android.os.Bundle
|
|||||||
import androidx.activity.result.ActivityResultLauncher
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
import im.vector.app.core.dialogs.PhotoOrVideoDialog
|
import im.vector.app.core.dialogs.PhotoOrVideoDialog
|
||||||
import im.vector.app.core.platform.Restorable
|
import im.vector.app.core.platform.Restorable
|
||||||
|
import im.vector.app.core.resources.BuildMeta
|
||||||
import im.vector.app.features.settings.VectorPreferences
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
import im.vector.lib.multipicker.MultiPicker
|
import im.vector.lib.multipicker.MultiPicker
|
||||||
import org.matrix.android.sdk.BuildConfig
|
|
||||||
import org.matrix.android.sdk.api.session.content.ContentAttachmentData
|
import org.matrix.android.sdk.api.session.content.ContentAttachmentData
|
||||||
import timber.log.Timber
|
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.
|
* 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 {
|
interface Callback {
|
||||||
fun onContactAttachmentReady(contactAttachment: ContactAttachment) {
|
fun onContactAttachmentReady(contactAttachment: ContactAttachment)
|
||||||
if (BuildConfig.LOG_PRIVATE_DATA) {
|
|
||||||
Timber.v("On contact attachment ready: $contactAttachment")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onContentAttachmentsReady(attachments: List<ContentAttachmentData>)
|
fun onContentAttachmentsReady(attachments: List<ContentAttachmentData>)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,6 +143,9 @@ class AttachmentsHelper(val context: Context, val callback: Callback) : Restorab
|
|||||||
.firstOrNull()
|
.firstOrNull()
|
||||||
?.toContactAttachment()
|
?.toContactAttachment()
|
||||||
?.let {
|
?.let {
|
||||||
|
if (buildMeta.lowPrivacyLoggingEnabled) {
|
||||||
|
Timber.v("On contact attachment ready: $it")
|
||||||
|
}
|
||||||
callback.onContactAttachmentReady(it)
|
callback.onContactAttachmentReady(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
)
|
@ -20,7 +20,6 @@ import android.content.Context
|
|||||||
import androidx.lifecycle.DefaultLifecycleObserver
|
import androidx.lifecycle.DefaultLifecycleObserver
|
||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.lifecycle.LifecycleOwner
|
||||||
import im.vector.app.ActiveSessionDataSource
|
import im.vector.app.ActiveSessionDataSource
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.core.pushers.UnifiedPushHelper
|
import im.vector.app.core.pushers.UnifiedPushHelper
|
||||||
import im.vector.app.core.services.CallAndroidService
|
import im.vector.app.core.services.CallAndroidService
|
||||||
import im.vector.app.features.analytics.AnalyticsTracker
|
import im.vector.app.features.analytics.AnalyticsTracker
|
||||||
@ -74,6 +73,7 @@ class WebRtcCallManager @Inject constructor(
|
|||||||
private val activeSessionDataSource: ActiveSessionDataSource,
|
private val activeSessionDataSource: ActiveSessionDataSource,
|
||||||
private val analyticsTracker: AnalyticsTracker,
|
private val analyticsTracker: AnalyticsTracker,
|
||||||
private val unifiedPushHelper: UnifiedPushHelper,
|
private val unifiedPushHelper: UnifiedPushHelper,
|
||||||
|
private val voipConfig: VoipConfig,
|
||||||
) : CallListener,
|
) : CallListener,
|
||||||
DefaultLifecycleObserver {
|
DefaultLifecycleObserver {
|
||||||
|
|
||||||
@ -444,7 +444,7 @@ class WebRtcCallManager @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onCallAssertedIdentityReceived(callAssertedIdentityContent: CallAssertedIdentityContent) {
|
override fun onCallAssertedIdentityReceived(callAssertedIdentityContent: CallAssertedIdentityContent) {
|
||||||
if (!BuildConfig.handleCallAssertedIdentityEvents) {
|
if (!voipConfig.handleCallAssertedIdentityEvents) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val call = callsByCallId[callAssertedIdentityContent.callId]
|
val call = callsByCallId[callAssertedIdentityContent.callId]
|
||||||
|
@ -22,11 +22,11 @@ import com.airbnb.mvrx.ViewModelContext
|
|||||||
import dagger.assisted.Assisted
|
import dagger.assisted.Assisted
|
||||||
import dagger.assisted.AssistedFactory
|
import dagger.assisted.AssistedFactory
|
||||||
import dagger.assisted.AssistedInject
|
import dagger.assisted.AssistedInject
|
||||||
import im.vector.app.config.analyticsConfig
|
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
||||||
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
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.AnalyticsTracker
|
||||||
import im.vector.app.features.analytics.extensions.toAnalyticsType
|
import im.vector.app.features.analytics.extensions.toAnalyticsType
|
||||||
import im.vector.app.features.analytics.plan.Signup
|
import im.vector.app.features.analytics.plan.Signup
|
||||||
@ -80,7 +80,8 @@ class HomeActivityViewModel @AssistedInject constructor(
|
|||||||
private val analyticsStore: AnalyticsStore,
|
private val analyticsStore: AnalyticsStore,
|
||||||
private val lightweightSettingsStorage: LightweightSettingsStorage,
|
private val lightweightSettingsStorage: LightweightSettingsStorage,
|
||||||
private val vectorPreferences: VectorPreferences,
|
private val vectorPreferences: VectorPreferences,
|
||||||
private val analyticsTracker: AnalyticsTracker
|
private val analyticsTracker: AnalyticsTracker,
|
||||||
|
private val analyticsConfig: AnalyticsConfig,
|
||||||
) : VectorViewModel<HomeActivityViewState, HomeActivityViewActions, HomeActivityViewEvents>(initialState) {
|
) : VectorViewModel<HomeActivityViewState, HomeActivityViewActions, HomeActivityViewEvents>(initialState) {
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
|
@ -23,11 +23,11 @@ import android.view.ViewGroup
|
|||||||
import androidx.core.app.ActivityOptionsCompat
|
import androidx.core.app.ActivityOptionsCompat
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.extensions.observeK
|
import im.vector.app.core.extensions.observeK
|
||||||
import im.vector.app.core.extensions.replaceChildFragment
|
import im.vector.app.core.extensions.replaceChildFragment
|
||||||
import im.vector.app.core.platform.VectorBaseFragment
|
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.core.utils.startSharePlainTextIntent
|
||||||
import im.vector.app.databinding.FragmentHomeDrawerBinding
|
import im.vector.app.databinding.FragmentHomeDrawerBinding
|
||||||
import im.vector.app.features.analytics.plan.MobileScreen
|
import im.vector.app.features.analytics.plan.MobileScreen
|
||||||
@ -43,7 +43,8 @@ import javax.inject.Inject
|
|||||||
class HomeDrawerFragment @Inject constructor(
|
class HomeDrawerFragment @Inject constructor(
|
||||||
private val session: Session,
|
private val session: Session,
|
||||||
private val vectorPreferences: VectorPreferences,
|
private val vectorPreferences: VectorPreferences,
|
||||||
private val avatarRenderer: AvatarRenderer
|
private val avatarRenderer: AvatarRenderer,
|
||||||
|
private val buildMeta: BuildMeta,
|
||||||
) : VectorBaseFragment<FragmentHomeDrawerBinding>() {
|
) : VectorBaseFragment<FragmentHomeDrawerBinding>() {
|
||||||
|
|
||||||
private lateinit var sharedActionViewModel: HomeSharedActionViewModel
|
private lateinit var sharedActionViewModel: HomeSharedActionViewModel
|
||||||
@ -112,7 +113,7 @@ class HomeDrawerFragment @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Debug menu
|
// Debug menu
|
||||||
views.homeDrawerHeaderDebugView.isVisible = BuildConfig.DEBUG && vectorPreferences.developerMode()
|
views.homeDrawerHeaderDebugView.isVisible = buildMeta.isDebug && vectorPreferences.developerMode()
|
||||||
views.homeDrawerHeaderDebugView.debouncedClicks {
|
views.homeDrawerHeaderDebugView.debouncedClicks {
|
||||||
sharedActionViewModel.post(HomeActivitySharedAction.CloseDrawer)
|
sharedActionViewModel.post(HomeActivitySharedAction.CloseDrawer)
|
||||||
navigator.openDebug(requireActivity())
|
navigator.openDebug(requireActivity())
|
||||||
|
@ -24,8 +24,8 @@ import androidx.annotation.WorkerThread
|
|||||||
import androidx.core.content.pm.ShortcutInfoCompat
|
import androidx.core.content.pm.ShortcutInfoCompat
|
||||||
import androidx.core.content.pm.ShortcutManagerCompat
|
import androidx.core.content.pm.ShortcutManagerCompat
|
||||||
import androidx.core.graphics.drawable.IconCompat
|
import androidx.core.graphics.drawable.IconCompat
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.core.glide.GlideApp
|
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.core.utils.DimensionConverter
|
||||||
import im.vector.app.features.MainActivity
|
import im.vector.app.features.MainActivity
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
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 val useAdaptiveIcon = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
|
||||||
private const val adaptiveIconSizeDp = 108
|
private const val adaptiveIconSizeDp = 108
|
||||||
private const val adaptiveIconOuterSidesDp = 18
|
private const val adaptiveIconOuterSidesDp = 18
|
||||||
private const val directShareCategory = BuildConfig.APPLICATION_ID + ".SHORTCUT_SHARE"
|
|
||||||
|
|
||||||
class ShortcutCreator @Inject constructor(
|
class ShortcutCreator @Inject constructor(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val avatarRenderer: AvatarRenderer,
|
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 adaptiveIconSize = dimensionConverter.dpToPx(adaptiveIconSizeDp)
|
||||||
private val adaptiveIconOuterSides = dimensionConverter.dpToPx(adaptiveIconOuterSidesDp)
|
private val adaptiveIconOuterSides = dimensionConverter.dpToPx(adaptiveIconOuterSidesDp)
|
||||||
private val iconSize by lazy {
|
private val iconSize by lazy {
|
||||||
|
@ -67,7 +67,6 @@ import com.airbnb.mvrx.fragmentViewModel
|
|||||||
import com.airbnb.mvrx.withState
|
import com.airbnb.mvrx.withState
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.vanniktech.emoji.EmojiPopup
|
import com.vanniktech.emoji.EmojiPopup
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.animations.play
|
import im.vector.app.core.animations.play
|
||||||
import im.vector.app.core.dialogs.ConfirmationDialogBuilder
|
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.VectorMenuProvider
|
||||||
import im.vector.app.core.platform.lifecycleAwareLazy
|
import im.vector.app.core.platform.lifecycleAwareLazy
|
||||||
import im.vector.app.core.platform.showOptimizedSnackbar
|
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.ColorProvider
|
||||||
import im.vector.app.core.resources.UserPreferencesProvider
|
import im.vector.app.core.resources.UserPreferencesProvider
|
||||||
import im.vector.app.core.time.Clock
|
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.core.utils.toast
|
||||||
import im.vector.app.databinding.DialogReportContentBinding
|
import im.vector.app.databinding.DialogReportContentBinding
|
||||||
import im.vector.app.databinding.FragmentTimelineBinding
|
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.extensions.toAnalyticsInteraction
|
||||||
import im.vector.app.features.analytics.plan.Interaction
|
import im.vector.app.features.analytics.plan.Interaction
|
||||||
import im.vector.app.features.analytics.plan.MobileScreen
|
import im.vector.app.features.analytics.plan.MobileScreen
|
||||||
@ -275,7 +276,9 @@ class TimelineFragment @Inject constructor(
|
|||||||
private val callManager: WebRtcCallManager,
|
private val callManager: WebRtcCallManager,
|
||||||
private val audioMessagePlaybackTracker: AudioMessagePlaybackTracker,
|
private val audioMessagePlaybackTracker: AudioMessagePlaybackTracker,
|
||||||
private val shareIntentHandler: ShareIntentHandler,
|
private val shareIntentHandler: ShareIntentHandler,
|
||||||
private val clock: Clock
|
private val clock: Clock,
|
||||||
|
private val vectorFeatures: VectorFeatures,
|
||||||
|
private val buildMeta: BuildMeta,
|
||||||
) :
|
) :
|
||||||
VectorBaseFragment<FragmentTimelineBinding>(),
|
VectorBaseFragment<FragmentTimelineBinding>(),
|
||||||
TimelineEventController.Callback,
|
TimelineEventController.Callback,
|
||||||
@ -372,7 +375,7 @@ class TimelineFragment @Inject constructor(
|
|||||||
sharedActionViewModel = activityViewModelProvider.get(MessageSharedActionViewModel::class.java)
|
sharedActionViewModel = activityViewModelProvider.get(MessageSharedActionViewModel::class.java)
|
||||||
sharedActivityActionViewModel = activityViewModelProvider.get(RoomDetailSharedActionViewModel::class.java)
|
sharedActivityActionViewModel = activityViewModelProvider.get(RoomDetailSharedActionViewModel::class.java)
|
||||||
knownCallsViewModel = activityViewModelProvider.get(SharedKnownCallsViewModel::class.java)
|
knownCallsViewModel = activityViewModelProvider.get(SharedKnownCallsViewModel::class.java)
|
||||||
attachmentsHelper = AttachmentsHelper(requireContext(), this).register()
|
attachmentsHelper = AttachmentsHelper(requireContext(), this, buildMeta).register()
|
||||||
callActionsHandler = StartCallActionsHandler(
|
callActionsHandler = StartCallActionsHandler(
|
||||||
roomId = timelineArgs.roomId,
|
roomId = timelineArgs.roomId,
|
||||||
fragment = this,
|
fragment = this,
|
||||||
@ -1559,7 +1562,7 @@ class TimelineFragment @Inject constructor(
|
|||||||
attachmentTypeSelector = AttachmentTypeSelectorView(vectorBaseActivity, vectorBaseActivity.layoutInflater, this@TimelineFragment)
|
attachmentTypeSelector = AttachmentTypeSelectorView(vectorBaseActivity, vectorBaseActivity.layoutInflater, this@TimelineFragment)
|
||||||
attachmentTypeSelector.setAttachmentVisibility(
|
attachmentTypeSelector.setAttachmentVisibility(
|
||||||
AttachmentTypeSelectorView.Type.LOCATION,
|
AttachmentTypeSelectorView.Type.LOCATION,
|
||||||
BuildConfig.enableLocationSharing
|
vectorFeatures.isLocationSharingEnabled(),
|
||||||
)
|
)
|
||||||
attachmentTypeSelector.setAttachmentVisibility(
|
attachmentTypeSelector.setAttachmentVisibility(
|
||||||
AttachmentTypeSelectorView.Type.POLL, !isThreadTimeLine()
|
AttachmentTypeSelectorView.Type.POLL, !isThreadTimeLine()
|
||||||
@ -2646,7 +2649,6 @@ class TimelineFragment @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onContactAttachmentReady(contactAttachment: ContactAttachment) {
|
override fun onContactAttachmentReady(contactAttachment: ContactAttachment) {
|
||||||
super.onContactAttachmentReady(contactAttachment)
|
|
||||||
val formattedContact = contactAttachment.toHumanReadable()
|
val formattedContact = contactAttachment.toHumanReadable()
|
||||||
messageComposerViewModel.handle(MessageComposerAction.SendMessage(formattedContact, false))
|
messageComposerViewModel.handle(MessageComposerAction.SendMessage(formattedContact, false))
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
|||||||
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||||
import im.vector.app.core.mvrx.runCatchingToAsync
|
import im.vector.app.core.mvrx.runCatchingToAsync
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
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.resources.StringProvider
|
||||||
import im.vector.app.core.utils.BehaviorDataSource
|
import im.vector.app.core.utils.BehaviorDataSource
|
||||||
import im.vector.app.features.analytics.AnalyticsTracker
|
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.location.live.tracking.LocationSharingServiceConnection
|
||||||
import im.vector.app.features.notifications.NotificationDrawerManager
|
import im.vector.app.features.notifications.NotificationDrawerManager
|
||||||
import im.vector.app.features.powerlevel.PowerLevelsFlowFactory
|
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.getOutboundSessionKeySharingStrategyOrDefault
|
||||||
import im.vector.app.features.raw.wellknown.withElementWellKnown
|
import im.vector.app.features.raw.wellknown.withElementWellKnown
|
||||||
import im.vector.app.features.session.coroutineScope
|
import im.vector.app.features.session.coroutineScope
|
||||||
@ -137,6 +139,8 @@ class TimelineViewModel @AssistedInject constructor(
|
|||||||
private val locationSharingServiceConnection: LocationSharingServiceConnection,
|
private val locationSharingServiceConnection: LocationSharingServiceConnection,
|
||||||
private val stopLiveLocationShareUseCase: StopLiveLocationShareUseCase,
|
private val stopLiveLocationShareUseCase: StopLiveLocationShareUseCase,
|
||||||
private val redactLiveLocationShareEventUseCase: RedactLiveLocationShareEventUseCase,
|
private val redactLiveLocationShareEventUseCase: RedactLiveLocationShareEventUseCase,
|
||||||
|
private val cryptoConfig: CryptoConfig,
|
||||||
|
buildMeta: BuildMeta,
|
||||||
timelineFactory: TimelineFactory,
|
timelineFactory: TimelineFactory,
|
||||||
spaceStateHandler: SpaceStateHandler,
|
spaceStateHandler: SpaceStateHandler,
|
||||||
) : VectorViewModel<RoomDetailViewState, RoomDetailAction, RoomDetailViewEvents>(initialState),
|
) : VectorViewModel<RoomDetailViewState, RoomDetailAction, RoomDetailViewEvents>(initialState),
|
||||||
@ -150,7 +154,7 @@ class TimelineViewModel @AssistedInject constructor(
|
|||||||
val timeline = timelineFactory.createTimeline(viewModelScope, room, eventId, initialState.rootThreadEventId)
|
val timeline = timelineFactory.createTimeline(viewModelScope, room, eventId, initialState.rootThreadEventId)
|
||||||
|
|
||||||
// Same lifecycle than the ViewModel (survive to screen rotation)
|
// 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
|
// Slot to keep a pending action during permission request
|
||||||
var pendingAction: RoomDetailAction? = null
|
var pendingAction: RoomDetailAction? = null
|
||||||
@ -205,7 +209,7 @@ class TimelineViewModel @AssistedInject constructor(
|
|||||||
// Ensure to share the outbound session keys with all members
|
// Ensure to share the outbound session keys with all members
|
||||||
if (room.roomCryptoService().isEncrypted()) {
|
if (room.roomCryptoService().isEncrypted()) {
|
||||||
rawService.withElementWellKnown(viewModelScope, session.sessionParams) {
|
rawService.withElementWellKnown(viewModelScope, session.sessionParams) {
|
||||||
val strategy = it.getOutboundSessionKeySharingStrategyOrDefault()
|
val strategy = it.getOutboundSessionKeySharingStrategyOrDefault(cryptoConfig.fallbackKeySharingStrategy)
|
||||||
if (strategy == OutboundSessionKeySharingStrategy.WhenEnteringRoom) {
|
if (strategy == OutboundSessionKeySharingStrategy.WhenEnteringRoom) {
|
||||||
prepareForEncryption()
|
prepareForEncryption()
|
||||||
}
|
}
|
||||||
@ -688,7 +692,7 @@ class TimelineViewModel @AssistedInject constructor(
|
|||||||
// Ensure outbound session keys
|
// Ensure outbound session keys
|
||||||
if (room.roomCryptoService().isEncrypted()) {
|
if (room.roomCryptoService().isEncrypted()) {
|
||||||
rawService.withElementWellKnown(viewModelScope, session.sessionParams) {
|
rawService.withElementWellKnown(viewModelScope, session.sessionParams) {
|
||||||
val strategy = it.getOutboundSessionKeySharingStrategyOrDefault()
|
val strategy = it.getOutboundSessionKeySharingStrategyOrDefault(cryptoConfig.fallbackKeySharingStrategy)
|
||||||
if (strategy == OutboundSessionKeySharingStrategy.WhenTyping && action.focused) {
|
if (strategy == OutboundSessionKeySharingStrategy.WhenTyping && action.focused) {
|
||||||
// Should we add some rate limit here, or do it only once per model lifecycle?
|
// Should we add some rate limit here, or do it only once per model lifecycle?
|
||||||
prepareForEncryption()
|
prepareForEncryption()
|
||||||
|
@ -20,7 +20,7 @@ import android.content.Context
|
|||||||
import android.media.AudioAttributes
|
import android.media.AudioAttributes
|
||||||
import android.media.MediaPlayer
|
import android.media.MediaPlayer
|
||||||
import androidx.core.content.FileProvider
|
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.home.room.detail.timeline.helper.AudioMessagePlaybackTracker
|
||||||
import im.vector.app.features.voice.VoiceFailure
|
import im.vector.app.features.voice.VoiceFailure
|
||||||
import im.vector.app.features.voice.VoiceRecorder
|
import im.vector.app.features.voice.VoiceRecorder
|
||||||
@ -43,6 +43,7 @@ import javax.inject.Inject
|
|||||||
class AudioMessageHelper @Inject constructor(
|
class AudioMessageHelper @Inject constructor(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val playbackTracker: AudioMessagePlaybackTracker,
|
private val playbackTracker: AudioMessagePlaybackTracker,
|
||||||
|
private val buildMeta: BuildMeta,
|
||||||
voiceRecorderProvider: VoiceRecorderProvider
|
voiceRecorderProvider: VoiceRecorderProvider
|
||||||
) {
|
) {
|
||||||
private var mediaPlayer: MediaPlayer? = null
|
private var mediaPlayer: MediaPlayer? = null
|
||||||
@ -88,7 +89,7 @@ class AudioMessageHelper @Inject constructor(
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
voiceMessageFile?.let {
|
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
|
return outputFileUri
|
||||||
.toMultiPickerAudioType(context)
|
.toMultiPickerAudioType(context)
|
||||||
?.apply {
|
?.apply {
|
||||||
|
@ -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
|
||||||
|
)
|
@ -21,7 +21,6 @@ import android.util.AttributeSet
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.hardware.vibrate
|
import im.vector.app.core.hardware.vibrate
|
||||||
import im.vector.app.core.time.Clock
|
import im.vector.app.core.time.Clock
|
||||||
@ -57,6 +56,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Inject lateinit var clock: Clock
|
@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.
|
// 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")
|
@Suppress("UNNECESSARY_LATEINIT")
|
||||||
@ -202,7 +202,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
|
|||||||
|
|
||||||
private fun onRecordingTick(isLocked: Boolean, milliseconds: Long) {
|
private fun onRecordingTick(isLocked: Boolean, milliseconds: Long) {
|
||||||
voiceMessageViews.renderRecordingTimer(isLocked, milliseconds / 1_000)
|
voiceMessageViews.renderRecordingTimer(isLocked, milliseconds / 1_000)
|
||||||
val timeDiffToRecordingLimit = BuildConfig.VOICE_MESSAGE_DURATION_LIMIT_MS - milliseconds
|
val timeDiffToRecordingLimit = voiceMessageConfig.lengthLimitMs - milliseconds
|
||||||
if (timeDiffToRecordingLimit <= 0) {
|
if (timeDiffToRecordingLimit <= 0) {
|
||||||
post {
|
post {
|
||||||
callback.onRecordingLimitReached()
|
callback.onRecordingLimitReached()
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package im.vector.app.features.home.room.detail.timeline.url
|
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.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -27,7 +27,8 @@ import org.matrix.android.sdk.api.session.room.timeline.getLatestEventId
|
|||||||
|
|
||||||
class PreviewUrlRetriever(
|
class PreviewUrlRetriever(
|
||||||
session: Session,
|
session: Session,
|
||||||
private val coroutineScope: CoroutineScope
|
private val coroutineScope: CoroutineScope,
|
||||||
|
private val buildMeta: BuildMeta,
|
||||||
) {
|
) {
|
||||||
private val mediaService = session.mediaService()
|
private val mediaService = session.mediaService()
|
||||||
|
|
||||||
@ -77,7 +78,7 @@ class PreviewUrlRetriever(
|
|||||||
mediaService.getPreviewUrl(
|
mediaService.getPreviewUrl(
|
||||||
url = urlToRetrieve,
|
url = urlToRetrieve,
|
||||||
timestamp = null,
|
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(
|
}.fold(
|
||||||
{
|
{
|
||||||
|
@ -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,
|
||||||
|
)
|
@ -24,8 +24,8 @@ import androidx.annotation.RequiresPermission
|
|||||||
import androidx.annotation.VisibleForTesting
|
import androidx.annotation.VisibleForTesting
|
||||||
import androidx.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
import androidx.core.location.LocationListenerCompat
|
import androidx.core.location.LocationListenerCompat
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
|
import im.vector.app.core.resources.BuildMeta
|
||||||
import im.vector.app.features.session.coroutineScope
|
import im.vector.app.features.session.coroutineScope
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.asSharedFlow
|
import kotlinx.coroutines.flow.asSharedFlow
|
||||||
@ -40,7 +40,8 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class LocationTracker @Inject constructor(
|
class LocationTracker @Inject constructor(
|
||||||
context: Context,
|
context: Context,
|
||||||
private val activeSessionHolder: ActiveSessionHolder
|
private val activeSessionHolder: ActiveSessionHolder,
|
||||||
|
private val buildMeta: BuildMeta,
|
||||||
) : LocationListenerCompat {
|
) : LocationListenerCompat {
|
||||||
|
|
||||||
private val locationManager = context.getSystemService<LocationManager>()
|
private val locationManager = context.getSystemService<LocationManager>()
|
||||||
@ -104,7 +105,7 @@ class LocationTracker @Inject constructor(
|
|||||||
}
|
}
|
||||||
.maxByOrNull { location -> location.time }
|
.maxByOrNull { location -> location.time }
|
||||||
?.let { latestKnownLocation ->
|
?.let { latestKnownLocation ->
|
||||||
if (BuildConfig.LOW_PRIVACY_LOG_ENABLE) {
|
if (buildMeta.lowPrivacyLoggingEnabled) {
|
||||||
Timber.d("lastKnownLocation: $latestKnownLocation")
|
Timber.d("lastKnownLocation: $latestKnownLocation")
|
||||||
} else {
|
} else {
|
||||||
Timber.d("lastKnownLocation: ${latestKnownLocation.provider}")
|
Timber.d("lastKnownLocation: ${latestKnownLocation.provider}")
|
||||||
@ -162,7 +163,7 @@ class LocationTracker @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onLocationChanged(location: Location) {
|
override fun onLocationChanged(location: Location) {
|
||||||
if (BuildConfig.LOW_PRIVACY_LOG_ENABLE) {
|
if (buildMeta.lowPrivacyLoggingEnabled) {
|
||||||
Timber.d("onLocationChanged: $location")
|
Timber.d("onLocationChanged: $location")
|
||||||
} else {
|
} else {
|
||||||
Timber.d("onLocationChanged: ${location.provider}")
|
Timber.d("onLocationChanged: ${location.provider}")
|
||||||
@ -196,7 +197,7 @@ class LocationTracker @Inject constructor(
|
|||||||
|
|
||||||
private fun notifyLocation(location: Location) {
|
private fun notifyLocation(location: Location) {
|
||||||
activeSessionHolder.getSafeActiveSession()?.coroutineScope?.launch {
|
activeSessionHolder.getSafeActiveSession()?.coroutineScope?.launch {
|
||||||
if (BuildConfig.LOW_PRIVACY_LOG_ENABLE) {
|
if (buildMeta.lowPrivacyLoggingEnabled) {
|
||||||
Timber.d("notify location: $location")
|
Timber.d("notify location: $location")
|
||||||
} else {
|
} else {
|
||||||
Timber.d("notify location: ${location.provider}")
|
Timber.d("notify location: ${location.provider}")
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package im.vector.app.features.location
|
package im.vector.app.features.location
|
||||||
|
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.features.raw.wellknown.getElementWellknown
|
import im.vector.app.features.raw.wellknown.getElementWellknown
|
||||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||||
import org.matrix.android.sdk.api.raw.RawService
|
import org.matrix.android.sdk.api.raw.RawService
|
||||||
@ -25,9 +24,10 @@ import javax.inject.Inject
|
|||||||
|
|
||||||
class UrlMapProvider @Inject constructor(
|
class UrlMapProvider @Inject constructor(
|
||||||
private val session: Session,
|
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 {
|
private val fallbackMapUrl = buildString {
|
||||||
append(MAP_BASE_URL)
|
append(MAP_BASE_URL)
|
||||||
|
@ -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.home.room.detail.arguments.TimelineArgs
|
||||||
import im.vector.app.features.location.live.map.LiveLocationMapViewActivity
|
import im.vector.app.features.location.live.map.LiveLocationMapViewActivity
|
||||||
import im.vector.app.features.location.live.map.LiveLocationMapViewArgs
|
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.notifications.NotificationUtils
|
||||||
import im.vector.app.features.themes.ThemeUtils
|
import im.vector.app.features.themes.ThemeUtils
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -41,6 +42,7 @@ class LiveLocationNotificationBuilder @Inject constructor(
|
|||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val stringProvider: StringProvider,
|
private val stringProvider: StringProvider,
|
||||||
private val clock: Clock,
|
private val clock: Clock,
|
||||||
|
private val actionIds: NotificationActionIds,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -66,7 +68,7 @@ class LiveLocationNotificationBuilder @Inject constructor(
|
|||||||
liveLocationMapViewArgs = LiveLocationMapViewArgs(roomId = roomId),
|
liveLocationMapViewArgs = LiveLocationMapViewArgs(roomId = roomId),
|
||||||
firstStartMainActivity = true
|
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
|
// 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")
|
mapIntent.data = createIgnoredUri("openLiveLocationMap?$roomId")
|
||||||
|
|
||||||
|
@ -27,9 +27,9 @@ import androidx.core.view.isInvisible
|
|||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.google.android.material.textfield.TextInputLayout
|
import com.google.android.material.textfield.TextInputLayout
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.extensions.hideKeyboard
|
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.ensureProtocol
|
||||||
import im.vector.app.core.utils.openUrlInChromeCustomTab
|
import im.vector.app.core.utils.openUrlInChromeCustomTab
|
||||||
import im.vector.app.databinding.FragmentLoginServerUrlFormBinding
|
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.
|
* 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 {
|
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginServerUrlFormBinding {
|
||||||
return FragmentLoginServerUrlFormBinding.inflate(inflater, container, false)
|
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)
|
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(
|
views.loginServerUrlFormHomeServerUrl.setAdapter(
|
||||||
ArrayAdapter(
|
ArrayAdapter(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
|
@ -23,8 +23,8 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.resources.BuildMeta
|
||||||
import im.vector.app.databinding.FragmentLoginSplashBinding
|
import im.vector.app.databinding.FragmentLoginSplashBinding
|
||||||
import im.vector.app.features.analytics.plan.MobileScreen
|
import im.vector.app.features.analytics.plan.MobileScreen
|
||||||
import im.vector.app.features.settings.VectorPreferences
|
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.
|
* In this screen, the user is viewing an introduction to what he can do with this application.
|
||||||
*/
|
*/
|
||||||
class LoginSplashFragment @Inject constructor(
|
class LoginSplashFragment @Inject constructor(
|
||||||
private val vectorPreferences: VectorPreferences
|
private val vectorPreferences: VectorPreferences,
|
||||||
|
private val buildMeta: BuildMeta,
|
||||||
) : AbstractLoginFragment<FragmentLoginSplashBinding>() {
|
) : AbstractLoginFragment<FragmentLoginSplashBinding>() {
|
||||||
|
|
||||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginSplashBinding {
|
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginSplashBinding {
|
||||||
@ -57,12 +58,12 @@ class LoginSplashFragment @Inject constructor(
|
|||||||
private fun setupViews() {
|
private fun setupViews() {
|
||||||
views.loginSplashSubmit.debouncedClicks { getStarted() }
|
views.loginSplashSubmit.debouncedClicks { getStarted() }
|
||||||
|
|
||||||
if (BuildConfig.DEBUG || vectorPreferences.developerMode()) {
|
if (buildMeta.isDebug || vectorPreferences.developerMode()) {
|
||||||
views.loginSplashVersion.isVisible = true
|
views.loginSplashVersion.isVisible = true
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
views.loginSplashVersion.text = "Version : ${BuildConfig.VERSION_NAME}\n" +
|
views.loginSplashVersion.text = "Version : ${buildMeta.versionName}\n" +
|
||||||
"Branch: ${BuildConfig.GIT_BRANCH_NAME}\n" +
|
"Branch: ${buildMeta.gitBranchName}\n" +
|
||||||
"Build: ${BuildConfig.BUILD_NUMBER}"
|
"Build: ${buildMeta.buildNumber}"
|
||||||
views.loginSplashVersion.debouncedClicks { navigator.openDebug(requireContext()) }
|
views.loginSplashVersion.debouncedClicks { navigator.openDebug(requireContext()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,9 +26,9 @@ import android.widget.ArrayAdapter
|
|||||||
import androidx.core.view.isInvisible
|
import androidx.core.view.isInvisible
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.google.android.material.textfield.TextInputLayout
|
import com.google.android.material.textfield.TextInputLayout
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.extensions.hideKeyboard
|
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.ensureProtocol
|
||||||
import im.vector.app.databinding.FragmentLoginServerUrlForm2Binding
|
import im.vector.app.databinding.FragmentLoginServerUrlForm2Binding
|
||||||
import kotlinx.coroutines.flow.launchIn
|
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.
|
* 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 {
|
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginServerUrlForm2Binding {
|
||||||
return FragmentLoginServerUrlForm2Binding.inflate(inflater, container, false)
|
return FragmentLoginServerUrlForm2Binding.inflate(inflater, container, false)
|
||||||
@ -80,7 +82,7 @@ class LoginServerUrlFormFragment2 @Inject constructor() : AbstractLoginFragment2
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setupUi(state: LoginViewState2) {
|
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(
|
views.loginServerUrlFormHomeServerUrl.setAdapter(
|
||||||
ArrayAdapter(
|
ArrayAdapter(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
|
@ -22,7 +22,7 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.view.isVisible
|
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.databinding.FragmentLoginSplash2Binding
|
||||||
import im.vector.app.features.settings.VectorPreferences
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -32,7 +32,8 @@ import javax.inject.Inject
|
|||||||
* This is the new splash screen.
|
* This is the new splash screen.
|
||||||
*/
|
*/
|
||||||
class LoginSplashSignUpSignInSelectionFragment2 @Inject constructor(
|
class LoginSplashSignUpSignInSelectionFragment2 @Inject constructor(
|
||||||
private val vectorPreferences: VectorPreferences
|
private val vectorPreferences: VectorPreferences,
|
||||||
|
private val buildMeta: BuildMeta,
|
||||||
) : AbstractLoginFragment2<FragmentLoginSplash2Binding>() {
|
) : AbstractLoginFragment2<FragmentLoginSplash2Binding>() {
|
||||||
|
|
||||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginSplash2Binding {
|
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginSplash2Binding {
|
||||||
@ -49,12 +50,12 @@ class LoginSplashSignUpSignInSelectionFragment2 @Inject constructor(
|
|||||||
views.loginSignupSigninSignUp.setOnClickListener { signUp() }
|
views.loginSignupSigninSignUp.setOnClickListener { signUp() }
|
||||||
views.loginSignupSigninSignIn.setOnClickListener { signIn() }
|
views.loginSignupSigninSignIn.setOnClickListener { signIn() }
|
||||||
|
|
||||||
if (BuildConfig.DEBUG || vectorPreferences.developerMode()) {
|
if (buildMeta.isDebug || vectorPreferences.developerMode()) {
|
||||||
views.loginSplashVersion.isVisible = true
|
views.loginSplashVersion.isVisible = true
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
views.loginSplashVersion.text = "Version : ${BuildConfig.VERSION_NAME}\n" +
|
views.loginSplashVersion.text = "Version : ${buildMeta.versionName}\n" +
|
||||||
"Branch: ${BuildConfig.GIT_BRANCH_NAME}\n" +
|
"Branch: ${buildMeta.gitBranchName}\n" +
|
||||||
"Build: ${BuildConfig.BUILD_NUMBER}"
|
"Build: ${buildMeta.buildNumber}"
|
||||||
views.loginSplashVersion.debouncedClicks { navigator.openDebug(requireContext()) }
|
views.loginSplashVersion.debouncedClicks { navigator.openDebug(requireContext()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,10 +33,10 @@ import androidx.core.view.ViewCompat
|
|||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.SpaceStateHandler
|
import im.vector.app.SpaceStateHandler
|
||||||
|
import im.vector.app.config.OnboardingVariant
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
import im.vector.app.core.error.fatalError
|
import im.vector.app.core.error.fatalError
|
||||||
import im.vector.app.features.VectorFeatures
|
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.AnalyticsTracker
|
||||||
import im.vector.app.features.analytics.extensions.toAnalyticsViewRoom
|
import im.vector.app.features.analytics.extensions.toAnalyticsViewRoom
|
||||||
import im.vector.app.features.analytics.plan.ViewRoom
|
import im.vector.app.features.analytics.plan.ViewRoom
|
||||||
|
@ -16,9 +16,9 @@
|
|||||||
package im.vector.app.features.notifications
|
package im.vector.app.features.notifications
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.extensions.takeAs
|
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.resources.StringProvider
|
||||||
import im.vector.app.core.time.Clock
|
import im.vector.app.core.time.Clock
|
||||||
import im.vector.app.features.displayname.getBestName
|
import im.vector.app.features.displayname.getBestName
|
||||||
@ -62,6 +62,7 @@ class NotifiableEventResolver @Inject constructor(
|
|||||||
private val noticeEventFormatter: NoticeEventFormatter,
|
private val noticeEventFormatter: NoticeEventFormatter,
|
||||||
private val displayableEventFormatter: DisplayableEventFormatter,
|
private val displayableEventFormatter: DisplayableEventFormatter,
|
||||||
private val clock: Clock,
|
private val clock: Clock,
|
||||||
|
private val buildMeta: BuildMeta,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
// private val eventDisplay = RiotEventDisplay(context)
|
// private val eventDisplay = RiotEventDisplay(context)
|
||||||
@ -264,7 +265,7 @@ class NotifiableEventResolver @Inject constructor(
|
|||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Timber.e("## unsupported notifiable event for eventId [${event.eventId}]")
|
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]")
|
Timber.e("## unsupported notifiable event for event [$event]")
|
||||||
}
|
}
|
||||||
// TODO generic handling?
|
// TODO generic handling?
|
||||||
|
@ -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"
|
||||||
|
}
|
@ -48,31 +48,32 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
|
|||||||
@Inject lateinit var activeSessionHolder: ActiveSessionHolder
|
@Inject lateinit var activeSessionHolder: ActiveSessionHolder
|
||||||
@Inject lateinit var analyticsTracker: AnalyticsTracker
|
@Inject lateinit var analyticsTracker: AnalyticsTracker
|
||||||
@Inject lateinit var clock: Clock
|
@Inject lateinit var clock: Clock
|
||||||
|
@Inject lateinit var actionIds: NotificationActionIds
|
||||||
|
|
||||||
override fun onReceive(context: Context?, intent: Intent?) {
|
override fun onReceive(context: Context?, intent: Intent?) {
|
||||||
if (intent == null || context == null) return
|
if (intent == null || context == null) return
|
||||||
Timber.v("NotificationBroadcastReceiver received : $intent")
|
Timber.v("NotificationBroadcastReceiver received : $intent")
|
||||||
when (intent.action) {
|
when (intent.action) {
|
||||||
NotificationUtils.SMART_REPLY_ACTION ->
|
actionIds.smartReply ->
|
||||||
handleSmartReply(intent, context)
|
handleSmartReply(intent, context)
|
||||||
NotificationUtils.DISMISS_ROOM_NOTIF_ACTION ->
|
actionIds.dismissRoom ->
|
||||||
intent.getStringExtra(KEY_ROOM_ID)?.let { roomId ->
|
intent.getStringExtra(KEY_ROOM_ID)?.let { roomId ->
|
||||||
notificationDrawerManager.updateEvents { it.clearMessagesForRoom(roomId) }
|
notificationDrawerManager.updateEvents { it.clearMessagesForRoom(roomId) }
|
||||||
}
|
}
|
||||||
NotificationUtils.DISMISS_SUMMARY_ACTION ->
|
actionIds.dismissSummary ->
|
||||||
notificationDrawerManager.clearAllEvents()
|
notificationDrawerManager.clearAllEvents()
|
||||||
NotificationUtils.MARK_ROOM_READ_ACTION ->
|
actionIds.markRoomRead ->
|
||||||
intent.getStringExtra(KEY_ROOM_ID)?.let { roomId ->
|
intent.getStringExtra(KEY_ROOM_ID)?.let { roomId ->
|
||||||
notificationDrawerManager.updateEvents { it.clearMessagesForRoom(roomId) }
|
notificationDrawerManager.updateEvents { it.clearMessagesForRoom(roomId) }
|
||||||
handleMarkAsRead(roomId)
|
handleMarkAsRead(roomId)
|
||||||
}
|
}
|
||||||
NotificationUtils.JOIN_ACTION -> {
|
actionIds.join -> {
|
||||||
intent.getStringExtra(KEY_ROOM_ID)?.let { roomId ->
|
intent.getStringExtra(KEY_ROOM_ID)?.let { roomId ->
|
||||||
notificationDrawerManager.updateEvents { it.clearMemberShipNotificationForRoom(roomId) }
|
notificationDrawerManager.updateEvents { it.clearMemberShipNotificationForRoom(roomId) }
|
||||||
handleJoinRoom(roomId)
|
handleJoinRoom(roomId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NotificationUtils.REJECT_ACTION -> {
|
actionIds.reject -> {
|
||||||
intent.getStringExtra(KEY_ROOM_ID)?.let { roomId ->
|
intent.getStringExtra(KEY_ROOM_ID)?.let { roomId ->
|
||||||
notificationDrawerManager.updateEvents { it.clearMemberShipNotificationForRoom(roomId) }
|
notificationDrawerManager.updateEvents { it.clearMemberShipNotificationForRoom(roomId) }
|
||||||
handleRejectRoom(roomId)
|
handleRejectRoom(roomId)
|
||||||
|
@ -20,8 +20,8 @@ import android.os.Handler
|
|||||||
import android.os.HandlerThread
|
import android.os.HandlerThread
|
||||||
import androidx.annotation.WorkerThread
|
import androidx.annotation.WorkerThread
|
||||||
import im.vector.app.ActiveSessionDataSource
|
import im.vector.app.ActiveSessionDataSource
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.resources.BuildMeta
|
||||||
import im.vector.app.core.utils.FirstThrottler
|
import im.vector.app.core.utils.FirstThrottler
|
||||||
import im.vector.app.features.displayname.getBestName
|
import im.vector.app.features.displayname.getBestName
|
||||||
import im.vector.app.features.settings.VectorPreferences
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
@ -46,7 +46,8 @@ class NotificationDrawerManager @Inject constructor(
|
|||||||
private val activeSessionDataSource: ActiveSessionDataSource,
|
private val activeSessionDataSource: ActiveSessionDataSource,
|
||||||
private val notifiableEventProcessor: NotifiableEventProcessor,
|
private val notifiableEventProcessor: NotifiableEventProcessor,
|
||||||
private val notificationRenderer: NotificationRenderer,
|
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)
|
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
|
// If we support multi session, event list should be per userId
|
||||||
// Currently only manage single session
|
// Currently only manage single session
|
||||||
if (BuildConfig.LOW_PRIVACY_LOG_ENABLE) {
|
if (buildMeta.lowPrivacyLoggingEnabled) {
|
||||||
Timber.d("onNotifiableEventReceived(): $notifiableEvent")
|
Timber.d("onNotifiableEventReceived(): $notifiableEvent")
|
||||||
} else {
|
} else {
|
||||||
Timber.d("onNotifiableEventReceived(): is push: ${notifiableEvent.canBeReplaced}")
|
Timber.d("onNotifiableEventReceived(): is push: ${notifiableEvent.canBeReplaced}")
|
||||||
|
@ -45,7 +45,6 @@ import androidx.core.content.getSystemService
|
|||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
import androidx.core.graphics.drawable.IconCompat
|
import androidx.core.graphics.drawable.IconCompat
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.extensions.createIgnoredUri
|
import im.vector.app.core.extensions.createIgnoredUri
|
||||||
import im.vector.app.core.platform.PendingIntentCompat
|
import im.vector.app.core.platform.PendingIntentCompat
|
||||||
@ -69,16 +68,13 @@ import javax.inject.Inject
|
|||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
/**
|
|
||||||
* Util class for creating notifications.
|
|
||||||
* Note: Cannot inject ColorProvider in the constructor, because it requires an Activity
|
|
||||||
*/
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class NotificationUtils @Inject constructor(
|
class NotificationUtils @Inject constructor(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val stringProvider: StringProvider,
|
private val stringProvider: StringProvider,
|
||||||
private val vectorPreferences: VectorPreferences,
|
private val vectorPreferences: VectorPreferences,
|
||||||
private val clock: Clock,
|
private val clock: Clock,
|
||||||
|
private val actionIds: NotificationActionIds,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -94,21 +90,6 @@ class NotificationUtils @Inject constructor(
|
|||||||
*/
|
*/
|
||||||
const val NOTIFICATION_ID_FOREGROUND_SERVICE = 61
|
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
|
* IDs for channels
|
||||||
* ========================================================================================== */
|
* ========================================================================================== */
|
||||||
@ -651,7 +632,7 @@ class NotificationUtils @Inject constructor(
|
|||||||
// Add actions and notification intents
|
// Add actions and notification intents
|
||||||
// Mark room as read
|
// Mark room as read
|
||||||
val markRoomReadIntent = Intent(context, NotificationBroadcastReceiver::class.java)
|
val markRoomReadIntent = Intent(context, NotificationBroadcastReceiver::class.java)
|
||||||
markRoomReadIntent.action = MARK_ROOM_READ_ACTION
|
markRoomReadIntent.action = actionIds.markRoomRead
|
||||||
markRoomReadIntent.data = createIgnoredUri(roomInfo.roomId)
|
markRoomReadIntent.data = createIgnoredUri(roomInfo.roomId)
|
||||||
markRoomReadIntent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomInfo.roomId)
|
markRoomReadIntent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomInfo.roomId)
|
||||||
val markRoomReadPendingIntent = PendingIntent.getBroadcast(
|
val markRoomReadPendingIntent = PendingIntent.getBroadcast(
|
||||||
@ -698,7 +679,7 @@ class NotificationUtils @Inject constructor(
|
|||||||
|
|
||||||
val intent = Intent(context, NotificationBroadcastReceiver::class.java)
|
val intent = Intent(context, NotificationBroadcastReceiver::class.java)
|
||||||
intent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomInfo.roomId)
|
intent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomInfo.roomId)
|
||||||
intent.action = DISMISS_ROOM_NOTIF_ACTION
|
intent.action = actionIds.dismissRoom
|
||||||
val pendingIntent = PendingIntent.getBroadcast(
|
val pendingIntent = PendingIntent.getBroadcast(
|
||||||
context.applicationContext,
|
context.applicationContext,
|
||||||
clock.epochMillis().toInt(),
|
clock.epochMillis().toInt(),
|
||||||
@ -733,7 +714,7 @@ class NotificationUtils @Inject constructor(
|
|||||||
val roomId = inviteNotifiableEvent.roomId
|
val roomId = inviteNotifiableEvent.roomId
|
||||||
// offer to type a quick reject button
|
// offer to type a quick reject button
|
||||||
val rejectIntent = Intent(context, NotificationBroadcastReceiver::class.java)
|
val rejectIntent = Intent(context, NotificationBroadcastReceiver::class.java)
|
||||||
rejectIntent.action = REJECT_ACTION
|
rejectIntent.action = actionIds.reject
|
||||||
rejectIntent.data = createIgnoredUri("$roomId&$matrixId")
|
rejectIntent.data = createIgnoredUri("$roomId&$matrixId")
|
||||||
rejectIntent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomId)
|
rejectIntent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomId)
|
||||||
val rejectIntentPendingIntent = PendingIntent.getBroadcast(
|
val rejectIntentPendingIntent = PendingIntent.getBroadcast(
|
||||||
@ -751,7 +732,7 @@ class NotificationUtils @Inject constructor(
|
|||||||
|
|
||||||
// offer to type a quick accept button
|
// offer to type a quick accept button
|
||||||
val joinIntent = Intent(context, NotificationBroadcastReceiver::class.java)
|
val joinIntent = Intent(context, NotificationBroadcastReceiver::class.java)
|
||||||
joinIntent.action = JOIN_ACTION
|
joinIntent.action = actionIds.join
|
||||||
joinIntent.data = createIgnoredUri("$roomId&$matrixId")
|
joinIntent.data = createIgnoredUri("$roomId&$matrixId")
|
||||||
joinIntent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomId)
|
joinIntent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomId)
|
||||||
val joinIntentPendingIntent = PendingIntent.getBroadcast(
|
val joinIntentPendingIntent = PendingIntent.getBroadcast(
|
||||||
@ -834,7 +815,7 @@ class NotificationUtils @Inject constructor(
|
|||||||
|
|
||||||
private fun buildOpenRoomIntent(roomId: String): PendingIntent? {
|
private fun buildOpenRoomIntent(roomId: String): PendingIntent? {
|
||||||
val roomIntentTap = RoomDetailActivity.newIntent(context, TimelineArgs(roomId = roomId, switchToParentSpace = true), true)
|
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
|
// 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")
|
roomIntentTap.data = createIgnoredUri("openRoom?$roomId")
|
||||||
|
|
||||||
@ -872,7 +853,7 @@ class NotificationUtils @Inject constructor(
|
|||||||
val intent: Intent
|
val intent: Intent
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
intent = Intent(context, NotificationBroadcastReceiver::class.java)
|
intent = Intent(context, NotificationBroadcastReceiver::class.java)
|
||||||
intent.action = SMART_REPLY_ACTION
|
intent.action = actionIds.smartReply
|
||||||
intent.data = createIgnoredUri(roomId)
|
intent.data = createIgnoredUri(roomId)
|
||||||
intent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomId)
|
intent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomId)
|
||||||
return PendingIntent.getBroadcast(
|
return PendingIntent.getBroadcast(
|
||||||
@ -948,7 +929,7 @@ class NotificationUtils @Inject constructor(
|
|||||||
|
|
||||||
private fun getDismissSummaryPendingIntent(): PendingIntent {
|
private fun getDismissSummaryPendingIntent(): PendingIntent {
|
||||||
val intent = Intent(context, NotificationBroadcastReceiver::class.java)
|
val intent = Intent(context, NotificationBroadcastReceiver::class.java)
|
||||||
intent.action = DISMISS_SUMMARY_ACTION
|
intent.action = actionIds.dismissSummary
|
||||||
intent.data = createIgnoredUri("deleteSummary")
|
intent.data = createIgnoredUri("deleteSummary")
|
||||||
return PendingIntent.getBroadcast(
|
return PendingIntent.getBroadcast(
|
||||||
context.applicationContext,
|
context.applicationContext,
|
||||||
@ -987,7 +968,7 @@ class NotificationUtils @Inject constructor(
|
|||||||
|
|
||||||
fun displayDiagnosticNotification() {
|
fun displayDiagnosticNotification() {
|
||||||
val testActionIntent = Intent(context, TestNotificationReceiver::class.java)
|
val testActionIntent = Intent(context, TestNotificationReceiver::class.java)
|
||||||
testActionIntent.action = DIAGNOSTIC_ACTION
|
testActionIntent.action = actionIds.diagnostic
|
||||||
val testPendingIntent = PendingIntent.getBroadcast(
|
val testPendingIntent = PendingIntent.getBroadcast(
|
||||||
context,
|
context,
|
||||||
0,
|
0,
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package im.vector.app.features.onboarding
|
package im.vector.app.features.onboarding
|
||||||
|
|
||||||
|
import im.vector.app.config.OnboardingVariant
|
||||||
import im.vector.app.core.platform.ScreenOrientationLocker
|
import im.vector.app.core.platform.ScreenOrientationLocker
|
||||||
import im.vector.app.databinding.ActivityLoginBinding
|
import im.vector.app.databinding.ActivityLoginBinding
|
||||||
import im.vector.app.features.VectorFeatures
|
import im.vector.app.features.VectorFeatures
|
||||||
@ -34,8 +35,8 @@ class OnboardingVariantFactory @Inject constructor(
|
|||||||
onboardingViewModel: Lazy<OnboardingViewModel>,
|
onboardingViewModel: Lazy<OnboardingViewModel>,
|
||||||
loginViewModel2: Lazy<LoginViewModel2>
|
loginViewModel2: Lazy<LoginViewModel2>
|
||||||
) = when (vectorFeatures.onboardingVariant()) {
|
) = when (vectorFeatures.onboardingVariant()) {
|
||||||
VectorFeatures.OnboardingVariant.LEGACY -> error("Legacy is not supported by the FTUE")
|
OnboardingVariant.LEGACY -> error("Legacy is not supported by the FTUE")
|
||||||
VectorFeatures.OnboardingVariant.FTUE_AUTH -> FtueAuthVariant(
|
OnboardingVariant.FTUE_AUTH -> FtueAuthVariant(
|
||||||
views = views,
|
views = views,
|
||||||
onboardingViewModel = onboardingViewModel.value,
|
onboardingViewModel = onboardingViewModel.value,
|
||||||
activity = activity,
|
activity = activity,
|
||||||
@ -43,7 +44,7 @@ class OnboardingVariantFactory @Inject constructor(
|
|||||||
vectorFeatures = vectorFeatures,
|
vectorFeatures = vectorFeatures,
|
||||||
orientationLocker = orientationLocker
|
orientationLocker = orientationLocker
|
||||||
)
|
)
|
||||||
VectorFeatures.OnboardingVariant.LOGIN_2 -> Login2Variant(
|
OnboardingVariant.LOGIN_2 -> Login2Variant(
|
||||||
views = views,
|
views = views,
|
||||||
loginViewModel = loginViewModel2.value,
|
loginViewModel = loginViewModel2.value,
|
||||||
activity = activity,
|
activity = activity,
|
||||||
|
@ -32,7 +32,6 @@ import im.vector.app.core.extensions.isMatrixId
|
|||||||
import im.vector.app.core.extensions.toReducedUrl
|
import im.vector.app.core.extensions.toReducedUrl
|
||||||
import im.vector.app.core.extensions.vectorStore
|
import im.vector.app.core.extensions.vectorStore
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
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.resources.StringProvider
|
||||||
import im.vector.app.core.utils.ensureProtocol
|
import im.vector.app.core.utils.ensureProtocol
|
||||||
import im.vector.app.core.utils.ensureTrailingSlash
|
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.auth.registration.RegistrationWizard
|
||||||
import org.matrix.android.sdk.api.failure.isHomeserverUnavailable
|
import org.matrix.android.sdk.api.failure.isHomeserverUnavailable
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
|
import org.matrix.android.sdk.api.util.BuildVersionSdkIntProvider
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import java.util.concurrent.CancellationException
|
import java.util.concurrent.CancellationException
|
||||||
@ -86,7 +86,7 @@ class OnboardingViewModel @AssistedInject constructor(
|
|||||||
private val startAuthenticationFlowUseCase: StartAuthenticationFlowUseCase,
|
private val startAuthenticationFlowUseCase: StartAuthenticationFlowUseCase,
|
||||||
private val vectorOverrides: VectorOverrides,
|
private val vectorOverrides: VectorOverrides,
|
||||||
private val registrationActionHandler: RegistrationActionHandler,
|
private val registrationActionHandler: RegistrationActionHandler,
|
||||||
private val buildMeta: BuildMeta,
|
private val sdkIntProvider: BuildVersionSdkIntProvider,
|
||||||
) : VectorViewModel<OnboardingViewState, OnboardingAction, OnboardingViewEvents>(initialState) {
|
) : VectorViewModel<OnboardingViewState, OnboardingAction, OnboardingViewEvents>(initialState) {
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
@ -708,7 +708,7 @@ class OnboardingViewModel @AssistedInject constructor(
|
|||||||
|
|
||||||
private fun onAuthenticationStartError(error: Throwable, trigger: OnboardingAction.HomeServerChange) {
|
private fun onAuthenticationStartError(error: Throwable, trigger: OnboardingAction.HomeServerChange) {
|
||||||
when {
|
when {
|
||||||
error.isHomeserverUnavailable() && applicationContext.inferNoConnectivity(buildMeta) -> _viewEvents.post(
|
error.isHomeserverUnavailable() && applicationContext.inferNoConnectivity(sdkIntProvider) -> _viewEvents.post(
|
||||||
OnboardingViewEvents.Failure(error)
|
OnboardingViewEvents.Failure(error)
|
||||||
)
|
)
|
||||||
deeplinkUrlIsUnavailable(error, trigger) -> _viewEvents.post(
|
deeplinkUrlIsUnavailable(error, trigger) -> _viewEvents.post(
|
||||||
|
@ -27,9 +27,9 @@ import androidx.core.view.isInvisible
|
|||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.google.android.material.textfield.TextInputLayout
|
import com.google.android.material.textfield.TextInputLayout
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.extensions.hideKeyboard
|
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.ensureProtocol
|
||||||
import im.vector.app.core.utils.openUrlInChromeCustomTab
|
import im.vector.app.core.utils.openUrlInChromeCustomTab
|
||||||
import im.vector.app.databinding.FragmentLoginServerUrlFormBinding
|
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.
|
* 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 {
|
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginServerUrlFormBinding {
|
||||||
return FragmentLoginServerUrlFormBinding.inflate(inflater, container, false)
|
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)
|
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(
|
views.loginServerUrlFormHomeServerUrl.setAdapter(
|
||||||
ArrayAdapter(
|
ArrayAdapter(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
|
@ -27,10 +27,10 @@ import androidx.lifecycle.LifecycleOwner
|
|||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.viewpager2.widget.ViewPager2
|
import androidx.viewpager2.widget.ViewPager2
|
||||||
import com.google.android.material.tabs.TabLayoutMediator
|
import com.google.android.material.tabs.TabLayoutMediator
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.extensions.incrementByOneAndWrap
|
import im.vector.app.core.extensions.incrementByOneAndWrap
|
||||||
import im.vector.app.core.extensions.setCurrentItem
|
import im.vector.app.core.extensions.setCurrentItem
|
||||||
|
import im.vector.app.core.resources.BuildMeta
|
||||||
import im.vector.app.databinding.FragmentFtueSplashCarouselBinding
|
import im.vector.app.databinding.FragmentFtueSplashCarouselBinding
|
||||||
import im.vector.app.features.VectorFeatures
|
import im.vector.app.features.VectorFeatures
|
||||||
import im.vector.app.features.onboarding.OnboardingAction
|
import im.vector.app.features.onboarding.OnboardingAction
|
||||||
@ -48,7 +48,8 @@ class FtueAuthSplashCarouselFragment @Inject constructor(
|
|||||||
private val vectorPreferences: VectorPreferences,
|
private val vectorPreferences: VectorPreferences,
|
||||||
private val vectorFeatures: VectorFeatures,
|
private val vectorFeatures: VectorFeatures,
|
||||||
private val carouselController: SplashCarouselController,
|
private val carouselController: SplashCarouselController,
|
||||||
private val carouselStateFactory: SplashCarouselStateFactory
|
private val carouselStateFactory: SplashCarouselStateFactory,
|
||||||
|
private val buildMeta: BuildMeta,
|
||||||
) : AbstractFtueAuthFragment<FragmentFtueSplashCarouselBinding>() {
|
) : AbstractFtueAuthFragment<FragmentFtueSplashCarouselBinding>() {
|
||||||
|
|
||||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtueSplashCarouselBinding {
|
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtueSplashCarouselBinding {
|
||||||
@ -76,11 +77,11 @@ class FtueAuthSplashCarouselFragment @Inject constructor(
|
|||||||
debouncedClicks { alreadyHaveAnAccount() }
|
debouncedClicks { alreadyHaveAnAccount() }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BuildConfig.DEBUG || vectorPreferences.developerMode()) {
|
if (buildMeta.isDebug || vectorPreferences.developerMode()) {
|
||||||
views.loginSplashVersion.isVisible = true
|
views.loginSplashVersion.isVisible = true
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
views.loginSplashVersion.text = "Version : ${BuildConfig.VERSION_NAME}#${BuildConfig.BUILD_NUMBER}\n" +
|
views.loginSplashVersion.text = "Version : ${buildMeta.versionName}#${buildMeta.buildNumber}\n" +
|
||||||
"Branch: ${BuildConfig.GIT_BRANCH_NAME}"
|
"Branch: ${buildMeta.gitBranchName}"
|
||||||
views.loginSplashVersion.debouncedClicks { navigator.openDebug(requireContext()) }
|
views.loginSplashVersion.debouncedClicks { navigator.openDebug(requireContext()) }
|
||||||
}
|
}
|
||||||
views.splashCarousel.registerAutomaticUntilInteractionTransitions()
|
views.splashCarousel.registerAutomaticUntilInteractionTransitions()
|
||||||
|
@ -22,8 +22,8 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.resources.BuildMeta
|
||||||
import im.vector.app.databinding.FragmentFtueAuthSplashBinding
|
import im.vector.app.databinding.FragmentFtueAuthSplashBinding
|
||||||
import im.vector.app.features.VectorFeatures
|
import im.vector.app.features.VectorFeatures
|
||||||
import im.vector.app.features.onboarding.OnboardingAction
|
import im.vector.app.features.onboarding.OnboardingAction
|
||||||
@ -36,7 +36,8 @@ import javax.inject.Inject
|
|||||||
*/
|
*/
|
||||||
class FtueAuthSplashFragment @Inject constructor(
|
class FtueAuthSplashFragment @Inject constructor(
|
||||||
private val vectorPreferences: VectorPreferences,
|
private val vectorPreferences: VectorPreferences,
|
||||||
private val vectorFeatures: VectorFeatures
|
private val vectorFeatures: VectorFeatures,
|
||||||
|
private val buildMeta: BuildMeta,
|
||||||
) : AbstractFtueAuthFragment<FragmentFtueAuthSplashBinding>() {
|
) : AbstractFtueAuthFragment<FragmentFtueAuthSplashBinding>() {
|
||||||
|
|
||||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtueAuthSplashBinding {
|
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtueAuthSplashBinding {
|
||||||
@ -59,12 +60,12 @@ class FtueAuthSplashFragment @Inject constructor(
|
|||||||
debouncedClicks { alreadyHaveAnAccount() }
|
debouncedClicks { alreadyHaveAnAccount() }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BuildConfig.DEBUG || vectorPreferences.developerMode()) {
|
if (buildMeta.isDebug || vectorPreferences.developerMode()) {
|
||||||
views.loginSplashVersion.isVisible = true
|
views.loginSplashVersion.isVisible = true
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
views.loginSplashVersion.text = "Version : ${BuildConfig.VERSION_NAME}\n" +
|
views.loginSplashVersion.text = "Version : ${buildMeta.versionName}\n" +
|
||||||
"Branch: ${BuildConfig.GIT_BRANCH_NAME}\n" +
|
"Branch: ${buildMeta.gitBranchName}\n" +
|
||||||
"Build: ${BuildConfig.BUILD_NUMBER}"
|
"Build: ${buildMeta.buildNumber}"
|
||||||
views.loginSplashVersion.debouncedClicks { navigator.openDebug(requireContext()) }
|
views.loginSplashVersion.debouncedClicks { navigator.openDebug(requireContext()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import im.vector.app.R
|
|||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
import im.vector.app.core.extensions.getAllChildFragments
|
import im.vector.app.core.extensions.getAllChildFragments
|
||||||
import im.vector.app.core.extensions.toOnOff
|
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.VectorLocale
|
||||||
import im.vector.app.features.settings.VectorPreferences
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
import im.vector.app.features.settings.devtools.GossipingEventsSerializer
|
import im.vector.app.features.settings.devtools.GossipingEventsSerializer
|
||||||
@ -50,6 +51,7 @@ import okhttp3.Response
|
|||||||
import org.json.JSONException
|
import org.json.JSONException
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import org.matrix.android.sdk.api.Matrix
|
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.JsonDict
|
||||||
import org.matrix.android.sdk.api.util.MatrixJsonParser
|
import org.matrix.android.sdk.api.util.MatrixJsonParser
|
||||||
import org.matrix.android.sdk.api.util.MimeTypes
|
import org.matrix.android.sdk.api.util.MimeTypes
|
||||||
@ -74,7 +76,9 @@ class BugReporter @Inject constructor(
|
|||||||
private val vectorPreferences: VectorPreferences,
|
private val vectorPreferences: VectorPreferences,
|
||||||
private val vectorFileLogger: VectorFileLogger,
|
private val vectorFileLogger: VectorFileLogger,
|
||||||
private val systemLocaleProvider: SystemLocaleProvider,
|
private val systemLocaleProvider: SystemLocaleProvider,
|
||||||
private val matrix: Matrix
|
private val matrix: Matrix,
|
||||||
|
private val buildMeta: BuildMeta,
|
||||||
|
private val sdkIntProvider: BuildVersionSdkIntProvider,
|
||||||
) {
|
) {
|
||||||
var inMultiWindowMode = false
|
var inMultiWindowMode = false
|
||||||
|
|
||||||
@ -278,14 +282,14 @@ class BugReporter @Inject constructor(
|
|||||||
.addFormDataPart("can_contact", canContact.toString())
|
.addFormDataPart("can_contact", canContact.toString())
|
||||||
.addFormDataPart("device_id", deviceId)
|
.addFormDataPart("device_id", deviceId)
|
||||||
.addFormDataPart("version", versionProvider.getVersion(longFormat = true, useBuildNumber = false))
|
.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("matrix_sdk_version", Matrix.getSdkVersion())
|
||||||
.addFormDataPart("olm_version", olmVersion)
|
.addFormDataPart("olm_version", olmVersion)
|
||||||
.addFormDataPart("device", Build.MODEL.trim())
|
.addFormDataPart("device", Build.MODEL.trim())
|
||||||
.addFormDataPart("verbose_log", vectorPreferences.labAllowedExtendedLogging().toOnOff())
|
.addFormDataPart("verbose_log", vectorPreferences.labAllowedExtendedLogging().toOnOff())
|
||||||
.addFormDataPart("multi_window", inMultiWindowMode.toOnOff())
|
.addFormDataPart("multi_window", inMultiWindowMode.toOnOff())
|
||||||
.addFormDataPart(
|
.addFormDataPart(
|
||||||
"os", Build.VERSION.RELEASE + " (API " + Build.VERSION.SDK_INT + ") " +
|
"os", Build.VERSION.RELEASE + " (API " + sdkIntProvider.get() + ") " +
|
||||||
Build.VERSION.INCREMENTAL + "-" + Build.VERSION.CODENAME
|
Build.VERSION.INCREMENTAL + "-" + Build.VERSION.CODENAME
|
||||||
)
|
)
|
||||||
.addFormDataPart("locale", Locale.getDefault().toString())
|
.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") {
|
if (buildNumber.isNotEmpty() && buildNumber != "0") {
|
||||||
builder.addFormDataPart("build_number", buildNumber)
|
builder.addFormDataPart("build_number", buildNumber)
|
||||||
}
|
}
|
||||||
@ -339,9 +343,9 @@ class BugReporter @Inject constructor(
|
|||||||
screenshot = null
|
screenshot = null
|
||||||
|
|
||||||
// add some github labels
|
// add some github labels
|
||||||
builder.addFormDataPart("label", BuildConfig.VERSION_NAME)
|
builder.addFormDataPart("label", buildMeta.versionName)
|
||||||
builder.addFormDataPart("label", BuildConfig.FLAVOR_DESCRIPTION)
|
builder.addFormDataPart("label", buildMeta.flavorDescription)
|
||||||
builder.addFormDataPart("label", BuildConfig.GIT_BRANCH_NAME)
|
builder.addFormDataPart("label", buildMeta.gitBranchName)
|
||||||
|
|
||||||
// Special for Element
|
// Special for Element
|
||||||
builder.addFormDataPart("label", "[Element]")
|
builder.addFormDataPart("label", "[Element]")
|
||||||
|
@ -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
|
||||||
|
)
|
@ -68,7 +68,7 @@ data class E2EWellKnownConfig(
|
|||||||
val secureBackupSetupMethods: List<String>? = null,
|
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.
|
* One of on_room_opening, on_typing or disabled.
|
||||||
*/
|
*/
|
||||||
@Json(name = "outbound_keys_pre_sharing_mode")
|
@Json(name = "outbound_keys_pre_sharing_mode")
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package im.vector.app.features.raw.wellknown
|
package im.vector.app.features.raw.wellknown
|
||||||
|
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy
|
import im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
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.isE2EByDefault() = elementE2E?.e2eDefault ?: riotE2E?.e2eDefault ?: true
|
||||||
|
|
||||||
fun ElementWellKnown?.getOutboundSessionKeySharingStrategyOrDefault(): OutboundSessionKeySharingStrategy {
|
fun ElementWellKnown?.getOutboundSessionKeySharingStrategyOrDefault(fallback: OutboundSessionKeySharingStrategy): OutboundSessionKeySharingStrategy {
|
||||||
return when (this?.elementE2E?.outboundsKeyPreSharingMode) {
|
return when (this?.elementE2E?.outboundsKeyPreSharingMode) {
|
||||||
"on_room_opening" -> OutboundSessionKeySharingStrategy.WhenEnteringRoom
|
"on_room_opening" -> OutboundSessionKeySharingStrategy.WhenEnteringRoom
|
||||||
"on_typing" -> OutboundSessionKeySharingStrategy.WhenTyping
|
"on_typing" -> OutboundSessionKeySharingStrategy.WhenTyping
|
||||||
"disabled" -> OutboundSessionKeySharingStrategy.WhenSendingEvent
|
"disabled" -> OutboundSessionKeySharingStrategy.WhenSendingEvent
|
||||||
else -> BuildConfig.outboundSessionKeySharingStrategy
|
else -> fallback
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,9 +19,9 @@ package im.vector.app.features.settings
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.di.DefaultSharedPreferences
|
import im.vector.app.core.di.DefaultSharedPreferences
|
||||||
|
import im.vector.app.core.resources.BuildMeta
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -53,12 +53,14 @@ object VectorLocale {
|
|||||||
private set
|
private set
|
||||||
|
|
||||||
private lateinit var context: Context
|
private lateinit var context: Context
|
||||||
|
private lateinit var buildMeta: BuildMeta
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Init this object.
|
* Init this object.
|
||||||
*/
|
*/
|
||||||
fun init(context: Context) {
|
fun init(context: Context, buildMeta: BuildMeta) {
|
||||||
this.context = context
|
this.context = context
|
||||||
|
this.buildMeta = buildMeta
|
||||||
val preferences = DefaultSharedPreferences.getInstance(context)
|
val preferences = DefaultSharedPreferences.getInstance(context)
|
||||||
|
|
||||||
if (preferences.contains(APPLICATION_LOCALE_LANGUAGE_KEY)) {
|
if (preferences.contains(APPLICATION_LOCALE_LANGUAGE_KEY)) {
|
||||||
@ -174,7 +176,7 @@ object VectorLocale {
|
|||||||
.setScript(script)
|
.setScript(script)
|
||||||
.build()
|
.build()
|
||||||
} catch (exception: IllformedLocaleException) {
|
} catch (exception: IllformedLocaleException) {
|
||||||
if (BuildConfig.DEBUG) {
|
if (buildMeta.isDebug) {
|
||||||
throw exception
|
throw exception
|
||||||
}
|
}
|
||||||
// Ignore this locale in production
|
// Ignore this locale in production
|
||||||
|
@ -23,9 +23,9 @@ import android.provider.MediaStore
|
|||||||
import androidx.annotation.BoolRes
|
import androidx.annotation.BoolRes
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import com.squareup.seismic.ShakeDetector
|
import com.squareup.seismic.ShakeDetector
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.di.DefaultSharedPreferences
|
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.core.time.Clock
|
||||||
import im.vector.app.features.disclaimer.SHARED_PREF_KEY
|
import im.vector.app.features.disclaimer.SHARED_PREF_KEY
|
||||||
import im.vector.app.features.home.ShortcutsHandler
|
import im.vector.app.features.home.ShortcutsHandler
|
||||||
@ -38,6 +38,7 @@ import javax.inject.Inject
|
|||||||
class VectorPreferences @Inject constructor(
|
class VectorPreferences @Inject constructor(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val clock: Clock,
|
private val clock: Clock,
|
||||||
|
private val buildMeta: BuildMeta,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -364,7 +365,7 @@ class VectorPreferences @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun failFast(): Boolean {
|
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 {
|
fun didAskUserToEnableSessionPush(): Boolean {
|
||||||
|
@ -18,10 +18,10 @@ package im.vector.app.features.settings
|
|||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
import im.vector.app.BuildConfig
|
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.extensions.orEmpty
|
import im.vector.app.core.extensions.orEmpty
|
||||||
import im.vector.app.core.preference.VectorPreference
|
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.FirstThrottler
|
||||||
import im.vector.app.core.utils.copyToClipboard
|
import im.vector.app.core.utils.copyToClipboard
|
||||||
import im.vector.app.core.utils.openAppSettingsPage
|
import im.vector.app.core.utils.openAppSettingsPage
|
||||||
@ -32,7 +32,8 @@ import org.matrix.android.sdk.api.Matrix
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class VectorSettingsHelpAboutFragment @Inject constructor(
|
class VectorSettingsHelpAboutFragment @Inject constructor(
|
||||||
private val versionProvider: VersionProvider
|
private val versionProvider: VersionProvider,
|
||||||
|
private val buildMeta: BuildMeta,
|
||||||
) : VectorSettingsBaseFragment() {
|
) : VectorSettingsBaseFragment() {
|
||||||
|
|
||||||
override var titleRes = R.string.preference_root_help_about
|
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 {
|
findPreference<VectorPreference>(VectorPreferences.SETTINGS_VERSION_PREFERENCE_KEY)!!.let {
|
||||||
it.summary = buildString {
|
it.summary = buildString {
|
||||||
append(versionProvider.getVersion(longFormat = false, useBuildNumber = true))
|
append(versionProvider.getVersion(longFormat = false, useBuildNumber = true))
|
||||||
if (BuildConfig.DEBUG) {
|
if (buildMeta.isDebug) {
|
||||||
append(" ")
|
append(" ")
|
||||||
append(BuildConfig.GIT_BRANCH_NAME)
|
append(buildMeta.gitBranchName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,6 @@ import androidx.recyclerview.widget.RecyclerView
|
|||||||
import com.airbnb.mvrx.fragmentViewModel
|
import com.airbnb.mvrx.fragmentViewModel
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.config.analyticsConfig
|
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
import im.vector.app.core.dialogs.ExportKeysDialog
|
import im.vector.app.core.dialogs.ExportKeysDialog
|
||||||
import im.vector.app.core.extensions.queryExportKeys
|
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.openFileSelection
|
||||||
import im.vector.app.core.utils.toast
|
import im.vector.app.core.utils.toast
|
||||||
import im.vector.app.databinding.DialogImportE2eKeysBinding
|
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.plan.MobileScreen
|
||||||
import im.vector.app.features.analytics.ui.consent.AnalyticsConsentViewActions
|
import im.vector.app.features.analytics.ui.consent.AnalyticsConsentViewActions
|
||||||
import im.vector.app.features.analytics.ui.consent.AnalyticsConsentViewModel
|
import im.vector.app.features.analytics.ui.consent.AnalyticsConsentViewModel
|
||||||
@ -84,7 +84,8 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
|
|||||||
private val keysExporter: KeysExporter,
|
private val keysExporter: KeysExporter,
|
||||||
private val keysImporter: KeysImporter,
|
private val keysImporter: KeysImporter,
|
||||||
private val rawService: RawService,
|
private val rawService: RawService,
|
||||||
private val navigator: Navigator
|
private val navigator: Navigator,
|
||||||
|
private val analyticsConfig: AnalyticsConfig,
|
||||||
) : VectorSettingsBaseFragment() {
|
) : VectorSettingsBaseFragment() {
|
||||||
|
|
||||||
override var titleRes = R.string.settings_security_and_privacy
|
override var titleRes = R.string.settings_security_and_privacy
|
||||||
|
@ -34,7 +34,7 @@ import im.vector.app.core.extensions.cleanup
|
|||||||
import im.vector.app.core.extensions.registerStartForActivityResult
|
import im.vector.app.core.extensions.registerStartForActivityResult
|
||||||
import im.vector.app.core.platform.VectorBaseFragment
|
import im.vector.app.core.platform.VectorBaseFragment
|
||||||
import im.vector.app.databinding.FragmentSettingsNotificationsTroubleshootBinding
|
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.rageshake.BugReporter
|
||||||
import im.vector.app.features.settings.VectorSettingsFragmentInteractionListener
|
import im.vector.app.features.settings.VectorSettingsFragmentInteractionListener
|
||||||
import im.vector.app.features.settings.troubleshoot.NotificationTroubleshootTestManager
|
import im.vector.app.features.settings.troubleshoot.NotificationTroubleshootTestManager
|
||||||
@ -46,7 +46,8 @@ import javax.inject.Inject
|
|||||||
|
|
||||||
class VectorSettingsNotificationsTroubleshootFragment @Inject constructor(
|
class VectorSettingsNotificationsTroubleshootFragment @Inject constructor(
|
||||||
private val bugReporter: BugReporter,
|
private val bugReporter: BugReporter,
|
||||||
private val testManagerFactory: NotificationTroubleshootTestManagerFactory
|
private val testManagerFactory: NotificationTroubleshootTestManagerFactory,
|
||||||
|
private val actionIds: NotificationActionIds,
|
||||||
) : VectorBaseFragment<FragmentSettingsNotificationsTroubleshootBinding>() {
|
) : VectorBaseFragment<FragmentSettingsNotificationsTroubleshootBinding>() {
|
||||||
|
|
||||||
private var testManager: NotificationTroubleshootTestManager? = null
|
private var testManager: NotificationTroubleshootTestManager? = null
|
||||||
@ -151,11 +152,11 @@ class VectorSettingsNotificationsTroubleshootFragment @Inject constructor(
|
|||||||
|
|
||||||
tryOrNull("Unable to register the receiver") {
|
tryOrNull("Unable to register the receiver") {
|
||||||
LocalBroadcastManager.getInstance(requireContext())
|
LocalBroadcastManager.getInstance(requireContext())
|
||||||
.registerReceiver(broadcastReceiverPush, IntentFilter(NotificationUtils.PUSH_ACTION))
|
.registerReceiver(broadcastReceiverPush, IntentFilter(actionIds.push))
|
||||||
}
|
}
|
||||||
tryOrNull("Unable to register the receiver") {
|
tryOrNull("Unable to register the receiver") {
|
||||||
LocalBroadcastManager.getInstance(requireContext())
|
LocalBroadcastManager.getInstance(requireContext())
|
||||||
.registerReceiver(broadcastReceiverNotification, IntentFilter(NotificationUtils.DIAGNOSTIC_ACTION))
|
.registerReceiver(broadcastReceiverNotification, IntentFilter(actionIds.diagnostic))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,24 +16,27 @@
|
|||||||
|
|
||||||
package im.vector.app.features.version
|
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 im.vector.app.core.resources.VersionCodeProvider
|
||||||
import javax.inject.Inject
|
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 {
|
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()) {
|
if (flavor.isNotBlank()) {
|
||||||
flavor += "-"
|
flavor += "-"
|
||||||
}
|
}
|
||||||
|
|
||||||
var gitVersion = BuildConfig.GIT_REVISION
|
var gitVersion = buildMeta.gitRevision
|
||||||
val gitRevisionDate = BuildConfig.GIT_REVISION_DATE
|
val gitRevisionDate = buildMeta.gitRevisionDate
|
||||||
val buildNumber = BuildConfig.BUILD_NUMBER
|
val buildNumber = buildMeta.buildNumber
|
||||||
|
|
||||||
var useLongFormat = longFormat
|
var useLongFormat = longFormat
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ import im.vector.app.features.session.coroutineScope
|
|||||||
import im.vector.app.test.fakes.FakeActiveSessionHolder
|
import im.vector.app.test.fakes.FakeActiveSessionHolder
|
||||||
import im.vector.app.test.fakes.FakeContext
|
import im.vector.app.test.fakes.FakeContext
|
||||||
import im.vector.app.test.fakes.FakeLocationManager
|
import im.vector.app.test.fakes.FakeLocationManager
|
||||||
|
import im.vector.app.test.fixtures.aBuildMeta
|
||||||
import im.vector.app.test.test
|
import im.vector.app.test.test
|
||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
import io.mockk.just
|
import io.mockk.just
|
||||||
@ -56,7 +57,7 @@ class LocationTrackerTest {
|
|||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
mockkStatic("im.vector.app.features.session.SessionCoroutineScopesKt")
|
mockkStatic("im.vector.app.features.session.SessionCoroutineScopesKt")
|
||||||
locationTracker = LocationTracker(fakeContext.instance, fakeActiveSessionHolder.instance)
|
locationTracker = LocationTracker(fakeContext.instance, fakeActiveSessionHolder.instance, aBuildMeta())
|
||||||
fakeLocationManager.givenRemoveUpdates(locationTracker)
|
fakeLocationManager.givenRemoveUpdates(locationTracker)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package im.vector.app.features.onboarding
|
package im.vector.app.features.onboarding
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.os.Build
|
||||||
import com.airbnb.mvrx.test.MvRxTestRule
|
import com.airbnb.mvrx.test.MvRxTestRule
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.features.login.LoginConfig
|
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.ReAuthHelper
|
||||||
import im.vector.app.features.login.SignMode
|
import im.vector.app.features.login.SignMode
|
||||||
import im.vector.app.features.onboarding.StartAuthenticationFlowUseCase.StartAuthenticationResult
|
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.FakeActiveSessionHolder
|
||||||
import im.vector.app.test.fakes.FakeAnalyticsTracker
|
import im.vector.app.test.fakes.FakeAnalyticsTracker
|
||||||
import im.vector.app.test.fakes.FakeAuthenticationService
|
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.FakeVectorOverrides
|
||||||
import im.vector.app.test.fakes.toTestString
|
import im.vector.app.test.fakes.toTestString
|
||||||
import im.vector.app.test.fixtures.a401ServerError
|
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.fixtures.aHomeServerCapabilities
|
||||||
import im.vector.app.test.test
|
import im.vector.app.test.test
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
@ -720,7 +721,7 @@ class OnboardingViewModelTest {
|
|||||||
fakeStartAuthenticationFlowUseCase.instance,
|
fakeStartAuthenticationFlowUseCase.instance,
|
||||||
FakeVectorOverrides(),
|
FakeVectorOverrides(),
|
||||||
fakeRegistrationActionHandler.instance,
|
fakeRegistrationActionHandler.instance,
|
||||||
aBuildMeta(),
|
TestBuildVersionSdkIntProvider().also { it.value = Build.VERSION_CODES.O },
|
||||||
).also {
|
).also {
|
||||||
viewModel = it
|
viewModel = it
|
||||||
initialState = state
|
initialState = state
|
||||||
|
@ -24,10 +24,5 @@ object AnalyticsConfigFixture {
|
|||||||
postHogHost: String = "http://posthog.url",
|
postHogHost: String = "http://posthog.url",
|
||||||
postHogApiKey: String = "api-key",
|
postHogApiKey: String = "api-key",
|
||||||
policyLink: String = "http://policy.link"
|
policyLink: String = "http://policy.link"
|
||||||
) = object : AnalyticsConfig {
|
) = AnalyticsConfig(isEnabled, postHogHost, postHogApiKey, policyLink)
|
||||||
override val isEnabled: Boolean = isEnabled
|
|
||||||
override val postHogHost = postHogHost
|
|
||||||
override val postHogApiKey = postHogApiKey
|
|
||||||
override val policyLink = policyLink
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,17 @@
|
|||||||
|
|
||||||
package im.vector.app.test.fixtures
|
package im.vector.app.test.fixtures
|
||||||
|
|
||||||
import android.os.Build
|
|
||||||
import im.vector.app.core.resources.BuildMeta
|
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 = "",
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user