Skip to content

Commit ec93ad5

Browse files
[SELF-654] feat: add native modules (#919)
* feat: add ios native modules * fix: extractMRZ * Add android OCR native module * wire native mrz module with adapter * wire Native modules and fix tests * fixes * fix license header logic * fix tests * fix types * fix: ci test * fix: android build ci * fix: ios build CI * add podfile.lock * add yarn.lock * update lock files * add yarn.lock * add license * order methods * update lock * pipeline fixes * prettier * update lock file * fix native modules on external apps * bundle @selfxyz/common into mobile-sdk-alpha * chore: address yarn lock issues (#1004) * address yarn lock issues * fix postinstall * update lock * fix build issues * fix pipeline issue * fix ci * fix bad merge * fix android ci * fix ci errors * fix mobile sdk ci. stop gap fix for now until we create a package * tweaks * retry aapt2 approach * use ^0.8.4 instead of ^0.8.0 due to the use of custom errors * workflow fixes * fix file * update * fix ci * test ci fix * fix test --------- Co-authored-by: Justin Hernandez <[email protected]> Co-authored-by: Justin Hernandez <[email protected]>
1 parent 145cc89 commit ec93ad5

File tree

96 files changed

+8582
-2507
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+8582
-2507
lines changed

.github/workflows/mobile-ci.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -434,8 +434,6 @@ jobs:
434434
common/dist
435435
packages/mobile-sdk-alpha/dist
436436
key: built-deps-${{ env.GH_CACHE_VERSION }}-${{ env.NODE_VERSION_SANITIZED }}-${{ hashFiles('common/**/*', 'packages/mobile-sdk-alpha/**/*', '!common/dist/**', '!packages/mobile-sdk-alpha/dist/**') }}
437-
- name: Build Android
438-
run: |
439-
cd android
440-
./gradlew assembleDebug
437+
- name: Build Android (with AAPT2 symlink fix)
438+
run: yarn android:ci
441439
working-directory: ./app

.gitignore

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,7 @@ output/*
1111
*.tsbuildinfo
1212
.yarnrc.yml
1313

14-
# PR Action Items - prevent accidental commits
15-
PR-*-ACTION*.md
14+
# CI-generated tarballs (don't commit these!)
15+
mobile-sdk-alpha-ci.tgz
16+
**/mobile-sdk-alpha-*.tgz
17+
/tmp/mobile-sdk-alpha*.tgz

app/Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,4 +315,4 @@ RUBY VERSION
315315
ruby 3.2.7p253
316316

317317
BUNDLED WITH
318-
2.6.9
318+
2.4.19

app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/ui/fragments/CameraFragment.kt

Lines changed: 60 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -108,39 +108,6 @@ abstract class CameraFragment : androidx.fragment.app.Fragment(), ActivityCompat
108108

109109
}
110110

111-
private fun setZoomProperties(zoom: Zoom.VariableZoom) {
112-
cameraZoom = zoom
113-
setZoomProgress(zoomProgress, cameraZoom!!)
114-
115-
}
116-
117-
118-
private fun setZoomProgress(progress: Int, zoom: Zoom.VariableZoom) {
119-
zoomProgress = progress
120-
fotoapparat?.setZoom(progress.toFloat() / zoom.maxZoom)
121-
}
122-
123-
124-
/** Determine the space between the first two fingers */
125-
private fun getFingerSpacing(event: MotionEvent): Float {
126-
// ...
127-
val x = event.getX(0) - event.getX(1)
128-
val y = event.getY(0) - event.getY(1)
129-
130-
return Math.sqrt((x * x + y * y).toDouble()).toFloat()
131-
}
132-
133-
134-
protected fun setFlash(isEnable: Boolean) {
135-
configuration = configuration.copy(flashMode = if (isEnable) torch() else off())
136-
fotoapparat?.updateConfiguration(configuration)
137-
}
138-
139-
protected fun setFocusMode(focusModeSelector: FocusModeSelector) {
140-
configuration = configuration.copy(focusMode = focusModeSelector)
141-
fotoapparat?.updateConfiguration(configuration)
142-
}
143-
144111
override fun onResume() {
145112
super.onResume()
146113

@@ -178,6 +145,37 @@ abstract class CameraFragment : androidx.fragment.app.Fragment(), ActivityCompat
178145

179146
}
180147

148+
protected fun setFlash(isEnable: Boolean) {
149+
configuration = configuration.copy(flashMode = if (isEnable) torch() else off())
150+
fotoapparat?.updateConfiguration(configuration)
151+
}
152+
153+
protected fun setFocusMode(focusModeSelector: FocusModeSelector) {
154+
configuration = configuration.copy(focusMode = focusModeSelector)
155+
fotoapparat?.updateConfiguration(configuration)
156+
}
157+
158+
private fun setZoomProperties(zoom: Zoom.VariableZoom) {
159+
cameraZoom = zoom
160+
setZoomProgress(zoomProgress, cameraZoom!!)
161+
162+
}
163+
164+
165+
private fun setZoomProgress(progress: Int, zoom: Zoom.VariableZoom) {
166+
zoomProgress = progress
167+
fotoapparat?.setZoom(progress.toFloat() / zoom.maxZoom)
168+
}
169+
170+
171+
/** Determine the space between the first two fingers */
172+
private fun getFingerSpacing(event: MotionEvent): Float {
173+
// ...
174+
val x = event.getX(0) - event.getX(1)
175+
val y = event.getY(0) - event.getY(1)
176+
177+
return Math.sqrt((x * x + y * y).toDouble()).toFloat()
178+
}
181179

182180
////////////////////////////////////////////////////////////////////////////////////////
183181
//
@@ -246,24 +244,6 @@ abstract class CameraFragment : androidx.fragment.app.Fragment(), ActivityCompat
246244
//
247245
////////////////////////////////////////////////////////////////////////////////////////
248246

249-
protected fun hasCameraPermission(): Boolean {
250-
return ContextCompat.checkSelfPermission(context!!, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED
251-
}
252-
253-
protected fun checkPermissions(permissions: ArrayList<String> = ArrayList()) {
254-
//request permission
255-
val hasPermissionCamera = ContextCompat.checkSelfPermission(context!!,
256-
Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
257-
if (!hasPermissionCamera && !permissions.contains(Manifest.permission.CAMERA)) {
258-
permissions.add(Manifest.permission.CAMERA)
259-
}
260-
261-
if (permissions.isNotEmpty()) {
262-
requestPermissions(permissions.toArray(arrayOf<String>()),
263-
REQUEST_PERMISSIONS)
264-
}
265-
}
266-
267247

268248
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
269249
grantResults: IntArray) {
@@ -310,23 +290,31 @@ abstract class CameraFragment : androidx.fragment.app.Fragment(), ActivityCompat
310290
.show(childFragmentManager, FRAGMENT_DIALOG)
311291
}
312292

293+
protected fun hasCameraPermission(): Boolean {
294+
return ContextCompat.checkSelfPermission(context!!, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED
295+
}
296+
297+
protected fun checkPermissions(permissions: ArrayList<String> = ArrayList()) {
298+
//request permission
299+
val hasPermissionCamera = ContextCompat.checkSelfPermission(context!!,
300+
Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
301+
if (!hasPermissionCamera && !permissions.contains(Manifest.permission.CAMERA)) {
302+
permissions.add(Manifest.permission.CAMERA)
303+
}
304+
305+
if (permissions.isNotEmpty()) {
306+
requestPermissions(permissions.toArray(arrayOf<String>()),
307+
REQUEST_PERMISSIONS)
308+
}
309+
}
310+
313311

314312
////////////////////////////////////////////////////////////////////////////////////////
315313
//
316314
// Dialogs UI
317315
//
318316
////////////////////////////////////////////////////////////////////////////////////////
319317

320-
/**
321-
* Shows a [Toast] on the UI thread.
322-
*
323-
* @param text The message to show
324-
*/
325-
private fun showToast(text: String) {
326-
val activity = activity
327-
activity?.runOnUiThread { Toast.makeText(activity, text, Toast.LENGTH_SHORT).show() }
328-
}
329-
330318
/**
331319
* Shows an error message dialog.
332320
*/
@@ -402,6 +390,16 @@ abstract class CameraFragment : androidx.fragment.app.Fragment(), ActivityCompat
402390
return 0
403391
}
404392

393+
/**
394+
* Shows a [Toast] on the UI thread.
395+
*
396+
* @param text The message to show
397+
*/
398+
private fun showToast(text: String) {
399+
val activity = activity
400+
activity?.runOnUiThread { Toast.makeText(activity, text, Toast.LENGTH_SHORT).show() }
401+
}
402+
405403

406404
companion object {
407405

@@ -415,4 +413,4 @@ abstract class CameraFragment : androidx.fragment.app.Fragment(), ActivityCompat
415413
private val FRAGMENT_DIALOG = TAG
416414

417415
}
418-
}
416+
}

app/android/app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ dependencies {
190190
exclude group: 'edu.ucar', module: 'jj2000'
191191
}
192192
implementation project(':passportreader')
193-
implementation 'org.jmrtd:jmrtd:0.7.18'
193+
implementation 'org.jmrtd:jmrtd:0.7.35'
194194

195195
implementation 'com.github.blikoon:QRCodeScanner:0.1.2'
196196

app/android/app/src/main/java/com/proofofpassportapp/MainActivity.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import com.facebook.react.ReactActivityDelegate
1212
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
1313
import com.facebook.react.defaults.DefaultReactActivityDelegate
1414
import io.tradle.nfc.RNPassportReaderModule
15+
import com.selfxyz.selfSDK.RNSelfPassportReaderModule
1516

1617
class MainActivity : ReactActivity() {
1718
/**

app/android/app/src/main/java/com/proofofpassportapp/MainApplication.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint
1515
import com.facebook.react.defaults.DefaultReactNativeHost
1616
import com.facebook.soloader.SoLoader
1717
import com.facebook.react.soloader.OpenSourceMergedSoMapping
18+
import com.selfxyz.selfSDK.RNSelfPassportReaderPackage
1819

1920
class MainApplication : Application(), ReactApplication {
2021

@@ -25,6 +26,7 @@ class MainApplication : Application(), ReactApplication {
2526
add(CameraActivityPackage())
2627
add(QRCodeScannerPackage())
2728
add(BackupPackage())
29+
// add(RNSelfPassportReaderPackage())
2830
}
2931

3032
override fun getJSMainModuleName(): String = "index"
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// SPDX-License-Identifier: BUSL-1.1; Copyright (c) 2025 Social Connect Labs, Inc.; Licensed under BUSL-1.1 (see LICENSE); Apache-2.0 from 2029-06-11
2+
3+
package com.proofofpassportapp
4+
5+
import com.facebook.react.bridge.ReactApplicationContext
6+
import com.facebook.react.bridge.ReactContextBaseJavaModule
7+
import com.facebook.react.bridge.WritableMap
8+
import com.facebook.react.bridge.Arguments
9+
import com.facebook.react.modules.core.DeviceEventManagerModule
10+
11+
class NativeLoggerBridgeModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
12+
13+
override fun getName(): String {
14+
return "NativeLoggerBridge"
15+
}
16+
17+
companion object {
18+
private fun sendLogEvent(context: ReactApplicationContext, level: String, category: String, message: String, data: Map<String, Any>? = null) {
19+
val params: WritableMap = Arguments.createMap().apply {
20+
putString("level", level)
21+
putString("category", category)
22+
putString("message", message)
23+
if (data != null && data.isNotEmpty()) {
24+
val dataMap = Arguments.createMap()
25+
data.forEach { (key, value) ->
26+
when (value) {
27+
is String -> dataMap.putString(key, value)
28+
is Int -> dataMap.putInt(key, value)
29+
is Double -> dataMap.putDouble(key, value)
30+
is Boolean -> dataMap.putBoolean(key, value)
31+
else -> dataMap.putString(key, value.toString())
32+
}
33+
}
34+
putMap("data", dataMap)
35+
}
36+
}
37+
38+
context
39+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
40+
.emit("logEvent", params)
41+
}
42+
43+
fun logDebug(context: ReactApplicationContext, category: String, message: String, data: Map<String, Any>? = null) {
44+
sendLogEvent(context, "debug", category, message, data)
45+
}
46+
47+
fun logInfo(context: ReactApplicationContext, category: String, message: String, data: Map<String, Any>? = null) {
48+
sendLogEvent(context, "info", category, message, data)
49+
}
50+
51+
fun logWarn(context: ReactApplicationContext, category: String, message: String, data: Map<String, Any>? = null) {
52+
sendLogEvent(context, "warn", category, message, data)
53+
}
54+
55+
fun logError(context: ReactApplicationContext, category: String, message: String, data: Map<String, Any>? = null) {
56+
sendLogEvent(context, "error", category, message, data)
57+
}
58+
}
59+
}

app/ios/Podfile.lock

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,10 @@ PODS:
173173
- Mixpanel-swift (5.0.0):
174174
- Mixpanel-swift/Complete (= 5.0.0)
175175
- Mixpanel-swift/Complete (5.0.0)
176+
- mobile-sdk-alpha (0.1.0):
177+
- NFCPassportReader
178+
- QKMRZParser
179+
- React-Core
176180
- nanopb (2.30910.0):
177181
- nanopb/decode (= 2.30910.0)
178182
- nanopb/encode (= 2.30910.0)
@@ -2115,6 +2119,7 @@ DEPENDENCIES:
21152119
- lottie-ios
21162120
- lottie-react-native (from `../../node_modules/lottie-react-native`)
21172121
- Mixpanel-swift (~> 5.0.0)
2122+
- "mobile-sdk-alpha (from `../../node_modules/@selfxyz/mobile-sdk-alpha`)"
21182123
- NFCPassportReader (from `https://github.com/seshanthS/NFCPassportReader`, commit `9eff7c4e3a9037fdc1e03301584e0d5dcf14d76b`)
21192124
- QKMRZScanner
21202125
- RCT-Folly (from `../../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
@@ -2247,6 +2252,8 @@ EXTERNAL SOURCES:
22472252
:tag: hermes-2024-11-12-RNv0.76.2-5b4aa20c719830dcf5684832b89a6edb95ac3d64
22482253
lottie-react-native:
22492254
:path: "../../node_modules/lottie-react-native"
2255+
mobile-sdk-alpha:
2256+
:path: "../../node_modules/@selfxyz/mobile-sdk-alpha"
22502257
NFCPassportReader:
22512258
:commit: 9eff7c4e3a9037fdc1e03301584e0d5dcf14d76b
22522259
:git: https://github.com/seshanthS/NFCPassportReader
@@ -2447,6 +2454,7 @@ SPEC CHECKSUMS:
24472454
lottie-ios: a881093fab623c467d3bce374367755c272bdd59
24482455
lottie-react-native: 7bb65bc88d3f9996ea2f646a96694285405df2f9
24492456
Mixpanel-swift: e9bef28a9648faff384d5ba6f48ecc2787eb24c0
2457+
mobile-sdk-alpha: 96949ad8c8b61a9fa6b918a4202f9cebb9c678cc
24502458
nanopb: 438bc412db1928dac798aa6fd75726007be04262
24512459
NFCPassportReader: 48873f856f91215dbfa1eaaec20eae639672862e
24522460
OpenSSL-Universal: 84efb8a29841f2764ac5403e0c4119a28b713346

app/jest.config.cjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module.exports = {
66
preset: 'react-native',
77
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
88
transformIgnorePatterns: [
9-
'node_modules/(?!(react-native|@react-native|@react-navigation|@react-native-community|@segment/analytics-react-native|@openpassport|react-native-keychain|react-native-check-version|react-native-nfc-manager|react-native-passport-reader|react-native-gesture-handler|uuid|@stablelib|@react-native-google-signin|react-native-cloud-storage|@react-native-clipboard|@react-native-firebase)/)',
9+
'node_modules/(?!(react-native|@react-native|@react-navigation|@react-native-community|@segment/analytics-react-native|@openpassport|react-native-keychain|react-native-check-version|react-native-nfc-manager|react-native-passport-reader|react-native-gesture-handler|uuid|@stablelib|@react-native-google-signin|react-native-cloud-storage|@react-native-clipboard|@react-native-firebase|@selfxyz)/)',
1010
],
1111
setupFiles: ['<rootDir>/jest.setup.js'],
1212
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.[jt]sx?$',

0 commit comments

Comments
 (0)