From 1c66da78730da495e8cc406c9405939c24ff2ae2 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Tue, 21 May 2024 14:49:38 -0400 Subject: [PATCH] Update slow notification debugging info. --- .../DebugLogsPromptDialogFragment.kt | 37 +++++++++- .../logsubmit/LogSectionNotifications.java | 1 + .../logsubmit/LogSectionSystemInfo.java | 7 +- .../SlowNotificationHeuristics.kt | 5 +- .../SlowNotificationsViewModel.kt | 70 ------------------- .../notifications/VitalsViewModel.kt | 11 +-- 6 files changed, 45 insertions(+), 86 deletions(-) delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/notifications/SlowNotificationsViewModel.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/DebugLogsPromptDialogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/DebugLogsPromptDialogFragment.kt index 54ebfbde79..2a45f13ff4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/DebugLogsPromptDialogFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/DebugLogsPromptDialogFragment.kt @@ -5,6 +5,7 @@ package org.thoughtcrime.securesms.components +import android.os.Build import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -20,9 +21,12 @@ import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.databinding.PromptLogsBottomSheetBinding import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.keyvalue.SignalStore +import org.thoughtcrime.securesms.notifications.SlowNotificationHeuristics import org.thoughtcrime.securesms.util.BottomSheetUtil import org.thoughtcrime.securesms.util.CommunicationActions +import org.thoughtcrime.securesms.util.DeviceProperties import org.thoughtcrime.securesms.util.NetworkUtil +import org.thoughtcrime.securesms.util.PowerManagerCompat import org.thoughtcrime.securesms.util.SupportEmailUtil class DebugLogsPromptDialogFragment : FixedRoundedCornerBottomSheetDialogFragment() { @@ -124,9 +128,12 @@ class DebugLogsPromptDialogFragment : FixedRoundedCornerBottomSheetDialogFragmen if (debugLog != null) { suffix.append("\n") - suffix.append(getString(R.string.HelpFragment__debug_log)) - suffix.append(" ") - suffix.append(debugLog) + suffix.append(getString(R.string.HelpFragment__debug_log)).append(" ").append(debugLog).append("\n\n") + suffix.append("-- Highlights").append("\n") + suffix.append("Slow notifications detected: ").append(SlowNotificationHeuristics.isHavingDelayedNotifications()).append("\n") + suffix.append("Ignoring battery optimizations: ").append(batteryOptimizationsString()).append("\n") + suffix.append("Background restricted: ").append(backgroundRestrictedString()).append("\n") + suffix.append("Data saver: ").append(dataSaverString()).append("\n") } val category = when (purpose) { @@ -143,6 +150,30 @@ class DebugLogsPromptDialogFragment : FixedRoundedCornerBottomSheetDialogFragmen ) } + private fun batteryOptimizationsString(): String { + return if (Build.VERSION.SDK_INT < 23) { + "N/A (API < 23)" + } else { + PowerManagerCompat.isIgnoringBatteryOptimizations(requireContext()).toString() + } + } + + private fun backgroundRestrictedString(): String { + return if (Build.VERSION.SDK_INT < 28) { + "N/A (API < 28)" + } else { + DeviceProperties.isBackgroundRestricted(requireContext()).toString() + } + } + + private fun dataSaverString(): String { + return if (Build.VERSION.SDK_INT < 24) { + "N/A (API < 24)" + } else { + DeviceProperties.getDataSaverState(requireContext()).toString() + } + } + enum class Purpose(val serialized: Int) { NOTIFICATIONS(1), diff --git a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionNotifications.java b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionNotifications.java index cae3f3678b..f46d4d62ab 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionNotifications.java +++ b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionNotifications.java @@ -9,6 +9,7 @@ import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; import org.thoughtcrime.securesms.keyvalue.SignalStore; +import org.thoughtcrime.securesms.notifications.SlowNotificationHeuristics; import org.thoughtcrime.securesms.util.ServiceUtil; final class LogSectionNotifications implements LogSection { diff --git a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionSystemInfo.java b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionSystemInfo.java index bb5c141d6b..3ae1ba0bdf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionSystemInfo.java +++ b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionSystemInfo.java @@ -28,6 +28,7 @@ import org.thoughtcrime.securesms.util.ByteUnit; import org.thoughtcrime.securesms.util.ContextUtil; import org.thoughtcrime.securesms.util.DeviceProperties; import org.thoughtcrime.securesms.util.NetworkUtil; +import org.thoughtcrime.securesms.util.PowerManagerCompat; import org.thoughtcrime.securesms.util.ScreenDensity; import org.thoughtcrime.securesms.util.ServiceUtil; import org.thoughtcrime.securesms.util.TextSecurePreferences; @@ -76,10 +77,8 @@ public class LogSectionSystemInfo implements LogSection { builder.append("Device ID : ").append(SignalStore.account().getDeviceId()).append("\n"); builder.append("Censored : ").append(ApplicationDependencies.getSignalServiceNetworkAccess().isCensored()).append("\n"); builder.append("Network Status : ").append(NetworkUtil.getNetworkStatus(context)).append("\n"); - builder.append("Data Saver : ").append(DeviceProperties.getDataSaverState(context)).append("\n"); builder.append("Play Services : ").append(getPlayServicesString(context)).append("\n"); builder.append("FCM : ").append(SignalStore.account().isFcmEnabled()).append("\n"); - builder.append("BkgRestricted : ").append(Build.VERSION.SDK_INT >= 28 ? DeviceProperties.isBackgroundRestricted(context) : "N/A").append("\n"); builder.append("Locale : ").append(Locale.getDefault()).append("\n"); builder.append("Linked Devices : ").append(TextSecurePreferences.isMultiDevice(context)).append("\n"); builder.append("First Version : ").append(TextSecurePreferences.getFirstInstallVersion(context)).append("\n"); @@ -92,7 +91,9 @@ public class LogSectionSystemInfo implements LogSection { builder.append("Telecom : ").append(AndroidTelecomUtil.getTelecomSupported()).append("\n"); builder.append("User-Agent : ").append(StandardUserAgentInterceptor.USER_AGENT).append("\n"); builder.append("SlowNotifications : ").append(SlowNotificationHeuristics.isHavingDelayedNotifications()).append("\n"); - builder.append("PotentiallyBattery: ").append(SlowNotificationHeuristics.isPotentiallyCausedByBatteryOptimizations()).append("\n"); + builder.append("IgnoringBatteryOpt: ").append(PowerManagerCompat.isIgnoringBatteryOptimizations(context)).append("\n"); + builder.append("BkgRestricted : ").append(Build.VERSION.SDK_INT >= 28 ? DeviceProperties.isBackgroundRestricted(context) : "N/A").append("\n"); + builder.append("Data Saver : ").append(DeviceProperties.getDataSaverState(context)).append("\n"); builder.append("APNG Animation : ").append(DeviceProperties.shouldAllowApngStickerAnimation(context)).append("\n"); if (BuildConfig.MANAGES_APP_UPDATES) { builder.append("ApkManifestUrl : ").append(BuildConfig.APK_UPDATE_MANIFEST_URL).append("\n"); diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/SlowNotificationHeuristics.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/SlowNotificationHeuristics.kt index 87dfc946b2..a2a85f925d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/SlowNotificationHeuristics.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/SlowNotificationHeuristics.kt @@ -79,9 +79,12 @@ object SlowNotificationHeuristics { if (Build.VERSION.SDK_INT < 23) { return false } - if (!LocaleFeatureFlags.isBatterySaverPromptEnabled() || SignalStore.uiHints().hasDismissedBatterySaverPrompt()) { + + val remoteEnabled = LocaleFeatureFlags.isBatterySaverPromptEnabled() || LocaleFeatureFlags.isDelayedNotificationPromptEnabled() + if (!remoteEnabled || SignalStore.uiHints().hasDismissedBatterySaverPrompt()) { return false } + if (System.currentTimeMillis() - SignalStore.uiHints().lastBatterySaverPrompt < TimeUnit.DAYS.toMillis(7)) { return false } diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/SlowNotificationsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/SlowNotificationsViewModel.kt deleted file mode 100644 index 4433e38df1..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/SlowNotificationsViewModel.kt +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2023 Signal Messenger, LLC - * SPDX-License-Identifier: AGPL-3.0-only - */ - -package org.thoughtcrime.securesms.notifications - -import android.os.Build -import androidx.annotation.WorkerThread -import androidx.lifecycle.ViewModel -import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers -import io.reactivex.rxjava3.core.Observable -import io.reactivex.rxjava3.core.Single -import io.reactivex.rxjava3.schedulers.Schedulers -import io.reactivex.rxjava3.subjects.BehaviorSubject -import org.thoughtcrime.securesms.notifications.SlowNotificationHeuristics.isHavingDelayedNotifications -import org.thoughtcrime.securesms.notifications.SlowNotificationHeuristics.isPotentiallyCausedByBatteryOptimizations -import org.thoughtcrime.securesms.notifications.SlowNotificationHeuristics.shouldPromptBatterySaver -import org.thoughtcrime.securesms.notifications.SlowNotificationHeuristics.shouldPromptUserForLogs -import java.util.concurrent.TimeUnit - -/** - * View model for checking for slow notifications and if we should prompt the user with help or for information. - */ -class SlowNotificationsViewModel : ViewModel() { - - private val checkSubject = BehaviorSubject.create() - - val slowNotificationState: Observable - - init { - slowNotificationState = checkSubject - .subscribeOn(Schedulers.io()) - .observeOn(Schedulers.io()) - .throttleFirst(1, TimeUnit.MINUTES) - .switchMapSingle { - checkHeuristics() - } - .distinctUntilChanged() - .observeOn(AndroidSchedulers.mainThread()) - } - - fun checkSlowNotificationHeuristics() { - checkSubject.onNext(Unit) - } - - @WorkerThread - private fun checkHeuristics(): Single { - return Single.fromCallable { - var state = State.NONE - if (isHavingDelayedNotifications()) { - if (isPotentiallyCausedByBatteryOptimizations() && Build.VERSION.SDK_INT >= 23) { - if (shouldPromptBatterySaver()) { - state = State.PROMPT_BATTERY_SAVER_DIALOG - } - } else if (shouldPromptUserForLogs()) { - state = State.PROMPT_DEBUGLOGS - } - } - - return@fromCallable state - }.subscribeOn(Schedulers.io()) - } - - enum class State { - NONE, - PROMPT_BATTERY_SAVER_DIALOG, - PROMPT_DEBUGLOGS - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/VitalsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/VitalsViewModel.kt index 970c34ad64..b296f1274f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/VitalsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/VitalsViewModel.kt @@ -6,7 +6,6 @@ package org.thoughtcrime.securesms.notifications import android.app.Application -import android.os.Build import androidx.lifecycle.AndroidViewModel import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.core.Observable @@ -16,7 +15,6 @@ import io.reactivex.rxjava3.subjects.BehaviorSubject import org.thoughtcrime.securesms.crash.CrashConfig import org.thoughtcrime.securesms.database.LogDatabase import org.thoughtcrime.securesms.keyvalue.SignalStore -import org.thoughtcrime.securesms.util.LocaleFeatureFlags import java.util.concurrent.TimeUnit import kotlin.time.Duration.Companion.days @@ -49,13 +47,8 @@ class VitalsViewModel(private val context: Application) : AndroidViewModel(conte return Single.fromCallable { var state = State.NONE if (SlowNotificationHeuristics.isHavingDelayedNotifications()) { - if (LocaleFeatureFlags.isBatterySaverPromptEnabled() && - SlowNotificationHeuristics.isPotentiallyCausedByBatteryOptimizations() && - Build.VERSION.SDK_INT >= 23 - ) { - if (SlowNotificationHeuristics.shouldPromptBatterySaver()) { - state = State.PROMPT_BATTERY_SAVER_DIALOG - } + if (SlowNotificationHeuristics.isPotentiallyCausedByBatteryOptimizations() && SlowNotificationHeuristics.shouldPromptBatterySaver()) { + state = State.PROMPT_BATTERY_SAVER_DIALOG } else if (SlowNotificationHeuristics.shouldPromptUserForLogs()) { state = State.PROMPT_DEBUGLOGS_FOR_NOTIFICATIONS }