diff --git a/common/src/main/java/io/opentelemetry/android/common/internal/features/networkattributes/data/CurrentNetwork.java b/common/src/main/java/io/opentelemetry/android/common/internal/features/networkattributes/data/CurrentNetwork.java index f776ccec3..b0cb670de 100644 --- a/common/src/main/java/io/opentelemetry/android/common/internal/features/networkattributes/data/CurrentNetwork.java +++ b/common/src/main/java/io/opentelemetry/android/common/internal/features/networkattributes/data/CurrentNetwork.java @@ -116,6 +116,9 @@ public Builder carrier(@Nullable Carrier carrier) { } public Builder subType(@Nullable String subType) { + if ((subType != null) && subType.isEmpty()) { + return subType(null); + } this.subType = subType; return this; } diff --git a/core/src/test/java/io/opentelemetry/android/OpenTelemetryRumBuilderTest.java b/core/src/test/java/io/opentelemetry/android/OpenTelemetryRumBuilderTest.java index ed0653376..f939db4c0 100644 --- a/core/src/test/java/io/opentelemetry/android/OpenTelemetryRumBuilderTest.java +++ b/core/src/test/java/io/opentelemetry/android/OpenTelemetryRumBuilderTest.java @@ -24,6 +24,7 @@ import static org.mockito.Mockito.when; import android.app.Application; +import android.net.ConnectivityManager; import android.os.Looper; import androidx.annotation.NonNull; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -98,6 +99,7 @@ public class OpenTelemetryRumBuilderTest { @Mock android.content.Context applicationContext; @Mock InitializationEvents initializationEvents; + @Mock ConnectivityManager connectivityManager; private AutoCloseable mocks; @Before @@ -105,6 +107,8 @@ public void setup() { mocks = MockitoAnnotations.openMocks(this); when(application.getApplicationContext()).thenReturn(applicationContext); when(application.getMainLooper()).thenReturn(looper); + when(application.getSystemService(android.content.Context.CONNECTIVITY_SERVICE)) + .thenReturn(connectivityManager); InitializationEvents.set(initializationEvents); } diff --git a/services/src/main/java/io/opentelemetry/android/internal/services/network/detector/NetworkDetector.java b/services/src/main/java/io/opentelemetry/android/internal/services/network/detector/NetworkDetector.java deleted file mode 100644 index 5a2c730bd..000000000 --- a/services/src/main/java/io/opentelemetry/android/internal/services/network/detector/NetworkDetector.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.android.internal.services.network.detector; - -import android.content.Context; -import android.net.ConnectivityManager; -import android.os.Build; -import android.telephony.TelephonyManager; -import io.opentelemetry.android.common.internal.features.networkattributes.data.CurrentNetwork; -import io.opentelemetry.android.internal.services.network.CarrierFinder; - -/** - * This class is internal and not for public use. Its APIs are unstable and can change at any time. - */ -public interface NetworkDetector { - CurrentNetwork detectCurrentNetwork(); - - static NetworkDetector create(Context context) { - ConnectivityManager connectivityManager = - (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - TelephonyManager telephonyManager = - (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - CarrierFinder carrierFinder = new CarrierFinder(telephonyManager); - return new PostApi28NetworkDetector( - connectivityManager, telephonyManager, carrierFinder, context); - } - return new SimpleNetworkDetector(connectivityManager); - } -} diff --git a/services/src/main/java/io/opentelemetry/android/internal/services/network/detector/NetworkDetector.kt b/services/src/main/java/io/opentelemetry/android/internal/services/network/detector/NetworkDetector.kt new file mode 100644 index 000000000..76bab84ec --- /dev/null +++ b/services/src/main/java/io/opentelemetry/android/internal/services/network/detector/NetworkDetector.kt @@ -0,0 +1,42 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.android.internal.services.network.detector + +import android.content.Context +import android.net.ConnectivityManager +import android.os.Build +import android.telephony.TelephonyManager +import io.opentelemetry.android.common.internal.features.networkattributes.data.CurrentNetwork +import io.opentelemetry.android.internal.services.network.CarrierFinder + +/** + * This class is internal and not for public use. Its APIs are unstable and can change at any time. + */ +interface NetworkDetector { + fun detectCurrentNetwork(): CurrentNetwork + + companion object { + @JvmStatic + fun create(context: Context): NetworkDetector { + // TODO: Use ServiceManager to get the ConnectivityManager or similar (not yet managed/abstracted) + val connectivityManager = + context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + // TODO: Use ServiceManager to get the TelephonyManager or similar (not yet managed/abstracted) + val telephonyManager = + context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager + val carrierFinder = CarrierFinder(telephonyManager) + return PostApi28NetworkDetector( + connectivityManager, + telephonyManager, + carrierFinder, + context, + ) + } + return SimpleNetworkDetector(connectivityManager) + } + } +} diff --git a/services/src/main/java/io/opentelemetry/android/internal/services/network/detector/PostApi28NetworkDetector.java b/services/src/main/java/io/opentelemetry/android/internal/services/network/detector/PostApi28NetworkDetector.java deleted file mode 100644 index da622fcbc..000000000 --- a/services/src/main/java/io/opentelemetry/android/internal/services/network/detector/PostApi28NetworkDetector.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.android.internal.services.network.detector; - -import static io.opentelemetry.android.internal.services.network.CurrentNetworkProvider.NO_NETWORK; -import static io.opentelemetry.android.internal.services.network.CurrentNetworkProvider.UNKNOWN_NETWORK; - -import android.Manifest; -import android.annotation.SuppressLint; -import android.content.Context; -import android.content.pm.PackageManager; -import android.net.ConnectivityManager; -import android.net.NetworkCapabilities; -import android.os.Build; -import android.telephony.TelephonyManager; -import androidx.annotation.RequiresApi; -import androidx.core.app.ActivityCompat; -import io.opentelemetry.android.common.internal.features.networkattributes.data.Carrier; -import io.opentelemetry.android.common.internal.features.networkattributes.data.CurrentNetwork; -import io.opentelemetry.android.common.internal.features.networkattributes.data.NetworkState; -import io.opentelemetry.android.internal.services.network.CarrierFinder; - -/** - * This class is internal and not for public use. Its APIs are unstable and can change at any time. - */ -@RequiresApi(api = Build.VERSION_CODES.P) -class PostApi28NetworkDetector implements NetworkDetector { - private final ConnectivityManager connectivityManager; - private final TelephonyManager telephonyManager; - private final CarrierFinder carrierFinder; - private final Context context; - - PostApi28NetworkDetector( - ConnectivityManager connectivityManager, - TelephonyManager telephonyManager, - CarrierFinder carrierFinder, - Context context) { - this.connectivityManager = connectivityManager; - this.telephonyManager = telephonyManager; - this.carrierFinder = carrierFinder; - this.context = context; - } - - @SuppressLint("MissingPermission") - @Override - public CurrentNetwork detectCurrentNetwork() { - NetworkCapabilities capabilities = - connectivityManager.getNetworkCapabilities(connectivityManager.getActiveNetwork()); - if (capabilities == null) { - return NO_NETWORK; - } - String subType = null; - Carrier carrier = carrierFinder.get(); - if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { - // If the app has the permission, use it to get a subtype. - if (canReadPhoneState()) { - subType = getDataNetworkTypeName(telephonyManager.getDataNetworkType()); - } - return CurrentNetwork.builder(NetworkState.TRANSPORT_CELLULAR) - .carrier(carrier) - .subType(subType) - .build(); - } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { - return CurrentNetwork.builder(NetworkState.TRANSPORT_WIFI).carrier(carrier).build(); - } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) { - return CurrentNetwork.builder(NetworkState.TRANSPORT_VPN).carrier(carrier).build(); - } - // there is an active network, but it doesn't fall into the neat buckets above - return UNKNOWN_NETWORK; - } - - // visible for testing - boolean canReadPhoneState() { - return ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) - == PackageManager.PERMISSION_GRANTED; - } - - private String getDataNetworkTypeName(int dataNetworkType) { - switch (dataNetworkType) { - case TelephonyManager.NETWORK_TYPE_1xRTT: - return "1xRTT"; - case TelephonyManager.NETWORK_TYPE_CDMA: - return "CDMA"; - case TelephonyManager.NETWORK_TYPE_EDGE: - return "EDGE"; - case TelephonyManager.NETWORK_TYPE_EHRPD: - return "EHRPD"; - case TelephonyManager.NETWORK_TYPE_EVDO_0: - return "EVDO_0"; - case TelephonyManager.NETWORK_TYPE_EVDO_A: - return "EVDO_A"; - case TelephonyManager.NETWORK_TYPE_EVDO_B: - return "EVDO_B"; - case TelephonyManager.NETWORK_TYPE_GPRS: - return "GPRS"; - case TelephonyManager.NETWORK_TYPE_GSM: - return "GSM"; - case TelephonyManager.NETWORK_TYPE_HSDPA: - return "HSDPA"; - case TelephonyManager.NETWORK_TYPE_HSPA: - return "HSPA"; - case TelephonyManager.NETWORK_TYPE_HSPAP: - return "HSPAP"; - case TelephonyManager.NETWORK_TYPE_HSUPA: - return "HSUPA"; - case TelephonyManager.NETWORK_TYPE_IDEN: - return "IDEN"; - case TelephonyManager.NETWORK_TYPE_IWLAN: - return "IWLAN"; - case TelephonyManager.NETWORK_TYPE_LTE: - return "LTE"; - case TelephonyManager.NETWORK_TYPE_NR: - return "NR"; - case TelephonyManager.NETWORK_TYPE_TD_SCDMA: - return "SCDMA"; - case TelephonyManager.NETWORK_TYPE_UMTS: - return "UMTS"; - case TelephonyManager.NETWORK_TYPE_UNKNOWN: - return "UNKNOWN"; - } - return "UNKNOWN"; - } -} diff --git a/services/src/main/java/io/opentelemetry/android/internal/services/network/detector/PostApi28NetworkDetector.kt b/services/src/main/java/io/opentelemetry/android/internal/services/network/detector/PostApi28NetworkDetector.kt new file mode 100644 index 000000000..6f4e02459 --- /dev/null +++ b/services/src/main/java/io/opentelemetry/android/internal/services/network/detector/PostApi28NetworkDetector.kt @@ -0,0 +1,125 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.android.internal.services.network.detector + +import android.Manifest +import android.annotation.SuppressLint +import android.content.Context +import android.content.pm.PackageManager +import android.net.ConnectivityManager +import android.net.NetworkCapabilities +import android.os.Build +import android.telephony.TelephonyManager +import android.telephony.TelephonyManager.NETWORK_TYPE_1xRTT +import android.telephony.TelephonyManager.NETWORK_TYPE_CDMA +import android.telephony.TelephonyManager.NETWORK_TYPE_EDGE +import android.telephony.TelephonyManager.NETWORK_TYPE_EHRPD +import android.telephony.TelephonyManager.NETWORK_TYPE_EVDO_0 +import android.telephony.TelephonyManager.NETWORK_TYPE_EVDO_A +import android.telephony.TelephonyManager.NETWORK_TYPE_EVDO_B +import android.telephony.TelephonyManager.NETWORK_TYPE_GPRS +import android.telephony.TelephonyManager.NETWORK_TYPE_GSM +import android.telephony.TelephonyManager.NETWORK_TYPE_HSDPA +import android.telephony.TelephonyManager.NETWORK_TYPE_HSPA +import android.telephony.TelephonyManager.NETWORK_TYPE_HSPAP +import android.telephony.TelephonyManager.NETWORK_TYPE_HSUPA +import android.telephony.TelephonyManager.NETWORK_TYPE_IDEN +import android.telephony.TelephonyManager.NETWORK_TYPE_IWLAN +import android.telephony.TelephonyManager.NETWORK_TYPE_LTE +import android.telephony.TelephonyManager.NETWORK_TYPE_NR +import android.telephony.TelephonyManager.NETWORK_TYPE_TD_SCDMA +import android.telephony.TelephonyManager.NETWORK_TYPE_UMTS +import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN +import androidx.annotation.RequiresApi +import androidx.core.app.ActivityCompat +import io.opentelemetry.android.common.internal.features.networkattributes.data.Carrier +import io.opentelemetry.android.common.internal.features.networkattributes.data.CurrentNetwork +import io.opentelemetry.android.common.internal.features.networkattributes.data.NetworkState +import io.opentelemetry.android.common.internal.features.networkattributes.data.NetworkState.TRANSPORT_CELLULAR +import io.opentelemetry.android.common.internal.features.networkattributes.data.NetworkState.TRANSPORT_VPN +import io.opentelemetry.android.common.internal.features.networkattributes.data.NetworkState.TRANSPORT_WIFI +import io.opentelemetry.android.internal.services.network.CarrierFinder +import io.opentelemetry.android.internal.services.network.CurrentNetworkProvider +import io.opentelemetry.android.internal.services.network.CurrentNetworkProvider.UNKNOWN_NETWORK + +/** + * This class is internal and not for public use. Its APIs are unstable and can change at any time. + */ +@RequiresApi(api = Build.VERSION_CODES.P) +internal class PostApi28NetworkDetector + @JvmOverloads + constructor( + private val connectivityManager: ConnectivityManager, + private val telephonyManager: TelephonyManager, + private val carrierFinder: CarrierFinder, + private val context: Context, + private val readPhoneState: () -> Boolean = { canReadPhoneState(context) }, + ) : NetworkDetector { + @SuppressLint("MissingPermission") + override fun detectCurrentNetwork(): CurrentNetwork { + val capabilities = + connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork) + ?: return CurrentNetworkProvider.NO_NETWORK + val carrier = carrierFinder.get() + + fun hasTransport(transportId: Int): Boolean = capabilities.hasTransport(transportId) + + val network = buildFromCarrier(carrier) + return when { + hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> withCellDataType(carrier) + hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> network(TRANSPORT_WIFI) + hasTransport(NetworkCapabilities.TRANSPORT_VPN) -> network(TRANSPORT_VPN) + else -> UNKNOWN_NETWORK + } + } + + private fun buildFromCarrier(carrier: Carrier): (NetworkState) -> CurrentNetwork = + { CurrentNetwork.builder(it).carrier(carrier).build() } + + private fun withCellDataType(carrier: Carrier): CurrentNetwork { + val builder = + CurrentNetwork + .builder(TRANSPORT_CELLULAR) + .carrier(carrier) + if (readPhoneState()) { + val dataNetworkType = getDataNetworkTypeName(telephonyManager.dataNetworkType) + return builder.subType(dataNetworkType).build() + } + return builder.build() + } + + private fun getDataNetworkTypeName(dataNetworkType: Int): String = + when (dataNetworkType) { + NETWORK_TYPE_1xRTT -> "1xRTT" + NETWORK_TYPE_CDMA -> "CDMA" + NETWORK_TYPE_EDGE -> "EDGE" + NETWORK_TYPE_EHRPD -> "EHRPD" + NETWORK_TYPE_EVDO_0 -> "EVDO_0" + NETWORK_TYPE_EVDO_A -> "EVDO_A" + NETWORK_TYPE_EVDO_B -> "EVDO_B" + NETWORK_TYPE_GPRS -> "GPRS" + NETWORK_TYPE_GSM -> "GSM" + NETWORK_TYPE_HSDPA -> "HSDPA" + NETWORK_TYPE_HSPA -> "HSPA" + NETWORK_TYPE_HSPAP -> "HSPAP" + NETWORK_TYPE_HSUPA -> "HSUPA" + NETWORK_TYPE_IDEN -> "IDEN" + NETWORK_TYPE_IWLAN -> "IWLAN" + NETWORK_TYPE_LTE -> "LTE" + NETWORK_TYPE_NR -> "NR" + NETWORK_TYPE_TD_SCDMA -> "SCDMA" + NETWORK_TYPE_UMTS -> "UMTS" + NETWORK_TYPE_UNKNOWN -> "UNKNOWN" + else -> "UNKNOWN" + } + } + +// visible for testing +fun canReadPhoneState(context: Context): Boolean = + ( + ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) + == PackageManager.PERMISSION_GRANTED + ) diff --git a/services/src/main/java/io/opentelemetry/android/internal/services/network/detector/SimpleNetworkDetector.java b/services/src/main/java/io/opentelemetry/android/internal/services/network/detector/SimpleNetworkDetector.java deleted file mode 100644 index fc0c8767e..000000000 --- a/services/src/main/java/io/opentelemetry/android/internal/services/network/detector/SimpleNetworkDetector.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.android.internal.services.network.detector; - -import static io.opentelemetry.android.internal.services.network.CurrentNetworkProvider.NO_NETWORK; -import static io.opentelemetry.android.internal.services.network.CurrentNetworkProvider.UNKNOWN_NETWORK; - -import android.net.ConnectivityManager; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.net.NetworkInfo; -import androidx.annotation.RequiresApi; -import io.opentelemetry.android.common.internal.features.networkattributes.data.CurrentNetwork; -import io.opentelemetry.android.common.internal.features.networkattributes.data.NetworkState; - -/** - * This class is internal and not for public use. Its APIs are unstable and can change at any time. - */ -class SimpleNetworkDetector implements NetworkDetector { - private final ConnectivityManager connectivityManager; - - SimpleNetworkDetector(ConnectivityManager connectivityManager) { - this.connectivityManager = connectivityManager; - } - - @Override - public CurrentNetwork detectCurrentNetwork() { - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) { - return detectUsingModernApi(); - } else { - return detectUsingLegacyApi(); - } - } - - @RequiresApi(api = android.os.Build.VERSION_CODES.Q) - private CurrentNetwork detectUsingModernApi() { - Network network = connectivityManager.getActiveNetwork(); - if (network == null) { - return NO_NETWORK; - } - - NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network); - if (capabilities == null) { - return UNKNOWN_NETWORK; - } - - if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { - return buildCurrentNetwork(NetworkState.TRANSPORT_CELLULAR, ""); - } - if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { - return buildCurrentNetwork(NetworkState.TRANSPORT_WIFI, ""); - } - if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) { - return buildCurrentNetwork(NetworkState.TRANSPORT_VPN, ""); - } - if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) { - return buildCurrentNetwork(NetworkState.TRANSPORT_WIRED, ""); - } - - return UNKNOWN_NETWORK; - } - - @SuppressWarnings("deprecation") - private CurrentNetwork detectUsingLegacyApi() { - NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo(); - if (activeNetwork == null) { - return NO_NETWORK; - } - - switch (activeNetwork.getType()) { - case ConnectivityManager.TYPE_MOBILE: - return buildCurrentNetwork( - NetworkState.TRANSPORT_CELLULAR, activeNetwork.getSubtypeName()); - case ConnectivityManager.TYPE_WIFI: - return buildCurrentNetwork( - NetworkState.TRANSPORT_WIFI, activeNetwork.getSubtypeName()); - case ConnectivityManager.TYPE_VPN: - return buildCurrentNetwork( - NetworkState.TRANSPORT_VPN, activeNetwork.getSubtypeName()); - case ConnectivityManager.TYPE_ETHERNET: - return buildCurrentNetwork( - NetworkState.TRANSPORT_WIRED, activeNetwork.getSubtypeName()); - default: - return UNKNOWN_NETWORK; - } - } - - private CurrentNetwork buildCurrentNetwork(NetworkState state, String subType) { - return CurrentNetwork.builder(state).subType(subType).build(); - } -} diff --git a/services/src/main/java/io/opentelemetry/android/internal/services/network/detector/SimpleNetworkDetector.kt b/services/src/main/java/io/opentelemetry/android/internal/services/network/detector/SimpleNetworkDetector.kt new file mode 100644 index 000000000..e816f62b1 --- /dev/null +++ b/services/src/main/java/io/opentelemetry/android/internal/services/network/detector/SimpleNetworkDetector.kt @@ -0,0 +1,76 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.android.internal.services.network.detector + +import android.net.ConnectivityManager +import android.net.ConnectivityManager.TYPE_ETHERNET +import android.net.ConnectivityManager.TYPE_MOBILE +import android.net.ConnectivityManager.TYPE_VPN +import android.net.ConnectivityManager.TYPE_WIFI +import android.net.NetworkCapabilities +import android.os.Build +import androidx.annotation.RequiresApi +import io.opentelemetry.android.common.internal.features.networkattributes.data.CurrentNetwork +import io.opentelemetry.android.common.internal.features.networkattributes.data.NetworkState +import io.opentelemetry.android.common.internal.features.networkattributes.data.NetworkState.TRANSPORT_CELLULAR +import io.opentelemetry.android.common.internal.features.networkattributes.data.NetworkState.TRANSPORT_VPN +import io.opentelemetry.android.common.internal.features.networkattributes.data.NetworkState.TRANSPORT_WIFI +import io.opentelemetry.android.common.internal.features.networkattributes.data.NetworkState.TRANSPORT_WIRED +import io.opentelemetry.android.internal.services.network.CurrentNetworkProvider +import io.opentelemetry.android.internal.services.network.CurrentNetworkProvider.UNKNOWN_NETWORK + +/** + * This class is internal and not for public use. Its APIs are unstable and can change at any time. + */ +internal class SimpleNetworkDetector( + private val connectivityManager: ConnectivityManager, +) : NetworkDetector { + override fun detectCurrentNetwork(): CurrentNetwork = + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + detectUsingModernApi() + } else { + detectUsingLegacyApi() + } + + @RequiresApi(api = Build.VERSION_CODES.Q) + private fun detectUsingModernApi(): CurrentNetwork { + val network = connectivityManager.activeNetwork ?: return CurrentNetworkProvider.NO_NETWORK + + val capabilities = + connectivityManager.getNetworkCapabilities(network) + ?: return UNKNOWN_NETWORK + + fun hasTransport(capability: Int): Boolean = capabilities.hasCapability(capability) + return when { + hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> network(TRANSPORT_CELLULAR) + hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> network(TRANSPORT_WIFI) + hasTransport(NetworkCapabilities.TRANSPORT_VPN) -> network(TRANSPORT_VPN) + hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> network(TRANSPORT_WIRED) + else -> UNKNOWN_NETWORK + } + } + + @Suppress("deprecation") + private fun detectUsingLegacyApi(): CurrentNetwork { + val activeNetwork = + connectivityManager.activeNetworkInfo + ?: return CurrentNetworkProvider.NO_NETWORK + + val network = buildFromSubType(activeNetwork.subtypeName) + return when (activeNetwork.type) { + TYPE_MOBILE -> network(TRANSPORT_CELLULAR) + TYPE_WIFI -> network(TRANSPORT_WIFI) + TYPE_VPN -> network(TRANSPORT_VPN) + TYPE_ETHERNET -> network(TRANSPORT_WIRED) + else -> UNKNOWN_NETWORK + } + } + + private fun buildFromSubType(subType: String?): (NetworkState) -> CurrentNetwork = + { CurrentNetwork.builder(it).subType(subType).build() } + + private fun network(state: NetworkState): CurrentNetwork = CurrentNetwork.builder(state).build() +} diff --git a/services/src/test/java/io/opentelemetry/android/internal/services/network/detector/PostApi28NetworkDetectorTest.java b/services/src/test/java/io/opentelemetry/android/internal/services/network/detector/PostApi28NetworkDetectorTest.java index 81f6645a8..4d3e1160e 100644 --- a/services/src/test/java/io/opentelemetry/android/internal/services/network/detector/PostApi28NetworkDetectorTest.java +++ b/services/src/test/java/io/opentelemetry/android/internal/services/network/detector/PostApi28NetworkDetectorTest.java @@ -5,7 +5,9 @@ package io.opentelemetry.android.internal.services.network.detector; +import static io.opentelemetry.android.common.internal.features.networkattributes.data.NetworkState.NO_NETWORK_AVAILABLE; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -19,7 +21,7 @@ import io.opentelemetry.android.common.internal.features.networkattributes.data.CurrentNetwork; import io.opentelemetry.android.common.internal.features.networkattributes.data.NetworkState; import io.opentelemetry.android.internal.services.network.CarrierFinder; -import org.junit.Assert; +import kotlin.jvm.functions.Function0; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -36,10 +38,12 @@ public class PostApi28NetworkDetectorTest { Context context; Network network; NetworkCapabilities networkCapabilities; + Carrier carrier = new Carrier(0, "flib"); CarrierFinder carrierFinder; @Before public void setup() { + connectivityManager = mock(ConnectivityManager.class); telephonyManager = mock(TelephonyManager.class); context = mock(Context.class); @@ -49,6 +53,7 @@ public void setup() { when(connectivityManager.getActiveNetwork()).thenReturn(network); when(connectivityManager.getNetworkCapabilities(network)).thenReturn(networkCapabilities); + when(carrierFinder.get()).thenReturn(carrier); } @Test @@ -59,8 +64,7 @@ public void none() { new PostApi28NetworkDetector( connectivityManager, telephonyManager, carrierFinder, context); CurrentNetwork currentNetwork = networkDetector.detectCurrentNetwork(); - Assert.assertEquals( - CurrentNetwork.builder(NetworkState.NO_NETWORK_AVAILABLE).build(), currentNetwork); + assertEquals(CurrentNetwork.builder(NO_NETWORK_AVAILABLE).build(), currentNetwork); } @Test @@ -71,8 +75,9 @@ public void wifi() { new PostApi28NetworkDetector( connectivityManager, telephonyManager, carrierFinder, context); CurrentNetwork currentNetwork = networkDetector.detectCurrentNetwork(); - Assert.assertEquals( - CurrentNetwork.builder(NetworkState.TRANSPORT_WIFI).build(), currentNetwork); + assertEquals( + CurrentNetwork.builder(NetworkState.TRANSPORT_WIFI).carrier(carrier).build(), + currentNetwork); } @Test @@ -81,12 +86,21 @@ public void cellular() { when(networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) .thenReturn(true); + Function0 readPhoneState = () -> true; + PostApi28NetworkDetector networkDetector = new PostApi28NetworkDetector( - connectivityManager, telephonyManager, carrierFinder, context); + connectivityManager, + telephonyManager, + carrierFinder, + context, + readPhoneState); CurrentNetwork currentNetwork = networkDetector.detectCurrentNetwork(); - Assert.assertEquals( - CurrentNetwork.builder(NetworkState.TRANSPORT_CELLULAR).subType("LTE").build(), + assertEquals( + CurrentNetwork.builder(NetworkState.TRANSPORT_CELLULAR) + .carrier(carrier) + .subType("LTE") + .build(), currentNetwork); } @@ -96,17 +110,18 @@ public void cellular_noTelephonyPermissions() { when(networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) .thenReturn(true); + Function0 readPhoneState = () -> false; PostApi28NetworkDetector networkDetector = new PostApi28NetworkDetector( - connectivityManager, telephonyManager, carrierFinder, context) { - @Override - boolean canReadPhoneState() { - return false; - } - }; + connectivityManager, + telephonyManager, + carrierFinder, + context, + readPhoneState); CurrentNetwork currentNetwork = networkDetector.detectCurrentNetwork(); - Assert.assertEquals( - CurrentNetwork.builder(NetworkState.TRANSPORT_CELLULAR).build(), currentNetwork); + assertEquals( + CurrentNetwork.builder(NetworkState.TRANSPORT_CELLULAR).carrier(carrier).build(), + currentNetwork); } @Test @@ -115,7 +130,7 @@ public void other() { new PostApi28NetworkDetector( connectivityManager, telephonyManager, carrierFinder, context); CurrentNetwork currentNetwork = networkDetector.detectCurrentNetwork(); - Assert.assertEquals( + assertEquals( CurrentNetwork.builder(NetworkState.TRANSPORT_UNKNOWN).build(), currentNetwork); } @@ -127,13 +142,13 @@ public void vpn() { new PostApi28NetworkDetector( connectivityManager, telephonyManager, carrierFinder, context); CurrentNetwork currentNetwork = networkDetector.detectCurrentNetwork(); - Assert.assertEquals( - CurrentNetwork.builder(NetworkState.TRANSPORT_VPN).build(), currentNetwork); + assertEquals( + CurrentNetwork.builder(NetworkState.TRANSPORT_VPN).carrier(carrier).build(), + currentNetwork); } @Test public void carrierIsSet() { - Carrier carrier = new Carrier(0, "flib"); when(networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) .thenReturn(true); when(carrierFinder.get()).thenReturn(carrier);