@onekeyfe/react-native-lite-card 1.0.0

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 (91) hide show
  1. package/LICENSE +20 -0
  2. package/android/build.gradle +102 -0
  3. package/android/gradle.properties +5 -0
  4. package/android/src/main/AndroidManifest.xml +3 -0
  5. package/android/src/main/assets/config/command.json +205 -0
  6. package/android/src/main/cpp/CMakeLists.txt +15 -0
  7. package/android/src/main/cpp/validation.c +227 -0
  8. package/android/src/main/cpp/validation.h +19 -0
  9. package/android/src/main/java/so/onekey/app/wallet/LoggerManager.kt +35 -0
  10. package/android/src/main/java/so/onekey/app/wallet/OKLiteManager.kt +399 -0
  11. package/android/src/main/java/so/onekey/app/wallet/OKLitePackage.kt +16 -0
  12. package/android/src/main/java/so/onekey/app/wallet/keys/KeysNativeProvider.kt +13 -0
  13. package/android/src/main/java/so/onekey/app/wallet/nfc/Exceptions.kt +58 -0
  14. package/android/src/main/java/so/onekey/app/wallet/nfc/NfcUtils.kt +151 -0
  15. package/android/src/main/java/so/onekey/app/wallet/nfc/broadcast/NfcStatusChangeBroadcastReceiver.kt +56 -0
  16. package/android/src/main/java/so/onekey/app/wallet/nfc/gpchannel/GPChannelNatives.kt +32 -0
  17. package/android/src/main/java/so/onekey/app/wallet/onekeyLite/NfcConstant.kt +38 -0
  18. package/android/src/main/java/so/onekey/app/wallet/onekeyLite/OnekeyLiteCard.kt +241 -0
  19. package/android/src/main/java/so/onekey/app/wallet/onekeyLite/entitys/APDUParam.kt +17 -0
  20. package/android/src/main/java/so/onekey/app/wallet/onekeyLite/entitys/CardInfo.java +84 -0
  21. package/android/src/main/java/so/onekey/app/wallet/onekeyLite/entitys/CardResponse.java +37 -0
  22. package/android/src/main/java/so/onekey/app/wallet/onekeyLite/entitys/CardState.kt +10 -0
  23. package/android/src/main/java/so/onekey/app/wallet/onekeyLite/entitys/ParsedCertInfo.java +39 -0
  24. package/android/src/main/java/so/onekey/app/wallet/onekeyLite/entitys/SecureChanelParam.java +113 -0
  25. package/android/src/main/java/so/onekey/app/wallet/onekeyLite/entitys/SendResponse.kt +26 -0
  26. package/android/src/main/java/so/onekey/app/wallet/onekeyLite/nfc/CommandGenerator.kt +178 -0
  27. package/android/src/main/java/so/onekey/app/wallet/onekeyLite/nfc/Connection.kt +430 -0
  28. package/android/src/main/java/so/onekey/app/wallet/onekeyLite/nfc/GPCAPDUGenerator.kt +56 -0
  29. package/android/src/main/java/so/onekey/app/wallet/utils/EventUtils.kt +14 -0
  30. package/android/src/main/java/so/onekey/app/wallet/utils/GpsUtil.kt +38 -0
  31. package/android/src/main/java/so/onekey/app/wallet/utils/HexUtils.java +93 -0
  32. package/android/src/main/java/so/onekey/app/wallet/utils/LogUtil.kt +11 -0
  33. package/android/src/main/java/so/onekey/app/wallet/utils/MiUtil.kt +93 -0
  34. package/android/src/main/java/so/onekey/app/wallet/utils/NfcPermissionUtils.kt +24 -0
  35. package/android/src/main/java/so/onekey/app/wallet/utils/Utils.java +433 -0
  36. package/android/src/main/jniLibs/arm64-v8a/libgpchannelNDK.so +0 -0
  37. package/android/src/main/jniLibs/armeabi-v7a/libgpchannelNDK.so +0 -0
  38. package/ios/Classes/OKLiteCommand/OKLiteCommandModal.h +39 -0
  39. package/ios/Classes/OKLiteCommand/OKLiteCommandModal.m +143 -0
  40. package/ios/Classes/OKLiteCommand/OKLiteCommandTool.h +28 -0
  41. package/ios/Classes/OKLiteCommand/OKLiteCommandTool.m +53 -0
  42. package/ios/Classes/OKLiteManager.h +17 -0
  43. package/ios/Classes/OKLiteManager.m +222 -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 +602 -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.framework/GPChannelSDKCore +0 -0
  69. package/ios/GPChannelSDKCore.framework/Headers/GPChannelSDK.h +315 -0
  70. package/ios/GPChannelSDKCore.framework/Headers/GPChannelSDKCore.h +19 -0
  71. package/ios/GPChannelSDKCore.framework/Info.plist +0 -0
  72. package/ios/GPChannelSDKCore.framework/Modules/module.modulemap +7 -0
  73. package/ios/GPChannelSDKCore.framework/_CodeSignature/CodeResources +147 -0
  74. package/keys/keys.c +51 -0
  75. package/keys/keys.h +4 -0
  76. package/lib/commonjs/index.js +114 -0
  77. package/lib/commonjs/index.js.map +1 -0
  78. package/lib/commonjs/types.js +27 -0
  79. package/lib/commonjs/types.js.map +1 -0
  80. package/lib/module/index.js +108 -0
  81. package/lib/module/index.js.map +1 -0
  82. package/lib/module/types.js +21 -0
  83. package/lib/module/types.js.map +1 -0
  84. package/lib/typescript/src/index.d.ts +35 -0
  85. package/lib/typescript/src/index.d.ts.map +1 -0
  86. package/lib/typescript/src/types.d.ts +31 -0
  87. package/lib/typescript/src/types.d.ts.map +1 -0
  88. package/package.json +166 -0
  89. package/react-native-lite-card.podspec +42 -0
  90. package/src/index.ts +154 -0
  91. package/src/types.ts +37 -0
