Skip to content

Commit

Permalink
Refactor network detectors to kotlin (#752)
Browse files Browse the repository at this point in the history
* Rename .java to .kt

* assisted kotlin conversion

* empty to null

* default param

* refactor to simplify

* Rename .java to .kt

* assisted convert to kotlin

* refactor to simplify

* cleanup and format

* Rename .java to .kt

* convert to kotlin
  • Loading branch information
breedx-splk authored Jan 22, 2025
1 parent fcc50a0 commit b554ad3
Show file tree
Hide file tree
Showing 9 changed files with 285 additions and 273 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -98,13 +99,16 @@ public class OpenTelemetryRumBuilderTest {
@Mock android.content.Context applicationContext;

@Mock InitializationEvents initializationEvents;
@Mock ConnectivityManager connectivityManager;
private AutoCloseable mocks;

@Before
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);
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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)
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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
)
Loading

0 comments on commit b554ad3

Please sign in to comment.