Skip to content

Commit cb15848

Browse files
authored
Merge 85f5bae into 42ff8e9
2 parents 42ff8e9 + 85f5bae commit cb15848

File tree

14 files changed

+710
-80
lines changed

14 files changed

+710
-80
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
- Cache network capabilities and status to reduce IPC calls ([#4560](https://github.com/getsentry/sentry-java/pull/4560))
1313
- Deduplicate battery breadcrumbs ([#4561](https://github.com/getsentry/sentry-java/pull/4561))
1414
- Have single `NetworkCallback` registered at a time to reduce IPC calls ([#4562](https://github.com/getsentry/sentry-java/pull/4562))
15+
- Do not register for SystemEvents and NetworkCallbacks immediately when launched with non-foreground importance ([#4579](https://github.com/getsentry/sentry-java/pull/4579))
1516

1617
## 8.17.0
1718

sentry-android-core/api/sentry-android-core.api

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,16 +167,29 @@ public final class io/sentry/android/core/AppLifecycleIntegration : io/sentry/In
167167
}
168168

169169
public final class io/sentry/android/core/AppState : java/io/Closeable {
170+
public fun addAppStateListener (Lio/sentry/android/core/AppState$AppStateListener;)V
170171
public fun close ()V
171172
public static fun getInstance ()Lio/sentry/android/core/AppState;
173+
public fun getLifecycleObserver ()Lio/sentry/android/core/AppState$LifecycleObserver;
172174
public fun isInBackground ()Ljava/lang/Boolean;
175+
public fun registerLifecycleObserver (Lio/sentry/SentryOptions;)V
176+
public fun removeAppStateListener (Lio/sentry/android/core/AppState$AppStateListener;)V
177+
public fun resetInstance ()V
178+
public fun unregisterLifecycleObserver ()V
173179
}
174180

175181
public abstract interface class io/sentry/android/core/AppState$AppStateListener {
176182
public abstract fun onBackground ()V
177183
public abstract fun onForeground ()V
178184
}
179185

186+
public final class io/sentry/android/core/AppState$LifecycleObserver : androidx/lifecycle/DefaultLifecycleObserver {
187+
public fun <init> (Lio/sentry/android/core/AppState;)V
188+
public fun getListeners ()Ljava/util/List;
189+
public fun onStart (Landroidx/lifecycle/LifecycleOwner;)V
190+
public fun onStop (Landroidx/lifecycle/LifecycleOwner;)V
191+
}
192+
180193
public final class io/sentry/android/core/BuildConfig {
181194
public static final field BUILD_TYPE Ljava/lang/String;
182195
public static final field DEBUG Z

sentry-android-core/src/main/java/io/sentry/android/core/AppState.java

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import io.sentry.ISentryLifecycleToken;
99
import io.sentry.NoOpLogger;
1010
import io.sentry.SentryLevel;
11+
import io.sentry.SentryOptions;
1112
import io.sentry.android.core.internal.util.AndroidThreadChecker;
1213
import io.sentry.util.AutoClosableReentrantLock;
1314
import java.io.Closeable;
@@ -35,11 +36,18 @@ private AppState() {}
3536

3637
private volatile @Nullable Boolean inBackground = null;
3738

39+
@ApiStatus.Internal
3840
@TestOnly
39-
void resetInstance() {
41+
public void resetInstance() {
4042
instance = new AppState();
4143
}
4244

45+
@ApiStatus.Internal
46+
@TestOnly
47+
public LifecycleObserver getLifecycleObserver() {
48+
return lifecycleObserver;
49+
}
50+
4351
public @Nullable Boolean isInBackground() {
4452
return inBackground;
4553
}
@@ -48,23 +56,24 @@ void setInBackground(final boolean inBackground) {
4856
this.inBackground = inBackground;
4957
}
5058

51-
void addAppStateListener(final @NotNull AppStateListener listener) {
59+
public void addAppStateListener(final @NotNull AppStateListener listener) {
5260
try (final @NotNull ISentryLifecycleToken ignored = lock.acquire()) {
5361
ensureLifecycleObserver(NoOpLogger.getInstance());
5462

5563
lifecycleObserver.listeners.add(listener);
5664
}
5765
}
5866

59-
void removeAppStateListener(final @NotNull AppStateListener listener) {
67+
public void removeAppStateListener(final @NotNull AppStateListener listener) {
6068
try (final @NotNull ISentryLifecycleToken ignored = lock.acquire()) {
6169
if (lifecycleObserver != null) {
6270
lifecycleObserver.listeners.remove(listener);
6371
}
6472
}
6573
}
6674

67-
void registerLifecycleObserver(final @Nullable SentryAndroidOptions options) {
75+
@ApiStatus.Internal
76+
public void registerLifecycleObserver(final @Nullable SentryOptions options) {
6877
if (lifecycleObserver != null) {
6978
return;
7079
}
@@ -120,7 +129,8 @@ private void addObserverInternal(final @NotNull ILogger logger) {
120129
}
121130
}
122131

123-
void unregisterLifecycleObserver() {
132+
@ApiStatus.Internal
133+
public void unregisterLifecycleObserver() {
124134
if (lifecycleObserver == null) {
125135
return;
126136
}
@@ -154,7 +164,8 @@ public void close() throws IOException {
154164
unregisterLifecycleObserver();
155165
}
156166

157-
final class LifecycleObserver implements DefaultLifecycleObserver {
167+
@ApiStatus.Internal
168+
public final class LifecycleObserver implements DefaultLifecycleObserver {
158169
final List<AppStateListener> listeners =
159170
new CopyOnWriteArrayList<AppStateListener>() {
160171
@Override
@@ -170,12 +181,18 @@ public boolean add(AppStateListener appStateListener) {
170181
}
171182
};
172183

184+
@ApiStatus.Internal
185+
@TestOnly
186+
public List<AppStateListener> getListeners() {
187+
return listeners;
188+
}
189+
173190
@Override
174191
public void onStart(@NonNull LifecycleOwner owner) {
192+
setInBackground(false);
175193
for (AppStateListener listener : listeners) {
176194
listener.onForeground();
177195
}
178-
setInBackground(false);
179196
}
180197

181198
@Override

sentry-android-core/src/main/java/io/sentry/android/core/ContextUtils.java

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import io.sentry.SentryOptions;
2222
import io.sentry.android.core.util.AndroidLazyEvaluator;
2323
import io.sentry.protocol.App;
24-
import io.sentry.util.LazyEvaluator;
2524
import java.io.BufferedReader;
2625
import java.io.File;
2726
import java.io.FileReader;
@@ -91,20 +90,6 @@ private ContextUtils() {}
9190
// to avoid doing a bunch of Binder calls we use LazyEvaluator to cache the values that are static
9291
// during the app process running
9392

94-
private static final @NotNull LazyEvaluator<Boolean> isForegroundImportance =
95-
new LazyEvaluator<>(
96-
() -> {
97-
try {
98-
final ActivityManager.RunningAppProcessInfo appProcessInfo =
99-
new ActivityManager.RunningAppProcessInfo();
100-
ActivityManager.getMyMemoryState(appProcessInfo);
101-
return appProcessInfo.importance == IMPORTANCE_FOREGROUND;
102-
} catch (Throwable ignored) {
103-
// should never happen
104-
}
105-
return false;
106-
});
107-
10893
/**
10994
* Since this packageInfo uses flags 0 we can assume it's static and cache it as the package name
11095
* or version code cannot change during runtime, only after app update (which will spin up a new
@@ -284,7 +269,15 @@ static String getVersionName(final @NotNull PackageInfo packageInfo) {
284269
*/
285270
@ApiStatus.Internal
286271
public static boolean isForegroundImportance() {
287-
return isForegroundImportance.getValue();
272+
try {
273+
final ActivityManager.RunningAppProcessInfo appProcessInfo =
274+
new ActivityManager.RunningAppProcessInfo();
275+
ActivityManager.getMyMemoryState(appProcessInfo);
276+
return appProcessInfo.importance == IMPORTANCE_FOREGROUND;
277+
} catch (Throwable ignored) {
278+
// should never happen
279+
}
280+
return false;
288281
}
289282

290283
/**
@@ -544,7 +537,6 @@ public static Context getApplicationContext(final @NotNull Context context) {
544537

545538
@TestOnly
546539
static void resetInstance() {
547-
isForegroundImportance.resetValue();
548540
staticPackageInfo33.resetValue();
549541
staticPackageInfo.resetValue();
550542
applicationName.resetValue();

sentry-android-core/src/main/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegration.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import java.util.HashMap;
4444
import java.util.List;
4545
import java.util.Map;
46+
import java.util.concurrent.atomic.AtomicBoolean;
4647
import org.jetbrains.annotations.NotNull;
4748
import org.jetbrains.annotations.Nullable;
4849
import org.jetbrains.annotations.TestOnly;
@@ -62,6 +63,7 @@ public final class SystemEventsBreadcrumbsIntegration
6263
private volatile boolean isClosed = false;
6364
private volatile boolean isStopped = false;
6465
private volatile IntentFilter filter = null;
66+
private final @NotNull AtomicBoolean isReceiverRegistered = new AtomicBoolean(false);
6567
private final @NotNull AutoClosableReentrantLock receiverLock = new AutoClosableReentrantLock();
6668

6769
public SystemEventsBreadcrumbsIntegration(final @NotNull Context context) {
@@ -99,14 +101,15 @@ public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions
99101

100102
if (this.options.isEnableSystemEventBreadcrumbs()) {
101103
AppState.getInstance().addAppStateListener(this);
102-
registerReceiver(this.scopes, this.options, /* reportAsNewIntegration= */ true);
104+
105+
if (ContextUtils.isForegroundImportance()) {
106+
registerReceiver(this.scopes, this.options);
107+
}
103108
}
104109
}
105110

106111
private void registerReceiver(
107-
final @NotNull IScopes scopes,
108-
final @NotNull SentryAndroidOptions options,
109-
final boolean reportAsNewIntegration) {
112+
final @NotNull IScopes scopes, final @NotNull SentryAndroidOptions options) {
110113

111114
if (!options.isEnableSystemEventBreadcrumbs()) {
112115
return;
@@ -137,7 +140,7 @@ private void registerReceiver(
137140
// registerReceiver can throw SecurityException but it's not documented in the
138141
// official docs
139142
ContextUtils.registerReceiver(context, options, receiver, filter);
140-
if (reportAsNewIntegration) {
143+
if (!isReceiverRegistered.getAndSet(true)) {
141144
options
142145
.getLogger()
143146
.log(SentryLevel.DEBUG, "SystemEventsBreadcrumbsIntegration installed.");
@@ -237,7 +240,7 @@ public void onForeground() {
237240

238241
isStopped = false;
239242

240-
registerReceiver(scopes, options, /* reportAsNewIntegration= */ false);
243+
registerReceiver(scopes, options);
241244
}
242245

243246
@Override

0 commit comments

Comments
 (0)