@@ -0,0 +1,399 @@
1
+ package so.onekey.app.wallet
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 com.facebook.react.bridge.*
11
+ import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter
12
+ import kotlinx.coroutines.*
13
+ import kotlinx.coroutines.channels.Channel
14
+ import so.onekey.app.wallet.nfc.NFCExceptions
15
+ import so.onekey.app.wallet.nfc.NfcUtils
16
+ import so.onekey.app.wallet.nfc.broadcast.NfcStatusChangeBroadcastReceiver
17
+ import so.onekey.app.wallet.onekeyLite.OneKeyLiteCard
18
+ import so.onekey.app.wallet.onekeyLite.entitys.CardState
19
+ import so.onekey.app.wallet.utils.NfcPermissionUtils
20
+ import so.onekey.app.wallet.utils.Utils
21
+ import java.util.concurrent.Executors
22
+ import java.util.concurrent.atomic.AtomicInteger
23
+
24
+
25
+ public fun NFCScope(): CoroutineScope = CoroutineScope(SupervisorJob() + NFCDispatcher)
26
+ private val NFCDispatcher = Executors.newFixedThreadPool(1).asCoroutineDispatcher()
27
+
28
+ class OKLiteManager(private val context: ReactApplicationContext) :
29
+ ReactContextBaseJavaModule(context), LifecycleEventListener, CoroutineScope by NFCScope() {
30
+ companion object {
31
+ private val TAG = OKLiteManager::class.simpleName
32
+
33
+ // NFC UI 事件
34
+ private const val NFC_UI_EVENT = "nfc_ui_event"
35
+
36
+ // NFC 主动连接
37
+ private const val NFC_ACTIVE_CONNECTION = "nfc_active_connection"
38
+ }
39
+
40
+ @IntDef(NFCState.Dead, NFCState.Started)
41
+ annotation class NFCState {
42
+ companion object {
43
+ const val Dead = -1
44
+ const val Started = 0
45
+ }
46
+ }
47
+
48
+ private val mNFCConnectedChannel = Channel<IsoDep?>(1)
49
+ private val mNFCState = AtomicInteger(NFCState.Dead)
50
+ private val mShowDialogNumber = AtomicInteger(0)
51
+ private var mCurrentCardState: CardState? = null
52
+
53
+ private val mActivityEventListener = object : BaseActivityEventListener() {
54
+ override fun onNewIntent(intent: Intent?) {
55
+ super.onNewIntent(intent)
56
+ val action = intent?.action
57
+ if ((action == NfcAdapter.ACTION_NDEF_DISCOVERED)
58
+ || action == NfcAdapter.ACTION_TECH_DISCOVERED
59
+ || action == NfcAdapter.ACTION_TAG_DISCOVERED
60
+ ) {
61
+ val tags = intent.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG)
62
+ val isoDep: IsoDep? = IsoDep.get(tags)
63
+ if (isoDep == null) {
64
+ // 未知设备
65
+ val dataMap = Arguments.createMap().apply {
66
+ putString("type", "unknown")
67
+ }
68
+ sendEvent(context, NFC_ACTIVE_CONNECTION, dataMap)
69
+ Log.d(TAG, "Unknown device")
70
+ return
71
+ }
72
+
73
+ Log.d(TAG, isoDep.toString())
74
+ launch(Dispatchers.IO) {
75
+ mNFCConnectedChannel.trySend(isoDep)
76
+ try {
77
+ // 处理主动触发 NFC
78
+ delay(100)
79
+ if (!mNFCConnectedChannel.isEmpty) {
80
+ Log.e(TAG, "There is no way to use NFC")
81
+ mNFCConnectedChannel.receive()
82
+ val startRequest = OneKeyLiteCard.initRequest(isoDep)
83
+ val dataMap = Arguments.createMap().apply {
84
+ putInt("code", -1)
85
+ putString("type", "OneKey_Lite")
86
+ putString("serialNum", startRequest.serialNum)
87
+ putBoolean("isNewCard", startRequest.isNewCard)
88
+ putBoolean("hasBackup", startRequest.hasBackup)
89
+ }
90
+ sendEvent(context, NFC_ACTIVE_CONNECTION, dataMap)
91
+ }
92
+ } catch (e: Exception) {
93
+ e.printStackTrace()
94
+ // 未知设备或连接失败
95
+ val dataMap = Arguments.createMap().apply {
96
+ putInt("code", -1)
97
+ putString("type", "unknown")
98
+ }
99
+ sendEvent(context, NFC_ACTIVE_CONNECTION, dataMap)
100
+ }
101
+ }
102
+ }
103
+ }
104
+ }
105
+
106
+ init {
107
+ context.addLifecycleEventListener(this)
108
+ context.addActivityEventListener(mActivityEventListener)
109
+ }
110
+
111
+ override fun getName() = "OKLiteManager"
112
+
113
+ override fun initialize() {
114
+ super.initialize()
115
+ Utils.init(context)
116
+ Utils.getActivityLifecycle()
117
+ Utils.getTopActivity()?.registerReceiver(
118
+ mNfcStateBroadcastReceiver,
119
+ NfcStatusChangeBroadcastReceiver.nfcBroadcastReceiverIntentFilter
120
+ )
121
+ Utils.getTopActivity()?.let {
122
+ launch(Dispatchers.IO) {
123
+ OneKeyLiteCard.startNfc(it as FragmentActivity) {}
124
+ }
125
+ }
126
+
127
+ }
128
+
129
+ override fun onHostResume() {
130
+ Utils.getTopActivity()?.let {
131
+ launch(Dispatchers.IO) {
132
+ if (it !is FragmentActivity) return@launch
133
+ try {
134
+ OneKeyLiteCard.startNfc(it) {
135
+ mNFCState.set(NFCState.Started)
136
+
137
+ Log.d(TAG, "NFC starting success")
138
+ }
139
+ } catch (e: Exception) {
140
+ Log.e(TAG, "startNfc failed", e)
141
+ }
142
+ }
143
+ }
144
+ }
145
+
146
+ override fun onHostPause() {
147
+ Utils.getTopActivity()?.let {
148
+ launch(Dispatchers.IO) {
149
+ try {
150
+ OneKeyLiteCard.stopNfc(it as FragmentActivity)
151
+ mNFCState.set(NFCState.Dead)
152
+ Log.d(TAG, "NFC 已关闭")
153
+ } catch (e: Exception) {
154
+ Log.e(TAG, "stopNfc failed", e)
155
+ }
156
+ }
157
+ }
158
+ }
159
+
160
+ override fun onHostDestroy() {
161
+ try {
162
+ Utils.getTopActivity()?.unregisterReceiver(mNfcStateBroadcastReceiver)
163
+ } catch (ignore: Exception) {
164
+ }
165
+ }
166
+
167
+ private val mNfcStateBroadcastReceiver by lazy {
168
+ object : NfcStatusChangeBroadcastReceiver() {
169
+ override fun onCardPayMode() {
170
+ super.onCardPayMode()
171
+ }
172
+
173
+ override fun onNfcOff() {
174
+ super.onNfcOff()
175
+ }
176
+
177
+ override fun onNfcOn() {
178
+ super.onNfcOn()
179
+ Utils.getTopActivity()?.let {
180
+ launch(Dispatchers.IO) {
181
+ OneKeyLiteCard.startNfc(it as FragmentActivity) {}
182
+ }
183
+ }
184
+ }
185
+
186
+ override fun onNfcTurningOff() {
187
+ super.onNfcTurningOff()
188
+ }
189
+
190
+ override fun onNfcTurningOn() {
191
+ super.onNfcTurningOn()
192
+ }
193
+ }
194
+ }
195
+
196
+ private fun sendEvent(
197
+ reactContext: ReactContext,
198
+ eventName: String,
199
+ params: WritableMap
200
+ ) {
201
+ reactContext
202
+ .getJSModule(RCTDeviceEventEmitter::class.java)
203
+ .emit(eventName, params)
204
+ }
205
+
206
+ @Throws(NFCExceptions::class)
207
+ private suspend fun acquireDevice(): IsoDep? {
208
+ // 展示连接 ui
209
+ sendEvent(context, NFC_UI_EVENT, Arguments.createMap().also {
210
+ it.putInt("code", 1)
211
+ it.putString("message", "show_connect_ui")
212
+ })
213
+ mShowDialogNumber.incrementAndGet()
214
+ if (!mNFCConnectedChannel.isEmpty) {
215
+ mNFCConnectedChannel.tryReceive()
216
+ }
217
+ val receiveIsoDep = mNFCConnectedChannel.receive()
218
+ mCurrentCardState = null
219
+ if (receiveIsoDep == null) {
220
+ // 取消连接
221
+ releaseDevice()
222
+ } else {
223
+ val initChannelRequest = OneKeyLiteCard.initRequest(receiveIsoDep)
224
+
225
+ mCurrentCardState = initChannelRequest
226
+
227
+ // 展示连接结束 ui
228
+ sendEvent(context, NFC_UI_EVENT, Arguments.createMap().also {
229
+ it.putInt("code", 2)
230
+ it.putString("message", "connected")
231
+ })
232
+ }
233
+ return receiveIsoDep
234
+ }
235
+
236
+ private fun releaseDevice() {
237
+ if (mShowDialogNumber.get() <= 0) return
238
+
239
+ mCurrentCardState = null
240
+ val decrementAndGet = mShowDialogNumber.decrementAndGet()
241
+
242
+ // 关闭连接结束 ui
243
+ sendEvent(context, NFC_UI_EVENT, Arguments.createMap().also {
244
+ it.putInt("code", 3)
245
+ it.putString("message", "close_connect_ui")
246
+ })
247
+
248
+ // 还有需要处理的 NFC 事件
249
+ if (decrementAndGet > 0) {
250
+ // 展示连接 ui
251
+ sendEvent(context, NFC_UI_EVENT, Arguments.createMap().also {
252
+ it.putInt("code", 1)
253
+ it.putString("message", "show_connect_ui")
254
+ })
255
+ }
256
+ }
257
+
258
+ private suspend fun <T> handleOperation(
259
+ callback: Callback,
260
+ execute: (isoDep: IsoDep) -> T
261
+ ) {
262
+ val topActivity = Utils.getTopActivity()
263
+ if (topActivity == null) {
264
+ callback.invoke(NFCExceptions.InitializedException().createArguments(), null, null)
265
+ return
266
+ }
267
+ val isNfcExists = NfcUtils.isNfcExits(topActivity)
268
+ if (!isNfcExists) {
269
+ // 没有 NFC 设备
270
+ Log.d(TAG, "NFC device not found")
271
+ callback.invoke(NFCExceptions.NotExistsNFC().createArguments(), null, null)
272
+ return
273
+ }
274
+
275
+ val isNfcEnable = NfcUtils.isNfcEnable(topActivity)
276
+ if (!isNfcEnable) {
277
+ // 没有打开 NFC 开关
278
+ Log.d(TAG, "NFC device not enable")
279
+ callback.invoke(NFCExceptions.NotEnableNFC().createArguments(), null, null)
280
+ return
281
+ }
282
+
283
+ NfcPermissionUtils.checkPermission(topActivity) {
284
+ try {
285
+ Log.d(TAG, "NFC permission check success")
286
+ val isoDep = acquireDevice() ?: return
287
+ val executeResult = execute(isoDep)
288
+ callback.invoke(null, executeResult, mCurrentCardState.createArguments())
289
+ } catch (e: NFCExceptions) {
290
+ Log.e(TAG, "NFC device execute error", e)
291
+ callback.invoke(e.createArguments(), null, mCurrentCardState.createArguments())
292
+ } finally {
293
+ releaseDevice()
294
+ }
295
+ return
296
+ }
297
+ // 没有 NFC 使用权限
298
+ Log.d(TAG, "NFC device not permission")
299
+ callback.invoke(NFCExceptions.NotNFCPermission().createArguments(), null, null)
300
+ }
301
+
302
+ private fun CardState?.createArguments(): WritableMap {
303
+ val map = Arguments.createMap()
304
+ if (this == null) return map
305
+ map.putBoolean("hasBackup", this.hasBackup)
306
+ map.putBoolean("isNewCard", this.isNewCard)
307
+ map.putString("serialNum", this.serialNum)
308
+ map.putInt("pinRetryCount", this.pinRetryCount)
309
+ return map
310
+ }
311
+
312
+ private fun NFCExceptions?.createArguments(): WritableMap {
313
+ val map = Arguments.createMap()
314
+ if (this == null) return map
315
+ map.putInt("code", this.code)
316
+ map.putString("message", this.message)
317
+ return map
318
+ }
319
+
320
+ @ReactMethod
321
+ fun cancel() {
322
+ if (mNFCConnectedChannel.isEmpty) {
323
+ mNFCConnectedChannel.trySend(null)
324
+ }
325
+ }
326
+
327
+ @ReactMethod
328
+ fun getCardName(callback: Callback) = launch {
329
+ Log.d(TAG, "getCardName")
330
+ handleOperation(callback) { isoDep ->
331
+ Log.e(TAG, "getCardName Obtain the device")
332
+ val cardName = OneKeyLiteCard.getCardName(isoDep)
333
+ Log.e(TAG, "getCardName result $cardName")
334
+ cardName
335
+ }
336
+ }
337
+
338
+ @ReactMethod
339
+ fun getLiteInfo(callback: Callback) = launch {
340
+ Log.d(TAG, "getLiteInfo")
341
+ handleOperation(callback) { isoDep ->
342
+ Log.e(TAG, "getLiteInfo Obtain the device")
343
+ val cardInfo = OneKeyLiteCard.getCardInfo(isoDep)
344
+ Log.e(TAG, "getLiteInfo result $cardInfo")
345
+ cardInfo.createArguments()
346
+ }
347
+ }
348
+
349
+ @ReactMethod
350
+ fun setMnemonic(mnemonic: String, pwd: String, overwrite: Boolean, callback: Callback) =
351
+ launch {
352
+ handleOperation(callback) { isoDep ->
353
+ Log.e(TAG, "setMnemonic Obtain the device")
354
+ val isSuccess =
355
+ OneKeyLiteCard.setMnemonic(mCurrentCardState, isoDep, mnemonic, pwd, overwrite)
356
+ if (!isSuccess) throw NFCExceptions.ExecFailureException()
357
+ Log.e(TAG, "setMnemonic result success")
358
+ true
359
+ }
360
+ }
361
+
362
+ @ReactMethod
363
+ fun getMnemonicWithPin(pwd: String, callback: Callback) = launch {
364
+ Log.d(TAG, "getMnemonicWithPin")
365
+ handleOperation(callback) { isoDep ->
366
+ Log.e(TAG, "getMnemonicWithPin Obtain the device")
367
+ OneKeyLiteCard.getMnemonicWithPin(mCurrentCardState, isoDep, pwd)
368
+ }
369
+ }
370
+
371
+ @ReactMethod
372
+ fun changePin(oldPwd: String, newPwd: String, callback: Callback) = launch {
373
+ Log.d(TAG, "changePin")
374
+ handleOperation(callback) { isoDep ->
375
+ Log.e(TAG, "changePin Obtain the device")
376
+ OneKeyLiteCard.changPin(mCurrentCardState, isoDep, oldPwd, newPwd)
377
+ }
378
+ }
379
+
380
+ @ReactMethod
381
+ fun reset(callback: Callback) = launch {
382
+ Log.d(TAG, "reset")
383
+ handleOperation(callback) { isoDep ->
384
+ Log.e(TAG, "reset Obtain the device")
385
+ val isSuccess = OneKeyLiteCard.reset(isoDep)
386
+ if (!isSuccess) throw NFCExceptions.ExecFailureException()
387
+ Log.e(TAG, "reset result success")
388
+ true
389
+ }
390
+ }
391
+
392
+ @ReactMethod
393
+ fun intoSetting() = launch {
394
+ Log.d(TAG, "intoSetting")
395
+ Utils.getTopActivity()?.let {
396
+ NfcUtils.intentToNfcSetting(it)
397
+ }
398
+ }
399
+ }
@@ -0,0 +1,16 @@
1
+ package so.onekey.app.wallet
2
+
3
+ import com.facebook.react.ReactPackage
4
+ import com.facebook.react.bridge.NativeModule
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.uimanager.ViewManager
7
+
8
+ class OKLitePackage : ReactPackage {
9
+ override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> =
10
+ listOf<NativeModule>(
11
+ OKLiteManager(reactContext),
12
+ )
13
+
14
+ override fun createViewManagers(reactContext: ReactApplicationContext) =
15
+ emptyList<ViewManager<*, *>>()
16
+ }
@@ -0,0 +1,13 @@
1
+ package so.onekey.app.wallet.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.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,151 @@
1
+ package so.onekey.app.wallet.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.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 ("Smartisan".equals(Build.MANUFACTURER, true)) {
105
+ if (intentToNfcShare(context)) {
106
+ return true
107
+ }
108
+ }
109
+ if ("xiaomi".equals(Build.MANUFACTURER, true)) {
110
+ MiUtil.intentToAppSetting(context)
111
+ return true
112
+ }
113
+ if (isNfcExits(context)) {
114
+ return toIntent(context, Settings.ACTION_NFC_SETTINGS)
115
+ }
116
+ return false
117
+
118
+ }
119
+
120
+ /**
121
+ * 跳转至系统NFC Android Beam设置界面,同页面基本都有NFC开关.
122
+ *
123
+ * @param context [Context]
124
+ * @return `true` 跳转成功 <br></br> `false` 跳转失败
125
+ */
126
+ fun intentToNfcShare(context: Context): Boolean {
127
+ return if (isAndroidBeamExits(context)) {
128
+ toIntent(context, Settings.ACTION_NFCSHARING_SETTINGS)
129
+ } else false
130
+ }
131
+
132
+ /**
133
+ * 跳转方法.
134
+ *
135
+ * @param context [Context]
136
+ * @param action 意图
137
+ * @return 是否跳转成功 `true ` 成功<br></br>`false`失败
138
+ */
139
+ private fun toIntent(context: Context, action: String): Boolean {
140
+ try {
141
+ val intent = Intent(action)
142
+ context.startActivity(intent)
143
+ } catch (ex: Exception) {
144
+ ex.printStackTrace()
145
+ return false
146
+ }
147
+
148
+ return true
149
+ }
150
+
151
+ }
@@ -0,0 +1,56 @@
1
+ package so.onekey.app.wallet.nfc.broadcast
2
+
3
+ import android.content.BroadcastReceiver
4
+ import android.content.Context
5
+ import android.content.Intent
6
+ import android.content.IntentFilter
7
+ import android.nfc.NfcAdapter
8
+ import android.util.Log
9
+
10
+ open class NfcStatusChangeBroadcastReceiver : BroadcastReceiver() {
11
+
12
+ override fun onReceive(context: Context, intent: Intent) {
13
+ val action = intent.action
14
+ if (NfcAdapter.ACTION_ADAPTER_STATE_CHANGED == action) {
15
+ val state =
16
+ intent.getIntExtra(NfcAdapter.EXTRA_ADAPTER_STATE, NfcAdapter.STATE_OFF)
17
+
18
+ Log.e(TAG, "nfc state broadcast receiver, state is $state")
19
+ when (state) {
20
+ NfcAdapter.STATE_OFF -> onNfcOff()
21
+ NfcAdapter.STATE_ON -> onNfcOn()
22
+ NfcAdapter.STATE_TURNING_OFF -> onNfcTurningOff()
23
+ NfcAdapter.STATE_TURNING_ON -> onNfcTurningOn()
24
+ 5 -> onCardPayMode() //samsumg return 5 that minds card pay mode
25
+ else -> onNfcOff()
26
+ }
27
+ }
28
+ }
29
+
30
+ protected open fun onNfcTurningOn() {
31
+
32
+ }
33
+
34
+ protected open fun onNfcTurningOff() {
35
+
36
+ }
37
+
38
+ protected open fun onNfcOn() {
39
+
40
+ }
41
+
42
+ protected open fun onNfcOff() {
43
+
44
+ }
45
+
46
+ protected open fun onCardPayMode() {
47
+
48
+ }
49
+
50
+ companion object {
51
+ val TAG: String = NfcStatusChangeBroadcastReceiver::class.java.simpleName
52
+
53
+ val nfcBroadcastReceiverIntentFilter: IntentFilter
54
+ get() = IntentFilter("android.nfc.action.ADAPTER_STATE_CHANGED")
55
+ }
56
+ }