Skip to content

Commit 5623c46

Browse files
authored
Merge pull request #146 from getditto/rr/health-bluetooth-fix
fix NPE that occurs on emulators without bluetooth, update tools version
2 parents ce2fbb9 + e653ef6 commit 5623c46

File tree

11 files changed

+94
-29
lines changed

11 files changed

+94
-29
lines changed

DittoToolsAndroid/src/main/java/live/ditto/tools/health/HealthScreenActionHandler.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ import android.provider.Settings
77

88
class HealthScreenActionHandler {
99
fun handle(actionType: HealthUiActionType, context: Context) = when (actionType) {
10-
HealthUiActionType.NoAction -> {}
10+
HealthUiActionType.NoAction,
11+
HealthUiActionType.BluetoothUnsupported -> {
12+
}
13+
1114
HealthUiActionType.EnableWifi -> {
1215
context.startActivity(Intent(Settings.ACTION_WIFI_SETTINGS))
1316
}
@@ -23,5 +26,6 @@ class HealthScreenActionHandler {
2326
HealthUiActionType.EnableBluetooth -> {
2427
context.startActivity(Intent(Settings.ACTION_BLUETOOTH_SETTINGS))
2528
}
29+
2630
}
2731
}

DittoToolsAndroid/src/main/java/live/ditto/tools/health/HealthUiActionType.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ sealed class HealthUiActionType {
55
object RequestPermissions : HealthUiActionType()
66
object EnableWifi : HealthUiActionType()
77
object EnableBluetooth : HealthUiActionType()
8+
object BluetoothUnsupported : HealthUiActionType()
89
}

DittoToolsAndroid/src/main/java/live/ditto/tools/health/HealthUiStateCause.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ data class HealthUiStateCause(
1616
HealthUiActionType.EnableWifi -> false
1717
HealthUiActionType.RequestPermissions -> false
1818
HealthUiActionType.EnableBluetooth -> false
19+
HealthUiActionType.BluetoothUnsupported -> false
1920
}
2021
}
2122

@@ -24,5 +25,6 @@ data class HealthUiStateCause(
2425
HealthUiActionType.EnableWifi -> context.getString(R.string.enable_wifi)
2526
HealthUiActionType.RequestPermissions -> context.getString(R.string.request_permissions)
2627
HealthUiActionType.EnableBluetooth -> context.getString(R.string.enable_bluetooth)
28+
HealthUiActionType.BluetoothUnsupported -> ""
2729
}
2830
}

DittoToolsAndroid/src/main/java/live/ditto/tools/health/data/HealthUiState.kt

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ import live.ditto.tools.R
88
import live.ditto.tools.health.usecase.WifiAwareState
99
import live.ditto.tools.health.HealthUiActionType
1010
import live.ditto.tools.health.HealthUiStateCause
11+
import live.ditto.tools.health.usecase.BluetoothState
1112

