77import android .net .Network ;
88import android .net .NetworkCapabilities ;
99import android .os .Build ;
10+ import androidx .annotation .NonNull ;
11+ import androidx .annotation .RequiresApi ;
12+ import io .sentry .IConnectionStatusProvider ;
1013import io .sentry .ILogger ;
1114import io .sentry .SentryLevel ;
1215import io .sentry .android .core .BuildInfoProvider ;
16+ import java .util .HashMap ;
17+ import java .util .Map ;
1318import org .jetbrains .annotations .ApiStatus ;
1419import org .jetbrains .annotations .NotNull ;
1520import org .jetbrains .annotations .Nullable ;
21+ import org .jetbrains .annotations .TestOnly ;
1622
1723/**
1824 * Note: ConnectivityManager sometimes throws SecurityExceptions on Android 11. Hence all relevant
1925 * calls are guarded with try/catch. see https://issuetracker.google.com/issues/175055271 for more
2026 * details
2127 */
2228@ ApiStatus .Internal
23- public final class ConnectivityChecker {
29+ public final class AndroidConnectionStatusProvider implements IConnectionStatusProvider {
2430
25- public enum Status {
26- CONNECTED ,
27- NOT_CONNECTED ,
28- NO_PERMISSION ,
29- UNKNOWN
30- }
31+ private final @ NotNull Context context ;
32+ private final @ NotNull ILogger logger ;
33+ private final @ NotNull BuildInfoProvider buildInfoProvider ;
34+ private final @ NotNull Map <IConnectionStatusObserver , ConnectivityManager .NetworkCallback >
35+ registeredCallbacks ;
3136
32- private ConnectivityChecker () {}
37+ public AndroidConnectionStatusProvider (
38+ @ NotNull Context context ,
39+ @ NotNull ILogger logger ,
40+ @ NotNull BuildInfoProvider buildInfoProvider ) {
41+ this .context = context ;
42+ this .logger = logger ;
43+ this .buildInfoProvider = buildInfoProvider ;
44+ this .registeredCallbacks = new HashMap <>();
45+ }
3346
34- /**
35- * Return the Connection status
36- *
37- * @return the ConnectionStatus
38- */
39- public static @ NotNull ConnectivityChecker .Status getConnectionStatus (
40- final @ NotNull Context context , final @ NotNull ILogger logger ) {
47+ @ Override
48+ public @ NotNull ConnectionStatus getConnectionStatus () {
4149 final ConnectivityManager connectivityManager = getConnectivityManager (context , logger );
4250 if (connectivityManager == null ) {
43- return Status .UNKNOWN ;
51+ return ConnectionStatus .UNKNOWN ;
4452 }
4553 return getConnectionStatus (context , connectivityManager , logger );
4654 // getActiveNetworkInfo might return null if VPN doesn't specify its
@@ -50,6 +58,50 @@ private ConnectivityChecker() {}
5058 // connectivityManager.registerDefaultNetworkCallback(...)
5159 }
5260
61+ @ Override
62+ public @ Nullable String getConnectionType () {
63+ return getConnectionType (context , logger , buildInfoProvider );
64+ }
65+
66+ @ RequiresApi (api = Build .VERSION_CODES .LOLLIPOP )
67+ @ Override
68+ public boolean addConnectionStatusObserver (@ NotNull IConnectionStatusObserver observer ) {
69+ final ConnectivityManager .NetworkCallback callback =
70+ new ConnectivityManager .NetworkCallback () {
71+ @ Override
72+ public void onAvailable (@ NonNull Network network ) {
73+ observer .onConnectionStatusChanged (getConnectionStatus ());
74+ }
75+
76+ @ Override
77+ public void onLosing (@ NonNull Network network , int maxMsToLive ) {
78+ observer .onConnectionStatusChanged (getConnectionStatus ());
79+ }
80+
81+ @ Override
82+ public void onLost (@ NonNull Network network ) {
83+ observer .onConnectionStatusChanged (getConnectionStatus ());
84+ }
85+
86+ @ Override
87+ public void onUnavailable () {
88+ observer .onConnectionStatusChanged (getConnectionStatus ());
89+ }
90+ };
91+
92+ registeredCallbacks .put (observer , callback );
93+ return registerNetworkCallback (context , logger , buildInfoProvider , callback );
94+ }
95+
96+ @ Override
97+ public void removeConnectionStatusObserver (@ NotNull IConnectionStatusObserver observer ) {
98+ final @ Nullable ConnectivityManager .NetworkCallback callback =
99+ registeredCallbacks .remove (observer );
100+ if (callback != null ) {
101+ unregisterNetworkCallback (context , logger , buildInfoProvider , callback );
102+ }
103+ }
104+
53105 /**
54106 * Return the Connection status
55107 *
@@ -59,25 +111,27 @@ private ConnectivityChecker() {}
59111 * @return true if connected or no permission to check, false otherwise
60112 */
61113 @ SuppressWarnings ({"deprecation" , "MissingPermission" })
62- private static @ NotNull ConnectivityChecker . Status getConnectionStatus (
114+ private static @ NotNull IConnectionStatusProvider . ConnectionStatus getConnectionStatus (
63115 final @ NotNull Context context ,
64116 final @ NotNull ConnectivityManager connectivityManager ,
65117 final @ NotNull ILogger logger ) {
66118 if (!Permissions .hasPermission (context , Manifest .permission .ACCESS_NETWORK_STATE )) {
67119 logger .log (SentryLevel .INFO , "No permission (ACCESS_NETWORK_STATE) to check network status." );
68- return Status .NO_PERMISSION ;
120+ return ConnectionStatus .NO_PERMISSION ;
69121 }
70122
71123 try {
72124 final android .net .NetworkInfo activeNetworkInfo = connectivityManager .getActiveNetworkInfo ();
73125 if (activeNetworkInfo == null ) {
74126 logger .log (SentryLevel .INFO , "NetworkInfo is null, there's no active network." );
75- return Status . NOT_CONNECTED ;
127+ return ConnectionStatus . DISCONNECTED ;
76128 }
77- return activeNetworkInfo .isConnected () ? Status .CONNECTED : Status .NOT_CONNECTED ;
129+ return activeNetworkInfo .isConnected ()
130+ ? ConnectionStatus .CONNECTED
131+ : ConnectionStatus .DISCONNECTED ;
78132 } catch (Throwable t ) {
79133 logger .log (SentryLevel .ERROR , "Could not retrieve Connection Status" , t );
80- return Status .UNKNOWN ;
134+ return ConnectionStatus .UNKNOWN ;
81135 }
82136 }
83137
@@ -273,4 +327,11 @@ public static void unregisterNetworkCallback(
273327 logger .log (SentryLevel .ERROR , "unregisterNetworkCallback failed" , t );
274328 }
275329 }
330+
331+ @ TestOnly
332+ @ NotNull
333+ public Map <IConnectionStatusObserver , ConnectivityManager .NetworkCallback >
334+ getRegisteredCallbacks () {
335+ return registeredCallbacks ;
336+ }
276337}
0 commit comments