From 3bdf2e7e2cc2dd13248830beaccd69e979375781 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Mon, 8 Feb 2021 15:37:45 -0500 Subject: [PATCH] Add a system to improve app foreground observation. There was previously a crash that occurred when multiple threads tried to use ProcessLifecycleOwner, and this will hopefully resolve that. --- .../securesms/ApplicationContext.java | 22 ++--- .../securesms/PassphraseRequiredActivity.java | 4 +- .../ConversationListFragment.java | 15 ++-- .../dependencies/ApplicationDependencies.java | 23 +++-- .../ApplicationDependencyProvider.java | 6 ++ .../jobs/MultiDeviceContactUpdateJob.java | 2 +- .../messages/BackgroundMessageRetriever.java | 2 +- .../messages/IncomingMessageObserver.java | 10 +-- .../securesms/service/KeyCachingService.java | 2 +- .../securesms/service/WebRtcCallService.java | 4 +- .../securesms/shakereport/ShakeToReport.java | 3 +- .../securesms/util/AppForegroundObserver.java | 90 +++++++++++++++++++ .../webrtc/CallNotificationBuilder.java | 13 +-- 13 files changed, 147 insertions(+), 49 deletions(-) create mode 100644 app/src/main/java/org/thoughtcrime/securesms/util/AppForegroundObserver.java diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index 681d9223e..4451252a9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -23,9 +23,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; import androidx.appcompat.app.AppCompatDelegate; -import androidx.lifecycle.DefaultLifecycleObserver; -import androidx.lifecycle.LifecycleOwner; -import androidx.lifecycle.ProcessLifecycleOwner; import androidx.multidex.MultiDexApplication; import com.google.android.gms.security.ProviderInstaller; @@ -69,6 +66,7 @@ import org.thoughtcrime.securesms.service.RotateSenderCertificateListener; import org.thoughtcrime.securesms.service.RotateSignedPreKeyListener; import org.thoughtcrime.securesms.service.UpdateApkRefreshListener; import org.thoughtcrime.securesms.storage.StorageSyncHelper; +import org.thoughtcrime.securesms.util.AppForegroundObserver; import org.thoughtcrime.securesms.util.AppStartup; import org.thoughtcrime.securesms.util.DynamicTheme; import org.thoughtcrime.securesms.util.FeatureFlags; @@ -94,7 +92,7 @@ import java.util.concurrent.TimeUnit; * * @author Moxie Marlinspike */ -public class ApplicationContext extends MultiDexApplication implements DefaultLifecycleObserver { +public class ApplicationContext extends MultiDexApplication implements AppForegroundObserver.Listener { private static final String TAG = ApplicationContext.class.getSimpleName(); @@ -102,8 +100,6 @@ public class ApplicationContext extends MultiDexApplication implements DefaultLi private ViewOnceMessageManager viewOnceMessageManager; private PersistentLogger persistentLogger; - private volatile boolean isAppVisible; - public static ApplicationContext getInstance(Context context) { return (ApplicationContext)context.getApplicationContext(); } @@ -133,7 +129,7 @@ public class ApplicationContext extends MultiDexApplication implements DefaultLi .addBlocking("app-migrations", this::initializeApplicationMigrations) .addBlocking("ring-rtc", this::initializeRingRtc) .addBlocking("mark-registration", () -> RegistrationUtil.maybeMarkRegistrationComplete(this)) - .addBlocking("lifecycle-observer", () -> ProcessLifecycleOwner.get().getLifecycle().addObserver(this)) + .addBlocking("lifecycle-observer", () -> ApplicationDependencies.getAppForegroundObserver().addListener(this)) .addBlocking("message-retriever", this::initializeMessageRetrieval) .addBlocking("dynamic-theme", () -> DynamicTheme.setDefaultDayNightMode(this)) .addBlocking("vector-compat", () -> { @@ -164,16 +160,13 @@ public class ApplicationContext extends MultiDexApplication implements DefaultLi .addPostRender(() -> NotificationChannels.create(this)) .execute(); - ProcessLifecycleOwner.get().getLifecycle().addObserver(this); - Log.d(TAG, "onCreate() took " + (System.currentTimeMillis() - startTime) + " ms"); Tracer.getInstance().end("Application#onCreate()"); } @Override - public void onStart(@NonNull LifecycleOwner owner) { + public void onForeground() { long startTime = System.currentTimeMillis(); - isAppVisible = true; Log.i(TAG, "App is now visible."); ApplicationDependencies.getFrameRateTracker().begin(); @@ -194,8 +187,7 @@ public class ApplicationContext extends MultiDexApplication implements DefaultLi } @Override - public void onStop(@NonNull LifecycleOwner owner) { - isAppVisible = false; + public void onBackground() { Log.i(TAG, "App is no longer visible."); KeyCachingService.onAppBackgrounded(this); ApplicationDependencies.getMessageNotifier().clearVisibleThread(); @@ -214,10 +206,6 @@ public class ApplicationContext extends MultiDexApplication implements DefaultLi return viewOnceMessageManager; } - public boolean isAppVisible() { - return isAppVisible; - } - public PersistentLogger getPersistentLogger() { return persistentLogger; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/PassphraseRequiredActivity.java b/app/src/main/java/org/thoughtcrime/securesms/PassphraseRequiredActivity.java index d0d6c3cfe..eb2eac2f3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/PassphraseRequiredActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/PassphraseRequiredActivity.java @@ -91,8 +91,8 @@ public abstract class PassphraseRequiredActivity extends BaseActivity implements @Override public void onMasterSecretCleared() { Log.d(TAG, "onMasterSecretCleared()"); - if (ApplicationContext.getInstance(this).isAppVisible()) routeApplicationState(true); - else finish(); + if (ApplicationDependencies.getAppForegroundObserver().isForegrounded()) routeApplicationState(true); + else finish(); } protected T initFragment(@IdRes int target, diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java index ea0edeeea..d956b28ec 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java @@ -56,7 +56,6 @@ import androidx.appcompat.widget.TooltipCompat; import androidx.core.content.res.ResourcesCompat; import androidx.fragment.app.DialogFragment; import androidx.lifecycle.DefaultLifecycleObserver; -import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.ProcessLifecycleOwner; import androidx.lifecycle.ViewModelProviders; @@ -116,6 +115,7 @@ import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.service.KeyCachingService; import org.thoughtcrime.securesms.sms.MessageSender; import org.thoughtcrime.securesms.storage.StorageSyncHelper; +import org.thoughtcrime.securesms.util.AppForegroundObserver; import org.thoughtcrime.securesms.util.AppStartup; import org.thoughtcrime.securesms.util.AvatarUtil; import org.thoughtcrime.securesms.util.PlayStoreUtil; @@ -175,7 +175,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode private Stub megaphoneContainer; private SnapToTopDataObserver snapToTopDataObserver; private Drawable archiveDrawable; - private LifecycleObserver visibilityLifecycleObserver; + private AppForegroundObserver.Listener appForegroundObserver; private Stopwatch startupStopwatch; @@ -277,7 +277,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode public void onStart() { super.onStart(); ConversationFragment.prepare(requireContext()); - ProcessLifecycleOwner.get().getLifecycle().addObserver(visibilityLifecycleObserver); + ApplicationDependencies.getAppForegroundObserver().addListener(appForegroundObserver); } @Override @@ -292,7 +292,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode @Override public void onStop() { super.onStop(); - ProcessLifecycleOwner.get().getLifecycle().removeObserver(visibilityLifecycleObserver); + ApplicationDependencies.getAppForegroundObserver().removeListener(appForegroundObserver); } @Override @@ -554,11 +554,14 @@ public class ConversationListFragment extends MainFragment implements ActionMode viewModel.hasNoConversations().observe(getViewLifecycleOwner(), this::updateEmptyState); viewModel.getPipeState().observe(getViewLifecycleOwner(), this::updateProxyStatus); - visibilityLifecycleObserver = new DefaultLifecycleObserver() { + appForegroundObserver = new AppForegroundObserver.Listener() { @Override - public void onStart(@NonNull LifecycleOwner owner) { + public void onForeground() { viewModel.onVisible(); } + + @Override + public void onBackground() { } }; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencies.java b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencies.java index f164fe04b..92aec9c3e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencies.java +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencies.java @@ -24,6 +24,7 @@ import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess; import org.thoughtcrime.securesms.recipients.LiveRecipientCache; import org.thoughtcrime.securesms.service.TrimThreadsByDateManager; import org.thoughtcrime.securesms.shakereport.ShakeToReport; +import org.thoughtcrime.securesms.util.AppForegroundObserver; import org.thoughtcrime.securesms.util.EarlyMessageCache; import org.thoughtcrime.securesms.util.FrameRateTracker; import org.thoughtcrime.securesms.util.Hex; @@ -49,9 +50,10 @@ public class ApplicationDependencies { private static final Object FRAME_RATE_TRACKER_LOCK = new Object(); private static final Object JOB_MANAGER_LOCK = new Object(); - private static Application application; - private static Provider provider; - private static MessageNotifier messageNotifier; + private static Application application; + private static Provider provider; + private static MessageNotifier messageNotifier; + private static AppForegroundObserver appForegroundObserver; private static volatile SignalServiceAccountManager accountManager; private static volatile SignalServiceMessageSender messageSender; @@ -80,9 +82,12 @@ public class ApplicationDependencies { throw new IllegalStateException("Already initialized!"); } - ApplicationDependencies.application = application; - ApplicationDependencies.provider = provider; - ApplicationDependencies.messageNotifier = provider.provideMessageNotifier(); + ApplicationDependencies.application = application; + ApplicationDependencies.provider = provider; + ApplicationDependencies.messageNotifier = provider.provideMessageNotifier(); + ApplicationDependencies.appForegroundObserver = provider.provideAppForegroundObserver(); + + ApplicationDependencies.appForegroundObserver.begin(); } } @@ -378,6 +383,11 @@ public class ApplicationDependencies { return shakeToReport; } + public static @NonNull AppForegroundObserver getAppForegroundObserver() { + return appForegroundObserver; + } + + public interface Provider { @NonNull PipeConnectivityListener providePipeListener(); @NonNull GroupsV2Operations provideGroupsV2Operations(); @@ -399,5 +409,6 @@ public class ApplicationDependencies { @NonNull TypingStatusSender provideTypingStatusSender(); @NonNull DatabaseObserver provideDatabaseObserver(); @NonNull ShakeToReport provideShakeToReport(); + @NonNull AppForegroundObserver provideAppForegroundObserver(); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java index 18498a359..c4853a668 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java @@ -51,6 +51,7 @@ import org.thoughtcrime.securesms.recipients.LiveRecipientCache; import org.thoughtcrime.securesms.service.TrimThreadsByDateManager; import org.thoughtcrime.securesms.shakereport.ShakeToReport; import org.thoughtcrime.securesms.util.AlarmSleepTimer; +import org.thoughtcrime.securesms.util.AppForegroundObserver; import org.thoughtcrime.securesms.util.ByteUnit; import org.thoughtcrime.securesms.util.EarlyMessageCache; import org.thoughtcrime.securesms.util.FeatureFlags; @@ -224,6 +225,11 @@ public class ApplicationDependencyProvider implements ApplicationDependencies.Pr return new ShakeToReport(context); } + @Override + public @NonNull AppForegroundObserver provideAppForegroundObserver() { + return new AppForegroundObserver(); + } + private static class DynamicCredentialsProvider implements CredentialsProvider { private final Context context; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java index 0e99983fd..a6a474276 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java @@ -166,7 +166,7 @@ public class MultiDeviceContactUpdateJob extends BaseJob { private void generateFullContactUpdate() throws IOException, UntrustedIdentityException, NetworkException { - boolean isAppVisible = ApplicationContext.getInstance(context).isAppVisible(); + boolean isAppVisible = ApplicationDependencies.getAppForegroundObserver().isForegrounded(); long timeSinceLastSync = System.currentTimeMillis() - TextSecurePreferences.getLastFullContactSyncTime(context); Log.d(TAG, "Requesting a full contact sync. forced = " + forceSync + ", appVisible = " + isAppVisible + ", timeSinceLastSync = " + timeSinceLastSync + " ms"); diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/BackgroundMessageRetriever.java b/app/src/main/java/org/thoughtcrime/securesms/messages/BackgroundMessageRetriever.java index 7482c154b..8dd9564d2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/BackgroundMessageRetriever.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/BackgroundMessageRetriever.java @@ -107,7 +107,7 @@ public class BackgroundMessageRetriever { * care of it. */ public static boolean shouldIgnoreFetch(@NonNull Context context) { - return ApplicationContext.getInstance(context).isAppVisible() && + return ApplicationDependencies.getAppForegroundObserver().isForegrounded() && !ApplicationDependencies.getSignalServiceNetworkAccess().isCensored(context); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageObserver.java b/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageObserver.java index f49cab0ee..0395c7dc1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageObserver.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageObserver.java @@ -13,9 +13,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.app.NotificationCompat; import androidx.core.content.ContextCompat; -import androidx.lifecycle.DefaultLifecycleObserver; -import androidx.lifecycle.LifecycleOwner; -import androidx.lifecycle.ProcessLifecycleOwner; import org.signal.core.util.concurrent.SignalExecutors; import org.signal.core.util.logging.Log; @@ -27,6 +24,7 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.messages.IncomingMessageProcessor.Processor; import org.thoughtcrime.securesms.notifications.NotificationChannels; import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess; +import org.thoughtcrime.securesms.util.AppForegroundObserver; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.libsignal.InvalidVersionException; import org.whispersystems.libsignal.util.guava.Optional; @@ -71,14 +69,14 @@ public class IncomingMessageObserver { ContextCompat.startForegroundService(context, new Intent(context, ForegroundService.class)); } - ProcessLifecycleOwner.get().getLifecycle().addObserver(new DefaultLifecycleObserver() { + ApplicationDependencies.getAppForegroundObserver().addListener(new AppForegroundObserver.Listener() { @Override - public void onStart(@NonNull LifecycleOwner owner) { + public void onForeground() { onAppForegrounded(); } @Override - public void onStop(@NonNull LifecycleOwner owner) { + public void onBackground() { onAppBackgrounded(); } }); diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/KeyCachingService.java b/app/src/main/java/org/thoughtcrime/securesms/service/KeyCachingService.java index 61b431dc3..e06ad8cd7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/KeyCachingService.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/KeyCachingService.java @@ -226,7 +226,7 @@ public class KeyCachingService extends Service { } private static void startTimeoutIfAppropriate(@NonNull Context context) { - boolean appVisible = ApplicationContext.getInstance(context).isAppVisible(); + boolean appVisible = ApplicationDependencies.getAppForegroundObserver().isForegrounded(); boolean secretSet = KeyCachingService.masterSecret != null; boolean timeoutEnabled = TextSecurePreferences.isPassphraseTimeoutEnabled(context); diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.java b/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.java index 59d00df39..dcb375d9a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.java @@ -446,7 +446,7 @@ public class WebRtcCallService extends Service implements CallManager.Observer, } public void setCallInProgressNotification(int type, @NonNull Recipient recipient) { - startForeground(CallNotificationBuilder.getNotificationId(getApplicationContext(), type), + startForeground(CallNotificationBuilder.getNotificationId(type), CallNotificationBuilder.getCallInProgressNotification(this, type, recipient)); } @@ -480,7 +480,7 @@ public class WebRtcCallService extends Service implements CallManager.Observer, } public void startCallCardActivityIfPossible() { - if (Build.VERSION.SDK_INT >= 29 && !ApplicationContext.getInstance(getApplicationContext()).isAppVisible()) { + if (Build.VERSION.SDK_INT >= 29 && !ApplicationDependencies.getAppForegroundObserver().isForegrounded()) { return; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/shakereport/ShakeToReport.java b/app/src/main/java/org/thoughtcrime/securesms/shakereport/ShakeToReport.java index bff7ecf6f..2ef5c986a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/shakereport/ShakeToReport.java +++ b/app/src/main/java/org/thoughtcrime/securesms/shakereport/ShakeToReport.java @@ -13,6 +13,7 @@ import org.signal.core.util.logging.Log; import org.signal.core.util.tracing.Tracer; import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.logsubmit.SubmitDebugLogRepository; import org.thoughtcrime.securesms.sharing.ShareIntents; import org.thoughtcrime.securesms.util.FeatureFlags; @@ -131,7 +132,7 @@ public final class ShakeToReport implements ShakeDetector.Listener { } private void enableIfVisible() { - if (ApplicationContext.getInstance(application).isAppVisible()) { + if (ApplicationDependencies.getAppForegroundObserver().isForegrounded()) { enable(); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/AppForegroundObserver.java b/app/src/main/java/org/thoughtcrime/securesms/util/AppForegroundObserver.java new file mode 100644 index 000000000..5cb5d3229 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/util/AppForegroundObserver.java @@ -0,0 +1,90 @@ +package org.thoughtcrime.securesms.util; + +import androidx.annotation.AnyThread; +import androidx.annotation.MainThread; +import androidx.annotation.NonNull; +import androidx.lifecycle.DefaultLifecycleObserver; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.ProcessLifecycleOwner; + +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * A wrapper around {@link ProcessLifecycleOwner} that allows for safely adding/removing observers + * on multiple threads. + */ +public final class AppForegroundObserver { + + private final Set listeners = new CopyOnWriteArraySet<>(); + + private volatile Boolean isForegrounded = null; + + @MainThread + public void begin() { + Util.assertMainThread(); + + ProcessLifecycleOwner.get().getLifecycle().addObserver(new DefaultLifecycleObserver() { + @Override + public void onStart(@NonNull LifecycleOwner owner) { + onForeground(); + } + + @Override + public void onStop(@NonNull LifecycleOwner owner) { + onBackground(); + } + }); + } + + /** + * Adds a listener to be notified of when the app moves between the background and the foreground. + * To mimic the behavior of subscribing to {@link ProcessLifecycleOwner}, this listener will be + * immediately notified of the foreground state if we've experienced a foreground/background event + * already. + */ + @AnyThread + public void addListener(@NonNull Listener listener) { + listeners.add(listener); + + if (isForegrounded != null) { + if (isForegrounded) { + listener.onForeground(); + } else { + listener.onBackground(); + } + } + } + + @AnyThread + public void removeListener(@NonNull Listener listener) { + listeners.remove(listener); + } + + public boolean isForegrounded() { + return isForegrounded; + } + + @MainThread + private void onForeground() { + isForegrounded = true; + + for (Listener listener : listeners) { + listener.onForeground(); + } + } + + @MainThread + private void onBackground() { + isForegrounded = false; + + for (Listener listener : listeners) { + listener.onBackground(); + } + } + + public interface Listener { + void onForeground(); + void onBackground(); + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallNotificationBuilder.java b/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallNotificationBuilder.java index 646bcb220..a2c682d50 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallNotificationBuilder.java +++ b/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallNotificationBuilder.java @@ -14,6 +14,7 @@ import androidx.core.app.NotificationCompat; import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.WebRtcCallActivity; +import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.notifications.NotificationChannels; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.service.WebRtcCallService; @@ -55,7 +56,7 @@ public class CallNotificationBuilder { builder.addAction(getServiceNotificationAction(context, WebRtcCallService.ACTION_DENY_CALL, R.drawable.ic_close_grey600_32dp, R.string.NotificationBarManager__deny_call)); builder.addAction(getActivityNotificationAction(context, WebRtcCallActivity.ANSWER_ACTION, R.drawable.ic_phone_grey600_32dp, R.string.NotificationBarManager__answer_call)); - if (callActivityRestricted(context)) { + if (callActivityRestricted()) { builder.setFullScreenIntent(pendingIntent, true); builder.setPriority(NotificationCompat.PRIORITY_HIGH); builder.setCategory(NotificationCompat.CATEGORY_CALL); @@ -71,8 +72,8 @@ public class CallNotificationBuilder { return builder.build(); } - public static int getNotificationId(@NonNull Context context, int type) { - if (callActivityRestricted(context) && type == TYPE_INCOMING_RINGING) { + public static int getNotificationId(int type) { + if (callActivityRestricted() && type == TYPE_INCOMING_RINGING) { return WEBRTC_NOTIFICATION_RINGING; } else { return WEBRTC_NOTIFICATION; @@ -85,7 +86,7 @@ public class CallNotificationBuilder { } private static @NonNull String getNotificationChannel(@NonNull Context context, int type) { - if (callActivityRestricted(context) && type == TYPE_INCOMING_RINGING) { + if (callActivityRestricted() && type == TYPE_INCOMING_RINGING) { return NotificationChannels.CALLS; } else { return NotificationChannels.OTHER; @@ -112,7 +113,7 @@ public class CallNotificationBuilder { return new NotificationCompat.Action(iconResId, context.getString(titleResId), pendingIntent); } - private static boolean callActivityRestricted(@NonNull Context context) { - return Build.VERSION.SDK_INT >= 29 && !ApplicationContext.getInstance(context).isAppVisible(); + private static boolean callActivityRestricted() { + return Build.VERSION.SDK_INT >= 29 && !ApplicationDependencies.getAppForegroundObserver().isForegrounded(); } }