Skip to content

Commit 36739a6

Browse files
committed
Escalate deprecation of Bluetooth.availability
1 parent 310e4d3 commit 36739a6

File tree

4 files changed

+23
-126
lines changed

4 files changed

+23
-126
lines changed
Lines changed: 6 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,35 @@
11
package com.juul.kable
22

3-
import android.bluetooth.BluetoothAdapter.ERROR
4-
import android.bluetooth.BluetoothAdapter.EXTRA_STATE
5-
import android.bluetooth.BluetoothAdapter.STATE_OFF
6-
import android.bluetooth.BluetoothAdapter.STATE_ON
7-
import android.bluetooth.BluetoothAdapter.STATE_TURNING_OFF
8-
import android.bluetooth.BluetoothAdapter.STATE_TURNING_ON
93
import android.bluetooth.BluetoothManager
10-
import android.content.Context
11-
import android.content.IntentFilter
12-
import android.location.LocationManager
13-
import android.location.LocationManager.EXTRA_PROVIDER_ENABLED
14-
import android.location.LocationManager.PROVIDERS_CHANGED_ACTION
15-
import android.os.Build.VERSION.SDK_INT
16-
import android.os.Build.VERSION_CODES.R
17-
import androidx.core.content.ContextCompat
18-
import androidx.core.location.LocationManagerCompat
19-
import com.juul.kable.Bluetooth.Availability.Available
20-
import com.juul.kable.Bluetooth.Availability.Unavailable
21-
import com.juul.kable.Reason.AdapterNotAvailable
22-
import com.juul.kable.Reason.LocationServicesDisabled
23-
import com.juul.kable.Reason.Off
24-
import com.juul.kable.Reason.TurningOff
25-
import com.juul.kable.Reason.TurningOn
26-
import com.juul.tuulbox.coroutines.flow.broadcastReceiverFlow
27-
import kotlinx.coroutines.flow.Flow
28-
import kotlinx.coroutines.flow.combine
29-
import kotlinx.coroutines.flow.distinctUntilChanged
30-
import kotlinx.coroutines.flow.emitAll
31-
import kotlinx.coroutines.flow.flow
32-
import kotlinx.coroutines.flow.flowOf
33-
import kotlinx.coroutines.flow.map
34-
import kotlinx.coroutines.flow.onStart
35-
import android.bluetooth.BluetoothAdapter.ACTION_STATE_CHANGED as BLUETOOTH_STATE_CHANGED
364

