Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@

## Unreleased

### Changes

- Fallback to Current Activity Holder when React Context Activity is not present ([#4779](https://github.com/getsentry/sentry-react-native/pull/4779))

### Dependencies

- Bump Cocoa SDK from v8.49.1 to v8.49.2 ([#4792](https://github.com/getsentry/sentry-react-native/pull/4792))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package io.sentry.react.utils

import android.app.Activity
import com.facebook.react.bridge.ReactApplicationContext
import io.sentry.android.core.AndroidLogger
import io.sentry.android.core.CurrentActivityHolder
import org.junit.After
import org.junit.Assert.assertNull
import org.junit.Assert.assertSame
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.mockito.Mockito.mock
import org.mockito.kotlin.whenever

@RunWith(JUnit4::class)
class RNSentryActivityUtilsTest {
private val mockedLogger = mock(AndroidLogger::class.java)

@After
fun clearActivityHolder() {
CurrentActivityHolder.getInstance().clearActivity()
}

@Test
fun `returns react context activity`() {
val mockedCurrentActivity = mock(Activity::class.java)
val mockedReactContext = mock(ReactApplicationContext::class.java)
whenever(mockedReactContext.currentActivity).thenReturn(mockedCurrentActivity)

assertSame(RNSentryActivityUtils.getCurrentActivity(mockedReactContext, mockedLogger), mockedCurrentActivity)
}

@Test
fun `returns current activity holder activity`() {
val mockedCurrentActivity = mock(Activity::class.java)

val mockedReactContext = mock(ReactApplicationContext::class.java)
whenever(mockedReactContext.currentActivity).thenReturn(null)

CurrentActivityHolder.getInstance().setActivity(mockedCurrentActivity)
assertSame(RNSentryActivityUtils.getCurrentActivity(mockedReactContext, mockedLogger), mockedCurrentActivity)
}

@Test
fun `returns null when no activity exists`() {
val mockedReactContext = mock(ReactApplicationContext::class.java)
whenever(mockedReactContext.currentActivity).thenReturn(null)

assertNull(RNSentryActivityUtils.getCurrentActivity(mockedReactContext, mockedLogger))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import io.sentry.android.core.BuildInfoProvider;
import io.sentry.android.core.SentryAndroidDateProvider;
import io.sentry.android.core.internal.util.FirstDrawDoneListener;
import io.sentry.react.utils.RNSentryActivityUtils;
import java.util.Objects;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -151,11 +152,12 @@ private void processPropsChanged() {
return;
}

@Nullable Activity activity = reactContext.getCurrentActivity();
final @Nullable Activity activity =
RNSentryActivityUtils.getCurrentActivity(reactContext, logger);
if (activity == null) {
logger.log(
SentryLevel.ERROR,
"[TimeToDisplay] Won't emit next frame drawn event, reactContext is null.");
"[TimeToDisplay] Won't emit next frame drawn event, activity is null.");
return;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package io.sentry.react.utils;

import android.app.Activity;
import com.facebook.react.bridge.ReactApplicationContext;
import io.sentry.ILogger;
import io.sentry.SentryLevel;
import io.sentry.android.core.CurrentActivityHolder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/** Utility class for React Native Activity related functionality. */
public final class RNSentryActivityUtils {

private RNSentryActivityUtils() {
// Prevent instantiation
}

public static @Nullable Activity getCurrentActivity(
final @NotNull ReactApplicationContext reactContext, final @NotNull ILogger logger) {
final Activity activity = reactContext.getCurrentActivity();
if (activity != null) {
return activity;
}

logger.log(
SentryLevel.DEBUG,
"[RNSentryActivityUtils] Given ReactApplicationContext has no activity attached, using"
+ " CurrentActivityHolder as a fallback.");
return CurrentActivityHolder.getInstance().getActivity();
}
}
Loading