@onekeyfe/react-native-lite-card 0.1.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.
Files changed (95) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +37 -0
  3. package/ReactNativeLiteCard.podspec +22 -0
  4. package/android/build.gradle +79 -0
  5. package/android/gradle.properties +5 -0
  6. package/android/src/main/AndroidManifest.xml +2 -0
  7. package/android/src/main/config/command.json +205 -0
  8. package/android/src/main/cpp/CMakeLists.txt +19 -0
  9. package/android/src/main/cpp/validation.c +227 -0
  10. package/android/src/main/cpp/validation.h +19 -0
  11. package/android/src/main/java/com/onekeyfe/reactnativelitecard/LoggerManager.kt +35 -0
  12. package/android/src/main/java/com/onekeyfe/reactnativelitecard/ReactNativeLiteCardModule.kt +420 -0
  13. package/android/src/main/java/com/onekeyfe/reactnativelitecard/ReactNativeLiteCardPackage.kt +33 -0
  14. package/android/src/main/java/com/onekeyfe/reactnativelitecard/keys/KeysNativeProvider.kt +13 -0
  15. package/android/src/main/java/com/onekeyfe/reactnativelitecard/nfc/Exceptions.kt +58 -0
  16. package/android/src/main/java/com/onekeyfe/reactnativelitecard/nfc/NfcUtils.kt +142 -0
  17. package/android/src/main/java/com/onekeyfe/reactnativelitecard/nfc/broadcast/NfcStatusChangeBroadcastReceiver.kt +56 -0
  18. package/android/src/main/java/com/onekeyfe/reactnativelitecard/nfc/gpchannel/GPChannelNatives.kt +32 -0
  19. package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/NfcConstant.kt +38 -0
  20. package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/OnekeyLiteCard.kt +236 -0
  21. package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/entitys/APDUParam.kt +17 -0
  22. package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/entitys/CardInfo.java +84 -0
  23. package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/entitys/CardResponse.java +37 -0
  24. package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/entitys/CardState.kt +10 -0
  25. package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/entitys/ParsedCertInfo.java +39 -0
  26. package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/entitys/SecureChanelParam.java +113 -0
  27. package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/entitys/SendResponse.kt +26 -0
  28. package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/nfc/CommandGenerator.kt +178 -0
  29. package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/nfc/Connection.kt +439 -0
  30. package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/nfc/GPCAPDUGenerator.kt +56 -0
  31. package/android/src/main/java/com/onekeyfe/reactnativelitecard/utils/EventUtils.kt +14 -0
  32. package/android/src/main/java/com/onekeyfe/reactnativelitecard/utils/GpsUtil.kt +38 -0
  33. package/android/src/main/java/com/onekeyfe/reactnativelitecard/utils/HexUtils.java +93 -0
  34. package/android/src/main/java/com/onekeyfe/reactnativelitecard/utils/LogUtil.kt +11 -0
  35. package/android/src/main/java/com/onekeyfe/reactnativelitecard/utils/MiUtil.kt +93 -0
  36. package/android/src/main/java/com/onekeyfe/reactnativelitecard/utils/NfcPermissionUtils.kt +24 -0
  37. package/android/src/main/java/com/onekeyfe/reactnativelitecard/utils/Utils.java +437 -0
  38. package/android/src/main/jniLibs/arm64-v8a/libgpchannelNDK.so +0 -0
  39. package/android/src/main/jniLibs/armeabi-v7a/libgpchannelNDK.so +0 -0
  40. package/ios/Classes/OKLiteCommand/OKLiteCommandModal.h +39 -0
  41. package/ios/Classes/OKLiteCommand/OKLiteCommandModal.m +143 -0
  42. package/ios/Classes/OKLiteCommand/OKLiteCommandTool.h +28 -0
  43. package/ios/Classes/OKLiteCommand/OKLiteCommandTool.m +53 -0
  44. package/ios/Classes/OKNFCBridge.h +28 -0
  45. package/ios/Classes/OKNFCBridge.mm +221 -0
  46. package/ios/Classes/OKNFCLiteDefine.h +108 -0
  47. package/ios/Classes/OKNFTLite/OKLiteProtocol.h +37 -0
  48. package/ios/Classes/OKNFTLite/OKLiteV1.h +41 -0
  49. package/ios/Classes/OKNFTLite/OKLiteV1.m +609 -0
  50. package/ios/Classes/OKNFTLite/OKLiteV2.h +17 -0
  51. package/ios/Classes/OKNFTLite/OKLiteV2.m +132 -0
  52. package/ios/Classes/OKNFTLite/OKNFCManager.h +40 -0
  53. package/ios/Classes/OKNFTLite/OKNFCManager.m +330 -0
  54. package/ios/Classes/Utils/NFCConfig.h +19 -0
  55. package/ios/Classes/Utils/NFCConfig.m +18 -0
  56. package/ios/Classes/Utils/NSData+OKNFCHexData.h +17 -0
  57. package/ios/Classes/Utils/NSData+OKNFCHexData.m +24 -0
  58. package/ios/Classes/Utils/NSData+StringToData.h +12 -0
  59. package/ios/Classes/Utils/NSData+StringToData.m +25 -0
  60. package/ios/Classes/Utils/NSString+OKAdd.h +14 -0
  61. package/ios/Classes/Utils/NSString+OKAdd.m +40 -0
  62. package/ios/Classes/Utils/NSString+OKNFCHexStr.h +18 -0
  63. package/ios/Classes/Utils/NSString+OKNFCHexStr.m +38 -0
  64. package/ios/Classes/Utils/OKNFCUtility.h +18 -0
  65. package/ios/Classes/Utils/OKNFCUtility.m +22 -0
  66. package/ios/Classes/Utils/OKTools.h +17 -0
  67. package/ios/Classes/Utils/OKTools.m +21 -0
  68. package/ios/GPChannelSDKCore.xcframework/Info.plist +52 -0
  69. package/ios/GPChannelSDKCore.xcframework/ios-arm64/GPChannelSDKCore.framework/GPChannelSDKCore +0 -0
  70. package/ios/GPChannelSDKCore.xcframework/ios-arm64/GPChannelSDKCore.framework/Headers/GPChannelSDK.h +315 -0
  71. package/ios/GPChannelSDKCore.xcframework/ios-arm64/GPChannelSDKCore.framework/Headers/GPChannelSDKCore.h +19 -0
  72. package/ios/GPChannelSDKCore.xcframework/ios-arm64/GPChannelSDKCore.framework/Info.plist +0 -0
  73. package/ios/GPChannelSDKCore.xcframework/ios-arm64/GPChannelSDKCore.framework/Modules/module.modulemap +7 -0
  74. package/ios/GPChannelSDKCore.xcframework/ios-arm64/GPChannelSDKCore.framework/_CodeSignature/CodeResources +147 -0
  75. package/ios/GPChannelSDKCore.xcframework/ios-arm64_x86_64-simulator/GPChannelSDKCore.framework/GPChannelSDKCore +0 -0
  76. package/ios/GPChannelSDKCore.xcframework/ios-arm64_x86_64-simulator/GPChannelSDKCore.framework/Headers/GPChannelSDK.h +315 -0
  77. package/ios/GPChannelSDKCore.xcframework/ios-arm64_x86_64-simulator/GPChannelSDKCore.framework/Headers/GPChannelSDKCore.h +19 -0
  78. package/ios/GPChannelSDKCore.xcframework/ios-arm64_x86_64-simulator/GPChannelSDKCore.framework/Info.plist +0 -0
  79. package/ios/GPChannelSDKCore.xcframework/ios-arm64_x86_64-simulator/GPChannelSDKCore.framework/Modules/module.modulemap +7 -0
  80. package/ios/GPChannelSDKCore.xcframework/ios-arm64_x86_64-simulator/GPChannelSDKCore.framework/_CodeSignature/CodeResources +147 -0
  81. package/ios/ReactNativeLiteCard.h +5 -0
  82. package/ios/ReactNativeLiteCard.mm +222 -0
  83. package/lib/module/NativeReactNativeLiteCard.js +25 -0
  84. package/lib/module/NativeReactNativeLiteCard.js.map +1 -0
  85. package/lib/module/index.js +71 -0
  86. package/lib/module/index.js.map +1 -0
  87. package/lib/module/package.json +1 -0
  88. package/lib/typescript/package.json +1 -0
  89. package/lib/typescript/src/NativeReactNativeLiteCard.d.ts +59 -0
  90. package/lib/typescript/src/NativeReactNativeLiteCard.d.ts.map +1 -0
  91. package/lib/typescript/src/index.d.ts +23 -0
  92. package/lib/typescript/src/index.d.ts.map +1 -0
  93. package/package.json +168 -0
  94. package/src/NativeReactNativeLiteCard.ts +112 -0
  95. package/src/index.tsx +94 -0