375
@Deprecated(
386
message = "`Bluetooth.availability` has inconsistent behavior across platforms. " +
397
"Will be removed in a future release. " +
408
"See https://github.com/JuulLabs/kable/issues/737 for more details.",
9+
level = DeprecationLevel.ERROR,
4110
)
4211
public actual enum class Reason {
4312
@Deprecated(
4413
message = "`Bluetooth.availability` has inconsistent behavior across platforms. " +
4514
"Will be removed in a future release. " +
4615
"See https://github.com/JuulLabs/kable/issues/737 for more details.",
16+
level = DeprecationLevel.ERROR,
4717
)
4818
Off, // BluetoothAdapter.STATE_OFF
4919

5020
@Deprecated(
5121
message = "`Bluetooth.availability` has inconsistent behavior across platforms. " +
5222
"Will be removed in a future release. " +
5323
"See https://github.com/JuulLabs/kable/issues/737 for more details.",
24+
level = DeprecationLevel.ERROR,
5425
)
5526
TurningOff, // BluetoothAdapter.STATE_TURNING_OFF or BluetoothAdapter.STATE_BLE_TURNING_OFF
5627

5728
@Deprecated(
5829
message = "`Bluetooth.availability` has inconsistent behavior across platforms. " +
5930
"Will be removed in a future release. " +
6031
"See https://github.com/JuulLabs/kable/issues/737 for more details.",
32+
level = DeprecationLevel.ERROR,
6133
)
6234
TurningOn, // BluetoothAdapter.STATE_TURNING_ON or BluetoothAdapter.STATE_BLE_TURNING_ON
6335

@@ -69,6 +41,7 @@ public actual enum class Reason {
6941
message = "`Bluetooth.availability` has inconsistent behavior across platforms. " +
7042
"Will be removed in a future release. " +
7143
"See https://github.com/JuulLabs/kable/issues/737 for more details.",
44+
level = DeprecationLevel.ERROR,
7245
)
7346
AdapterNotAvailable,
7447

@@ -77,60 +50,7 @@ public actual enum class Reason {
7750
message = "`Bluetooth.availability` has inconsistent behavior across platforms. " +
7851
"Will be removed in a future release. " +
7952
"See https://github.com/JuulLabs/kable/issues/737 for more details.",
53+
level = DeprecationLevel.ERROR,
8054
)
8155
LocationServicesDisabled,
8256
}
83-
84-
private fun Context.getLocationManagerOrNull() =
85-
ContextCompat.getSystemService(this, LocationManager::class.java)
86-
87-
private fun Context.isLocationEnabledOrNull(): Boolean? =
88-
getLocationManagerOrNull()?.let(LocationManagerCompat::isLocationEnabled)
89-
90-
private val locationEnabledOrNullFlow = when {
91-
SDK_INT > R -> flowOf(true)
92-
else -> broadcastReceiverFlow(IntentFilter(PROVIDERS_CHANGED_ACTION))
93-
.map { intent ->
94-
if (SDK_INT == R) {
95-
intent.getBooleanExtra(EXTRA_PROVIDER_ENABLED, false)
96-
} else {
97-
applicationContext.isLocationEnabledOrNull()
98-
}
99-
}
100-
.onStart { emit(applicationContext.isLocationEnabledOrNull()) }
101-
.distinctUntilChanged()
102-
}
103-
104-
private val bluetoothStateFlow = flow {
105-
when (val adapter = getBluetoothAdapterOrNull()) {
106-
null -> emit(Unavailable(reason = AdapterNotAvailable))
107-
else -> emitAll(
108-
broadcastReceiverFlow(IntentFilter(BLUETOOTH_STATE_CHANGED))
109-
.map { intent -> intent.getIntExtra(EXTRA_STATE, ERROR) }
110-
.onStart {
111-
emit(if (adapter.isEnabled) STATE_ON else STATE_OFF)
112-
}
113-
.map { state ->
114-
when (state) {
115-
STATE_ON -> Available
116-
STATE_OFF -> Unavailable(reason = Off)
117-
STATE_TURNING_OFF -> Unavailable(reason = TurningOff)
118-
STATE_TURNING_ON -> Unavailable(reason = TurningOn)
119-
else -> error("Unexpected bluetooth state: $state")
120-
}
121-
},
122-
)
123-
}
124-
}
125-
126-
internal actual val bluetoothAvailability: Flow<Bluetooth.Availability> =
127-
combine(
128-
locationEnabledOrNullFlow,
129-
bluetoothStateFlow,
130-
) { locationEnabled, bluetoothState ->
131-
when (locationEnabled) {
132-
true -> bluetoothState
133-
false -> Unavailable(reason = LocationServicesDisabled)
134-
null -> Unavailable(reason = AdapterNotAvailable)
135-
}
136-
}
Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,50 @@
11
package com.juul.kable
22

