Fix ANR-like bug when resuming MainActivity.
This commit is contained in:
parent
74d5faf3fa
commit
39c1c1e371
5 changed files with 101 additions and 17 deletions
|
@ -1,10 +1,10 @@
|
|||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.ViewTreeObserver;
|
||||
|
@ -16,6 +16,7 @@ import androidx.lifecycle.ViewModelProvider;
|
|||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import org.signal.core.util.concurrent.LifecycleDisposable;
|
||||
import org.thoughtcrime.securesms.components.DebugLogsPromptDialogFragment;
|
||||
import org.thoughtcrime.securesms.components.PromptBatterySaverDialogFragment;
|
||||
import org.thoughtcrime.securesms.components.voice.VoiceNoteMediaController;
|
||||
|
@ -24,8 +25,7 @@ import org.thoughtcrime.securesms.conversationlist.RelinkDevicesReminderBottomSh
|
|||
import org.thoughtcrime.securesms.devicetransfer.olddevice.OldDeviceExitActivity;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.net.DeviceTransferBlockingInterceptor;
|
||||
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
||||
import org.thoughtcrime.securesms.notifications.SlowNotificationHeuristics;
|
||||
import org.thoughtcrime.securesms.notifications.SlowNotificationsViewModel;
|
||||
import org.thoughtcrime.securesms.stories.tabs.ConversationListTabRepository;
|
||||
import org.thoughtcrime.securesms.stories.tabs.ConversationListTabsViewModel;
|
||||
import org.thoughtcrime.securesms.util.AppStartup;
|
||||
|
@ -33,7 +33,6 @@ import org.thoughtcrime.securesms.util.CachedInflater;
|
|||
import org.thoughtcrime.securesms.util.CommunicationActions;
|
||||
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.PowerManagerCompat;
|
||||
import org.thoughtcrime.securesms.util.SplashScreenUtil;
|
||||
import org.thoughtcrime.securesms.util.WindowUtil;
|
||||
|
||||
|
@ -46,6 +45,9 @@ public class MainActivity extends PassphraseRequiredActivity implements VoiceNot
|
|||
|
||||
private VoiceNoteMediaController mediaController;
|
||||
private ConversationListTabsViewModel conversationListTabsViewModel;
|
||||
private SlowNotificationsViewModel slowNotificationsViewModel;
|
||||
|
||||
private final LifecycleDisposable lifecycleDisposable = new LifecycleDisposable();
|
||||
|
||||
private boolean onFirstRender = false;
|
||||
|
||||
|
@ -80,6 +82,7 @@ public class MainActivity extends PassphraseRequiredActivity implements VoiceNot
|
|||
}
|
||||
});
|
||||
|
||||
lifecycleDisposable.bindTo(this);
|
||||
|
||||
mediaController = new VoiceNoteMediaController(this, true);
|
||||
|
||||
|
@ -95,6 +98,28 @@ public class MainActivity extends PassphraseRequiredActivity implements VoiceNot
|
|||
|
||||
conversationListTabsViewModel = new ViewModelProvider(this, factory).get(ConversationListTabsViewModel.class);
|
||||
updateTabVisibility();
|
||||
|
||||
slowNotificationsViewModel = new ViewModelProvider(this).get(SlowNotificationsViewModel.class);
|
||||
|
||||
lifecycleDisposable.add(
|
||||
slowNotificationsViewModel
|
||||
.getSlowNotificationState()
|
||||
.subscribe(this::presentSlowNotificationState)
|
||||
);
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private void presentSlowNotificationState(SlowNotificationsViewModel.State slowNotificationState) {
|
||||
switch (slowNotificationState) {
|
||||
case NONE:
|
||||
break;
|
||||
case PROMPT_BATTERY_SAVER_DIALOG:
|
||||
PromptBatterySaverDialogFragment.show(getSupportFragmentManager());
|
||||
break;
|
||||
case PROMPT_DEBUGLOGS:
|
||||
DebugLogsPromptDialogFragment.show(this, getSupportFragmentManager());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -143,15 +168,7 @@ public class MainActivity extends PassphraseRequiredActivity implements VoiceNot
|
|||
|
||||
updateTabVisibility();
|
||||
|
||||
if (SlowNotificationHeuristics.isHavingDelayedNotifications()) {
|
||||
if (SlowNotificationHeuristics.isPotentiallyCausedByBatteryOptimizations() && Build.VERSION.SDK_INT >= 23) {
|
||||
if (SlowNotificationHeuristics.shouldPromptBatterySaver()) {
|
||||
PromptBatterySaverDialogFragment.show(this, getSupportFragmentManager());
|
||||
}
|
||||
} else if (SlowNotificationHeuristics.shouldPromptUserForLogs()) {
|
||||
DebugLogsPromptDialogFragment.show(this, getSupportFragmentManager());
|
||||
}
|
||||
}
|
||||
slowNotificationsViewModel.checkSlowNotificationHeuristics();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
package org.thoughtcrime.securesms.components
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
|
@ -27,7 +26,7 @@ class PromptBatterySaverDialogFragment : FixedRoundedCornerBottomSheetDialogFrag
|
|||
companion object {
|
||||
|
||||
@JvmStatic
|
||||
fun show(context: Context, fragmentManager: FragmentManager) {
|
||||
fun show(fragmentManager: FragmentManager) {
|
||||
if (fragmentManager.findFragmentByTag(BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG) == null) {
|
||||
PromptBatterySaverDialogFragment().apply {
|
||||
arguments = bundleOf()
|
||||
|
|
|
@ -190,7 +190,7 @@ class NotificationsSettingsFragment : DSLSettingsFragment(R.string.preferences__
|
|||
title = DSLSettingsText.from(R.string.preferences_notifications__troubleshoot),
|
||||
isEnabled = true,
|
||||
onClick = {
|
||||
PromptBatterySaverDialogFragment.show(requireContext(), childFragmentManager)
|
||||
PromptBatterySaverDialogFragment.show(childFragmentManager)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.notifications
|
||||
|
||||
import android.os.Build
|
||||
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<Unit>()
|
||||
|
||||
val slowNotificationState: Observable<State>
|
||||
|
||||
init {
|
||||
slowNotificationState = checkSubject
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.io())
|
||||
.throttleFirst(1, TimeUnit.MINUTES)
|
||||
.switchMapSingle {
|
||||
checkHeuristics()
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
}
|
||||
|
||||
fun checkSlowNotificationHeuristics() {
|
||||
checkSubject.onNext(Unit)
|
||||
}
|
||||
|
||||
private fun checkHeuristics(): Single<State> {
|
||||
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
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
org.gradle.jvmargs=-Xmx4g -Xms256m -XX:MaxMetaspaceSize=1g
|
||||
org.gradle.jvmargs=-Xmx6g -Xms256m -XX:MaxMetaspaceSize=1g
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
kapt.incremental.apt=false
|
||||
|
|
Loading…
Add table
Reference in a new issue