Skip to content

Commit 0f3ff2e

Browse files
authored
Merge pull request #8780 from element-hq/valere/utd_posthog_more_properties
UTD posthog reporting add more properties to captured event
2 parents 237580c + 752c884 commit 0f3ff2e

File tree

16 files changed

+1088
-110
lines changed

16 files changed

+1088
-110
lines changed

changelog.d/8780.misc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve UTD reporting by adding additional fields to the report.

matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/LiveEventListener.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

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

19+
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
1920
import org.matrix.android.sdk.api.session.events.model.Event
2021
import org.matrix.android.sdk.api.util.JsonDict
2122

@@ -27,7 +28,7 @@ interface LiveEventListener {
2728

2829
fun onEventDecrypted(event: Event, clearEvent: JsonDict)
2930

30-
fun onEventDecryptionError(event: Event, throwable: Throwable)
31+
fun onEventDecryptionError(event: Event, cryptoError: MXCryptoError)
3132

3233
fun onLiveToDeviceEvent(event: Event)
3334

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt

-2
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,6 @@ internal class Device @AssistedInject constructor(
172172
* This will not fetch out fresh data from the Rust side.
173173
**/
174174
internal fun toCryptoDeviceInfo(): CryptoDeviceInfo {
175-
// val keys = innerDevice.keys.map { (keyId, key) -> keyId to key }.toMap()
176-
177175
return CryptoDeviceInfo(
178176
deviceId = innerDevice.deviceId,
179177
userId = innerDevice.userId,

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt

+9-5
Original file line numberDiff line numberDiff line change
@@ -189,18 +189,21 @@ internal class OlmMachine @Inject constructor(
189189
is OwnUserIdentity -> ownIdentity.trustsOurOwnDevice()
190190
else -> false
191191
}
192+
val ownDevice = inner.getDevice(userId(), deviceId, 0u)!!
193+
val creationTime = ownDevice.firstTimeSeenTs.toLong()
192194

193195
return CryptoDeviceInfo(
194196
deviceId(),
195197
userId(),
196-
// TODO pass the algorithms here.
197-
listOf(),
198+
ownDevice.algorithms,
198199
keys,
199200
mapOf(),
200-
UnsignedDeviceInfo(),
201+
UnsignedDeviceInfo(
202+
deviceDisplayName = ownDevice.displayName
203+
),
201204
DeviceTrustLevel(crossSigningVerified, locallyVerified = true),
202205
false,
203-
null
206+
creationTime
204207
)
205208
}
206209

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

@@ -882,6 +885,7 @@ internal class OlmMachine @Inject constructor(
882885
inner.queryMissingSecretsFromOtherSessions()
883886
}
884887
}
888+
885889
@Throws(CryptoStoreException::class)
886890
suspend fun enableBackupV1(key: String, version: String) {
887891
return withContext(coroutineDispatchers.computation) {

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/StreamEventsManager.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import kotlinx.coroutines.SupervisorJob
2222
import kotlinx.coroutines.launch
2323
import org.matrix.android.sdk.api.extensions.tryOrNull
2424
import org.matrix.android.sdk.api.session.LiveEventListener
25+
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
2526
import org.matrix.android.sdk.api.session.crypto.model.MXEventDecryptionResult
2627
import org.matrix.android.sdk.api.session.events.model.Event
2728
import timber.log.Timber
@@ -75,7 +76,7 @@ internal class StreamEventsManager @Inject constructor() {
7576
}
7677
}
7778

78-
fun dispatchLiveEventDecryptionFailed(event: Event, error: Throwable) {
79+
fun dispatchLiveEventDecryptionFailed(event: Event, error: MXCryptoError) {
7980
Timber.v("## dispatchLiveEventDecryptionFailed ${event.eventId}")
8081
coroutineScope.launch {
8182
listeners.forEach {

vector-app/src/main/java/im/vector/app/VectorApplication.kt

+3
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import im.vector.app.core.debug.LeakDetector
5151
import im.vector.app.core.di.ActiveSessionHolder
5252
import im.vector.app.core.pushers.FcmHelper
5353
import im.vector.app.core.resources.BuildMeta
54+
import im.vector.app.features.analytics.DecryptionFailureTracker
5455
import im.vector.app.features.analytics.VectorAnalytics
5556
import im.vector.app.features.call.webrtc.WebRtcCallManager
5657
import im.vector.app.features.configuration.VectorConfiguration
@@ -100,6 +101,7 @@ class VectorApplication :
100101
@Inject lateinit var callManager: WebRtcCallManager
101102
@Inject lateinit var invitesAcceptor: InvitesAcceptor
102103
@Inject lateinit var autoRageShaker: AutoRageShaker
104+
@Inject lateinit var decryptionFailureTracker: DecryptionFailureTracker
103105
@Inject lateinit var vectorFileLogger: VectorFileLogger
104106
@Inject lateinit var vectorAnalytics: VectorAnalytics
105107
@Inject lateinit var flipperProxy: FlipperProxy
@@ -130,6 +132,7 @@ class VectorApplication :
130132
vectorAnalytics.init()
131133
invitesAcceptor.initialize()
132134
autoRageShaker.initialize()
135+
decryptionFailureTracker.start()
133136
vectorUncaughtExceptionHandler.activate()
134137

135138
// Remove Log handler statically added by Jitsi

vector/src/main/java/im/vector/app/UISIDetector.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package im.vector.app
1818

1919
import org.matrix.android.sdk.api.extensions.orFalse
2020
import org.matrix.android.sdk.api.session.LiveEventListener
21+
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
2122
import org.matrix.android.sdk.api.session.events.model.Event
2223
import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent
2324
import org.matrix.android.sdk.api.session.events.model.toModel
@@ -84,7 +85,7 @@ class UISIDetector(private val timeoutMillis: Long = 30_000L) : LiveEventListene
8485
}
8586
}
8687

87-
override fun onEventDecryptionError(event: Event, throwable: Throwable) {
88+
override fun onEventDecryptionError(event: Event, cryptoError: MXCryptoError) {
8889
val eventId = event.eventId
8990
val roomId = event.roomId
9091
if (!enabled || eventId == null || roomId == null) return

vector/src/main/java/im/vector/app/core/di/ActiveSessionHolder.kt

-6
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase
2323
import im.vector.app.core.services.GuardServiceStarter
2424
import im.vector.app.core.session.ConfigureAndStartSessionUseCase
2525
import im.vector.app.features.analytics.DecryptionFailureTracker
26-
import im.vector.app.features.analytics.plan.Error
2726
import im.vector.app.features.call.webrtc.WebRtcCallManager
2827
import im.vector.app.features.crypto.keysrequest.KeyRequestHandler
2928
import im.vector.app.features.crypto.verification.IncomingVerificationRequestHandler
@@ -75,11 +74,6 @@ class ActiveSessionHolder @Inject constructor(
7574
session.callSignalingService().addCallListener(callManager)
7675
imageManager.onSessionStarted(session)
7776
guardServiceStarter.start()
78-
decryptionFailureTracker.currentModule = if (session.cryptoService().name() == "rust-sdk") {
79-
Error.CryptoModule.Rust
80-
} else {
81-
Error.CryptoModule.Native
82-
}
8377
}
8478

8579
suspend fun clearActiveSession() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Copyright (c) 2024 New Vector Ltd
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package im.vector.app.features.analytics
18+
19+
import im.vector.app.features.analytics.plan.Error
20+
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
21+
22+
data class DecryptionFailure(
23+
val timeStamp: Long,
24+
val roomId: String,
25+
val failedEventId: String,
26+
val error: MXCryptoError,
27+
val wasVisibleOnScreen: Boolean,
28+
val ownIdentityTrustedAtTimeOfDecryptionFailure: Boolean,
29+
// If this is set, it means that the event was decrypted but late. Will be -1 if
30+
// the event was not decrypted after the maximum wait time.
31+
val timeToDecryptMillis: Long? = null,
32+
val isMatrixDotOrg: Boolean,
33+
val isFederated: Boolean? = null,
34+
val eventLocalAgeAtDecryptionFailure: Long? = null
35+
)
36+
37+
fun DecryptionFailure.toAnalyticsEvent(): Error {
38+
val errorMsg = (error as? MXCryptoError.Base)?.technicalMessage ?: error.message
39+
return Error(
40+
context = "mxc_crypto_error_type|${errorMsg}",
41+
domain = Error.Domain.E2EE,
42+
name = this.toAnalyticsErrorName(),
43+
// this is deprecated keep for backward compatibility
44+
cryptoModule = Error.CryptoModule.Rust,
45+
cryptoSDK = Error.CryptoSDK.Rust,
46+
eventLocalAgeMillis = eventLocalAgeAtDecryptionFailure?.toInt(),
47+
isFederated = isFederated,
48+
isMatrixDotOrg = isMatrixDotOrg,
49+
timeToDecryptMillis = timeToDecryptMillis?.toInt() ?: -1,
50+
wasVisibleToUser = wasVisibleOnScreen,
51+
userTrustsOwnIdentity = ownIdentityTrustedAtTimeOfDecryptionFailure,
52+
)
53+
}
54+
55+
private fun DecryptionFailure.toAnalyticsErrorName(): Error.Name {
56+
val error = this.error
57+
val name = if (error is MXCryptoError.Base) {
58+
when (error.errorType) {
59+
MXCryptoError.ErrorType.UNKNOWN_INBOUND_SESSION_ID,
60+
MXCryptoError.ErrorType.KEYS_WITHHELD -> Error.Name.OlmKeysNotSentError
61+
MXCryptoError.ErrorType.OLM -> Error.Name.OlmUnspecifiedError
62+
MXCryptoError.ErrorType.UNKNOWN_MESSAGE_INDEX -> Error.Name.OlmIndexError
63+
else -> Error.Name.UnknownError
64+
}
65+
} else {
66+
Error.Name.UnknownError
67+
}
68+
// check if it's an expected UTD!
69+
val localAge = this.eventLocalAgeAtDecryptionFailure
70+
val isHistorical = localAge != null && localAge < 0
71+
if (isHistorical && !this.ownIdentityTrustedAtTimeOfDecryptionFailure) {
72+
return Error.Name.HistoricalMessage
73+
}
74+
75+
return name
76+
}

0 commit comments

Comments
 (0)