3-
import com.juul.kable.Bluetooth.Availability.Available
4-
import com.juul.kable.Bluetooth.Availability.Unavailable
5-
import com.juul.kable.Reason.Off
6-
import com.juul.kable.Reason.Resetting
7-
import com.juul.kable.Reason.Unauthorized
8-
import com.juul.kable.Reason.Unknown
9-
import com.juul.kable.Reason.Unsupported
10-
import kotlinx.coroutines.flow.Flow
11-
import kotlinx.coroutines.flow.emitAll
12-
import kotlinx.coroutines.flow.flow
13-
import kotlinx.coroutines.flow.map
14-
import platform.CoreBluetooth.CBCentralManagerStatePoweredOff
15-
import platform.CoreBluetooth.CBCentralManagerStatePoweredOn
16-
import platform.CoreBluetooth.CBCentralManagerStateResetting
17-
import platform.CoreBluetooth.CBCentralManagerStateUnauthorized
18-
import platform.CoreBluetooth.CBCentralManagerStateUnsupported
19-
203
/** https://developer.apple.com/documentation/corebluetooth/cbmanagerstate */
214
@Deprecated(
225
message = "`Bluetooth.availability` has inconsistent behavior across platforms. " +
236
"Will be removed in a future release. " +
247
"See https://github.com/JuulLabs/kable/issues/737 for more details.",
8+
level = DeprecationLevel.ERROR,
259
)
2610
public actual enum class Reason {
2711
@Deprecated(
2812
message = "`Bluetooth.availability` has inconsistent behavior across platforms. " +
2913
"Will be removed in a future release. " +
3014
"See https://github.com/JuulLabs/kable/issues/737 for more details.",
15+
level = DeprecationLevel.ERROR,
3116
)
3217
Off, // CBManagerState.poweredOff
3318

3419
@Deprecated(
3520
message = "`Bluetooth.availability` has inconsistent behavior across platforms. " +
3621
"Will be removed in a future release. " +
3722
"See https://github.com/JuulLabs/kable/issues/737 for more details.",
23+
level = DeprecationLevel.ERROR,
3824
)
3925
Resetting, // CBManagerState.resetting
4026

4127
@Deprecated(
4228
message = "`Bluetooth.availability` has inconsistent behavior across platforms. " +
4329
"Will be removed in a future release. " +
4430
"See https://github.com/JuulLabs/kable/issues/737 for more details.",
31+
level = DeprecationLevel.ERROR,
4532
)
4633
Unauthorized, // CBManagerState.unauthorized
4734

4835
@Deprecated(
4936
message = "`Bluetooth.availability` has inconsistent behavior across platforms. " +
5037
"Will be removed in a future release. " +
5138
"See https://github.com/JuulLabs/kable/issues/737 for more details.",
39+
level = DeprecationLevel.ERROR,
5240
)
5341
Unsupported, // CBManagerState.unsupported
5442

5543
@Deprecated(
5644
message = "`Bluetooth.availability` has inconsistent behavior across platforms. " +
5745
"Will be removed in a future release. " +
5846
"See https://github.com/JuulLabs/kable/issues/737 for more details.",
47+
level = DeprecationLevel.ERROR,
5948
)
6049
Unknown, // CBManagerState.unknown
6150
}
62-
63-
internal actual val bluetoothAvailability: Flow<Bluetooth.Availability> = flow {
64-
// flow + emitAll dance so that lazy `CentralManager.Default` is not initialized until this flow is active.
65-
emitAll(CentralManager.Default.delegate.state)
66-
}.map { state ->
67-
when (state) {
68-
CBCentralManagerStatePoweredOn -> Available
69-
CBCentralManagerStatePoweredOff -> Unavailable(reason = Off)
70-
CBCentralManagerStateResetting -> Unavailable(reason = Resetting)
71-
CBCentralManagerStateUnauthorized -> Unavailable(reason = Unauthorized)
72-
CBCentralManagerStateUnsupported -> Unavailable(reason = Unsupported)
73-
else -> Unavailable(reason = Unknown)
74-
}
75-
}

kable-core/src/commonMain/kotlin/Bluetooth.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,15 @@ public object Bluetooth {
4545
message = "`Bluetooth.availability` has inconsistent behavior across platforms. " +
4646
"Will be removed in a future release. " +
4747
"See https://github.com/JuulLabs/kable/issues/737 for more details.",
48+
level = DeprecationLevel.ERROR,
4849
)
4950
public data object Available : Availability()
5051

5152
@Deprecated(
5253
message = "`Bluetooth.availability` has inconsistent behavior across platforms. " +
5354
"Will be removed in a future release. " +
5455
"See https://github.com/JuulLabs/kable/issues/737 for more details.",
56+
level = DeprecationLevel.ERROR,
5557
)
5658
public data class Unavailable(val reason: Reason?) : Availability()
5759
}
@@ -60,8 +62,10 @@ public object Bluetooth {
6062
message = "`Bluetooth.availability` has inconsistent behavior across platforms. " +
6163
"Will be removed in a future release. " +
6264
"See https://github.com/JuulLabs/kable/issues/737 for more details.",
65+
level = DeprecationLevel.ERROR,
6366
)
64-
public val availability: Flow<Availability> = bluetoothAvailability
67+
public val availability: Flow<Availability>
68+
get() = error("Deprecated")
6569

6670
/**
6771
* Checks if Bluetooth Low Energy is supported on the system. Being supported (a return of
@@ -76,5 +80,3 @@ public object Bluetooth {
7680
@ExperimentalApi // Due to the inability to query Bluetooth support w/o showing a dialog on Apple, this function may be removed.
7781
public suspend fun isSupported(): Boolean = isBluetoothSupported()
7882
}
79-
80-
internal expect val bluetoothAvailability: Flow<Bluetooth.Availability>
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package com.juul.kable
22

3-
import kotlinx.coroutines.flow.Flow
4-
import kotlinx.coroutines.flow.flowOf
5-
3+
@Deprecated(
4+
message = "`Bluetooth.availability` has inconsistent behavior across platforms. " +
5+
"Will be removed in a future release. " +
6+
"See https://github.com/JuulLabs/kable/issues/737 for more details.",
7+
level = DeprecationLevel.ERROR,
8+
)
69
public actual enum class Reason {
710
// Not implemented.
811
}
9-
10-
// This is not a proper implementation, but this property is deprecated, so...
11-
internal actual val bluetoothAvailability: Flow<Bluetooth.Availability> = flowOf(Bluetooth.Availability.Available)

0 commit comments

Comments
 (0)