Skip to content

Commit

Permalink
Merge pull request #8780 from element-hq/valere/utd_posthog_more_prop…
Browse files Browse the repository at this point in the history
…erties

UTD posthog reporting add more properties to captured event
  • Loading branch information
BillCarsonFr authored Apr 2, 2024
2 parents 237580c + 752c884 commit 0f3ff2e
Show file tree
Hide file tree
Showing 16 changed files with 1,088 additions and 110 deletions.
1 change: 1 addition & 0 deletions changelog.d/8780.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Improve UTD reporting by adding additional fields to the report.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package org.matrix.android.sdk.api.session

import org.matrix.android.sdk.api.session.crypto.MXCryptoError
import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.util.JsonDict

Expand All @@ -27,7 +28,7 @@ interface LiveEventListener {

fun onEventDecrypted(event: Event, clearEvent: JsonDict)

fun onEventDecryptionError(event: Event, throwable: Throwable)
fun onEventDecryptionError(event: Event, cryptoError: MXCryptoError)

fun onLiveToDeviceEvent(event: Event)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,6 @@ internal class Device @AssistedInject constructor(
* This will not fetch out fresh data from the Rust side.
**/
internal fun toCryptoDeviceInfo(): CryptoDeviceInfo {
// val keys = innerDevice.keys.map { (keyId, key) -> keyId to key }.toMap()

return CryptoDeviceInfo(
deviceId = innerDevice.deviceId,
userId = innerDevice.userId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,18 +189,21 @@ internal class OlmMachine @Inject constructor(
is OwnUserIdentity -> ownIdentity.trustsOurOwnDevice()
else -> false
}
val ownDevice = inner.getDevice(userId(), deviceId, 0u)!!
val creationTime = ownDevice.firstTimeSeenTs.toLong()

return CryptoDeviceInfo(
deviceId(),
userId(),
// TODO pass the algorithms here.
listOf(),
ownDevice.algorithms,
keys,
mapOf(),
UnsignedDeviceInfo(),
UnsignedDeviceInfo(
deviceDisplayName = ownDevice.displayName
),
DeviceTrustLevel(crossSigningVerified, locallyVerified = true),
false,
null
creationTime
)
}

Expand Down Expand Up @@ -291,7 +294,7 @@ internal class OlmMachine @Inject constructor(
// checking the returned to devices to check for room keys.
// XXX Anyhow there is now proper signaling we should soon stop parsing them manually
receiveSyncChanges.toDeviceEvents.map {
outAdapter.fromJson(it) ?: Event()
outAdapter.fromJson(it) ?: Event()
}
}

Expand Down Expand Up @@ -882,6 +885,7 @@ internal class OlmMachine @Inject constructor(
inner.queryMissingSecretsFromOtherSessions()
}
}

@Throws(CryptoStoreException::class)
suspend fun enableBackupV1(key: String, version: String) {
return withContext(coroutineDispatchers.computation) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.session.LiveEventListener
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
import org.matrix.android.sdk.api.session.crypto.model.MXEventDecryptionResult
import org.matrix.android.sdk.api.session.events.model.Event
import timber.log.Timber
Expand Down Expand Up @@ -75,7 +76,7 @@ internal class StreamEventsManager @Inject constructor() {
}
}

fun dispatchLiveEventDecryptionFailed(event: Event, error: Throwable) {
fun dispatchLiveEventDecryptionFailed(event: Event, error: MXCryptoError) {
Timber.v("## dispatchLiveEventDecryptionFailed ${event.eventId}")
coroutineScope.launch {
listeners.forEach {
Expand Down
3 changes: 3 additions & 0 deletions vector-app/src/main/java/im/vector/app/VectorApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import im.vector.app.core.debug.LeakDetector
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.pushers.FcmHelper
import im.vector.app.core.resources.BuildMeta
import im.vector.app.features.analytics.DecryptionFailureTracker
import im.vector.app.features.analytics.VectorAnalytics
import im.vector.app.features.call.webrtc.WebRtcCallManager
import im.vector.app.features.configuration.VectorConfiguration
Expand Down Expand Up @@ -100,6 +101,7 @@ class VectorApplication :
@Inject lateinit var callManager: WebRtcCallManager
@Inject lateinit var invitesAcceptor: InvitesAcceptor
@Inject lateinit var autoRageShaker: AutoRageShaker
@Inject lateinit var decryptionFailureTracker: DecryptionFailureTracker
@Inject lateinit var vectorFileLogger: VectorFileLogger
@Inject lateinit var vectorAnalytics: VectorAnalytics
@Inject lateinit var flipperProxy: FlipperProxy
Expand Down Expand Up @@ -130,6 +132,7 @@ class VectorApplication :
vectorAnalytics.init()
invitesAcceptor.initialize()
autoRageShaker.initialize()
decryptionFailureTracker.start()
vectorUncaughtExceptionHandler.activate()

// Remove Log handler statically added by Jitsi
Expand Down
3 changes: 2 additions & 1 deletion vector/src/main/java/im/vector/app/UISIDetector.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package im.vector.app

import org.matrix.android.sdk.api.extensions.orFalse
import org.matrix.android.sdk.api.session.LiveEventListener
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent
import org.matrix.android.sdk.api.session.events.model.toModel
Expand Down Expand Up @@ -84,7 +85,7 @@ class UISIDetector(private val timeoutMillis: Long = 30_000L) : LiveEventListene
}
}

override fun onEventDecryptionError(event: Event, throwable: Throwable) {
override fun onEventDecryptionError(event: Event, cryptoError: MXCryptoError) {
val eventId = event.eventId
val roomId = event.roomId
if (!enabled || eventId == null || roomId == null) return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase
import im.vector.app.core.services.GuardServiceStarter
import im.vector.app.core.session.ConfigureAndStartSessionUseCase
import im.vector.app.features.analytics.DecryptionFailureTracker
import im.vector.app.features.analytics.plan.Error
import im.vector.app.features.call.webrtc.WebRtcCallManager
import im.vector.app.features.crypto.keysrequest.KeyRequestHandler
import im.vector.app.features.crypto.verification.IncomingVerificationRequestHandler
Expand Down Expand Up @@ -75,11 +74,6 @@ class ActiveSessionHolder @Inject constructor(
session.callSignalingService().addCallListener(callManager)
imageManager.onSessionStarted(session)
guardServiceStarter.start()
decryptionFailureTracker.currentModule = if (session.cryptoService().name() == "rust-sdk") {
Error.CryptoModule.Rust
} else {
Error.CryptoModule.Native
}
}

suspend fun clearActiveSession() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright (c) 2024 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.analytics

import im.vector.app.features.analytics.plan.Error
import org.matrix.android.sdk.api.session.crypto.MXCryptoError

data class DecryptionFailure(
val timeStamp: Long,
val roomId: String,
val failedEventId: String,
val error: MXCryptoError,
val wasVisibleOnScreen: Boolean,
val ownIdentityTrustedAtTimeOfDecryptionFailure: Boolean,
// If this is set, it means that the event was decrypted but late. Will be -1 if
// the event was not decrypted after the maximum wait time.
val timeToDecryptMillis: Long? = null,
val isMatrixDotOrg: Boolean,
val isFederated: Boolean? = null,
val eventLocalAgeAtDecryptionFailure: Long? = null
)

fun DecryptionFailure.toAnalyticsEvent(): Error {
val errorMsg = (error as? MXCryptoError.Base)?.technicalMessage ?: error.message
return Error(
context = "mxc_crypto_error_type|${errorMsg}",
domain = Error.Domain.E2EE,
name = this.toAnalyticsErrorName(),
// this is deprecated keep for backward compatibility
cryptoModule = Error.CryptoModule.Rust,
cryptoSDK = Error.CryptoSDK.Rust,
eventLocalAgeMillis = eventLocalAgeAtDecryptionFailure?.toInt(),
isFederated = isFederated,
isMatrixDotOrg = isMatrixDotOrg,
timeToDecryptMillis = timeToDecryptMillis?.toInt() ?: -1,
wasVisibleToUser = wasVisibleOnScreen,
userTrustsOwnIdentity = ownIdentityTrustedAtTimeOfDecryptionFailure,
)
}

private fun DecryptionFailure.toAnalyticsErrorName(): Error.Name {
val error = this.error
val name = if (error is MXCryptoError.Base) {
when (error.errorType) {
MXCryptoError.ErrorType.UNKNOWN_INBOUND_SESSION_ID,
MXCryptoError.ErrorType.KEYS_WITHHELD -> Error.Name.OlmKeysNotSentError
MXCryptoError.ErrorType.OLM -> Error.Name.OlmUnspecifiedError
MXCryptoError.ErrorType.UNKNOWN_MESSAGE_INDEX -> Error.Name.OlmIndexError
else -> Error.Name.UnknownError
}
} else {
Error.Name.UnknownError
}
// check if it's an expected UTD!
val localAge = this.eventLocalAgeAtDecryptionFailure
val isHistorical = localAge != null && localAge < 0
if (isHistorical && !this.ownIdentityTrustedAtTimeOfDecryptionFailure) {
return Error.Name.HistoricalMessage
}

return name
}
Loading

0 comments on commit 0f3ff2e

Please sign in to comment.