Push: improve Push history screen, log and stored data (#4601)

* Add adb tools to help with doze mode and app standby

* Add info about the device state when an error occurs in push.

* Keep more events in the DB.

* Push history: add confirmation dialog when resetting the data

* Push history: add a filter to see only the errors

* Update screenshots

* Push history: print out invalid/ignored data received.

* Increase log level for push, to make such log more visible.
It also appears that sometimes Timber.d are not present in the rageshakes.

* Log priority

* Do not include device state for invalid/ignored event.

* Fix tests.

* Fix format issue.

* Fix mistake in code blocks and do not filter when not necessary.

* Improve formatting and add missing unit test.

* Reduce nesting of blocks.

---------

Co-authored-by: ElementBot <android@element.io>
This commit is contained in:
Benoit Marty
2025-04-16 16:37:32 +02:00
committed by GitHub
parent 505d0b411d
commit f916e4e3d4
30 changed files with 388 additions and 58 deletions

View File

@@ -7,8 +7,13 @@
package io.element.android.libraries.push.impl.history
import android.content.Context
import android.os.Build
import android.os.PowerManager
import androidx.core.content.getSystemService
import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.ApplicationContext
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.SessionId
@@ -21,15 +26,38 @@ import javax.inject.Inject
class DefaultPushHistoryService @Inject constructor(
private val pushDatabase: PushDatabase,
private val systemClock: SystemClock,
@ApplicationContext context: Context,
) : PushHistoryService {
private val powerManager = context.getSystemService<PowerManager>()
private val packageName = context.packageName
override fun onPushReceived(
providerInfo: String,
eventId: EventId?,
roomId: RoomId?,
sessionId: SessionId?,
hasBeenResolved: Boolean,
includeDeviceState: Boolean,
comment: String?,
) {
val finalComment = buildString {
append(comment.orEmpty())
if (includeDeviceState && powerManager != null) {
// Add info about device state
append("\n")
append(" - Idle: ${powerManager.isDeviceIdleMode}\n")
append(" - Power Save Mode: ${powerManager.isPowerSaveMode}\n")
append(" - Ignoring Battery Optimizations: ${powerManager.isIgnoringBatteryOptimizations(packageName)}\n")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
append(" - Device Light Idle Mode: ${powerManager.isDeviceLightIdleMode}\n")
append(" - Low Power Standby Enabled: ${powerManager.isLowPowerStandbyEnabled}\n")
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
append(" - Exempt from Low Power Standby: ${powerManager.isExemptFromLowPowerStandby}\n")
}
}
}.takeIf { it.isNotEmpty() }
pushDatabase.pushHistoryQueries.insertPushHistory(
PushHistory(
pushDate = systemClock.epochMillis(),
@@ -38,11 +66,11 @@ class DefaultPushHistoryService @Inject constructor(
roomId = roomId?.value,
sessionId = sessionId?.value,
hasBeenResolved = if (hasBeenResolved) 1 else 0,
comment = comment,
comment = finalComment,
)
)
// Keep only the last 100 events
pushDatabase.pushHistoryQueries.removeOldest(100)
// Keep only the last 1_000 events
pushDatabase.pushHistoryQueries.removeOldest(1_000)
}
}

View File

@@ -22,19 +22,22 @@ interface PushHistoryService {
roomId: RoomId?,
sessionId: SessionId?,
hasBeenResolved: Boolean,
includeDeviceState: Boolean,
comment: String?,
)
}
fun PushHistoryService.onInvalidPushReceived(
providerInfo: String,
data: String,
) = onPushReceived(
providerInfo = providerInfo,
eventId = null,
roomId = null,
sessionId = null,
hasBeenResolved = false,
comment = "Invalid push data",
includeDeviceState = false,
comment = "Invalid or ignored push data:\n$data",
)
fun PushHistoryService.onUnableToRetrieveSession(
@@ -48,6 +51,7 @@ fun PushHistoryService.onUnableToRetrieveSession(
roomId = roomId,
sessionId = null,
hasBeenResolved = false,
includeDeviceState = true,
comment = "Unable to retrieve session: $reason",
)
@@ -63,6 +67,7 @@ fun PushHistoryService.onUnableToResolveEvent(
roomId = roomId,
sessionId = sessionId,
hasBeenResolved = false,
includeDeviceState = true,
comment = "Unable to resolve event: $reason",
)
@@ -78,6 +83,7 @@ fun PushHistoryService.onSuccess(
roomId = roomId,
sessionId = sessionId,
hasBeenResolved = true,
includeDeviceState = false,
comment = buildString {
append("Success")
if (comment.isNullOrBlank().not()) {
@@ -94,5 +100,6 @@ fun PushHistoryService.onDiagnosticPush(
roomId = null,
sessionId = null,
hasBeenResolved = true,
includeDeviceState = false,
comment = "Diagnostic push",
)

View File

@@ -72,9 +72,9 @@ class DefaultPushHandler @Inject constructor(
}
}
override suspend fun handleInvalid(providerInfo: String) {
override suspend fun handleInvalid(providerInfo: String, data: String) {
incrementPushDataStore.incrementPushCounter()
pushHistoryService.onInvalidPushReceived(providerInfo)
pushHistoryService.onInvalidPushReceived(providerInfo, data)
}
/**