Skip to content

Commit 53a1054

Browse files
committed
AndroidConnectionStatusProvider cache is now updated in the background, so lock is not acquired indefinitely
1 parent 27d7cf8 commit 53a1054

File tree

1 file changed

+66
-61
lines changed

1 file changed

+66
-61
lines changed

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

Lines changed: 66 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,16 @@ private void updateCacheAndNotifyObservers(
268268

269269
// Only notify observers if something meaningful changed
270270
if (shouldUpdate) {
271-
updateCache(networkCapabilities);
271+
cachedNetworkCapabilities = networkCapabilities;
272+
lastCacheUpdateTime = timeProvider.getCurrentTimeMillis();
273+
options
274+
.getLogger()
275+
.log(
276+
SentryLevel.DEBUG,
277+
"Cache updated - Status: "
278+
+ getConnectionStatusFromCache()
279+
+ ", Type: "
280+
+ getConnectionTypeFromCache());
272281

273282
final @NotNull ConnectionStatus status = getConnectionStatusFromCache();
274283
try (final @NotNull ISentryLifecycleToken ignored = lock.acquire()) {
@@ -349,59 +358,54 @@ private boolean hasSignificantTransportChanges(
349358
}
350359

351360
@SuppressLint({"NewApi", "MissingPermission"})
352-
private void updateCache(@Nullable NetworkCapabilities networkCapabilities) {
361+
private void updateCache() {
353362
try (final @NotNull ISentryLifecycleToken ignored = lock.acquire()) {
354-
try {
355-
if (networkCapabilities != null) {
356-
cachedNetworkCapabilities = networkCapabilities;
357-
} else {
358-
if (!Permissions.hasPermission(context, Manifest.permission.ACCESS_NETWORK_STATE)) {
359-
options
360-
.getLogger()
361-
.log(
362-
SentryLevel.INFO,
363-
"No permission (ACCESS_NETWORK_STATE) to check network status.");
364-
cachedNetworkCapabilities = null;
365-
lastCacheUpdateTime = timeProvider.getCurrentTimeMillis();
366-
return;
367-
}
368-
369-
if (buildInfoProvider.getSdkInfoVersion() < Build.VERSION_CODES.M) {
370-
cachedNetworkCapabilities = null;
371-
lastCacheUpdateTime = timeProvider.getCurrentTimeMillis();
372-
return;
373-
}
374-
375-
// Fallback: query current active network
376-
final ConnectivityManager connectivityManager =
377-
getConnectivityManager(context, options.getLogger());
378-
if (connectivityManager != null) {
379-
final Network activeNetwork = connectivityManager.getActiveNetwork();
380-
381-
cachedNetworkCapabilities =
382-
activeNetwork != null
383-
? connectivityManager.getNetworkCapabilities(activeNetwork)
384-
: null;
385-
} else {
386-
cachedNetworkCapabilities =
387-
null; // Clear cached capabilities if connectivity manager is null
388-
}
389-
}
390-
lastCacheUpdateTime = timeProvider.getCurrentTimeMillis();
391-
363+
cachedNetworkCapabilities = null;
364+
lastCacheUpdateTime = timeProvider.getCurrentTimeMillis();
365+
}
366+
try {
367+
if (!Permissions.hasPermission(context, Manifest.permission.ACCESS_NETWORK_STATE)) {
392368
options
393369
.getLogger()
394-
.log(
395-
SentryLevel.DEBUG,
396-
"Cache updated - Status: "
397-
+ getConnectionStatusFromCache()
398-
+ ", Type: "
399-
+ getConnectionTypeFromCache());
400-
} catch (Throwable t) {
401-
options.getLogger().log(SentryLevel.WARNING, "Failed to update connection status cache", t);
402-
cachedNetworkCapabilities = null;
403-
lastCacheUpdateTime = timeProvider.getCurrentTimeMillis();
370+
.log(SentryLevel.INFO, "No permission (ACCESS_NETWORK_STATE) to check network status.");
371+
return;
404372
}
373+
374+
if (buildInfoProvider.getSdkInfoVersion() < Build.VERSION_CODES.M) {
375+
return;
376+
}
377+
378+
// Fallback: query current active network in the background
379+
submitSafe(
380+
() -> {
381+
final ConnectivityManager connectivityManager =
382+
getConnectivityManager(context, options.getLogger());
383+
if (connectivityManager != null) {
384+
final @Nullable NetworkCapabilities capabilities =
385+
getNetworkCapabilities(connectivityManager);
386+
387+
try (final @NotNull ISentryLifecycleToken ignored2 = lock.acquire()) {
388+
cachedNetworkCapabilities = capabilities;
389+
lastCacheUpdateTime = timeProvider.getCurrentTimeMillis();
390+
391+
if (capabilities != null) {
392+
options
393+
.getLogger()
394+
.log(
395+
SentryLevel.DEBUG,
396+
"Cache updated - Status: "
397+
+ getConnectionStatusFromCache()
398+
+ ", Type: "
399+
+ getConnectionTypeFromCache());
400+
}
401+
}
402+
}
403+
});
404+
405+
} catch (Throwable t) {
406+
options.getLogger().log(SentryLevel.WARNING, "Failed to update connection status cache", t);
407+
cachedNetworkCapabilities = null;
408+
lastCacheUpdateTime = timeProvider.getCurrentTimeMillis();
405409
}
406410
}
407411

@@ -412,15 +416,15 @@ private boolean isCacheValid() {
412416
@Override
413417
public @NotNull ConnectionStatus getConnectionStatus() {
414418
if (!isCacheValid()) {
415-
updateCache(null);
419+
updateCache();
416420
}
417421
return getConnectionStatusFromCache();
418422
}
419423

420424
@Override
421425
public @Nullable String getConnectionType() {
422426
if (!isCacheValid()) {
423-
updateCache(null);
427+
updateCache();
424428
}
425429
return getConnectionTypeFromCache();
426430
}
@@ -490,7 +494,7 @@ public void onForeground() {
490494
() -> {
491495
// proactively update cache and notify observers on foreground to ensure connectivity
492496
// state is not stale
493-
updateCache(null);
497+
updateCache();
494498

495499
final @NotNull ConnectionStatus status = getConnectionStatusFromCache();
496500
if (status == ConnectionStatus.DISCONNECTED) {
@@ -575,6 +579,14 @@ public NetworkCapabilities getCachedNetworkCapabilities() {
575579
}
576580
}
577581

582+
@RequiresApi(Build.VERSION_CODES.M)
583+
@SuppressLint("MissingPermission")
584+
private static @Nullable NetworkCapabilities getNetworkCapabilities(
585+
final @NotNull ConnectivityManager connectivityManager) {
586+
final Network activeNetwork = connectivityManager.getActiveNetwork();
587+
return activeNetwork != null ? connectivityManager.getNetworkCapabilities(activeNetwork) : null;
588+
}
589+
578590
/**
579591
* Check the connection type of the active network
580592
*
@@ -603,14 +615,7 @@ public NetworkCapabilities getCachedNetworkCapabilities() {
603615
boolean cellular = false;
604616

605617
if (buildInfoProvider.getSdkInfoVersion() >= Build.VERSION_CODES.M) {
606-
607-
final Network activeNetwork = connectivityManager.getActiveNetwork();
608-
if (activeNetwork == null) {
609-
logger.log(SentryLevel.INFO, "Network is null and cannot check network status");
610-
return null;
611-
}
612-
final NetworkCapabilities networkCapabilities =
613-
connectivityManager.getNetworkCapabilities(activeNetwork);
618+
final NetworkCapabilities networkCapabilities = getNetworkCapabilities(connectivityManager);
614619
if (networkCapabilities == null) {
615620
logger.log(SentryLevel.INFO, "NetworkCapabilities is null and cannot check network type");
616621
return null;

0 commit comments

Comments
 (0)