Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit cf708bd

Browse filesBrowse files
authored
Avoid StrictMode warnings (#4724)
* Removed few useless IO calls * Added SentryOptions.runtimeManager to run methods with Stricmode LAX policies
1 parent e881bae commit cf708bd
Copy full SHA for cf708bd

18 files changed

+261-51Lines changed: 261 additions & 51 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎CHANGELOG.md‎

Copy file name to clipboardExpand all lines: CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
### Fixes
1010

11+
- Avoid StrictMode warnings ([#4724](https://github.com/getsentry/sentry-java/pull/4724))
1112
- Use logger from options for JVM profiler ([#4771](https://github.com/getsentry/sentry-java/pull/4771))
1213
- Session Replay: Avoid deadlock when pausing replay if no connection ([#4788](https://github.com/getsentry/sentry-java/pull/4788))
1314

Collapse file

‎sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java‎

Copy file name to clipboardExpand all lines: sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java
+11-5Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import io.sentry.android.core.internal.modules.AssetsModulesLoader;
3131
import io.sentry.android.core.internal.util.AndroidConnectionStatusProvider;
3232
import io.sentry.android.core.internal.util.AndroidCurrentDateProvider;
33+
import io.sentry.android.core.internal.util.AndroidRuntimeManager;
3334
import io.sentry.android.core.internal.util.AndroidThreadChecker;
3435
import io.sentry.android.core.internal.util.SentryFrameMetricsCollector;
3536
import io.sentry.android.core.performance.AppStartMetrics;
@@ -108,7 +109,7 @@ static void loadDefaultAndMetadataOptions(
108109
final @NotNull BuildInfoProvider buildInfoProvider) {
109110
Objects.requireNonNull(context, "The context is required.");
110111

111-
context = ContextUtils.getApplicationContext(context);
112+
@NotNull final Context finalContext = ContextUtils.getApplicationContext(context);
112113

113114
Objects.requireNonNull(options, "The options object is required.");
114115
Objects.requireNonNull(logger, "The ILogger object is required.");
@@ -120,17 +121,22 @@ static void loadDefaultAndMetadataOptions(
120121
options.setDefaultScopeType(ScopeType.CURRENT);
121122
options.setOpenTelemetryMode(SentryOpenTelemetryMode.OFF);
122123
options.setDateProvider(new SentryAndroidDateProvider());
124+
options.setRuntimeManager(new AndroidRuntimeManager());
123125

124126
// set a lower flush timeout on Android to avoid ANRs
125127
options.setFlushTimeoutMillis(DEFAULT_FLUSH_TIMEOUT_MS);
126128

127129
options.setFrameMetricsCollector(
128-
new SentryFrameMetricsCollector(context, logger, buildInfoProvider));
130+
new SentryFrameMetricsCollector(finalContext, logger, buildInfoProvider));
129131

130-
ManifestMetadataReader.applyMetadata(context, options, buildInfoProvider);
131-
options.setCacheDirPath(getCacheDir(context).getAbsolutePath());
132+
ManifestMetadataReader.applyMetadata(finalContext, options, buildInfoProvider);
132133

133-
readDefaultOptionValues(options, context, buildInfoProvider);
134+
options.setCacheDirPath(
135+
options
136+
.getRuntimeManager()
137+
.runWithRelaxedPolicy(() -> getCacheDir(finalContext).getAbsolutePath()));
138+
139+
readDefaultOptionValues(options, finalContext, buildInfoProvider);
134140
AppState.getInstance().registerLifecycleObserver(options);
135141
}
136142

Collapse file

‎sentry-android-core/src/main/java/io/sentry/android/core/SentryPerformanceProvider.java‎

Copy file name to clipboardExpand all lines: sentry-android-core/src/main/java/io/sentry/android/core/SentryPerformanceProvider.java
+5-1Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@
2020
import io.sentry.SentryOptions;
2121
import io.sentry.TracesSampler;
2222
import io.sentry.TracesSamplingDecision;
23+
import io.sentry.android.core.internal.util.AndroidRuntimeManager;
2324
import io.sentry.android.core.internal.util.SentryFrameMetricsCollector;
2425
import io.sentry.android.core.performance.AppStartMetrics;
2526
import io.sentry.android.core.performance.TimeSpan;
2627
import io.sentry.util.AutoClosableReentrantLock;
28+
import io.sentry.util.runtime.IRuntimeManager;
2729
import java.io.BufferedReader;
2830
import java.io.File;
2931
import java.io.FileInputStream;
@@ -108,7 +110,9 @@ private void launchAppStartProfiler(final @NotNull AppStartMetrics appStartMetri
108110
return;
109111
}
110112

111-
final @NotNull File cacheDir = AndroidOptionsInitializer.getCacheDir(context);
113+
final @NotNull IRuntimeManager runtimeManager = new AndroidRuntimeManager();
114+
final @NotNull File cacheDir =
115+
runtimeManager.runWithRelaxedPolicy(() -> AndroidOptionsInitializer.getCacheDir(context));
112116
final @NotNull File configFile = new File(cacheDir, APP_START_PROFILING_CONFIG_FILE_NAME);
113117

114118
// No config exists: app start profiling is not enabled
Collapse file

‎sentry-android-core/src/main/java/io/sentry/android/core/cache/AndroidEnvelopeCache.java‎

Copy file name to clipboardExpand all lines: sentry-android-core/src/main/java/io/sentry/android/core/cache/AndroidEnvelopeCache.java
+9-8Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import io.sentry.util.HintUtils;
2020
import io.sentry.util.Objects;
2121
import java.io.File;
22+
import java.io.FileNotFoundException;
2223
import java.io.FileOutputStream;
2324
import java.io.OutputStream;
2425
import org.jetbrains.annotations.ApiStatus;
@@ -157,18 +158,18 @@ public static boolean hasStartupCrashMarker(final @NotNull SentryOptions options
157158

158159
final File lastAnrMarker = new File(cacheDirPath, LAST_ANR_REPORT);
159160
try {
160-
if (lastAnrMarker.exists() && lastAnrMarker.canRead()) {
161-
final String content = FileUtils.readText(lastAnrMarker);
162-
// we wrapped into try-catch already
163-
//noinspection ConstantConditions
164-
return content.equals("null") ? null : Long.parseLong(content.trim());
165-
} else {
161+
final String content = FileUtils.readText(lastAnrMarker);
162+
// we wrapped into try-catch already
163+
//noinspection ConstantConditions
164+
return content.equals("null") ? null : Long.parseLong(content.trim());
165+
} catch (Throwable e) {
166+
if (e instanceof FileNotFoundException) {
166167
options
167168
.getLogger()
168169
.log(DEBUG, "Last ANR marker does not exist. %s.", lastAnrMarker.getAbsolutePath());
170+
} else {
171+
options.getLogger().log(ERROR, "Error reading last ANR marker", e);
169172
}
170-
} catch (Throwable e) {
171-
options.getLogger().log(ERROR, "Error reading last ANR marker", e);
172173
}
173174
return null;
174175
}
Collapse file
+23Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package io.sentry.android.core.internal.util;
2+
3+
import android.os.StrictMode;
4+
import io.sentry.util.runtime.IRuntimeManager;
5+
import org.jetbrains.annotations.ApiStatus;
6+
import org.jetbrains.annotations.NotNull;
7+
8+
@ApiStatus.Internal
9+
public final class AndroidRuntimeManager implements IRuntimeManager {
10+
@Override
11+
public <T> T runWithRelaxedPolicy(final @NotNull IRuntimeManagerCallback<T> toRun) {
12+
final @NotNull StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
13+
final @NotNull StrictMode.VmPolicy oldVmPolicy = StrictMode.getVmPolicy();
14+
StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.LAX);
15+
StrictMode.setVmPolicy(StrictMode.VmPolicy.LAX);
16+
try {
17+
return toRun.run();
18+
} finally {
19+
StrictMode.setThreadPolicy(oldPolicy);
20+
StrictMode.setVmPolicy(oldVmPolicy);
21+
}
22+
}
23+
}
Collapse file

‎sentry-android-core/src/main/java/io/sentry/android/core/internal/util/CpuInfoUtils.java‎

Copy file name to clipboardExpand all lines: sentry-android-core/src/main/java/io/sentry/android/core/internal/util/CpuInfoUtils.java
-2Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ private CpuInfoUtils() {}
5151
if (!cpuDir.getName().matches("cpu[0-9]+")) continue;
5252
File cpuMaxFreqFile = new File(cpuDir, CPUINFO_MAX_FREQ_PATH);
5353

54-
if (!cpuMaxFreqFile.exists() || !cpuMaxFreqFile.canRead()) continue;
55-
5654
long khz;
5755
try {
5856
String content = FileUtils.readText(cpuMaxFreqFile);
Collapse file

‎sentry-android-core/src/test/java/io/sentry/android/core/AndroidOptionsInitializerTest.kt‎

Copy file name to clipboardExpand all lines: sentry-android-core/src/test/java/io/sentry/android/core/AndroidOptionsInitializerTest.kt
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import io.sentry.android.core.internal.debugmeta.AssetsDebugMetaLoader
2424
import io.sentry.android.core.internal.gestures.AndroidViewGestureTargetLocator
2525
import io.sentry.android.core.internal.modules.AssetsModulesLoader
2626
import io.sentry.android.core.internal.util.AndroidConnectionStatusProvider
27+
import io.sentry.android.core.internal.util.AndroidRuntimeManager
2728
import io.sentry.android.core.internal.util.AndroidThreadChecker
2829
import io.sentry.android.core.performance.AppStartMetrics
2930
import io.sentry.android.fragment.FragmentLifecycleIntegration
@@ -917,4 +918,10 @@ class AndroidOptionsInitializerTest {
917918
fixture.sentryOptions.compositePerformanceCollector is DefaultCompositePerformanceCollector
918919
}
919920
}
921+
922+
@Test
923+
fun `AndroidRuntimeManager is set in the options`() {
924+
fixture.initSut()
925+
assertIs<AndroidRuntimeManager>(fixture.sentryOptions.runtimeManager)
926+
}
920927
}
Collapse file
+87Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package io.sentry.android.core.internal.util
2+
3+
import android.os.StrictMode
4+
import androidx.test.ext.junit.runners.AndroidJUnit4
5+
import kotlin.test.AfterTest
6+
import kotlin.test.Test
7+
import kotlin.test.assertEquals
8+
import kotlin.test.assertNotEquals
9+
import kotlin.test.assertTrue
10+
import org.junit.runner.RunWith
11+
12+
@RunWith(AndroidJUnit4::class)
13+
class AndroidRuntimeManagerTest {
14+
15+
val sut = AndroidRuntimeManager()
16+
17+
@AfterTest
18+
fun `clean up`() {
19+
// Revert StrictMode policies to avoid issues with other tests
20+
StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.LAX)
21+
StrictMode.setVmPolicy(StrictMode.VmPolicy.LAX)
22+
}
23+
24+
@Test
25+
fun `runWithRelaxedPolicy changes policy when running and restores it afterwards`() {
26+
var called = false
27+
val threadPolicy = StrictMode.ThreadPolicy.Builder().detectAll().penaltyDeath().build()
28+
val vmPolicy = StrictMode.VmPolicy.Builder().detectAll().penaltyDeath().build()
29+
assertNotEquals(StrictMode.ThreadPolicy.LAX, threadPolicy)
30+
assertNotEquals(StrictMode.VmPolicy.LAX, vmPolicy)
31+
32+
// Set and assert the StrictMode policies
33+
StrictMode.setThreadPolicy(threadPolicy)
34+
StrictMode.setVmPolicy(vmPolicy)
35+
assertEquals(threadPolicy.toString(), StrictMode.getThreadPolicy().toString())
36+
assertEquals(vmPolicy.toString(), StrictMode.getVmPolicy().toString())
37+
38+
// Run the function and assert LAX policies
39+
called =
40+
sut.runWithRelaxedPolicy {
41+
assertEquals(
42+
StrictMode.ThreadPolicy.LAX.toString(),
43+
StrictMode.getThreadPolicy().toString(),
44+
)
45+
assertEquals(StrictMode.VmPolicy.LAX.toString(), StrictMode.getVmPolicy().toString())
46+
true
47+
}
48+
49+
// Policies should be reverted back
50+
assertEquals(threadPolicy.toString(), StrictMode.getThreadPolicy().toString())
51+
assertEquals(vmPolicy.toString(), StrictMode.getVmPolicy().toString())
52+
53+
// Ensure the code ran
54+
assertTrue(called)
55+
}
56+
57+
@Test
58+
fun `runWithRelaxedPolicy changes policy and restores it afterwards even if the code throws`() {
59+
var called = false
60+
val threadPolicy = StrictMode.ThreadPolicy.Builder().detectAll().penaltyDeath().build()
61+
val vmPolicy = StrictMode.VmPolicy.Builder().detectAll().penaltyDeath().build()
62+
63+
// Set and assert the StrictMode policies
64+
StrictMode.setThreadPolicy(threadPolicy)
65+
StrictMode.setVmPolicy(vmPolicy)
66+
67+
// Run the function and assert LAX policies
68+
try {
69+
sut.runWithRelaxedPolicy {
70+
assertEquals(
71+
StrictMode.ThreadPolicy.LAX.toString(),
72+
StrictMode.getThreadPolicy().toString(),
73+
)
74+
assertEquals(StrictMode.VmPolicy.LAX.toString(), StrictMode.getVmPolicy().toString())
75+
called = true
76+
throw Exception("Test exception")
77+
}
78+
} catch (_: Exception) {}
79+
80+
// Policies should be reverted back
81+
assertEquals(threadPolicy.toString(), StrictMode.getThreadPolicy().toString())
82+
assertEquals(vmPolicy.toString(), StrictMode.getVmPolicy().toString())
83+
84+
// Ensure the code ran
85+
assertTrue(called)
86+
}
87+
}
Collapse file

‎sentry-android-integration-tests/sentry-uitest-android/src/androidTest/java/io/sentry/uitest/android/SdkInitTests.kt‎

Copy file name to clipboardExpand all lines: sentry-android-integration-tests/sentry-uitest-android/src/androidTest/java/io/sentry/uitest/android/SdkInitTests.kt
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.sentry.uitest.android
22

3+
import android.os.StrictMode
34
import androidx.lifecycle.Lifecycle
45
import androidx.test.core.app.launchActivity
56
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -252,6 +253,15 @@ class SdkInitTests : BaseUiTest() {
252253
assertDefaultIntegrations()
253254
}
254255

256+
@Test
257+
fun initNotThrowStrictMode() {
258+
StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder().detectAll().penaltyDeath().build())
259+
StrictMode.setVmPolicy(StrictMode.VmPolicy.Builder().detectAll().penaltyDeath().build())
260+
val sampleScenario = launchActivity<EmptyActivity>()
261+
initSentry()
262+
sampleScenario.moveToState(Lifecycle.State.DESTROYED)
263+
}
264+
255265
private fun assertDefaultIntegrations() {
256266
val integrations =
257267
mutableListOf(
Collapse file

‎sentry/api/sentry.api‎

Copy file name to clipboardExpand all lines: sentry/api/sentry.api
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3394,6 +3394,7 @@ public class io/sentry/SentryOptions {
33943394
public fun getReadTimeoutMillis ()I
33953395
public fun getRelease ()Ljava/lang/String;
33963396
public fun getReplayController ()Lio/sentry/ReplayController;
3397+
public fun getRuntimeManager ()Lio/sentry/util/runtime/IRuntimeManager;
33973398
public fun getSampleRate ()Ljava/lang/Double;
33983399
public fun getScopeObservers ()Ljava/util/List;
33993400
public fun getSdkVersion ()Lio/sentry/protocol/SdkVersion;
@@ -3539,6 +3540,7 @@ public class io/sentry/SentryOptions {
35393540
public fun setReadTimeoutMillis (I)V
35403541
public fun setRelease (Ljava/lang/String;)V
35413542
public fun setReplayController (Lio/sentry/ReplayController;)V
3543+
public fun setRuntimeManager (Lio/sentry/util/runtime/IRuntimeManager;)V
35423544
public fun setSampleRate (Ljava/lang/Double;)V
35433545
public fun setSdkVersion (Lio/sentry/protocol/SdkVersion;)V
35443546
public fun setSendClientReports (Z)V
@@ -7293,6 +7295,19 @@ public final class io/sentry/util/UrlUtils$UrlDetails {
72937295
public fun getUrlOrFallback ()Ljava/lang/String;
72947296
}
72957297

7298+
public abstract interface class io/sentry/util/runtime/IRuntimeManager {
7299+
public abstract fun runWithRelaxedPolicy (Lio/sentry/util/runtime/IRuntimeManager$IRuntimeManagerCallback;)Ljava/lang/Object;
7300+
}
7301+
7302+
public abstract interface class io/sentry/util/runtime/IRuntimeManager$IRuntimeManagerCallback {
7303+
public abstract fun run ()Ljava/lang/Object;
7304+
}
7305+
7306+
public final class io/sentry/util/runtime/NeutralRuntimeManager : io/sentry/util/runtime/IRuntimeManager {
7307+
public fun <init> ()V
7308+
public fun runWithRelaxedPolicy (Lio/sentry/util/runtime/IRuntimeManager$IRuntimeManagerCallback;)Ljava/lang/Object;
7309+
}
7310+
72967311
public abstract interface class io/sentry/util/thread/IThreadChecker {
72977312
public abstract fun currentThreadSystemId ()J
72987313
public abstract fun getCurrentThreadName ()Ljava/lang/String;

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.