omnipay-reactnative-sdk 1.2.2-beta.4 → 1.2.2-beta.6

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 (135) hide show
  1. package/README.md +93 -43
  2. package/android/build.gradle +16 -15
  3. package/android/src/main/AndroidManifest.xml +1 -1
  4. package/android/src/main/java/com/omniretail/omnipay/OmnipayActivityPackage.java +2 -2
  5. package/android/src/main/java/com/omniretail/omnipay/OmnipayLivenessCameraView.java +153 -0
  6. package/android/src/main/java/com/omniretail/omnipay/OmnipayLivenessCameraViewManager.java +49 -0
  7. package/android/src/main/java/com/omniretail/omnipay/OmnipayLivenessModule.java +524 -0
  8. package/ios/OmnipayLivenessCameraView.h +15 -0
  9. package/ios/OmnipayLivenessCameraView.m +80 -0
  10. package/ios/OmnipayLivenessCameraViewManager.m +19 -0
  11. package/ios/OmnipayLivenessModule.h +38 -0
  12. package/ios/OmnipayLivenessModule.m +554 -0
  13. package/lib/commonjs/components/OmnipayProvider.js +2 -66
  14. package/lib/commonjs/components/OmnipayProvider.js.map +1 -1
  15. package/lib/commonjs/components/OmnipayView.js.map +1 -1
  16. package/lib/commonjs/components/biometrics/FaceVerification.js +252 -345
  17. package/lib/commonjs/components/biometrics/FaceVerification.js.map +1 -1
  18. package/lib/commonjs/components/biometrics/LivenessDetection.js +90 -198
  19. package/lib/commonjs/components/biometrics/LivenessDetection.js.map +1 -1
  20. package/lib/commonjs/components/biometrics/OmnipayLivenessCameraView.js +15 -0
  21. package/lib/commonjs/components/biometrics/OmnipayLivenessCameraView.js.map +1 -0
  22. package/lib/commonjs/components/biometrics/PermissionManager.js +279 -0
  23. package/lib/commonjs/components/biometrics/PermissionManager.js.map +1 -0
  24. package/lib/commonjs/components/biometrics/index.js +45 -0
  25. package/lib/commonjs/components/biometrics/index.js.map +1 -0
  26. package/lib/commonjs/components/biometrics/types.js +17 -0
  27. package/lib/commonjs/components/biometrics/types.js.map +1 -0
  28. package/lib/commonjs/components/views/BvnVerification.js.map +1 -1
  29. package/lib/commonjs/components/views/PaylaterAgreement.js.map +1 -1
  30. package/lib/commonjs/components/views/Registration.js.map +1 -1
  31. package/lib/commonjs/index.js +23 -18
  32. package/lib/commonjs/index.js.map +1 -1
  33. package/lib/module/components/OmnipayProvider.js +3 -67
  34. package/lib/module/components/OmnipayProvider.js.map +1 -1
  35. package/lib/module/components/OmnipayView.js.map +1 -1
  36. package/lib/module/components/biometrics/FaceVerification.js +254 -346
  37. package/lib/module/components/biometrics/FaceVerification.js.map +1 -1
  38. package/lib/module/components/biometrics/LivenessDetection.js +75 -197
  39. package/lib/module/components/biometrics/LivenessDetection.js.map +1 -1
  40. package/lib/module/components/biometrics/OmnipayLivenessCameraView.js +7 -0
  41. package/lib/module/components/biometrics/OmnipayLivenessCameraView.js.map +1 -0
  42. package/lib/module/components/biometrics/PermissionManager.js +272 -0
  43. package/lib/module/components/biometrics/PermissionManager.js.map +1 -0
  44. package/lib/module/components/biometrics/index.js +12 -0
  45. package/lib/module/components/biometrics/index.js.map +1 -0
  46. package/lib/module/components/biometrics/types.js +16 -0
  47. package/lib/module/components/biometrics/types.js.map +1 -0
  48. package/lib/module/components/views/BvnVerification.js.map +1 -1
  49. package/lib/module/components/views/PaylaterAgreement.js.map +1 -1
  50. package/lib/module/components/views/Registration.js.map +1 -1
  51. package/lib/module/index.js +5 -4
  52. package/lib/module/index.js.map +1 -1
  53. package/lib/typescript/{src/components → components}/OmnipayProvider.d.ts +1 -1
  54. package/lib/typescript/components/OmnipayProvider.d.ts.map +1 -0
  55. package/lib/typescript/{src/components → components}/OmnipayView.d.ts +21 -20
  56. package/lib/typescript/components/OmnipayView.d.ts.map +1 -0
  57. package/lib/typescript/components/biometrics/FaceVerification.d.ts +11 -0
  58. package/lib/typescript/components/biometrics/FaceVerification.d.ts.map +1 -0
  59. package/lib/typescript/components/biometrics/LivenessDetection.d.ts +33 -0
  60. package/lib/typescript/components/biometrics/LivenessDetection.d.ts.map +1 -0
  61. package/lib/typescript/components/biometrics/OmnipayLivenessCameraView.d.ts +18 -0
  62. package/lib/typescript/components/biometrics/OmnipayLivenessCameraView.d.ts.map +1 -0
  63. package/lib/typescript/components/biometrics/PermissionManager.d.ts +58 -0
  64. package/lib/typescript/components/biometrics/PermissionManager.d.ts.map +1 -0
  65. package/lib/typescript/components/biometrics/index.d.ts +5 -0
  66. package/lib/typescript/components/biometrics/index.d.ts.map +1 -0
  67. package/lib/typescript/components/biometrics/types.d.ts +73 -0
  68. package/lib/typescript/components/biometrics/types.d.ts.map +1 -0
  69. package/lib/typescript/{src/components → components}/views/BvnVerification.d.ts +2 -1
  70. package/lib/typescript/components/views/BvnVerification.d.ts.map +1 -0
  71. package/lib/typescript/{src/components → components}/views/PaylaterAgreement.d.ts +2 -1
  72. package/lib/typescript/components/views/PaylaterAgreement.d.ts.map +1 -0
  73. package/lib/typescript/{src/components → components}/views/Registration.d.ts +2 -1
  74. package/lib/typescript/components/views/Registration.d.ts.map +1 -0
  75. package/lib/typescript/functions.d.ts.map +1 -0
  76. package/lib/typescript/hooks/useOmnipay.d.ts +28 -0
  77. package/lib/typescript/hooks/useOmnipay.d.ts.map +1 -0
  78. package/lib/typescript/index.d.ts +7 -0
  79. package/lib/typescript/index.d.ts.map +1 -0
  80. package/lib/typescript/lib/colors.d.ts.map +1 -0
  81. package/lib/typescript/lib/config.d.ts.map +1 -0
  82. package/omnipay-reactnative-sdk.podspec +32 -29
  83. package/package.json +15 -10
  84. package/src/components/OmnipayProvider.tsx +3 -106
  85. package/src/components/OmnipayView.tsx +1 -1
  86. package/src/components/biometrics/FaceVerification.tsx +291 -368
  87. package/src/components/biometrics/LivenessDetection.ts +113 -250
  88. package/src/components/biometrics/OmnipayLivenessCameraView.tsx +19 -0
  89. package/src/components/biometrics/PermissionManager.ts +317 -0
  90. package/src/components/biometrics/index.ts +11 -0
  91. package/src/components/biometrics/types.ts +86 -0
  92. package/src/components/views/BvnVerification.tsx +1 -1
  93. package/src/components/views/PaylaterAgreement.tsx +1 -1
  94. package/src/components/views/Registration.tsx +1 -1
  95. package/src/index.tsx +4 -15
  96. package/android/src/main/java/com/omniretail/omnipay/LivenessCameraViewManager.java +0 -116
  97. package/android/src/main/java/com/omniretail/omnipay/LivenessDetectionModule.java +0 -588
  98. package/ios/LivenessCameraView.h +0 -22
  99. package/ios/LivenessCameraView.m +0 -135
  100. package/ios/LivenessCameraViewManager.h +0 -12
  101. package/ios/LivenessCameraViewManager.m +0 -24
  102. package/ios/LivenessDetectionModule.h +0 -46
  103. package/ios/LivenessDetectionModule.m +0 -603
  104. package/lib/commonjs/components/biometrics/LivenessCameraView.js +0 -45
  105. package/lib/commonjs/components/biometrics/LivenessCameraView.js.map +0 -1
  106. package/lib/module/components/biometrics/LivenessCameraView.js +0 -39
  107. package/lib/module/components/biometrics/LivenessCameraView.js.map +0 -1
  108. package/lib/typescript/demo/src/App.d.ts +0 -3
  109. package/lib/typescript/demo/src/App.d.ts.map +0 -1
  110. package/lib/typescript/demo/src/Body.d.ts +0 -3
  111. package/lib/typescript/demo/src/Body.d.ts.map +0 -1
  112. package/lib/typescript/demo/src/NotificationsExample.d.ts +0 -4
  113. package/lib/typescript/demo/src/NotificationsExample.d.ts.map +0 -1
  114. package/lib/typescript/src/components/OmnipayProvider.d.ts.map +0 -1
  115. package/lib/typescript/src/components/OmnipayView.d.ts.map +0 -1
  116. package/lib/typescript/src/components/biometrics/FaceVerification.d.ts +0 -12
  117. package/lib/typescript/src/components/biometrics/FaceVerification.d.ts.map +0 -1
  118. package/lib/typescript/src/components/biometrics/LivenessCameraView.d.ts +0 -22
  119. package/lib/typescript/src/components/biometrics/LivenessCameraView.d.ts.map +0 -1
  120. package/lib/typescript/src/components/biometrics/LivenessDetection.d.ts +0 -73
  121. package/lib/typescript/src/components/biometrics/LivenessDetection.d.ts.map +0 -1
  122. package/lib/typescript/src/components/views/BvnVerification.d.ts.map +0 -1
  123. package/lib/typescript/src/components/views/PaylaterAgreement.d.ts.map +0 -1
  124. package/lib/typescript/src/components/views/Registration.d.ts.map +0 -1
  125. package/lib/typescript/src/functions.d.ts.map +0 -1
  126. package/lib/typescript/src/hooks/useOmnipay.d.ts +0 -28
  127. package/lib/typescript/src/hooks/useOmnipay.d.ts.map +0 -1
  128. package/lib/typescript/src/index.d.ts +0 -8
  129. package/lib/typescript/src/index.d.ts.map +0 -1
  130. package/lib/typescript/src/lib/colors.d.ts.map +0 -1
  131. package/lib/typescript/src/lib/config.d.ts.map +0 -1
  132. package/src/components/biometrics/LivenessCameraView.tsx +0 -61
  133. /package/lib/typescript/{src/functions.d.ts → functions.d.ts} +0 -0
  134. /package/lib/typescript/{src/lib → lib}/colors.d.ts +0 -0
  135. /package/lib/typescript/{src/lib → lib}/config.d.ts +0 -0
