Skip to content

Commit cad8b26

Browse files
committed
Update LowEnergyScanCallback
1 parent a1fd695 commit cad8b26

2 files changed

Lines changed: 46 additions & 14 deletions

File tree

Sources/AndroidBluetooth/AndroidCentral.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ public final class AndroidCentral: CentralManager {
112112
let scanCallBack = LowEnergyScanCallback(central: self)
113113
do {
114114
try scanner.startScan(scanCallBack)
115+
await storage.update {
116+
$0.scan.callback = scanCallBack
117+
}
115118
}
116119
catch {
117120
continuation.finish(throwing: error)

Sources/AndroidBluetooth/AndroidCentralCallback.swift

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,27 +21,56 @@ extension AndroidCentral {
2121
@JavaClass("org.pureswift.bluetooth.le.ScanCallback")
2222
internal class LowEnergyScanCallback: AndroidBluetooth.ScanCallback {
2323

24-
weak var central: AndroidCentral?
25-
2624
@JavaMethod
27-
@_nonoverride convenience init(environment: JNIEnvironment? = nil)
25+
@_nonoverride convenience init(swiftPeer: Int64, environment: JNIEnvironment? = nil)
2826

2927
convenience init(central: AndroidCentral, environment: JNIEnvironment? = nil) {
30-
self.init(environment: environment)
31-
self.central = central
28+
// Get Swift pointer to AndroidCentral
29+
let swiftPeer = Int64(bitPattern: UInt64(UInt(bitPattern: Unmanaged.passUnretained(central).toOpaque())))
30+
self.init(swiftPeer: swiftPeer, environment: environment)
31+
assert(getSwiftPeer() == swiftPeer)
32+
}
33+
34+
@JavaMethod
35+
func setSwiftPeer(_ swiftPeer: Int64)
36+
37+
@JavaMethod
38+
func getSwiftPeer() -> Int64
39+
40+
@JavaMethod
41+
override func finalize()
42+
43+
44+
}
45+
}
46+
47+
private extension AndroidCentral.LowEnergyScanCallback {
48+
49+
func central(_ swiftPeer: Int64) -> AndroidCentral? {
50+
// Get the Swift peer pointer from Java/Kotlin side
51+
guard swiftPeer != 0 else {
52+
return nil
3253
}
54+
// Convert back to AndroidCentral reference
55+
let pointer = UnsafeRawPointer(bitPattern: Int(truncatingIfNeeded: swiftPeer))
56+
guard let pointer else {
57+
return nil
58+
}
59+
return Unmanaged<AndroidCentral>.fromOpaque(pointer).takeUnretainedValue()
3360
}
3461
}
3562

3663
@JavaImplementation("org.pureswift.bluetooth.le.ScanCallback")
3764
extension AndroidCentral.LowEnergyScanCallback {
3865

3966
@JavaMethod
40-
func onScanResult(error: Int32, result: AndroidBluetooth.ScanResult?) {
41-
guard let central else {
42-
return
43-
}
44-
guard let result, let scanData = try? ScanData(result) else {
67+
func Swift_release(_ swiftPeer: Int64) {
68+
setSwiftPeer(0)
69+
}
70+
71+
@JavaMethod("Swift_onScanResult")
72+
func onScanResult(_ swiftPeer: Int64, error: Int32, result: AndroidBluetooth.ScanResult?) {
73+
guard let central = central(swiftPeer), let result, let scanData = try? ScanData(result) else {
4574
assertionFailure()
4675
return
4776
}
@@ -58,8 +87,8 @@ extension AndroidCentral.LowEnergyScanCallback {
5887
}
5988

6089
@JavaMethod
61-
func onBatchScanResults(results: [AndroidBluetooth.ScanResult?]) {
62-
guard let central else {
90+
func onBatchScanResults(_ swiftPeer: Int64, results: [AndroidBluetooth.ScanResult?]) {
91+
guard let central = central(swiftPeer) else {
6392
return
6493
}
6594
central.log?("\(type(of: self)): \(#function)")
@@ -81,8 +110,8 @@ extension AndroidCentral.LowEnergyScanCallback {
81110
}
82111

83112
@JavaMethod
84-
func onScanFailedSwift(error: Int32) {
85-
113+
func onScanFailedSwift(_ swiftPeer: Int64, error: Int32) {
114+
let central = central(swiftPeer)
86115
central?.log?("\(type(of: self)): \(#function)")
87116

88117
// TODO: Map error codes

0 commit comments

Comments
 (0)