@@ -0,0 +1,420 @@
1
+ package com.onekeyfe.reactnativelitecard
2
+
3
+ import android.content.Intent
4
+ import android.nfc.NfcAdapter
5
+ import android.nfc.Tag
6
+ import android.nfc.tech.IsoDep
7
+ import android.util.Log
8
+ import androidx.annotation.IntDef
9
+ import androidx.fragment.app.FragmentActivity
10
+ import kotlinx.coroutines.*
11
+ import kotlinx.coroutines.channels.Channel
12
+ import com.facebook.react.bridge.Callback
13
+ import com.facebook.react.bridge.ReactApplicationContext
14
+ import com.facebook.react.module.annotations.ReactModule
15
+ import so.onekey.app.wallet.lite.nfc.NFCExceptions
16
+ import so.onekey.app.wallet.lite.nfc.NfcUtils
17
+ import so.onekey.app.wallet.lite.onekeyLite.OneKeyLiteCard
18
+ import so.onekey.app.wallet.lite.onekeyLite.entitys.CardState
19
+ import so.onekey.app.wallet.lite.utils.NfcPermissionUtils
20
+ import so.onekey.app.wallet.lite.utils.Utils
21
+ import java.util.concurrent.atomic.AtomicInteger
22
+ import com.facebook.react.bridge.Arguments
23
+ import com.facebook.react.bridge.BaseActivityEventListener
24
+ import com.facebook.react.bridge.LifecycleEventListener
25
+ import com.facebook.react.bridge.WritableMap
26
+ import so.onekey.app.wallet.lite.nfc.broadcast.NfcStatusChangeBroadcastReceiver
27
+ import java.util.concurrent.Executors.newFixedThreadPool
28
+
29
+ private val NFCDispatcher = newFixedThreadPool(1).asCoroutineDispatcher()
30
+ public fun NFCScope(): CoroutineScope = CoroutineScope(SupervisorJob() + NFCDispatcher)
31
+
32
+ @ReactModule(name = ReactNativeLiteCardModule.NAME)
33
+ class ReactNativeLiteCardModule(reactContext: ReactApplicationContext) :
34
+ NativeReactNativeLiteCardSpec(reactContext), LifecycleEventListener, CoroutineScope by NFCScope() {
35
+
36
+ companion object {
37
+ const val NAME = "ReactNativeLiteCard"
38
+ private val TAG = ReactNativeLiteCardModule::class.simpleName
39
+ }
40
+
41
+ @IntDef(NFCState.Dead, NFCState.Started)
42
+ annotation class NFCState {
43
+ companion object {
44
+ const val Dead = -1
45
+ const val Started = 0
46
+ }
47
+ }
48
+
49
+ override fun getName(): String {
50
+ return NAME
51
+ }
52
+
53
+ private val mNFCConnectedChannel = Channel<IsoDep?>(1)
54
+ private var lastIsoDep: IsoDep? = null
55
+ private val mNFCState = AtomicInteger(NFCState.Dead)
56
+ private val mShowDialogNumber = AtomicInteger(0)
57
+ private var mCurrentCardState: CardState? = null
58
+
59
+ private val mActivityEventListener = object : BaseActivityEventListener() {
60
+ override fun onNewIntent(intent: Intent) {
61
+ super.onNewIntent(intent)
62
+ val action = intent.action
63
+ if (action == null) {
64
+ return
65
+ }
66
+ if ((action == NfcAdapter.ACTION_NDEF_DISCOVERED)
67
+ || action == NfcAdapter.ACTION_TECH_DISCOVERED
68
+ || action == NfcAdapter.ACTION_TAG_DISCOVERED
69
+ ) {
70
+ val tags = intent.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG)
71
+ val isoDep: IsoDep? = IsoDep.get(tags)
72
+ if (isoDep == null) {
73
+ // 未知设备
74
+ val dataMap = Arguments.createMap().apply {
75
+ putString("type", "unknown")
76
+ }
77
+ emitOnNFCActiveConnection(dataMap)
78
+ Log.d(TAG, "Unknown device")
79
+ return
80
+ }
81
+
82
+ Log.d(TAG, isoDep.toString())
83
+ launch(Dispatchers.IO) {
84
+ mNFCConnectedChannel.trySend(isoDep)
85
+ try {
86
+ // 处理主动触发 NFC
87
+ delay(100)
88
+ if (!mNFCConnectedChannel.isEmpty) {
89
+ Log.e(TAG, "There is no way to use NFC")
90
+ // mNFCConnectedChannel.receive()
91
+ val startRequest = OneKeyLiteCard.initRequest(isoDep)
92
+ val dataMap = Arguments.createMap().apply {
93
+ putInt("code", -1)
94
+ putString("type", "OneKey_Lite")
95
+ putString("serialNum", startRequest.serialNum)
96
+ putBoolean("isNewCard", startRequest.isNewCard)
97
+ putBoolean("hasBackup", startRequest.hasBackup)
98
+ }
99
+ emitOnNFCActiveConnection(dataMap)
100
+ }
101
+ } catch (e: Exception) {
102
+ e.printStackTrace()
103
+ // 未知设备或连接失败
104
+ val dataMap = Arguments.createMap().apply {
105
+ putInt("code", -1)
106
+ putString("type", "unknown")
107
+ }
108
+ emitOnNFCActiveConnection(dataMap)
109
+ emitOnNFCActiveConnection(dataMap)
110
+ }
111
+ }
112
+ }
113
+ }
114
+ }
115
+
116
+ init {
117
+ reactContext.addLifecycleEventListener(this)
118
+ reactContext.addActivityEventListener(mActivityEventListener)
119
+ }
120
+
121
+ private fun releaseDevice() {
122
+ if (mShowDialogNumber.get() <= 0) return
123
+
124
+ mCurrentCardState = null
125
+ val decrementAndGet = mShowDialogNumber.decrementAndGet()
126
+
127
+ // 关闭连接结束 ui
128
+ emitOnNFCUIEvent(Arguments.createMap().also {
129
+ it.putInt("code", 3)
130
+ it.putString("message", "close_connect_ui")
131
+ })
132
+
133
+ // 还有需要处理的 NFC 事件
134
+ if (decrementAndGet > 0) {
135
+ // 展示连接 ui
136
+ emitOnNFCUIEvent(Arguments.createMap().also {
137
+ it.putInt("code", 1)
138
+ it.putString("message", "show_connect_ui")
139
+ })
140
+ }
141
+ }
142
+
143
+ @Throws(NFCExceptions::class)
144
+ private suspend fun acquireDevice(): IsoDep? {
145
+ // 展示连接 ui
146
+ emitOnNFCUIEvent(Arguments.createMap().also {
147
+ it.putInt("code", 1)
148
+ it.putString("message", "show_connect_ui")
149
+ })
150
+ mShowDialogNumber.incrementAndGet()
151
+ val tryReceiveResult = mNFCConnectedChannel.tryReceive()
152
+
153
+ fun IsoDep?.isSafeConnected(): Boolean {
154
+ return runCatching { this?.isConnected ?: false }.getOrDefault(false)
155
+ }
156
+ var receiveIsoDep: IsoDep? = null
157
+
158
+ if (tryReceiveResult.isSuccess) {
159
+ receiveIsoDep = tryReceiveResult.getOrNull()
160
+ if (!receiveIsoDep.isSafeConnected()) {
161
+ receiveIsoDep = null
162
+ }
163
+ }
164
+
165
+ if (receiveIsoDep == null && lastIsoDep.isSafeConnected()) {
166
+ receiveIsoDep = lastIsoDep
167
+ }
168
+ if (receiveIsoDep == null) {
169
+ receiveIsoDep = mNFCConnectedChannel.receive()
170
+ }
171
+
172
+ lastIsoDep = receiveIsoDep
173
+ if (receiveIsoDep == null) {
174
+ // 取消连接
175
+ releaseDevice()
176
+ } else {
177
+ val initChannelRequest = OneKeyLiteCard.initRequest(receiveIsoDep)
178
+
179
+ mCurrentCardState = initChannelRequest
180
+
181
+ // 展示连接结束 ui
182
+ emitOnNFCUIEvent(Arguments.createMap().also {
183
+ it.putInt("code", 2)
184
+ it.putString("message", "connected")
185
+ })
186
+ }
187
+ return receiveIsoDep
188
+ }
189
+
190
+ private suspend fun <T> handleOperation(
191
+ callback: Callback?,
192
+ execute: (isoDep: IsoDep) -> T
193
+ ) {
194
+ val topActivity = Utils.getTopActivity() ?: return
195
+ NfcPermissionUtils.checkPermission(topActivity) {
196
+ try {
197
+ Log.d(TAG, "NFC permission check success")
198
+ val isoDep = acquireDevice() ?: return
199
+ val executeResult = execute(isoDep)
200
+ callback?.invoke(null, executeResult, mCurrentCardState.createArguments())
201
+ } catch (e: NFCExceptions) {
202
+ Log.e(TAG, "NFC device execute error", e)
203
+ callback?.invoke(e.createArguments(), null, mCurrentCardState.createArguments())
204
+ } finally {
205
+ releaseDevice()
206
+ }
207
+ return
208
+ }
209
+ // 没有 NFC 使用权限
210
+ Log.d(TAG, "NFC device not permission")
211
+ callback?.invoke(NFCExceptions.NotNFCPermission().createArguments(), null, null)
212
+ }
213
+
214
+ private fun CardState?.createArguments(): WritableMap {
215
+ val map = Arguments.createMap()
216
+ if (this == null) return map
217
+ map.putBoolean("hasBackup", this.hasBackup)
218
+ map.putBoolean("isNewCard", this.isNewCard)
219
+ map.putString("serialNum", this.serialNum)
220
+ map.putInt("pinRetryCount", this.pinRetryCount)
221
+ return map
222
+ }
223
+
224
+ private fun NFCExceptions?.createArguments(): WritableMap {
225
+ val map = Arguments.createMap()
226
+ if (this == null) return map
227
+ map.putInt("code", this.code)
228
+ map.putString("message", this.message)
229
+ return map
230
+ }
231
+
232
+ override fun getLiteInfo(callback: Callback?) {
233
+ launch {
234
+ Log.d(TAG, "getLiteInfo")
235
+ handleOperation<Any>(callback) { isoDep ->
236
+ Log.e(TAG, "getLiteInfo Obtain the device")
237
+ val cardInfo = OneKeyLiteCard.getCardInfo(isoDep)
238
+ Log.e(TAG, "getLiteInfo result $cardInfo")
239
+ cardInfo.createArguments()
240
+ }
241
+ }
242
+ }
243
+
244
+ override fun checkNFCPermission(callback: Callback?) {
245
+ val topActivity = Utils.getTopActivity()
246
+ if (topActivity == null) {
247
+ callback?.invoke(NFCExceptions.InitializedException().createArguments(), null, null)
248
+ return
249
+ }
250
+ val isNfcExists = NfcUtils.isNfcExits(topActivity)
251
+ if (!isNfcExists) {
252
+ // 没有 NFC 设备
253
+ Log.d(TAG, "NFC device not found")
254
+ callback?.invoke(NFCExceptions.NotExistsNFC().createArguments(), null, null)
255
+ return
256
+ }
257
+
258
+ val isNfcEnable = NfcUtils.isNfcEnable(topActivity)
259
+ if (!isNfcEnable) {
260
+ // 没有打开 NFC 开关
261
+ Log.d(TAG, "NFC device not enable")
262
+ callback?.invoke(NFCExceptions.NotEnableNFC().createArguments(), null, null)
263
+ return
264
+ }
265
+ NfcPermissionUtils.checkPermission(topActivity) {
266
+ callback?.invoke(null, null, null)
267
+ return
268
+ }
269
+ // 没有 NFC 使用权限
270
+ Log.d(TAG, "NFC device not permission")
271
+ callback?.invoke(NFCExceptions.NotNFCPermission().createArguments(), null, null)
272
+ }
273
+
274
+ override fun setMnemonic(
275
+ mnemonic: String?,
276
+ pwd: String?,
277
+ overwrite: Boolean,
278
+ callback: Callback?
279
+ ) {
280
+ launch {
281
+ handleOperation(callback) { isoDep ->
282
+ Log.e(TAG, "setMnemonic Obtain the device")
283
+ val isSuccess =
284
+ OneKeyLiteCard.setMnemonic(
285
+ mCurrentCardState,
286
+ isoDep,
287
+ mnemonic,
288
+ pwd,
289
+ overwrite
290
+ )
291
+ if (!isSuccess) throw NFCExceptions.ExecFailureException()
292
+ Log.e(TAG, "setMnemonic result success")
293
+ true
294
+ }
295
+ }
296
+ }
297
+
298
+ override fun getMnemonicWithPin(
299
+ pwd: String,
300
+ callback: Callback?
301
+ ) {
302
+ launch {
303
+ Log.d(TAG, "getMnemonicWithPin")
304
+ handleOperation(callback) { isoDep ->
305
+ Log.e(TAG, "getMnemonicWithPin Obtain the device")
306
+ OneKeyLiteCard.getMnemonicWithPin(mCurrentCardState, isoDep, pwd)
307
+ }
308
+ }
309
+ }
310
+
311
+ override fun changePin(
312
+ oldPin: String,
313
+ newPin: String,
314
+ callback: Callback?
315
+ ) {
316
+ launch {
317
+ Log.d(TAG, "changePin")
318
+ handleOperation(callback) { isoDep ->
319
+ Log.e(TAG, "changePin Obtain the device")
320
+ OneKeyLiteCard.changPin(mCurrentCardState, isoDep, oldPin, newPin)
321
+ }
322
+ }
323
+ }
324
+
325
+ override fun reset(callback: Callback?) {
326
+ launch {
327
+ Log.d(TAG, "reset")
328
+ handleOperation(callback) { isoDep ->
329
+ Log.e(TAG, "reset Obtain the device")
330
+ val isSuccess = OneKeyLiteCard.reset(isoDep)
331
+ if (!isSuccess) throw NFCExceptions.ExecFailureException()
332
+ Log.e(TAG, "reset result success")
333
+ true
334
+ }
335
+ }
336
+ }
337
+
338
+ override fun cancel() {
339
+ if (mNFCConnectedChannel.isEmpty) {
340
+ mNFCConnectedChannel.trySend(null)
341
+ }
342
+ }
343
+
344
+ override fun intoSetting() {
345
+ launch {
346
+ Log.d(TAG, "intoSetting")
347
+ Utils.getTopActivity()?.let {
348
+ NfcUtils.intentToNfcSetting(it)
349
+ }
350
+ }
351
+ }
352
+
353
+ private val mNfcStateBroadcastReceiver by lazy {
354
+ object : NfcStatusChangeBroadcastReceiver() {
355
+ override fun onCardPayMode() {
356
+ super.onCardPayMode()
357
+ }
358
+
359
+ override fun onNfcOff() {
360
+ super.onNfcOff()
361
+ }
362
+
363
+ override fun onNfcOn() {
364
+ super.onNfcOn()
365
+ Utils.getTopActivity()?.let {
366
+ launch(Dispatchers.IO) {
367
+ OneKeyLiteCard.startNfc(it as FragmentActivity) {}
368
+ }
369
+ }
370
+ }
371
+
372
+ override fun onNfcTurningOff() {
373
+ super.onNfcTurningOff()
374
+ }
375
+
376
+ override fun onNfcTurningOn() {
377
+ super.onNfcTurningOn()
378
+ }
379
+ }
380
+ }
381
+
382
+
383
+ override fun onHostResume() {
384
+ Utils.getTopActivity()?.let {
385
+ launch(Dispatchers.IO) {
386
+ if (it !is FragmentActivity) return@launch
387
+ try {
388
+ OneKeyLiteCard.startNfc(it) {
389
+ mNFCState.set(NFCState.Started)
390
+
391
+ Log.d(TAG, "NFC starting success")
392
+ }
393
+ } catch (e: Exception) {
394
+ Log.e(TAG, "startNfc failed", e)
395
+ }
396
+ }
397
+ }
398
+ }
399
+
400
+ override fun onHostPause() {
401
+ Utils.getTopActivity()?.let {
402
+ launch(Dispatchers.IO) {
403
+ try {
404
+ OneKeyLiteCard.stopNfc(it as FragmentActivity)
405
+ mNFCState.set(NFCState.Dead)
406
+ Log.d(TAG, "NFC 已关闭")
407
+ } catch (e: Exception) {
408
+ Log.e(TAG, "stopNfc failed", e)
409
+ }
410
+ }
411
+ }
412
+ }
413
+
414
+ override fun onHostDestroy() {
415
+ try {
416
+ Utils.getTopActivity()?.unregisterReceiver(mNfcStateBroadcastReceiver)
417
+ } catch (ignore: Exception) {
418
+ }
419
+ }
420
+ }
@@ -0,0 +1,33 @@
1
+ package com.onekeyfe.reactnativelitecard
2
+
3
+ import com.facebook.react.BaseReactPackage
4
+ import com.facebook.react.bridge.NativeModule
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.module.model.ReactModuleInfo
7
+ import com.facebook.react.module.model.ReactModuleInfoProvider
8
+ import java.util.HashMap
9
+
10
+ class ReactNativeLiteCardPackage : BaseReactPackage() {
11
+ override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
12
+ return if (name == ReactNativeLiteCardModule.NAME) {
13
+ ReactNativeLiteCardModule(reactContext)
14
+ } else {
15
+ null
16
+ }
17
+ }
18
+
19
+ override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
20
+ return ReactModuleInfoProvider {
21
+ val moduleInfos: MutableMap<String, ReactModuleInfo> = HashMap()
22
+ moduleInfos[ReactNativeLiteCardModule.NAME] = ReactModuleInfo(
23
+ ReactNativeLiteCardModule.NAME,
24
+ ReactNativeLiteCardModule.NAME,
25
+ false, // canOverrideExistingModule
26
+ false, // needsEagerInit
27
+ false, // isCxxModule
28
+ true // isTurboModule
29
+ )
30
+ moduleInfos
31
+ }
32
+ }
33
+ }
@@ -0,0 +1,13 @@
1
+ package so.onekey.app.wallet.lite.keys
2
+
3
+ import android.content.Context
4
+
5
+ class KeysNativeProvider {
6
+ companion object {
7
+ init {
8
+ System.loadLibrary("keys")
9
+ }
10
+ }
11
+
12
+ external fun getLiteSecureChannelInitParams(context: Context): String
13
+ }
@@ -0,0 +1,58 @@
1
+ package so.onekey.app.wallet.lite.nfc
2
+
3
+ sealed class NFCExceptions(val code: Int, override val message: String? = null) : Exception(message) {
4
+ fun toJson(): String {
5
+ return """{"code":$code,"message":"$message"}"""
6
+ }
7
+
8
+ // 初始化异常
9
+ class InitChannelException(message: String? = null) : NFCExceptions(1000, message)
10
+
11
+ // 没有 NFC 设备
12
+ class NotExistsNFC(message: String? = null) : NFCExceptions(1001, message)
13
+
14
+ // 没有开启 NFC 设备
15
+ class NotEnableNFC(message: String? = null) : NFCExceptions(1002, message)
16
+
17
+ // 没有使用 NFC 的权限
18
+ class NotNFCPermission(message: String? = null) : NFCExceptions(1003, message)
19
+
20
+ // 连接失败
21
+ class ConnectionFailException(message: String? = null) : NFCExceptions(2001, message)
22
+
23
+ // 操作中断(可能是连接问题)
24
+ class InterruptException(message: String? = null) : NFCExceptions(2002, message)
25
+
26
+ // 连接设备不匹配
27
+ class DeviceMismatchException(message: String? = null) : NFCExceptions(2003, message)
28
+
29
+ // 用户主动取消
30
+ class UserCancelExceptions(message: String? = null) : NFCExceptions(2004, message)
31
+
32
+ // 密码错误
33
+ class PasswordWrongException(message: String? = null) : NFCExceptions(3001, message)
34
+
35
+ // 输入密码为空
36
+ class InputPasswordEmptyException(message: String? = null) : NFCExceptions(3002, message)
37
+
38
+ // 未设置过密码
39
+ class PasswordEmptyException(message: String? = null) : NFCExceptions(3003, message)
40
+
41
+ // 设置初始化密码错误
42
+ class InitPasswordException(message: String? = null) : NFCExceptions(3004, message)
43
+
44
+ // 密码重试次数太多已经锁死
45
+ class CardLockException(message: String? = null) : NFCExceptions(3005, message)
46
+
47
+ // 密码重试次数太多已经自动重制卡片
48
+ class UpperErrorAutoResetException(message: String? = null) : NFCExceptions(3006, message)
49
+
50
+ // 未知的命令执行失败
51
+ class ExecFailureException(message: String? = null) : NFCExceptions(4000, message)
52
+
53
+ // 已经备份过内容
54
+ class InitializedException(message: String? = null) : NFCExceptions(4001, message)
55
+
56
+ // 没有备份过内容
57
+ class NotInitializedException(message: String? = null) : NFCExceptions(4002, message)
58
+ }
@@ -0,0 +1,142 @@
1
+ package so.onekey.app.wallet.lite.nfc
2
+
3
+ import android.app.Activity
4
+ import android.app.PendingIntent
5
+ import android.content.Context
6
+ import android.content.Intent
7
+ import android.content.IntentFilter
8
+ import android.nfc.NfcAdapter
9
+ import android.nfc.tech.*
10
+ import android.os.Build
11
+ import android.provider.Settings
12
+ import so.onekey.app.wallet.lite.utils.MiUtil
13
+
14
+ object NfcUtils {
15
+
16
+ @JvmField
17
+ var mNfcAdapter: NfcAdapter? = null
18
+
19
+ @JvmField
20
+ var mIntentFilter: Array<IntentFilter>? = null
21
+
22
+ @JvmField
23
+ var mPendingIntent: PendingIntent? = null
24
+
25
+ @JvmField
26
+ var mTechList: Array<Array<String>>? = null
27
+
28
+ private fun getPendingIntent(activity: Activity): PendingIntent? {
29
+ val intent = Intent(activity, activity.javaClass)
30
+ intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP)
31
+ var flag = 0
32
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
33
+ flag = PendingIntent.FLAG_MUTABLE
34
+ } else {
35
+ flag = PendingIntent.FLAG_UPDATE_CURRENT
36
+ }
37
+ return PendingIntent.getActivity(activity, 0, intent, flag)
38
+ }
39
+
40
+ private fun getIntentFilters(): Array<IntentFilter> {
41
+ return arrayOf(
42
+ IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED, "*/*"),
43
+ )
44
+ }
45
+
46
+ private fun getTechLists(): Array<Array<String>> {
47
+ return arrayOf(
48
+ arrayOf(NfcA::class.java.name),
49
+ arrayOf(IsoDep::class.java.name)
50
+ )
51
+ }
52
+
53
+ @JvmStatic
54
+ fun init(activity: Activity): NfcAdapter? {
55
+ mNfcAdapter = NfcAdapter.getDefaultAdapter(activity)
56
+ mTechList = getTechLists()
57
+ mPendingIntent = getPendingIntent(activity)
58
+ mIntentFilter = getIntentFilters()
59
+ return mNfcAdapter
60
+ }
61
+
62
+ /**
63
+ * 判断手机是否具备NFC功能.
64
+ *
65
+ * @param context [Context]
66
+ * @return `true`: 具备 `false`: 不具备
67
+ */
68
+ fun isNfcExits(context: Context): Boolean {
69
+ val nfcAdapter = NfcAdapter.getDefaultAdapter(context)
70
+ return nfcAdapter != null
71
+ }
72
+
73
+ /**
74
+ * 判断手机NFC是否开启.
75
+ *
76
+ * OPPO A37m 发现必须同时开启NFC以及Android Beam才可以使用
77
+ * 20180108 发现OPPO单独打开NFC即可读取标签,不清楚是否是系统更新
78
+ *
79
+ * @param context [Context]
80
+ * @return `true`: 已开启 `false`: 未开启
81
+ */
82
+ fun isNfcEnable(context: Context): Boolean {
83
+ val nfcAdapter = NfcAdapter.getDefaultAdapter(context)
84
+ return nfcAdapter != null && nfcAdapter.isEnabled
85
+ }
86
+
87
+ /**
88
+ * 判断手机是否具备Android Beam.
89
+ *
90
+ * @param context [Context]
91
+ * @return `true`:具备 `false`:不具备
92
+ */
93
+ fun isAndroidBeamExits(context: Context): Boolean {
94
+ return Build.VERSION.SDK_INT < Build.VERSION_CODES.Q && isNfcExits(context)
95
+ }
96
+
97
+ /**
98
+ * 跳转至系统NFC设置界面.
99
+ *
100
+ * @param context [Context]
101
+ * @return `true` 跳转成功 <br></br> `false` 跳转失败
102
+ */
103
+ fun intentToNfcSetting(context: Context): Boolean {
104
+ if (isNfcExits(context)) {
105
+ return toIntent(context, Settings.ACTION_NFC_SETTINGS)
106
+ }
107
+ return false
108
+
109
+ }
110
+
111
+ /**
112
+ * 跳转至系统NFC Android Beam设置界面,同页面基本都有NFC开关.
113
+ *
114
+ * @param context [Context]
115
+ * @return `true` 跳转成功 <br></br> `false` 跳转失败
116
+ */
117
+ fun intentToNfcShare(context: Context): Boolean {
118
+ return if (isAndroidBeamExits(context)) {
119
+ toIntent(context, Settings.ACTION_NFCSHARING_SETTINGS)
120
+ } else false
121
+ }
122
+
123
+ /**
124
+ * 跳转方法.
125
+ *
126
+ * @param context [Context]
127
+ * @param action 意图
128
+ * @return 是否跳转成功 `true ` 成功<br></br>`false`失败
129
+ */
130
+ private fun toIntent(context: Context, action: String): Boolean {
131
+ try {
132
+ val intent = Intent(action)
133
+ context.startActivity(intent)
134
+ } catch (ex: Exception) {
135
+ ex.printStackTrace()
136
+ return false
137
+ }
138
+
139
+ return true
140
+ }
141
+
142
+ }