package/README.md CHANGED
@@ -1,6 +1,17 @@
1
1
  # omnipay-reactnative-sdk
2
2
 
3
- Omnipay react native sdk
3
+ Omnipay react native sdk with **Liveness Detection** support
4
+
5
+ ## Features
6
+
7
+ - **Payment Processing** - Complete payment flow integration
8
+ - **User Registration & BVN Verification** - User onboarding flows
9
+ - **🆕 Liveness Detection** - Real-time face verification using ML Kit (Android) and Vision Framework (iOS)
10
+ - Smile detection
11
+ - Blink detection
12
+ - Head turn challenges
13
+ - Native camera integration
14
+ - Cross-platform support
4
15
 
5
16
  ## Installation
6
17
 
@@ -14,6 +25,8 @@ yarn add omnipay-reactnative-sdk
14
25
  yarn add react-native-select-contact react-native-webview react-native-share
15
26
  ```
16
27
 
28
+ **Note:** Liveness detection requires no additional dependencies. Camera permissions and native modules are handled automatically - no permission management code needed in your app.
29
+
17
30
  Make sure your manifest files includes permission to read contacts
18
31
 
19
32
  ```sh
@@ -102,45 +115,48 @@ initiateWallet({
102
115
  ### Properties
103
116
 
104
117
  #### OmnipayProvider Props
105
- | Name | Type | Description |
106
- | --------------- | -------- | -------------------------------------------------------- |
107
- | color | String | color of primary buttons and links |
108
- | env | String | dev or prod |
109
- | publicKey | String | public key of the company on omnipay |
118
+
119
+ | Name | Type | Description |
120
+ | --------- | ------ | ------------------------------------ |
121
+ | color | String | color of primary buttons and links |
122
+ | env | String | dev or prod |
123
+ | publicKey | String | public key of the company on omnipay |
110
124
 
111
125
  #### initiateBills Props
112
- | Name | Type | Description |
113
- | --------------- | -------- | -------------------------------------------------------- |
114
- | phoneNumber | String | phone number of the customer |
115
- | onClose | Function | this is used to notify you when the sdk closes |
126
+
127
+ | Name | Type | Description |
128
+ | ----------- | -------- | ---------------------------------------------- |
129
+ | phoneNumber | String | phone number of the customer |
130
+ | onClose | Function | this is used to notify you when the sdk closes |
116
131
 
117
132
  #### initiateWallet Props
118
- | Name | Type | Description |
119
- | ----------------------- | -------- | ---------------------------------------------------------------- |
120
- | phoneNumber | String | phone number of the customer |
121
- | customerRef | String | unique reference for the customer |
122
- | userRef | String | unique reference for the user |
123
- | onClose | Function | this is used to notify you when the sdk closes |
124
- | usesPaylater | Boolean | whether to show paylater tab in wallet view |
125
- | usesPromo | Boolean | whether to show promo tab in wallet view |
126
- | usesAirtimeData | Boolean | whether to show airtime and data shortcut in wallet view |
127
- | usesTransfer | Boolean | whether to show transfer shortcut in wallet view |
128
- | usesBills | Boolean | whether to show bills shortcut in wallet view |
129
- | usesPos | Boolean | whether to show pos shortcut in wallet view |
130
- | promoBalanceOffset | Number | offset for promo balance display |
131
- | deviceId | String | unique identifier for the device |
132
- | deviceName | String | name of the device |
133
- | hideWalletTransfer | Boolean | whether to hide wallet transfer functionality |
134
- | isBvnValidationRequired | Boolean | whether BVN validation is required |
135
- | walletTab | String | initial wallet tab to display ('Paylater', 'Account', 'Omoni') |
136
- | sessionId | String | unique session identifier |
137
- | kycStatus | String | KYC status of the user ('verified', 'unverified') |
138
- | launchPage | String | page to launch in the wallet |
139
133
 
134
+ | Name | Type | Description |
135
+ | ----------------------- | -------- | -------------------------------------------------------------- |
136
+ | phoneNumber | String | phone number of the customer |
137
+ | customerRef | String | unique reference for the customer |
138
+ | userRef | String | unique reference for the user |
139
+ | onClose | Function | this is used to notify you when the sdk closes |
140
+ | usesPaylater | Boolean | whether to show paylater tab in wallet view |
141
+ | usesPromo | Boolean | whether to show promo tab in wallet view |
142
+ | usesAirtimeData | Boolean | whether to show airtime and data shortcut in wallet view |
143
+ | usesTransfer | Boolean | whether to show transfer shortcut in wallet view |
144
+ | usesBills | Boolean | whether to show bills shortcut in wallet view |
145
+ | usesPos | Boolean | whether to show pos shortcut in wallet view |
146
+ | promoBalanceOffset | Number | offset for promo balance display |
147
+ | deviceId | String | unique identifier for the device |
148
+ | deviceName | String | name of the device |
149
+ | hideWalletTransfer | Boolean | whether to hide wallet transfer functionality |
150
+ | isBvnValidationRequired | Boolean | whether BVN validation is required |
151
+ | walletTab | String | initial wallet tab to display ('Paylater', 'Account', 'Omoni') |
152
+ | sessionId | String | unique session identifier |
153
+ | kycStatus | String | KYC status of the user ('verified', 'unverified') |
154
+ | launchPage | String | page to launch in the wallet |
140
155
 
141
156
  ## Registration Sdk
157
+
142
158
  ```js
143
- import { Omnipay } from "omnipay-reactnative-sdk";
159
+ import { Omnipay } from 'omnipay-reactnative-sdk';
144
160
 
145
161
  //render it anywhere on your page where you want to display the registration sdk
146
162
  <Omnipay.Registration
@@ -150,9 +166,9 @@ import { Omnipay } from "omnipay-reactnative-sdk";
150
166
  phoneNumber="09031234571"
151
167
  onRegistrationSuccessful={({ customerRef, walletId }) => {
152
168
  /**
153
- * the customer ref and walletid can be saved
169
+ * the customer ref and walletid can be saved
154
170
  * to your database at this point
155
- *
171
+ *
156
172
  * we will also be sending a webhook notification
157
173
  * so, you can either save at this point or via the webhook
158
174
  */
@@ -163,17 +179,51 @@ import { Omnipay } from "omnipay-reactnative-sdk";
163
179
  * the user is done with registration.
164
180
  * you can navigate them else where at this point
165
181
  */
166
-
167
182
  }}
168
- />
183
+ />;
169
184
  ```
170
185
 
171
186
  ### Properties
172
187
 
173
- | Name | Type | Description |
174
- | --------------- | -------- | -------------------------------------------------------- |
175
- | color | String | color of primary buttons and links |
176
- | env | String | dev or prod |
177
- | phoneNumber | String | phone number of the customer |
178
- | publicKey | String | public key of the company on omnipay |
179
- | view | String | the view to render on the sdk |
188
+ | Name | Type | Description |
189
+ | ----------- | ------ | ------------------------------------ |
190
+ | color | String | color of primary buttons and links |
191
+ | env | String | dev or prod |
192
+ | phoneNumber | String | phone number of the customer |
193
+ | publicKey | String | public key of the company on omnipay |
194
+ | view | String | the view to render on the sdk |
195
+
196
+ ## Liveness Detection
197
+
198
+ The SDK now includes advanced liveness detection capabilities for secure face verification.
199
+
200
+ ### Quick Start
201
+
202
+ ```typescript
203
+ import React from 'react';
204
+ import { OmnipayProvider } from 'omnipay-reactnative-sdk';
205
+
206
+ function MyApp() {
207
+ return (
208
+ <OmnipayProvider publicKey="your-public-key" env="dev" color="#007AFF">
209
+ <YourAppContent />
210
+ </OmnipayProvider>
211
+ );
212
+ }
213
+ ```
214
+
215
+ Face verification with liveness detection is **automatically integrated** and will appear as part of the SDK flow when needed. No additional setup or modal management required!
216
+
217
+ ### Features
218
+
219
+ - **Real-time face detection** using ML Kit (Android) and Vision Framework (iOS)
220
+ - **Multiple challenge types**: Smile, Blink, Head Turn Left/Right
221
+ - **Configurable timeouts** and challenge sequences
222
+ - **Native camera integration** with optimal performance
223
+ - **Automatic permission handling** - no additional setup required
224
+ - **Event-driven callbacks** for complete control
225
+ - **Base64 screenshot capture** after successful verification
226
+
227
+ ### Documentation
228
+
229
+ For complete liveness detection documentation, see [LIVENESS_DETECTION.md](./LIVENESS_DETECTION.md)
@@ -7,7 +7,7 @@ buildscript {
7
7
  mavenCentral()
8
8
  google()
9
9
  }
10
- def buildGradleVersion = ext.has('buildGradlePluginVersion') ? ext.get('buildGradlePluginVersion') : '4.2.0'
10
+ def buildGradleVersion = ext.has('buildGradlePluginVersion') ? ext.get('buildGradlePluginVersion') : '8.8.0'
11
11
 
12
12
  dependencies {
13
13
  classpath "com.android.tools.build:gradle:$buildGradleVersion"
@@ -22,14 +22,19 @@ def safeExtGet(prop, fallback) {
22
22
  }
23
23
 
24
24
  android {
25
- compileSdkVersion safeExtGet('compileSdkVersion', 31)
25
+ compileSdkVersion safeExtGet('compileSdkVersion', 34)
26
26
 
27
27
  defaultConfig {
28
- minSdkVersion safeExtGet('minSdkVersion', 21)
29
- targetSdkVersion safeExtGet('targetSdkVersion', 31)
28
+ minSdkVersion safeExtGet('minSdkVersion', 24)
29
+ targetSdkVersion safeExtGet('targetSdkVersion', 34)
30
30
  versionCode 1
31
31
  versionName "1.1"
32
32
  }
33
+
34
+ compileOptions {
35
+ sourceCompatibility JavaVersion.VERSION_11
36
+ targetCompatibility JavaVersion.VERSION_11
37
+ }
33
38
  }
34
39
 
35
40
  repositories {
@@ -44,16 +49,12 @@ repositories {
44
49
  dependencies {
45
50
  implementation "com.facebook.react:react-native:${safeExtGet('reactNativeVersion', '+')}"
46
51
 
47
- // CameraX dependencies for liveness detection
48
- implementation 'androidx.camera:camera-core:1.3.1'
49
- implementation 'androidx.camera:camera-camera2:1.3.1'
50
- implementation 'androidx.camera:camera-lifecycle:1.3.1'
51
- implementation 'androidx.camera:camera-view:1.3.1'
52
-
53
- // ML Kit for face detection
54
- implementation 'com.google.mlkit:face-detection:16.1.5'
52
+ // ML Kit dependencies for liveness detection
53
+ implementation 'com.google.mlkit:face-detection:16.1.6'
55
54
 
56
- // Additional required dependencies
57
- implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.7.0'
58
- implementation 'androidx.core:core-ktx:1.12.0'
55
+ // CameraX dependencies for camera handling
56
+ implementation "androidx.camera:camera-core:1.3.1"
57
+ implementation "androidx.camera:camera-camera2:1.3.1"
58
+ implementation "androidx.camera:camera-lifecycle:1.3.1"
59
+ implementation "androidx.camera:camera-view:1.3.1"
59
60
  }
@@ -3,7 +3,7 @@
3
3
 
4
4
  <!-- Camera permissions for liveness detection -->
5
5
  <uses-permission android:name="android.permission.CAMERA" />
6
- <uses-feature android:name="android.hardware.camera" android:required="true" />
6
+ <uses-feature android:name="android.hardware.camera" android:required="false" />
7
7
  <uses-feature android:name="android.hardware.camera.front" android:required="false" />
8
8
 
9
9
  <application>
@@ -16,14 +16,14 @@ public class OmnipayActivityPackage implements ReactPackage {
16
16
  public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
17
17
  List<NativeModule> modules = new ArrayList<>();
18
18
  modules.add(new OmnipayActivityModule(reactContext));
19
- modules.add(new LivenessDetectionModule(reactContext));
19
+ modules.add(new OmnipayLivenessModule(reactContext));
20
20
  return modules;
21
21
  }
22
22
 
23
23
  @Override
24
24
  public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
25
25
  List<ViewManager> viewManagers = new ArrayList<>();
26
- viewManagers.add(new LivenessCameraViewManager(reactContext));
26
+ viewManagers.add(new OmnipayLivenessCameraViewManager(reactContext));
27
27
  return viewManagers;
28
28
  }
29
29
 
@@ -0,0 +1,153 @@
1
+ package com.omniretail.omnipay;
2
+
3
+ import android.content.Context;
4
+ import android.util.AttributeSet;
5
+ import android.util.Log;
6
+ import android.view.LayoutInflater;
7
+ import android.view.View;
8
+ import android.widget.FrameLayout;
9
+
10
+ import androidx.annotation.NonNull;
11
+ import androidx.annotation.Nullable;
12
+ import androidx.camera.core.CameraSelector;
13
+ import androidx.camera.core.Preview;
14
+ import androidx.camera.lifecycle.ProcessCameraProvider;
15
+ import androidx.camera.view.PreviewView;
16
+ import androidx.core.content.ContextCompat;
17
+ import androidx.lifecycle.LifecycleOwner;
18
+
19
+ import com.facebook.react.bridge.Arguments;
20
+ import com.facebook.react.bridge.ReactContext;
21
+ import com.facebook.react.bridge.WritableMap;
22
+ import com.facebook.react.uimanager.events.RCTEventEmitter;
23
+ import com.google.common.util.concurrent.ListenableFuture;
24
+
25
+ import java.util.concurrent.ExecutionException;
26
+
27
+ public class OmnipayLivenessCameraView extends FrameLayout {
28
+ private static final String TAG = "OmnipayLivenessCameraView";
29
+
30
+ private PreviewView previewView;
31
+ private ProcessCameraProvider cameraProvider;
32
+ private Preview preview;
33
+ private boolean isInitialized = false;
34
+
35
+ public OmnipayLivenessCameraView(@NonNull Context context) {
36
+ super(context);
37
+ init();
38
+ }
39
+
40
+ public OmnipayLivenessCameraView(@NonNull Context context, @Nullable AttributeSet attrs) {
41
+ super(context, attrs);
42
+ init();
43
+ }
44
+
45
+ public OmnipayLivenessCameraView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
46
+ super(context, attrs, defStyleAttr);
47
+ init();
48
+ }
49
+
50
+ private void init() {
51
+ // Create and add PreviewView
52
+ previewView = new PreviewView(getContext());
53
+ previewView.setLayoutParams(new FrameLayout.LayoutParams(
54
+ FrameLayout.LayoutParams.MATCH_PARENT,
55
+ FrameLayout.LayoutParams.MATCH_PARENT
56
+ ));
57
+ previewView.setScaleType(PreviewView.ScaleType.FILL_CENTER);
58
+ addView(previewView);
59
+
60
+ // Initialize camera
61
+ initializeCamera();
62
+ }
63
+
64
+ private void initializeCamera() {
65
+ ListenableFuture<ProcessCameraProvider> cameraProviderFuture =
66
+ ProcessCameraProvider.getInstance(getContext());
67
+
68
+ cameraProviderFuture.addListener(() -> {
69
+ try {
70
+ cameraProvider = cameraProviderFuture.get();
71
+ setupCamera();
72
+ isInitialized = true;
73
+ sendEvent("onCameraReady", Arguments.createMap());
74
+ } catch (ExecutionException | InterruptedException e) {
75
+ Log.e(TAG, "Error initializing camera", e);
76
+ WritableMap errorMap = Arguments.createMap();
77
+ errorMap.putString("error", "Failed to initialize camera: " + e.getMessage());
78
+ sendEvent("onCameraError", errorMap);
79
+ }
80
+ }, ContextCompat.getMainExecutor(getContext()));
81
+ }
82
+
83
+ private void setupCamera() {
84
+ if (cameraProvider == null) {
85
+ return;
86
+ }
87
+
88
+ // Create preview use case
89
+ preview = new Preview.Builder().build();
90
+
91
+ // Connect preview to PreviewView
92
+ preview.setSurfaceProvider(previewView.getSurfaceProvider());
93
+
94
+ // Select front camera
95
+ CameraSelector cameraSelector = CameraSelector.DEFAULT_FRONT_CAMERA;
96
+
97
+ try {
98
+ // Unbind all use cases before rebinding
99
+ cameraProvider.unbindAll();
100
+
101
+ // Bind preview to camera
102
+ if (getContext() instanceof LifecycleOwner) {
103
+ cameraProvider.bindToLifecycle(
104
+ (LifecycleOwner) getContext(),
105
+ cameraSelector,
106
+ preview
107
+ );
108
+ } else {
109
+ Log.w(TAG, "Context is not a LifecycleOwner, camera preview may not work properly");
110
+ }
111
+ } catch (Exception e) {
112
+ Log.e(TAG, "Error binding camera", e);
113
+ WritableMap errorMap = Arguments.createMap();
114
+ errorMap.putString("error", "Failed to bind camera: " + e.getMessage());
115
+ sendEvent("onCameraError", errorMap);
116
+ }
117
+ }
118
+
119
+ public void setupCameraPreview(ProcessCameraProvider cameraProvider) {
120
+ this.cameraProvider = cameraProvider;
121
+ if (isInitialized) {
122
+ setupCamera();
123
+ }
124
+ }
125
+
126
+ public void startPreview() {
127
+ if (preview != null && cameraProvider != null) {
128
+ // Camera preview is automatically started when bound to lifecycle
129
+ Log.d(TAG, "Camera preview started");
130
+ }
131
+ }
132
+
133
+ public void stopPreview() {
134
+ if (cameraProvider != null) {
135
+ cameraProvider.unbindAll();
136
+ Log.d(TAG, "Camera preview stopped");
137
+ }
138
+ }
139
+
140
+ @Override
141
+ protected void onDetachedFromWindow() {
142
+ super.onDetachedFromWindow();
143
+ stopPreview();
144
+ }
145
+
146
+ private void sendEvent(String eventName, WritableMap params) {
147
+ ReactContext reactContext = (ReactContext) getContext();
148
+ if (reactContext != null) {
149
+ reactContext.getJSModule(RCTEventEmitter.class)
150
+ .receiveEvent(getId(), eventName, params);
151
+ }
152
+ }
153
+ }
@@ -0,0 +1,49 @@
1
+ package com.omniretail.omnipay;
2
+
3
+ import androidx.annotation.NonNull;
4
+ import androidx.annotation.Nullable;
5
+
6
+ import com.facebook.react.bridge.ReactApplicationContext;
7
+ import com.facebook.react.common.MapBuilder;
8
+ import com.facebook.react.uimanager.SimpleViewManager;
9
+ import com.facebook.react.uimanager.ThemedReactContext;
10
+ import com.facebook.react.uimanager.annotations.ReactProp;
11
+
12
+ import java.util.Map;
13
+
14
+ public class OmnipayLivenessCameraViewManager extends SimpleViewManager<OmnipayLivenessCameraView> {
15
+ public static final String REACT_CLASS = "OmnipayLivenessCameraView";
16
+
17
+ private ReactApplicationContext reactContext;
18
+
19
+ public OmnipayLivenessCameraViewManager(ReactApplicationContext reactContext) {
20
+ this.reactContext = reactContext;
21
+ }
22
+
23
+ @NonNull
24
+ @Override
25
+ public String getName() {
26
+ return REACT_CLASS;
27
+ }
28
+
29
+ @NonNull
30
+ @Override
31
+ protected OmnipayLivenessCameraView createViewInstance(@NonNull ThemedReactContext reactContext) {
32
+ return new OmnipayLivenessCameraView(reactContext);
33
+ }
34
+
35
+ @Nullable
36
+ @Override
37
+ public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
38
+ return MapBuilder.<String, Object>builder()
39
+ .put("onCameraReady", MapBuilder.of("registrationName", "onCameraReady"))
40
+ .put("onCameraError", MapBuilder.of("registrationName", "onCameraError"))
41
+ .build();
42
+ }
43
+
44
+ @Override
45
+ public void onDropViewInstance(@NonNull OmnipayLivenessCameraView view) {
46
+ view.stopPreview();
47
+ super.onDropViewInstance(view);
48
+ }
49
+ }