Skip to content

Commit 4f70a4e

Browse files
committed
Convert DiscoverReadersAction and ConnectionManager to use suspend/Flow
1 parent 9ffa362 commit 4f70a4e

File tree

4 files changed

+56
-86
lines changed

4 files changed

+56
-86
lines changed

libs/cardreader/src/main/java/com/woocommerce/android/cardreader/CardReaderManager.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ interface CardReaderManager {
4545

4646
fun setupTapToPayUx(config: TapToPayUxConfig)
4747

48-
fun startConnectionToReader(cardReader: CardReader, locationId: String)
48+
suspend fun startConnectionToReader(cardReader: CardReader, locationId: String)
4949
suspend fun disconnectReader(): Boolean
5050
fun cancelReconnection()
5151

libs/cardreader/src/main/java/com/woocommerce/android/cardreader/internal/CardReaderManagerImpl.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ internal class CardReaderManagerImpl(
9292
connectionManager.setupTapToPayUx(config)
9393
}
9494

95-
override fun startConnectionToReader(cardReader: CardReader, locationId: String) {
95+
override suspend fun startConnectionToReader(cardReader: CardReader, locationId: String) {
9696
if (!terminal.isInitialized()) error("Terminal not initialized")
9797
connectionManager.startConnectionToReader(cardReader, locationId)
9898
}

libs/cardreader/src/main/java/com/woocommerce/android/cardreader/internal/connection/ConnectionManager.kt

Lines changed: 31 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import android.app.Application
55
import android.content.pm.PackageManager
66
import android.os.Build
77
import com.stripe.stripeterminal.external.callable.Callback
8-
import com.stripe.stripeterminal.external.callable.ReaderCallback
98
import com.stripe.stripeterminal.external.models.ConnectionConfiguration.BluetoothConnectionConfiguration
109
import com.stripe.stripeterminal.external.models.ConnectionConfiguration.TapToPayConnectionConfiguration
1110
import com.stripe.stripeterminal.external.models.DeviceType
@@ -32,8 +31,6 @@ import kotlinx.coroutines.delay
3231
import kotlinx.coroutines.flow.map
3332
import kotlinx.coroutines.flow.merge
3433
import kotlinx.coroutines.launch
35-
import kotlin.coroutines.resume
36-
import kotlin.coroutines.suspendCoroutine
3734

3835
private const val ARTIFICIAL_STATUS_UPDATE_DELAY_IN_MILLIS = 500L
3936

@@ -124,43 +121,35 @@ internal class ConnectionManager(
124121
}
125122
}
126123

127-
fun startConnectionToReader(cardReader: CardReader, locationId: String) {
124+
suspend fun startConnectionToReader(cardReader: CardReader, locationId: String) {
128125
(cardReader as CardReaderImpl).let {
129126
updateReaderStatus(CardReaderStatus.Connecting)
130-
val readerCallback = object : ReaderCallback {
131-
override fun onSuccess(reader: Reader) {
132-
updateReaderStatus(CardReaderStatus.Connected(CardReaderImpl(reader)))
127+
try {
128+
val reader = when (it.cardReader.deviceType) {
129+
DeviceType.TAP_TO_PAY_DEVICE -> connectToBuiltInReader(cardReader, locationId)
130+
else -> connectToExternalReader(cardReader, locationId)
133131
}
134-
135-
override fun onFailure(e: TerminalException) {
136-
updateReaderStatus(
137-
CardReaderStatus.NotConnected(
138-
errorCode = e.errorCode.toErrorCode(),
139-
errorMessage = e.errorMessage,
140-
)
132+
updateReaderStatus(CardReaderStatus.Connected(CardReaderImpl(reader)))
133+
} catch (e: TerminalException) {
134+
updateReaderStatus(
135+
CardReaderStatus.NotConnected(
136+
errorCode = e.errorCode.toErrorCode(),
137+
errorMessage = e.errorMessage,
141138
)
142-
}
143-
}
144-
145-
when (it.cardReader.deviceType) {
146-
DeviceType.TAP_TO_PAY_DEVICE -> connectToBuiltInReader(cardReader, locationId, readerCallback)
147-
else -> connectToExternalReader(cardReader, locationId, readerCallback)
139+
)
148140
}
149141
}
150142
}
151143

152-
suspend fun disconnectReader() = suspendCoroutine { continuation ->
153-
terminal.disconnectReader(object : Callback {
154-
override fun onFailure(e: TerminalException) {
155-
updateReaderStatus(CardReaderStatus.NotConnected())
156-
continuation.resume(false)
157-
}
158-
159-
override fun onSuccess() {
160-
updateReaderStatus(CardReaderStatus.NotConnected())
161-
continuation.resume(true)
162-
}
163-
})
144+
suspend fun disconnectReader(): Boolean {
145+
return try {
146+
terminal.disconnectReader()
147+
updateReaderStatus(CardReaderStatus.NotConnected())
148+
true
149+
} catch (e: TerminalException) {
150+
updateReaderStatus(CardReaderStatus.NotConnected())
151+
false
152+
}
164153
}
165154

166155
fun cancelReconnection() {
@@ -213,31 +202,27 @@ internal class ConnectionManager(
213202
terminal.setupTapToPayUx(config)
214203
}
215204

216-
private fun connectToExternalReader(
205+
private suspend fun connectToExternalReader(
217206
cardReader: CardReaderImpl,
218-
locationId: String,
219-
readerCallback: ReaderCallback
220-
) {
221-
terminal.connectToReader(
207+
locationId: String
208+
): Reader {
209+
return terminal.connectToReader(
222210
cardReader.cardReader,
223-
BluetoothConnectionConfiguration(locationId, true, bluetoothReaderListener),
224-
readerCallback
211+
BluetoothConnectionConfiguration(locationId, true, bluetoothReaderListener)
225212
)
226213
}
227214

228-
private fun connectToBuiltInReader(
215+
private suspend fun connectToBuiltInReader(
229216
cardReader: CardReaderImpl,
230-
locationId: String,
231-
readerCallback: ReaderCallback
232-
) {
233-
terminal.connectToMobile(
217+
locationId: String
218+
): Reader {
219+
return terminal.connectToMobile(
234220
cardReader.cardReader,
235221
TapToPayConnectionConfiguration(
236222
locationId,
237223
autoReconnectOnUnexpectedDisconnect = true,
238224
tapToPayReaderListener
239-
),
240-
readerCallback
225+
)
241226
)
242227
}
243228

Lines changed: 23 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
package com.woocommerce.android.cardreader.internal.connection.actions
22

33
import androidx.annotation.RequiresPermission
4-
import com.stripe.stripeterminal.external.callable.Callback
5-
import com.stripe.stripeterminal.external.callable.DiscoveryListener
64
import com.stripe.stripeterminal.external.models.DiscoveryConfiguration
75
import com.stripe.stripeterminal.external.models.Reader
86
import com.stripe.stripeterminal.external.models.TerminalException
97
import com.woocommerce.android.cardreader.LogWrapper
8+
import com.woocommerce.android.cardreader.internal.LOG_TAG
109
import com.woocommerce.android.cardreader.internal.connection.actions.DiscoverReadersAction.DiscoverReadersStatus.Failure
1110
import com.woocommerce.android.cardreader.internal.connection.actions.DiscoverReadersAction.DiscoverReadersStatus.FoundReaders
1211
import com.woocommerce.android.cardreader.internal.connection.actions.DiscoverReadersAction.DiscoverReadersStatus.Started
1312
import com.woocommerce.android.cardreader.internal.connection.actions.DiscoverReadersAction.DiscoverReadersStatus.Success
14-
import com.woocommerce.android.cardreader.internal.sendAndLog
1513
import com.woocommerce.android.cardreader.internal.wrappers.TerminalWrapper
16-
import kotlinx.coroutines.channels.awaitClose
14+
import kotlinx.coroutines.CancellationException
1715
import kotlinx.coroutines.flow.Flow
18-
import kotlinx.coroutines.flow.callbackFlow
16+
import kotlinx.coroutines.flow.catch
17+
import kotlinx.coroutines.flow.distinctUntilChanged
18+
import kotlinx.coroutines.flow.map
19+
import kotlinx.coroutines.flow.onCompletion
20+
import kotlinx.coroutines.flow.onEach
21+
import kotlinx.coroutines.flow.onStart
1922

2023
private const val DISCOVERY_TIMEOUT_IN_SECONDS = 60
2124

@@ -55,40 +58,22 @@ internal class DiscoverReadersAction(
5558
],
5659
)
5760
private fun discoverReaders(config: DiscoveryConfiguration): Flow<DiscoverReadersStatus> {
58-
return callbackFlow {
59-
sendAndLog(Started, logWrapper)
60-
var foundReaders: List<Reader>? = null
61-
val cancelable = terminal.discoverReaders(
62-
config,
63-
object : DiscoveryListener {
64-
override fun onUpdateDiscoveredReaders(readers: List<Reader>) {
65-
if (readers != foundReaders) {
66-
foundReaders = readers
67-
this@callbackFlow.sendAndLog(FoundReaders(readers), logWrapper)
68-
}
69-
}
70-
},
71-
object : Callback {
72-
override fun onFailure(e: TerminalException) {
73-
this@callbackFlow.sendAndLog(Failure(e), logWrapper)
74-
this@callbackFlow.close()
75-
}
76-
77-
override fun onSuccess() {
78-
this@callbackFlow.sendAndLog(Success, logWrapper)
79-
this@callbackFlow.close()
80-
}
61+
return terminal.discoverReaders(config)
62+
.distinctUntilChanged()
63+
.map<List<Reader>, DiscoverReadersStatus> { readers -> FoundReaders(readers) }
64+
.onStart { emit(Started) }
65+
.onCompletion { cause ->
66+
if (cause == null || cause is CancellationException) {
67+
emit(Success)
68+
}
69+
}
70+
.catch { e ->
71+
if (e is TerminalException) {
72+
emit(Failure(e))
73+
} else {
74+
throw e
8175
}
82-
)
83-
awaitClose {
84-
cancelable.takeIf { !it.isCompleted }?.cancel(noopCallback)
8576
}
86-
}
77+
.onEach { logWrapper.d(LOG_TAG, it.toString()) }
8778
}
8879
}
89-
90-
private val noopCallback = object : Callback {
91-
override fun onFailure(e: TerminalException) {}
92-
93-
override fun onSuccess() {}
94-
}

0 commit comments

Comments
 (0)