react-native-mesmart 3.0.1 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -88,9 +88,10 @@ android {
88
88
  }
89
89
 
90
90
  repositories {
91
+ // local.properties e opcional (no EAS nao existe; o token vem da env var).
91
92
  def localProp = new Properties()
92
- def fileName = 'local.properties'
93
- localProp.load(new FileInputStream(rootProject.file(fileName)))
93
+ def localPropFile = rootProject.file('local.properties')
94
+ if (localPropFile.exists()) localPropFile.withInputStream { localProp.load(it) }
94
95
  def stoneToken = System.env.PACKAGECLOUD_READ_TOKEN != null ? System.env.PACKAGECLOUD_READ_TOKEN : localProp["packageCloudReadToken"] ?: ""
95
96
 
96
97
  mavenCentral()
@@ -9,11 +9,16 @@ import android.graphics.Typeface
9
9
  import android.text.Layout
10
10
  import android.text.StaticLayout
11
11
  import android.text.TextPaint
12
+ import android.util.Log
12
13
  import br.com.stone.posandroid.providers.PosPrintProvider
13
14
  import com.facebook.react.bridge.Promise
14
15
  import com.facebook.react.bridge.ReactApplicationContext
15
16
  import com.stone.utils.StoneUtils
16
17
  import stone.application.interfaces.StoneCallbackInterface
18
+ import java.lang.reflect.Field
19
+ import java.lang.reflect.InvocationHandler
20
+ import java.lang.reflect.InvocationTargetException
21
+ import java.lang.reflect.Proxy
17
22
 
18
23
  /**
19
24
  * Mesmas primitivas da Sunmi, mas acumuladas: o HAL da Tectoy avanca o papel pra corte no fim de
@@ -68,6 +73,7 @@ class PrinterT8(
68
73
  return
69
74
  }
70
75
 
76
+ guardLateEvents()
71
77
  val provider = PosPrintProvider(reactContext)
72
78
  job.forEach { provider.addBitmap(it) }
73
79
  provider.connectionCallback = object : StoneCallbackInterface {
@@ -87,6 +93,47 @@ class PrinterT8(
87
93
  provider.execute()
88
94
  }
89
95
 
96
+ /**
97
+ * O HAL da Tectoy (posandroid-manufacturer-tectoy 2.2.10, SDK Stone 4.20.x) solta o PosPrinter no
98
+ * fim do job (onFinish -> close -> release) com eventos de status ainda na fila do main looper; o
99
+ * proximo onInfo chama getPrintStateInfo() com mPosPrinter nulo e o NPE derruba o app. Abre aqui o
100
+ * gerenciador que o HAL reaproveita no job e embrulha o listener que ele entrega ao PosPrinter no
101
+ * beginPrint, pra descartar so os eventos que chegam depois do release. Tudo por reflexao: se o
102
+ * HAL mudar, imprime como antes.
103
+ */
104
+ private fun guardLateEvents() {
105
+ try {
106
+ val services = Class.forName("com.transire.transireservice.TransireServiceManager")
107
+ .getMethod("getInstance").invoke(null) ?: return
108
+ val manager = services.javaClass.getMethod("getPOIPrinterService").invoke(services) ?: return
109
+ val listenerField = field(manager.javaClass, "eventListener")
110
+ val listener = listenerField.get(manager) ?: return
111
+ if (Proxy.isProxyClass(listener.javaClass)) return
112
+
113
+ val guard = InvocationHandler { _, method, args ->
114
+ try {
115
+ method.invoke(listener, *(args ?: emptyArray<Any?>()))
116
+ } catch (e: InvocationTargetException) {
117
+ if (e.cause !is NullPointerException || !isReleased(args?.firstOrNull())) throw e.cause ?: e
118
+ Log.w(TAG, "Evento ${method.name} da impressora depois do release ignorado")
119
+ null
120
+ }
121
+ }
122
+ listenerField.set(
123
+ manager,
124
+ Proxy.newProxyInstance(listener.javaClass.classLoader, listener.javaClass.interfaces, guard)
125
+ )
126
+ } catch (t: Throwable) {
127
+ Log.w(TAG, "Impressora sem protecao contra eventos tardios do HAL", t)
128
+ }
129
+ }
130
+
131
+ private fun isReleased(printer: Any?): Boolean =
132
+ printer != null && runCatching { field(printer.javaClass, "mPosPrinter").get(printer) == null }.getOrDefault(false)
133
+
134
+ private fun field(type: Class<*>, name: String): Field =
135
+ type.getDeclaredField(name).apply { isAccessible = true }
136
+
90
137
  private fun textBlock(
91
138
  text: String,
92
139
  fontSize: Int,
@@ -133,6 +180,7 @@ class PrinterT8(
133
180
  .apply { eraseColor(Color.WHITE) }
134
181
 
135
182
  companion object {
183
+ private const val TAG = "PrinterT8"
136
184
  private const val PRINT_WIDTH = 384
137
185
  private const val DEFAULT_FONT_SIZE = 24
138
186
  private const val CALIBRATION_CHARS = 32
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-mesmart",
3
- "version": "3.0.1",
3
+ "version": "3.0.2",
4
4
  "description": "Native methods for integrating with Sunmi P2-B/P2-A11 POS, Pax A910/A920, Pagbank's Plugpag payment SDK, Stone's payment SDK, and Paystore's payment SDK.",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",