1213
data class HealthUiState(
1314
val defaultDispatcher: CoroutineDispatcher = Dispatchers.Default,
1415
val missingPermissions: List<String> = emptyList(),
1516
val wifiEnabled: Boolean = true,
16-
val bluetoothEnabled: Boolean = true,
17+
val bluetoothState: BluetoothState = BluetoothState.UNSUPPORTED,
1718
val wifiAwareState: WifiAwareState = WifiAwareState.UNSUPPORTED,
1819
val deviceDetails: DeviceDetails
1920
) {
@@ -81,22 +82,36 @@ data class HealthUiState(
8182
withActions: MutableList<HealthUiStateCause>,
8283
context: Context
8384
) {
84-
if (bluetoothEnabled) {
85-
noActions.add(
86-
HealthUiStateCause(
87-
reason = context.getString(R.string.bluetooth_status),
88-
details = listOf(context.getString(R.string.bluetooth_enabled)),
89-
actionType = HealthUiActionType.NoAction
85+
when (bluetoothState) {
86+
BluetoothState.ENABLED -> {
87+
noActions.add(
88+
HealthUiStateCause(
89+
reason = context.getString(R.string.bluetooth_status),
90+
details = listOf(context.getString(R.string.bluetooth_enabled)),
91+
actionType = HealthUiActionType.NoAction
92+
)
9093
)
91-
)
92-
} else {
93-
withActions.add(
94-
HealthUiStateCause(
95-
reason = context.getString(R.string.bluetooth_status),
96-
details = listOf(context.getString(R.string.bluetooth_not_enabled)),
97-
actionType = HealthUiActionType.EnableBluetooth
94+
}
95+
96+
BluetoothState.DISABLED -> {
97+
withActions.add(
98+
HealthUiStateCause(
99+
reason = context.getString(R.string.bluetooth_status),
100+
details = listOf(context.getString(R.string.bluetooth_not_enabled)),
101+
actionType = HealthUiActionType.EnableBluetooth
102+
)
98103
)
99-
)
104+
}
105+
106+
BluetoothState.UNSUPPORTED -> {
107+
noActions.add(
108+
HealthUiStateCause(
109+
reason = context.getString(R.string.bluetooth_status),
110+
details = listOf(context.getString(R.string.bluetooth_unsupported)),
111+
actionType = HealthUiActionType.BluetoothUnsupported
112+
)
113+
)
114+
}
100115
}
101116
}
102117
}

DittoToolsAndroid/src/main/java/live/ditto/tools/health/ui/composables/HealthScreen.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package live.ditto.tools.health.ui.composables
33
import androidx.compose.foundation.layout.Arrangement
44
import androidx.compose.foundation.layout.Column
55
import androidx.compose.foundation.layout.padding
6+
import androidx.compose.foundation.rememberScrollState
7+
import androidx.compose.foundation.verticalScroll
68
import androidx.compose.runtime.Composable
79
import androidx.compose.ui.Modifier
810
import androidx.compose.ui.unit.dp
@@ -14,7 +16,8 @@ fun HealthScreen(
1416
) {
1517
Column(
1618
modifier = modifier
17-
.padding(8.dp),
19+
.padding(8.dp)
20+
.verticalScroll(state = rememberScrollState()),
1821
verticalArrangement = Arrangement.spacedBy(16.dp)
1922
) {
2023
displayList.forEach { screen ->

DittoToolsAndroid/src/main/java/live/ditto/tools/health/ui/composables/TransportHealthInformation.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ private fun TransportHealthInformation(
6868
healthUiStateCauses.forEach { healthUiStateCause ->
6969
val actionType = healthUiStateCause.actionType
7070

71-
if (actionType == HealthUiActionType.NoAction) {
71+
if (actionType == HealthUiActionType.NoAction || actionType == HealthUiActionType.BluetoothUnsupported) {
7272
HealthCheckWithNoAction(
7373
header = healthUiStateCause.reason,
7474
isHealthy = healthUiStateCause.isHealthy,

DittoToolsAndroid/src/main/java/live/ditto/tools/health/ui/viewmodel/HealthViewModel.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import live.ditto.tools.health.usecase.GetWifiAwareStatusUseCase
1818
import live.ditto.tools.health.usecase.GetWifiStatusFlow
1919
import live.ditto.tools.health.data.DeviceDetails
2020
import live.ditto.tools.health.data.HealthUiState
21+
import live.ditto.tools.health.usecase.BluetoothState
2122
import live.ditto.tools.health.usecase.GetPermissionsMetricsUseCase
2223
import live.ditto.tools.healthmetrics.HealthMetric
2324
import live.ditto.tools.healthmetrics.HealthMetricProvider
@@ -110,9 +111,9 @@ class HealthViewModel(
110111
}
111112
}
112113

113-
private fun onBluetoothStatus(status: Boolean) {
114+
private fun onBluetoothStatus(bluetoothState: BluetoothState) {
114115
_state.update {
115-
it.copy(bluetoothEnabled = status)
116+
it.copy(bluetoothState = bluetoothState)
116117
}
117118
}
118119

DittoToolsAndroid/src/main/java/live/ditto/tools/health/usecase/GetBluetoothStatusFlow.kt

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,44 @@ class GetBluetoothStatusFlow(context: Context) {
1818
private val state = callbackFlow {
1919
val receiver = object : BroadcastReceiver() {
2020
override fun onReceive(context: Context, intent: Intent) {
21-
launch { send(bluetoothManager.adapter.isEnabled) }
21+
launch { send(determineBluetoothState(bluetoothManager = bluetoothManager)) }
2222
}
2323
}
2424

2525
context.registerReceiver(receiver, IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED))
2626

27-
send(bluetoothManager.adapter.isEnabled)
27+
if (bluetoothManager.adapter == null) {
28+
send(BluetoothState.UNSUPPORTED)
29+
} else {
30+
if (bluetoothManager.adapter.isEnabled) {
31+
send(BluetoothState.ENABLED)
32+
} else {
33+
send(BluetoothState.DISABLED)
34+
}
35+
}
2836

2937
awaitClose {
3038
context.unregisterReceiver(receiver)
3139
}
3240
}
3341

3442
operator fun invoke() = state
43+
44+
private fun determineBluetoothState(bluetoothManager: BluetoothManager): BluetoothState {
45+
return if (bluetoothManager.adapter == null) {
46+
BluetoothState.UNSUPPORTED
47+
} else {
48+
if (bluetoothManager.adapter.isEnabled) {
49+
BluetoothState.ENABLED
50+
} else {
51+
BluetoothState.DISABLED
52+
}
53+
}
54+
}
55+
}
56+
57+
enum class BluetoothState {
58+
ENABLED,
59+
DISABLED,
60+
UNSUPPORTED
3561
}

DittoToolsAndroid/src/main/java/live/ditto/tools/health/usecase/GetPermissionsMetricsUseCase.kt

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,19 @@ class GetPermissionsMetricsUseCase {
99
operator fun invoke(healthUiState: HealthUiState): HealthMetric {
1010
val missingPermissions = healthUiState.missingPermissions
1111
val wifiEnabled = healthUiState.wifiEnabled
12-
val bluetoothEnabled = healthUiState.bluetoothEnabled
12+
val bluetoothState = healthUiState.bluetoothState
1313
val wifiAwareState = healthUiState.wifiAwareState
1414

15-
val isHealthy = missingPermissions.isEmpty() && wifiEnabled && bluetoothEnabled
15+
val isHealthy by lazy {
16+
missingPermissions.isEmpty()
17+
&& wifiEnabled
18+
&& bluetoothState == BluetoothState.ENABLED
19+
}
1620

1721
val details = createDetailsMap(
1822
missingPermissions = missingPermissions,
1923
wifiEnabled = wifiEnabled,
20-
bluetoothEnabled = bluetoothEnabled,
24+
bluetoothState = bluetoothState,
2125
wifiAwareState = wifiAwareState
2226
)
2327

@@ -30,15 +34,15 @@ class GetPermissionsMetricsUseCase {
3034
private fun createDetailsMap(
3135
missingPermissions: List<String>,
3236
wifiEnabled: Boolean,
33-
bluetoothEnabled: Boolean,
37+
bluetoothState: BluetoothState,
3438
wifiAwareState: WifiAwareState
3539
): MutableMap<String, String> {
3640
return mutableMapOf<String, String>().apply {
3741
if (missingPermissions.isNotEmpty()) {
3842
this[KEY_MISSING_PERMISSIONS] = missingPermissions.joinToString()
3943
}
4044
this[KEY_WIFI_ENABLED] = wifiEnabled.toString()
41-
this[KEY_BLUETOOTH_ENABLED] = bluetoothEnabled.toString()
45+
this[KEY_BLUETOOTH_STATE] = getBluetoothStateDescription(bluetoothState)
4246
this[KEY_WIFI_AWARE_STATE] = getWifiAwareStateDescription(wifiAwareState)
4347
}
4448
}
@@ -51,10 +55,18 @@ class GetPermissionsMetricsUseCase {
5155
}
5256
}
5357

58+
private fun getBluetoothStateDescription(bluetoothState: BluetoothState): String {
59+
return when (bluetoothState) {
60+
BluetoothState.ENABLED -> "Bluetooth is enabled"
61+
BluetoothState.DISABLED -> "Bluetooth is disabled"
62+
BluetoothState.UNSUPPORTED -> "Bluetooth is not supported by this device"
63+
}
64+
}
65+
5466
companion object {
5567
const val KEY_MISSING_PERMISSIONS = "Missing Permissions"
5668
const val KEY_WIFI_ENABLED = "WiFi Enabled"
57-
const val KEY_BLUETOOTH_ENABLED = "Bluetooth Enabled"
69+
const val KEY_BLUETOOTH_STATE = "Bluetooth State"
5870
const val KEY_WIFI_AWARE_STATE = "Wifi Aware State"
5971
}
6072
}

DittoToolsAndroid/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
<string name="enable_wifi">Enable Wi-fi</string>
3939
<string name="request_permissions">Request Permissions</string>
4040
<string name="bluetooth_status">Bluetooth Status</string>
41+
<string name="bluetooth_unsupported">Bluetooth Unsupported</string>
4142
<string name="bluetooth_enabled">Bluetooth Enabled</string>
4243
<string name="bluetooth_not_enabled">Bluetooth Not Enabled</string>
4344
<string name="enable_bluetooth">Enable Bluetooth</string>

0 commit comments

Comments
 (0)