Skip to content

Commit

Permalink
Added new scanner DeviceId and RemoteScannerNotification classes to p…
Browse files Browse the repository at this point in the history
…roguard rules. Renamed IHardwareScanner, corrected ScannerController constructor with HardwareScanner interface instead of DataWedgeHardwareScanner implementation.
  • Loading branch information
jhetrifork committed Dec 14, 2023
1 parent 9e424fe commit 24cb240
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 31 deletions.
8 changes: 8 additions & 0 deletions kotlin-data-wedge-lib/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,11 @@
-keep class dk.gls.kdw.configuration.scanner.ParityFlowScannerController {
*;
}

-keep class dk.gls.kdw.configuration.scanner.DeviceId {
*;
}

-keep class dk.gls.kdw.configuration.scanner.RemoteScannerNotification {
*;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,19 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.channels.trySendBlocking
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch


class DataWedgeHardwareScanner(
private val context: Context,
dispatcher: CoroutineDispatcher = Dispatchers.IO
) : HardwareScanner {
private val dispatcher: CoroutineDispatcher = Dispatchers.IO
) : IHardwareScanner {

companion object {
//Scanner Intent data locations
Expand Down Expand Up @@ -67,7 +70,7 @@ class DataWedgeHardwareScanner(
private const val BUNDLE_NOTIFICATION_CONFIG = "NOTIFICATION_CONFIG"
private const val EXTRA_KEY_VALUE_DEVICE_IDENTIFIER = "DEVICE_IDENTIFIER"
private const val EXTRA_KEY_VALUE_NOTIFICATION_SETTINGS = "NOTIFICATION_SETTINGS"

private const val NOTIFICATIONS_DELAY: Long = 1000
}

private val scope = CoroutineScope(dispatcher)
Expand Down Expand Up @@ -96,19 +99,33 @@ class DataWedgeHardwareScanner(
broadcastScannerAction(context, EXTRA_SCANNER_RESUME)
}

//endregion

//region scanner notifications

/**
* Send a notification on the remote scanner (RMS)
* Send a variable amount of notification lists specifying the notifications for the remote scanner (RMS)
* The notifications are send with a delay between parsed lists of 1000 ms
* Official documentation
* @link https://techdocs.zebra.com/datawedge/8-2/guide/api/notify/
**/
override fun remoteScannerNotification(deviceId: DeviceId, notifications: List<RemoteScannerNotification>) {
override fun remoteScannerNotifications(deviceId: DeviceId, vararg notifications: List<RemoteScannerNotification>) {
CoroutineScope(dispatcher).launch {
notifications.asFlow().map {
remoteScannerNotification(deviceId, it)
delay(NOTIFICATIONS_DELAY)
}.collect()
}
}

private fun remoteScannerNotification(deviceId: DeviceId, notifications: List<RemoteScannerNotification>) {
val bundleNotificationConfig = Bundle()
bundleNotificationConfig.putString(EXTRA_KEY_VALUE_DEVICE_IDENTIFIER, deviceId.name)
bundleNotificationConfig.putIntArray(EXTRA_KEY_VALUE_NOTIFICATION_SETTINGS, notifications.map { it.value }.toIntArray())

val bundleNotify = Bundle()
bundleNotify.putBundle(BUNDLE_NOTIFICATION_CONFIG, bundleNotificationConfig)


val dataWedgeIntent = Intent()
dataWedgeIntent.action = ACTION_DATA_WEDGE
dataWedgeIntent.putExtra(ACTION_NOTIFICATION_NOTIFY, bundleNotify)
Expand Down Expand Up @@ -157,7 +174,7 @@ class DataWedgeHardwareScanner(
}
if (intent.hasExtra(RESULT_ENUMERATE_SCANNERS)) {
val scannerList = intent.getSerializableExtra(RESULT_ENUMERATE_SCANNERS) as ArrayList<Bundle>
if(scannerList.size > 0) {
if (scannerList.size > 0) {
scannerList.map { bunb ->
val name = bunb.getString("SCANNER_NAME")
val connectionState = bunb.getBoolean("SCANNER_CONNECTION_STATE")
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package dk.gls.kdw.configuration.scanner

import dk.gls.kdw.model.scanner.ScannerOutput
import kotlinx.coroutines.flow.Flow

interface IHardwareScanner {
/**
* Receive the [ScannerOutput] as a flow
*/
fun scannerOutputFlow(): Flow<ScannerOutput>

/** Suspend the scanner **/
fun suspendScanner()

/** Resume the scanner **/
fun resumeScanner()

/**
* Send a variable amount of notification lists specifying the notifications for the remote scanner (RMS)
* The notifications are send with a delay between parsed lists of 1000 ms
* Official documentation
* @link https://techdocs.zebra.com/datawedge/8-2/guide/api/notify/
**/
fun remoteScannerNotifications(deviceId: DeviceId, vararg notifications: List<RemoteScannerNotification>)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.launch

/**
* The parity flow scanner controller filters unnecessary calls to the underlying [DataWedgeHardwareScanner] by checking the last reported scanner status before sending new resume or suspend commands
* The parity flow scanner controller filters unnecessary calls to the underlying [IHardwareScanner] by checking the last reported scanner status before sending new resume or suspend commands
* Therefore this scanner controllers [resumeScanner] and [suspendScanner] methods can safely be called multiple times without resulting in unnecessary broadcast intents being send to the Data wedge
*/
class ParityFlowScannerController(dataWedgeHardwareScanner: DataWedgeHardwareScanner) : ScannerController(dataWedgeHardwareScanner) {
class ParityFlowScannerController(dataWedgeIHardwareScanner: IHardwareScanner) : ScannerController(dataWedgeIHardwareScanner) {

//We have an actual scanner status flow and a desired scanner status flow for combining later
private val actualScannerStatusEnumFlow = MutableSharedFlow<ScannerSimpleStatus>(replay = 1)
Expand All @@ -32,7 +31,7 @@ class ParityFlowScannerController(dataWedgeHardwareScanner: DataWedgeHardwareSca
/**
* Receive the [ScannerOutput] as a flow
*/
override fun scannerOutputFlow(): Flow<ScannerOutput> = dataWedgeHardwareScanner.scannerOutputFlow()
override fun scannerOutputFlow(): Flow<ScannerOutput> = dataWedgeIHardwareScanner.scannerOutputFlow()

//region Scanner status public interface

Expand All @@ -52,8 +51,8 @@ class ParityFlowScannerController(dataWedgeHardwareScanner: DataWedgeHardwareSca
desiredScannerStatusFlow.tryEmit(ScannerSimpleStatus.Enabled)
}

override fun remoteScannerNotification(deviceId: DeviceId, notifications: List<RemoteScannerNotification>) {
dataWedgeHardwareScanner.remoteScannerNotification(deviceId, notifications)
override fun remoteScannerNotifications(deviceId: DeviceId, vararg notifications: List<RemoteScannerNotification>) {
dataWedgeIHardwareScanner.remoteScannerNotifications(deviceId, *notifications)
}

//endregion
Expand All @@ -64,7 +63,7 @@ class ParityFlowScannerController(dataWedgeHardwareScanner: DataWedgeHardwareSca

private fun CoroutineScope.subscribeToScannerFlow() = launch {
scannerOutputFlow().collect {
if(it is ScannerOutput.Status) {
if (it is ScannerOutput.Status) {
actualScannerStatusEnumFlow.emit(it.scannerStatus.toScannerSimpleStatus())
}
}
Expand All @@ -76,8 +75,8 @@ class ParityFlowScannerController(dataWedgeHardwareScanner: DataWedgeHardwareSca
Log.d("ParityFlowScannerController", "scannerStatusParityFlow: $actual, $desired")
if (actual != desired) {
when (desired) {
ScannerSimpleStatus.Disabled -> dataWedgeHardwareScanner.suspendScanner()
ScannerSimpleStatus.Enabled -> dataWedgeHardwareScanner.resumeScanner()
ScannerSimpleStatus.Disabled -> dataWedgeIHardwareScanner.suspendScanner()
ScannerSimpleStatus.Enabled -> dataWedgeIHardwareScanner.resumeScanner()
}
}
}.collect()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import kotlinx.coroutines.flow.Flow
* The scanner controller makes it possible to suspend and resume the scanner and monitor [ScannerOutput] using a Flow
*/
abstract class ScannerController(
val dataWedgeHardwareScanner: DataWedgeHardwareScanner
val dataWedgeIHardwareScanner: IHardwareScanner
) {

abstract fun scannerOutputFlow(): Flow<ScannerOutput>
Expand All @@ -16,6 +16,5 @@ abstract class ScannerController(

abstract fun resumeScanner()

abstract fun remoteScannerNotification(deviceId: DeviceId, notifications: List<RemoteScannerNotification>)

abstract fun remoteScannerNotifications(deviceId: DeviceId, vararg notifications: List<RemoteScannerNotification>)
}

0 comments on commit 24cb240

Please sign in to comment.