diff --git a/CHANGELOG.md b/CHANGELOG.md index 184585e6a3..ac3d4f0e0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ - Fallback to Current Activity Holder when React Context Activity is not present ([#4779](https://github.com/getsentry/sentry-react-native/pull/4779)) +### Fixes + +- Initialize Sentry Android with ApplicationContext if available ([#4780](https://github.com/getsentry/sentry-react-native/pull/4780)) + ### Dependencies - Bump Cocoa SDK from v8.49.1 to v8.49.2 ([#4792](https://github.com/getsentry/sentry-react-native/pull/4792)) diff --git a/packages/core/RNSentryAndroidTester/app/src/test/java/io/sentry/react/RNSentryModuleInitWithApplicationTest.kt b/packages/core/RNSentryAndroidTester/app/src/test/java/io/sentry/react/RNSentryModuleInitWithApplicationTest.kt new file mode 100644 index 0000000000..7585335309 --- /dev/null +++ b/packages/core/RNSentryAndroidTester/app/src/test/java/io/sentry/react/RNSentryModuleInitWithApplicationTest.kt @@ -0,0 +1,29 @@ +package io.sentry.react + +import android.app.Application +import org.junit.Assert.assertSame +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito.mock +import org.mockito.kotlin.whenever +import org.robolectric.RobolectricTestRunner + +@RunWith(RobolectricTestRunner::class) +class RNSentryModuleInitWithApplicationTest { + @Test + fun `when application context is null fallback to react context`() { + val mockedReactContext = Utils.makeReactContextMock() + whenever(mockedReactContext.applicationContext).thenReturn(null) + + assertSame(RNSentryModuleImpl(mockedReactContext).applicationContext, mockedReactContext) + } + + @Test + fun `use application context if available`() { + val mockedApplicationContext = mock(Application::class.java) + val mockedReactContext = Utils.makeReactContextMock() + whenever(mockedReactContext.applicationContext).thenReturn(mockedApplicationContext) + + assertSame(RNSentryModuleImpl(mockedReactContext).applicationContext, mockedApplicationContext) + } +} diff --git a/packages/core/RNSentryAndroidTester/app/src/test/java/io/sentry/react/Utils.kt b/packages/core/RNSentryAndroidTester/app/src/test/java/io/sentry/react/Utils.kt index 989c2c0994..840e940917 100644 --- a/packages/core/RNSentryAndroidTester/app/src/test/java/io/sentry/react/Utils.kt +++ b/packages/core/RNSentryAndroidTester/app/src/test/java/io/sentry/react/Utils.kt @@ -10,7 +10,7 @@ import org.mockito.kotlin.whenever class Utils { companion object { - fun createRNSentryModuleWithMockedContext(): RNSentryModuleImpl { + fun makeReactContextMock(): ReactApplicationContext { val packageManager = mock(PackageManager::class.java) val packageInfo = mock(PackageInfo::class.java) @@ -18,9 +18,13 @@ class Utils { whenever(reactContext.packageManager).thenReturn(packageManager) whenever(packageManager.getPackageInfo(anyString(), anyInt())).thenReturn(packageInfo) + return reactContext + } + + fun createRNSentryModuleWithMockedContext(): RNSentryModuleImpl { RNSentryModuleImpl.lastStartTimestampMs = -1 - return RNSentryModuleImpl(reactContext) + return RNSentryModuleImpl(makeReactContextMock()) } } } diff --git a/packages/core/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java b/packages/core/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java index 8a6beaa024..8f6c814db6 100644 --- a/packages/core/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +++ b/packages/core/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java @@ -90,6 +90,7 @@ import java.util.concurrent.CountDownLatch; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.TestOnly; public class RNSentryModuleImpl { @@ -177,12 +178,22 @@ public void initNativeReactNavigationNewFrameTracking(Promise promise) { public void initNativeSdk(final ReadableMap rnOptions, Promise promise) { SentryAndroid.init( - this.getReactApplicationContext(), - options -> getSentryAndroidOptions(options, rnOptions, logger)); + getApplicationContext(), options -> getSentryAndroidOptions(options, rnOptions, logger)); promise.resolve(true); } + @TestOnly + protected Context getApplicationContext() { + final Context context = this.getReactApplicationContext().getApplicationContext(); + if (context == null) { + logger.log( + SentryLevel.ERROR, "ApplicationContext is null, using ReactApplicationContext fallback."); + return this.getReactApplicationContext(); + } + return context; + } + protected void getSentryAndroidOptions( @NotNull SentryAndroidOptions options, @NotNull ReadableMap rnOptions, ILogger logger) { @Nullable SdkVersion sdkVersion = options.getSdkVersion();