Skip to content

Commit

Permalink
Merge pull request #13 from gls-denmark/support-ring-scanner
Browse files Browse the repository at this point in the history
Support ring scanner
  • Loading branch information
jhetrifork authored Dec 18, 2023
2 parents e3f9dc4 + 24cb240 commit 635ab6a
Show file tree
Hide file tree
Showing 14 changed files with 215 additions and 41 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id("com.android.library") version "8.0.1" apply false
id("com.android.library") version "8.2.0-rc02" apply false
id("org.jetbrains.kotlin.android") version "1.8.0" apply false
kotlin("plugin.serialization") version "1.8.21"
}
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
4 changes: 2 additions & 2 deletions kotlin-data-wedge-lib/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ val libraryVersion = "0.0.5"

android {
namespace = "dk.gls.kdw"
compileSdk = 33
compileSdk = 34

defaultConfig {
minSdk = 26
minSdk = 30

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
Expand Down
10 changes: 7 additions & 3 deletions kotlin-data-wedge-lib/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
}

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

-keep class dk.gls.kdw.configuration.model.** {
Expand Down Expand Up @@ -61,10 +61,14 @@
*;
}

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

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

-keep class dk.gls.kdw.configuration.scanner.RemoteScannerNotification {
*;
}
5 changes: 5 additions & 0 deletions kotlin-data-wedge-lib/src/main/java/dk/gls/kdw/KDW.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package dk.gls.kdw

import dk.gls.kdw.implementation.KDWImplementation

object KDW : KDWImplementation()
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.util.Log
import dk.gls.kdw.model.scanner.ScannerOutput
import dk.gls.kdw.model.scanner.ScannerResult
import dk.gls.kdw.model.scanner.toScannerStatusEnum
Expand All @@ -13,19 +14,21 @@ 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 {
private const val TAG = "ScannerController"

//Scanner Intent data locations
private const val EXTRA_DATA_STRING = "com.symbol.datawedge.data_string"
private const val EXTRA_LABEL_TYPE = "com.symbol.datawedge.label_type"
Expand All @@ -36,6 +39,7 @@ class DataWedgeHardwareScanner(
private const val EXTRA_RESULT_NOTIFICATION = "com.symbol.datawedge.api.NOTIFICATION"
private const val EXTRA_REGISTER_NOTIFICATION = "com.symbol.datawedge.api.REGISTER_FOR_NOTIFICATION"


private const val EXTRA_RESULT_NOTIFICATION_TYPE = "NOTIFICATION_TYPE"
private const val EXTRA_KEY_VALUE_SCANNER_STATUS = "SCANNER_STATUS"
private const val EXTRA_KEY_VALUE_PROFILE_SWITCH = "PROFILE_SWITCH"
Expand All @@ -46,8 +50,8 @@ class DataWedgeHardwareScanner(
private const val ACTION_DATA_WEDGE = "com.symbol.datawedge.api.ACTION"
private const val EXTRA_SCANNER_INPUT_PLUGIN = "com.symbol.datawedge.api.SCANNER_INPUT_PLUGIN"

private const val ACTION_RESULT_NOTIFICATION = "com.symbol.datawedge.api.NOTIFICATION_ACTION"
private const val ACTION_RESULT = "com.symbol.datawedge.api.RESULT_ACTION"
private const val NOTIFICATION_ACTION = "com.symbol.datawedge.api.NOTIFICATION_ACTION"
private const val RESULT_ACTION = "com.symbol.datawedge.api.RESULT_ACTION"

// DataWedge scanning broadcast
private const val INTENT_FILTER_ACTION = "com.zebra.datacapture1.ACTION"
Expand All @@ -56,6 +60,17 @@ class DataWedgeHardwareScanner(
// DataWedge control scanner state
private const val EXTRA_SCANNER_SUSPEND = "SUSPEND_PLUGIN"
private const val EXTRA_SCANNER_RESUME = "RESUME_PLUGIN"

// Enumerate scanners
private const val RESULT_ENUMERATE_SCANNERS = "com.symbol.datawedge.api.RESULT_ENUMERATE_SCANNERS"
private const val ENUMERATE_SCANNERS = "com.symbol.datawedge.api.ENUMERATE_SCANNERS"

// Notify
private const val ACTION_NOTIFICATION_NOTIFY = "com.symbol.datawedge.api.notification.NOTIFY"
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 @@ -86,18 +101,53 @@ class DataWedgeHardwareScanner(

//endregion

//region scanner notifications

/**
* 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 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)

context.sendBroadcast(dataWedgeIntent)
}

//endregion

/** Register broadcast receiver for receiving barcode scans. Collect the received broadcasts and emit on scannerResult flow **/
private suspend fun subscribeToScannerFlow() {
callbackFlow {
val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent) {
Log.d("ScannerFlow", "${intent.action}, hasExtras: ${intent.hasExtra(RESULT_ENUMERATE_SCANNERS)}")
// Received a barcode scan
if (intent.action == INTENT_FILTER_ACTION) {
val scannerResult = extractDataFromIntent(intent)
trySendBlocking(ScannerOutput.Result(scannerResult))
}
// Received a scanner or profile switch status notification
if (intent.action == ACTION_RESULT_NOTIFICATION) {
if (intent.action == NOTIFICATION_ACTION) {
val extras = intent.getBundleExtra(EXTRA_RESULT_NOTIFICATION)
val notificationType = extras?.getString(EXTRA_RESULT_NOTIFICATION_TYPE)
when (notificationType) {
Expand All @@ -107,6 +157,11 @@ class DataWedgeHardwareScanner(

scannerStatus?.let {
val statusEnum = it.toScannerStatusEnum()


requestEnumerateScanners()


trySendBlocking(ScannerOutput.Status(statusEnum))
}
}
Expand All @@ -117,6 +172,19 @@ class DataWedgeHardwareScanner(
}
}
}
if (intent.hasExtra(RESULT_ENUMERATE_SCANNERS)) {
val scannerList = intent.getSerializableExtra(RESULT_ENUMERATE_SCANNERS) as ArrayList<Bundle>
if (scannerList.size > 0) {
scannerList.map { bunb ->
val name = bunb.getString("SCANNER_NAME")
val connectionState = bunb.getBoolean("SCANNER_CONNECTION_STATE")
val index = bunb.getInt("SCANNER_INDEX")
val id = bunb.getString("SCANNER_IDENTIFIER")

Log.d("ScannerList", "Scanner: name: $name connectionState: $connectionState index: $index id: $id")
}
}
}
}
}
context.registerReceiver(receiver, createIntentFilter())
Expand All @@ -128,13 +196,23 @@ class DataWedgeHardwareScanner(
}
}

/** Create and send intent filter in order to retrieve enumerate triggers **/
private fun requestEnumerateScanners() {
val dataWedgeIntent = Intent()

dataWedgeIntent.setAction(ACTION_DATA_WEDGE)
dataWedgeIntent.putExtra(ENUMERATE_SCANNERS, "")

context.sendBroadcast(dataWedgeIntent)
}

/** Create filter for the broadcast intent **/
private fun createIntentFilter(): IntentFilter {
val filter = IntentFilter()
// Register to received broadcasts via Data Wedge scanning
filter.addAction(ACTION_RESULT)
filter.addAction(RESULT_ACTION)
// For notification result
filter.addAction(ACTION_RESULT_NOTIFICATION)
filter.addAction(NOTIFICATION_ACTION)
// Register to received broadcasts via DataWedge scanning
filter.addAction(INTENT_FILTER_ACTION)
filter.addAction(INTENT_FILTER_ACTION_FROM_SERVICE)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package dk.gls.kdw.configuration.scanner

enum class DeviceId {
/** Built-in imager scanner **/
INTERNAL_IMAGER,
/** Built-in laser scanner **/
INTERNAL_LASER,
/** Built-in camera scanner **/
INTERNAL_CAMERA,
/** Pluggable Z-back scanner for ET50/ET55 **/
SERIAL_SSI,
/** RS507 Bluetooth scanner **/
BLUETOOTH_SSI,
/** RS6000 Bluetooth scanner **/
BLUETOOTH_RS6000,
/** RS5100 Bluetooth scanner **/
BLUETOOTH_RS5100,
/** DS2278 Bluetooth scanner **/
BLUETOOTH_DS2278,
/** DS3678 Bluetooth scanner **/
BLUETOOTH_DS3678,
/** Serial SSI scanner RS429 (for use with WT6000) **/
PLUGABLE_SSI,
/** Serial SSI scanner RS5000 (for use with WT6000) **/
PLUGABLE_SSI_RS5000,
/** DS3608 pluggable USB scanner **/
USB_SSI_DS3608
}

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
@@ -0,0 +1,35 @@
package dk.gls.kdw.configuration.scanner

enum class RemoteScannerNotification(val value: Int) {
ONE_HIGH_SHORT_BEEP(0),
TWO_HIGH_SHORT_BEEPS(1),
THREE_HIGH_SHORT_BEEPS(2),
FOUR_HIGH_SHORT_BEEPS(3),
FIVE_HIGH_SHORT_BEEPS(4),
ONE_LOW_SHORT_BEEP(5),
TWO_LOW_SHORT_BEEPS(6),
THREE_LOW_SHORT_BEEPS(7),
FOUR_LOW_SHORT_BEEPS(8),
FIVE_LOW_SHORT_BEEPS(9),
ONE_HIGH_LONG_BEEP(10),
TWO_HIGH_LONG_BEEPS(11),
THREE_HIGH_LONG_BEEPS(12),
FOUR_HIGH_LONG_BEEPS(13),
FIVE_HIGH_LONG_BEEPS(14),
ONE_LOW_LONG_BEEP(15),
TWO_LOW_LONG_BEEPS(16),
THREE_LOW_LONG_BEEPS(17),
FOUR_LOW_LONG_BEEPS(18),
FIVE_LOW_LONG_BEEPS(19),
FAST_WARBLE_BEEP(20),
SLOW_WARBLE_BEEP(21),
HIGH_LOW_BEEP(22),
LOW_HIGH_BEEP(23),
HIGH_LOW_HIGH_BEEP(24),
LOW_HIGH_LOW_BEEP(25),
HIGH_HIGH_LOW_LOW(26),
GREEN_LED_OFF(42),
GREEN_LED_ON(43),
RED_LED_ON(47),
RED_LED_OFF(48)
}
Loading

0 comments on commit 635ab6a

Please sign in to comment.