expo-camera 12.0.2 → 12.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.
- package/CHANGELOG.md +23 -2
- package/README.md +1 -1
- package/android/build.gradle +22 -19
- package/android/src/main/java/expo/modules/camera/CameraModule.kt +217 -0
- package/android/src/main/java/expo/modules/camera/CameraPackage.kt +10 -0
- package/android/src/main/java/expo/modules/camera/CameraViewHelper.kt +139 -0
- package/android/src/main/java/expo/modules/camera/CameraViewManager.kt +116 -0
- package/android/src/main/java/expo/modules/camera/Constants.kt +184 -0
- package/android/src/main/java/expo/modules/camera/ExpoCameraView.kt +329 -0
- package/android/src/main/java/expo/modules/camera/events/BarCodeScannedEvent.kt +50 -0
- package/android/src/main/java/expo/modules/camera/events/CameraMountErrorEvent.kt +33 -0
- package/android/src/main/java/expo/modules/camera/events/CameraReadyEvent.kt +23 -0
- package/android/src/main/java/expo/modules/camera/events/FaceDetectionErrorEvent.kt +39 -0
- package/android/src/main/java/expo/modules/camera/events/FacesDetectedEvent.kt +46 -0
- package/android/src/main/java/expo/modules/camera/events/PictureSavedEvent.kt +41 -0
- package/android/src/main/java/expo/modules/camera/tasks/BarCodeScannerAsyncTask.kt +26 -0
- package/android/src/main/java/expo/modules/camera/tasks/BarCodeScannerAsyncTaskDelegate.kt +8 -0
- package/android/src/main/java/expo/modules/camera/tasks/FaceDetectorAsyncTaskDelegate.kt +10 -0
- package/android/src/main/java/expo/modules/camera/tasks/FaceDetectorTask.kt +34 -0
- package/android/src/main/java/expo/modules/camera/tasks/PictureSavedDelegate.kt +7 -0
- package/android/src/main/java/expo/modules/camera/tasks/ResolveTakenPictureAsyncTask.kt +231 -0
- package/android/src/main/java/expo/modules/camera/utils/FileSystemUtils.kt +23 -0
- package/android/src/main/java/expo/modules/camera/utils/ImageDimensions.kt +14 -0
- package/build/ExponentCameraManager.web.js +3 -1
- package/build/ExponentCameraManager.web.js.map +1 -1
- package/ios/EXCamera.xcframework/ios-arm64/EXCamera.framework/EXCamera +0 -0
- package/ios/EXCamera.xcframework/ios-arm64/EXCamera.framework/Info.plist +0 -0
- package/ios/EXCamera.xcframework/ios-arm64_x86_64-simulator/EXCamera.framework/EXCamera +0 -0
- package/ios/EXCamera.xcframework/ios-arm64_x86_64-simulator/EXCamera.framework/Info.plist +0 -0
- package/package.json +7 -5
- package/plugin/build/withCamera.d.ts +2 -1
- package/plugin/build/withCamera.js +50 -30
- package/plugin/src/withCamera.ts +66 -27
- package/src/ExponentCameraManager.web.ts +3 -2
- package/src/{types → ts-declarations}/image-capture.d.ts +0 -0
- package/src/ts-declarations/lib.dom.d.ts +34 -0
- package/android/src/main/java/expo/modules/camera/CameraModule.java +0 -359
- package/android/src/main/java/expo/modules/camera/CameraPackage.java +0 -23
- package/android/src/main/java/expo/modules/camera/CameraViewHelper.java +0 -294
- package/android/src/main/java/expo/modules/camera/CameraViewManager.java +0 -142
- package/android/src/main/java/expo/modules/camera/ExpoCameraView.java +0 -376
- package/android/src/main/java/expo/modules/camera/events/BarCodeScannedEvent.java +0 -59
- package/android/src/main/java/expo/modules/camera/events/CameraMountErrorEvent.java +0 -38
- package/android/src/main/java/expo/modules/camera/events/CameraReadyEvent.java +0 -30
- package/android/src/main/java/expo/modules/camera/events/FaceDetectionErrorEvent.java +0 -50
- package/android/src/main/java/expo/modules/camera/events/FacesDetectedEvent.java +0 -63
- package/android/src/main/java/expo/modules/camera/events/PictureSavedEvent.java +0 -53
- package/android/src/main/java/expo/modules/camera/tasks/BarCodeScannerAsyncTask.java +0 -47
- package/android/src/main/java/expo/modules/camera/tasks/BarCodeScannerAsyncTaskDelegate.java +0 -8
- package/android/src/main/java/expo/modules/camera/tasks/FaceDetectorAsyncTaskDelegate.java +0 -13
- package/android/src/main/java/expo/modules/camera/tasks/FaceDetectorTask.java +0 -53
- package/android/src/main/java/expo/modules/camera/tasks/PictureSavedDelegate.java +0 -7
- package/android/src/main/java/expo/modules/camera/tasks/ResolveTakenPictureAsyncTask.java +0 -288
- package/android/src/main/java/expo/modules/camera/utils/FileSystemUtils.java +0 -21
- package/android/src/main/java/expo/modules/camera/utils/ImageDimensions.java +0 -64
|
@@ -1,376 +0,0 @@
|
|
|
1
|
-
package expo.modules.camera;
|
|
2
|
-
|
|
3
|
-
import android.Manifest;
|
|
4
|
-
import android.content.Context;
|
|
5
|
-
import android.graphics.Color;
|
|
6
|
-
import android.media.CamcorderProfile;
|
|
7
|
-
import android.net.Uri;
|
|
8
|
-
import android.os.Build;
|
|
9
|
-
import android.os.Bundle;
|
|
10
|
-
import android.view.View;
|
|
11
|
-
|
|
12
|
-
import com.google.android.cameraview.CameraView;
|
|
13
|
-
import com.google.android.cameraview.Size;
|
|
14
|
-
|
|
15
|
-
import expo.modules.core.ModuleRegistry;
|
|
16
|
-
import expo.modules.core.Promise;
|
|
17
|
-
import expo.modules.core.interfaces.LifecycleEventListener;
|
|
18
|
-
import expo.modules.core.interfaces.services.EventEmitter;
|
|
19
|
-
import expo.modules.core.interfaces.services.UIManager;
|
|
20
|
-
|
|
21
|
-
import java.io.File;
|
|
22
|
-
import java.io.IOException;
|
|
23
|
-
import java.util.ArrayList;
|
|
24
|
-
import java.util.List;
|
|
25
|
-
import java.util.Map;
|
|
26
|
-
import java.util.Queue;
|
|
27
|
-
import java.util.concurrent.ConcurrentHashMap;
|
|
28
|
-
import java.util.concurrent.ConcurrentLinkedQueue;
|
|
29
|
-
|
|
30
|
-
import expo.modules.camera.tasks.BarCodeScannerAsyncTask;
|
|
31
|
-
import expo.modules.camera.tasks.BarCodeScannerAsyncTaskDelegate;
|
|
32
|
-
import expo.modules.camera.tasks.FaceDetectorAsyncTaskDelegate;
|
|
33
|
-
import expo.modules.camera.tasks.FaceDetectorTask;
|
|
34
|
-
import expo.modules.camera.tasks.PictureSavedDelegate;
|
|
35
|
-
import expo.modules.camera.tasks.ResolveTakenPictureAsyncTask;
|
|
36
|
-
import expo.modules.camera.utils.FileSystemUtils;
|
|
37
|
-
import expo.modules.camera.utils.ImageDimensions;
|
|
38
|
-
import expo.modules.interfaces.barcodescanner.BarCodeScannerInterface;
|
|
39
|
-
import expo.modules.interfaces.barcodescanner.BarCodeScannerProviderInterface;
|
|
40
|
-
import expo.modules.interfaces.barcodescanner.BarCodeScannerResult;
|
|
41
|
-
import expo.modules.interfaces.barcodescanner.BarCodeScannerSettings;
|
|
42
|
-
import expo.modules.interfaces.camera.CameraViewInterface;
|
|
43
|
-
import expo.modules.interfaces.facedetector.FaceDetectorInterface;
|
|
44
|
-
import expo.modules.interfaces.facedetector.FaceDetectorProviderInterface;
|
|
45
|
-
import expo.modules.interfaces.permissions.Permissions;
|
|
46
|
-
|
|
47
|
-
public class ExpoCameraView extends CameraView implements LifecycleEventListener, BarCodeScannerAsyncTaskDelegate, FaceDetectorAsyncTaskDelegate, PictureSavedDelegate, CameraViewInterface {
|
|
48
|
-
private static final String MUTE_KEY = "mute";
|
|
49
|
-
private static final String QUALITY_KEY = "quality";
|
|
50
|
-
private static final String FAST_MODE_KEY = "fastMode";
|
|
51
|
-
private static final String MAX_DURATION_KEY = "maxDuration";
|
|
52
|
-
private static final String MAX_FILE_SIZE_KEY = "maxFileSize";
|
|
53
|
-
private static final String VIDEO_BITRATE_KEY = "videoBitrate";
|
|
54
|
-
|
|
55
|
-
private Queue<Promise> mPictureTakenPromises = new ConcurrentLinkedQueue<>();
|
|
56
|
-
private Map<Promise, Map<String, Object>> mPictureTakenOptions = new ConcurrentHashMap<>();
|
|
57
|
-
private Map<Promise, File> mPictureTakenDirectories = new ConcurrentHashMap<>();
|
|
58
|
-
private Promise mVideoRecordedPromise;
|
|
59
|
-
|
|
60
|
-
private boolean mIsPaused = false;
|
|
61
|
-
private boolean mIsNew = true;
|
|
62
|
-
|
|
63
|
-
// Concurrency lock for scanners to avoid flooding the runtime
|
|
64
|
-
public volatile boolean barCodeScannerTaskLock = false;
|
|
65
|
-
public volatile boolean faceDetectorTaskLock = false;
|
|
66
|
-
|
|
67
|
-
// Scanning-related properties
|
|
68
|
-
private BarCodeScannerInterface mBarCodeScanner;
|
|
69
|
-
private FaceDetectorInterface mFaceDetector;
|
|
70
|
-
private Map<String, Object> mPendingFaceDetectorSettings;
|
|
71
|
-
private boolean mShouldDetectFaces = false;
|
|
72
|
-
private boolean mShouldScanBarCodes = false;
|
|
73
|
-
|
|
74
|
-
private ModuleRegistry mModuleRegistry;
|
|
75
|
-
|
|
76
|
-
public ExpoCameraView(Context themedReactContext, ModuleRegistry moduleRegistry) {
|
|
77
|
-
super(themedReactContext, true);
|
|
78
|
-
mModuleRegistry = moduleRegistry;
|
|
79
|
-
initBarCodeScanner();
|
|
80
|
-
setChildrenDrawingOrderEnabled(true);
|
|
81
|
-
|
|
82
|
-
mModuleRegistry.getModule(UIManager.class).registerLifecycleEventListener(this);
|
|
83
|
-
|
|
84
|
-
addCallback(new Callback() {
|
|
85
|
-
@Override
|
|
86
|
-
public void onCameraOpened(CameraView cameraView) {
|
|
87
|
-
CameraViewHelper.emitCameraReadyEvent(mModuleRegistry.getModule(EventEmitter.class), cameraView);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
@Override
|
|
91
|
-
public void onMountError(CameraView cameraView) {
|
|
92
|
-
CameraViewHelper.emitMountErrorEvent(mModuleRegistry.getModule(EventEmitter.class), cameraView, "Camera component could not be rendered - is there any other instance running?");
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
@Override
|
|
96
|
-
public void onPictureTaken(CameraView cameraView, final byte[] data) {
|
|
97
|
-
Promise promise = mPictureTakenPromises.poll();
|
|
98
|
-
final File cacheDirectory = mPictureTakenDirectories.remove(promise);
|
|
99
|
-
Map<String, Object> options = mPictureTakenOptions.remove(promise);
|
|
100
|
-
|
|
101
|
-
if (options.containsKey(FAST_MODE_KEY) && (Boolean) options.get(FAST_MODE_KEY)) {
|
|
102
|
-
promise.resolve(null);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
new ResolveTakenPictureAsyncTask(data, promise, options, cacheDirectory, ExpoCameraView.this).execute();
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
@Override
|
|
109
|
-
public void onVideoRecorded(CameraView cameraView, String path) {
|
|
110
|
-
if (mVideoRecordedPromise != null) {
|
|
111
|
-
if (path != null) {
|
|
112
|
-
Bundle result = new Bundle();
|
|
113
|
-
result.putString("uri", Uri.fromFile(new File(path)).toString());
|
|
114
|
-
mVideoRecordedPromise.resolve(result);
|
|
115
|
-
} else {
|
|
116
|
-
mVideoRecordedPromise.reject("E_RECORDING", "Couldn't stop recording - there is none in progress");
|
|
117
|
-
}
|
|
118
|
-
mVideoRecordedPromise = null;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
@Override
|
|
123
|
-
public void onFramePreview(CameraView cameraView, byte[] data, int width, int height, int rotation) {
|
|
124
|
-
int correctRotation = CameraViewHelper.getCorrectCameraRotation(rotation, getFacing());
|
|
125
|
-
|
|
126
|
-
if (mShouldScanBarCodes && !barCodeScannerTaskLock && cameraView instanceof BarCodeScannerAsyncTaskDelegate) {
|
|
127
|
-
barCodeScannerTaskLock = true;
|
|
128
|
-
BarCodeScannerAsyncTaskDelegate delegate = (BarCodeScannerAsyncTaskDelegate) cameraView;
|
|
129
|
-
new BarCodeScannerAsyncTask(delegate, mBarCodeScanner, data, width, height, rotation).execute();
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (mShouldDetectFaces && !faceDetectorTaskLock && cameraView instanceof FaceDetectorAsyncTaskDelegate) {
|
|
133
|
-
faceDetectorTaskLock = true;
|
|
134
|
-
float density = cameraView.getResources().getDisplayMetrics().density;
|
|
135
|
-
|
|
136
|
-
ImageDimensions dimensions = new ImageDimensions(width, height, correctRotation, getFacing());
|
|
137
|
-
double scaleX = (double) cameraView.getWidth() / (dimensions.getWidth() * density);
|
|
138
|
-
double scaleY = (double) cameraView.getHeight() / (dimensions.getHeight() * density);
|
|
139
|
-
|
|
140
|
-
FaceDetectorAsyncTaskDelegate delegate = (FaceDetectorAsyncTaskDelegate) cameraView;
|
|
141
|
-
FaceDetectorTask task = new FaceDetectorTask(delegate, mFaceDetector, data, width, height, correctRotation, getFacing() == CameraView.FACING_FRONT, scaleX, scaleY);
|
|
142
|
-
task.execute();
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
@Override
|
|
149
|
-
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
|
150
|
-
View preview = getView();
|
|
151
|
-
if (null == preview) {
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
this.setBackgroundColor(Color.BLACK);
|
|
155
|
-
int width = right - left;
|
|
156
|
-
int height = bottom - top;
|
|
157
|
-
preview.layout(0, 0, width, height);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
@Override
|
|
161
|
-
public void requestLayout() {
|
|
162
|
-
// React handles this for us, so we don't need to call super.requestLayout();
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
@Override
|
|
166
|
-
public void onViewAdded(View child) {
|
|
167
|
-
// react adds children to containers at the beginning of children list and that moves pre-react added preview to the end of that list
|
|
168
|
-
// above would cause preview (TextureView that covers all available space) to be rendered at the top of children stack
|
|
169
|
-
// while we need this preview to be rendered last beneath all other children
|
|
170
|
-
|
|
171
|
-
// child is not preview
|
|
172
|
-
if (this.getView() == child || this.getView() == null) {
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// bring to front all non-preview children
|
|
177
|
-
List<View> childrenToBeReordered = new ArrayList<>();
|
|
178
|
-
for (int i = 0; i < this.getChildCount(); i++) {
|
|
179
|
-
View childView = this.getChildAt(i);
|
|
180
|
-
if (i == 0 && childView == this.getView()) {
|
|
181
|
-
// preview is already first in children list - do not reorder anything
|
|
182
|
-
return;
|
|
183
|
-
}
|
|
184
|
-
if (childView != this.getView()) {
|
|
185
|
-
childrenToBeReordered.add(childView);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
for (View childView : childrenToBeReordered) {
|
|
190
|
-
bringChildToFront(childView);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
requestLayout();
|
|
194
|
-
invalidate();
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
public void takePicture(Map<String, Object> options, final Promise promise, File cacheDirectory) {
|
|
198
|
-
mPictureTakenPromises.add(promise);
|
|
199
|
-
mPictureTakenOptions.put(promise, options);
|
|
200
|
-
mPictureTakenDirectories.put(promise, cacheDirectory);
|
|
201
|
-
try {
|
|
202
|
-
super.takePicture();
|
|
203
|
-
} catch (Exception e) {
|
|
204
|
-
mPictureTakenPromises.remove(promise);
|
|
205
|
-
mPictureTakenOptions.remove(promise);
|
|
206
|
-
mPictureTakenDirectories.remove(promise);
|
|
207
|
-
throw e;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
@Override
|
|
212
|
-
public void onPictureSaved(Bundle response) {
|
|
213
|
-
CameraViewHelper.emitPictureSavedEvent(mModuleRegistry.getModule(EventEmitter.class), this, response);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
public void record(Map<String, Object> options, final Promise promise, File cacheDirectory) {
|
|
217
|
-
try {
|
|
218
|
-
String path = FileSystemUtils.generateOutputPath(cacheDirectory, "Camera", ".mp4");
|
|
219
|
-
double maxDuration = -1;
|
|
220
|
-
if (options.get(MAX_DURATION_KEY) != null) {
|
|
221
|
-
maxDuration = (double) options.get(MAX_DURATION_KEY);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
double maxFileSize = -1;
|
|
225
|
-
if (options.get(MAX_FILE_SIZE_KEY) != null) {
|
|
226
|
-
maxFileSize = (double) options.get(MAX_FILE_SIZE_KEY);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
CamcorderProfile profile = CamcorderProfile.get(getCameraId(), CamcorderProfile.QUALITY_HIGH);
|
|
230
|
-
if (options.get(QUALITY_KEY) != null) {
|
|
231
|
-
profile = CameraViewHelper.getCamcorderProfile(getCameraId(), ((Double) options.get(QUALITY_KEY)).intValue());
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
if (options.get(VIDEO_BITRATE_KEY) != null) {
|
|
235
|
-
profile.videoBitRate = ((Double) options.get(VIDEO_BITRATE_KEY)).intValue();
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
Boolean muteValue = (Boolean) options.get(MUTE_KEY);
|
|
239
|
-
boolean recordAudio = muteValue == null || !muteValue;
|
|
240
|
-
|
|
241
|
-
if (super.record(path, (int) maxDuration * 1000, (int) maxFileSize, recordAudio, profile)) {
|
|
242
|
-
mVideoRecordedPromise = promise;
|
|
243
|
-
} else {
|
|
244
|
-
promise.reject("E_RECORDING_FAILED", "Starting video recording failed. Another recording might be in progress.");
|
|
245
|
-
}
|
|
246
|
-
} catch (IOException e) {
|
|
247
|
-
promise.reject("E_RECORDING_FAILED", "Starting video recording failed - could not create video file.");
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Initialize the barcode scanner.
|
|
253
|
-
* Supports all iOS codes except [code138, code39mod43, itf14]
|
|
254
|
-
* Additionally supports [codabar, code128, maxicode, rss14, rssexpanded, upc_a, upc_ean]
|
|
255
|
-
*/
|
|
256
|
-
private void initBarCodeScanner() {
|
|
257
|
-
BarCodeScannerProviderInterface barCodeScannerProvider = mModuleRegistry.getModule(BarCodeScannerProviderInterface.class);
|
|
258
|
-
if (barCodeScannerProvider != null) {
|
|
259
|
-
mBarCodeScanner = barCodeScannerProvider.createBarCodeDetectorWithContext(getContext());
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
public void setShouldScanBarCodes(boolean shouldScanBarCodes) {
|
|
264
|
-
this.mShouldScanBarCodes = shouldScanBarCodes;
|
|
265
|
-
setScanning(mShouldScanBarCodes || mShouldDetectFaces);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
public void setBarCodeScannerSettings(BarCodeScannerSettings settings) {
|
|
269
|
-
if (mBarCodeScanner != null) {
|
|
270
|
-
mBarCodeScanner.setSettings(settings);
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
@Override
|
|
275
|
-
public void onBarCodeScanned(BarCodeScannerResult barCode) {
|
|
276
|
-
if (!mShouldScanBarCodes) {
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
CameraViewHelper.emitBarCodeReadEvent(mModuleRegistry.getModule(EventEmitter.class), this, barCode);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
public void onBarCodeScanningTaskCompleted() {
|
|
284
|
-
barCodeScannerTaskLock = false;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
public int[] getPreviewSizeAsArray() {
|
|
288
|
-
Size previewSize = getPreviewSize();
|
|
289
|
-
return new int[]{previewSize.getWidth(), previewSize.getHeight()};
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
@Override
|
|
293
|
-
public void onHostResume() {
|
|
294
|
-
if (hasCameraPermissions()) {
|
|
295
|
-
if ((mIsPaused && !isCameraOpened()) || mIsNew) {
|
|
296
|
-
mIsPaused = false;
|
|
297
|
-
mIsNew = false;
|
|
298
|
-
if (!Build.FINGERPRINT.contains("generic")) {
|
|
299
|
-
start();
|
|
300
|
-
|
|
301
|
-
FaceDetectorProviderInterface faceDetectorProvider = mModuleRegistry.getModule(FaceDetectorProviderInterface.class);
|
|
302
|
-
if (faceDetectorProvider != null) {
|
|
303
|
-
mFaceDetector = faceDetectorProvider.createFaceDetectorWithContext(getContext());
|
|
304
|
-
if (mPendingFaceDetectorSettings != null) {
|
|
305
|
-
mFaceDetector.setSettings(mPendingFaceDetectorSettings);
|
|
306
|
-
mPendingFaceDetectorSettings = null;
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
} else {
|
|
312
|
-
CameraViewHelper.emitMountErrorEvent(mModuleRegistry.getModule(EventEmitter.class), this, "Camera permissions not granted - component could not be rendered.");
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
@Override
|
|
317
|
-
public void onHostPause() {
|
|
318
|
-
if (!mIsPaused && isCameraOpened()) {
|
|
319
|
-
if (mFaceDetector != null) {
|
|
320
|
-
mFaceDetector.release();
|
|
321
|
-
}
|
|
322
|
-
mIsPaused = true;
|
|
323
|
-
stop();
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
@Override
|
|
328
|
-
public void onHostDestroy() {
|
|
329
|
-
if (mFaceDetector != null) {
|
|
330
|
-
mFaceDetector.release();
|
|
331
|
-
}
|
|
332
|
-
stop();
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
private boolean hasCameraPermissions() {
|
|
336
|
-
return mModuleRegistry.getModule(Permissions.class).hasGrantedPermissions(Manifest.permission.CAMERA);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
public void setShouldDetectFaces(boolean shouldDetectFaces) {
|
|
340
|
-
mShouldDetectFaces = shouldDetectFaces;
|
|
341
|
-
setScanning(mShouldScanBarCodes || mShouldDetectFaces);
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
public void setFaceDetectorSettings(Map<String, Object> settings) {
|
|
345
|
-
if (mFaceDetector == null) {
|
|
346
|
-
mPendingFaceDetectorSettings = settings;
|
|
347
|
-
} else {
|
|
348
|
-
mFaceDetector.setSettings(settings);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
@Override
|
|
353
|
-
public void onFacesDetected(List<Bundle> facesReported) {
|
|
354
|
-
if (!mShouldDetectFaces) {
|
|
355
|
-
return;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
List<Bundle> facesDetected = facesReported == null ? new ArrayList<Bundle>() : facesReported;
|
|
359
|
-
CameraViewHelper.emitFacesDetectedEvent(mModuleRegistry.getModule(EventEmitter.class), this, facesDetected);
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
@Override
|
|
363
|
-
public void onFaceDetectionError(FaceDetectorInterface faceDetector) {
|
|
364
|
-
faceDetectorTaskLock = false;
|
|
365
|
-
if (!mShouldDetectFaces) {
|
|
366
|
-
return;
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
CameraViewHelper.emitFaceDetectionErrorEvent(mModuleRegistry.getModule(EventEmitter.class), this, faceDetector);
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
@Override
|
|
373
|
-
public void onFaceDetectingTaskCompleted() {
|
|
374
|
-
faceDetectorTaskLock = false;
|
|
375
|
-
}
|
|
376
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
package expo.modules.camera.events;
|
|
2
|
-
|
|
3
|
-
import android.os.Bundle;
|
|
4
|
-
import androidx.core.util.Pools;
|
|
5
|
-
|
|
6
|
-
import expo.modules.core.interfaces.services.EventEmitter;
|
|
7
|
-
import expo.modules.camera.CameraViewManager;
|
|
8
|
-
import expo.modules.interfaces.barcodescanner.BarCodeScannerResult;
|
|
9
|
-
|
|
10
|
-
public class BarCodeScannedEvent extends EventEmitter.BaseEvent {
|
|
11
|
-
private static final Pools.SynchronizedPool<BarCodeScannedEvent> EVENTS_POOL =
|
|
12
|
-
new Pools.SynchronizedPool<>(3);
|
|
13
|
-
|
|
14
|
-
private BarCodeScannerResult mBarCode;
|
|
15
|
-
private int mViewTag;
|
|
16
|
-
|
|
17
|
-
private BarCodeScannedEvent() {}
|
|
18
|
-
|
|
19
|
-
public static BarCodeScannedEvent obtain(int viewTag, BarCodeScannerResult barCode) {
|
|
20
|
-
BarCodeScannedEvent event = EVENTS_POOL.acquire();
|
|
21
|
-
if (event == null) {
|
|
22
|
-
event = new BarCodeScannedEvent();
|
|
23
|
-
}
|
|
24
|
-
event.init(viewTag, barCode);
|
|
25
|
-
return event;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
private void init(int viewTag, BarCodeScannerResult barCode) {
|
|
29
|
-
mViewTag = viewTag;
|
|
30
|
-
mBarCode = barCode;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* We want every distinct barcode to be reported to the JS listener.
|
|
35
|
-
* If we return some static value as a coalescing key there may be two barcode events
|
|
36
|
-
* containing two different barcodes waiting to be transmitted to JS
|
|
37
|
-
* that would get coalesced (because both of them would have the same coalescing key).
|
|
38
|
-
* So let's differentiate them with a hash of the contents (mod short's max value).
|
|
39
|
-
*/
|
|
40
|
-
@Override
|
|
41
|
-
public short getCoalescingKey() {
|
|
42
|
-
int hashCode = mBarCode.getValue().hashCode() % Short.MAX_VALUE;
|
|
43
|
-
return (short) hashCode;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
@Override
|
|
47
|
-
public String getEventName() {
|
|
48
|
-
return CameraViewManager.Events.EVENT_ON_BAR_CODE_SCANNED.toString();
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
@Override
|
|
52
|
-
public Bundle getEventBody() {
|
|
53
|
-
Bundle event = new Bundle();
|
|
54
|
-
event.putInt("target", mViewTag);
|
|
55
|
-
event.putString("data", mBarCode.getValue());
|
|
56
|
-
event.putInt("type", mBarCode.getType());
|
|
57
|
-
return event;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
package expo.modules.camera.events;
|
|
2
|
-
|
|
3
|
-
import android.os.Bundle;
|
|
4
|
-
import androidx.core.util.Pools;
|
|
5
|
-
|
|
6
|
-
import expo.modules.core.interfaces.services.EventEmitter;
|
|
7
|
-
import expo.modules.camera.CameraViewManager;
|
|
8
|
-
|
|
9
|
-
public class CameraMountErrorEvent extends EventEmitter.BaseEvent {
|
|
10
|
-
private static final Pools.SynchronizedPool<CameraMountErrorEvent> EVENTS_POOL = new Pools.SynchronizedPool<>(3);
|
|
11
|
-
private String mMessage;
|
|
12
|
-
private CameraMountErrorEvent() {}
|
|
13
|
-
|
|
14
|
-
public static CameraMountErrorEvent obtain(String message) {
|
|
15
|
-
CameraMountErrorEvent event = EVENTS_POOL.acquire();
|
|
16
|
-
if (event == null) {
|
|
17
|
-
event = new CameraMountErrorEvent();
|
|
18
|
-
}
|
|
19
|
-
event.init(message);
|
|
20
|
-
return event;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
private void init(String message) {
|
|
24
|
-
mMessage = message;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
@Override
|
|
28
|
-
public String getEventName() {
|
|
29
|
-
return CameraViewManager.Events.EVENT_ON_MOUNT_ERROR.toString();
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
@Override
|
|
33
|
-
public Bundle getEventBody() {
|
|
34
|
-
Bundle event = new Bundle();
|
|
35
|
-
event.putString("message", mMessage);
|
|
36
|
-
return event;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
package expo.modules.camera.events;
|
|
2
|
-
|
|
3
|
-
import android.os.Bundle;
|
|
4
|
-
import androidx.core.util.Pools;
|
|
5
|
-
|
|
6
|
-
import expo.modules.core.interfaces.services.EventEmitter;
|
|
7
|
-
import expo.modules.camera.CameraViewManager;
|
|
8
|
-
|
|
9
|
-
public class CameraReadyEvent extends EventEmitter.BaseEvent {
|
|
10
|
-
private static final Pools.SynchronizedPool<CameraReadyEvent> EVENTS_POOL = new Pools.SynchronizedPool<>(3);
|
|
11
|
-
private CameraReadyEvent() {}
|
|
12
|
-
|
|
13
|
-
public static CameraReadyEvent obtain() {
|
|
14
|
-
CameraReadyEvent event = EVENTS_POOL.acquire();
|
|
15
|
-
if (event == null) {
|
|
16
|
-
event = new CameraReadyEvent();
|
|
17
|
-
}
|
|
18
|
-
return event;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
@Override
|
|
22
|
-
public String getEventName() {
|
|
23
|
-
return CameraViewManager.Events.EVENT_CAMERA_READY.toString();
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
@Override
|
|
27
|
-
public Bundle getEventBody() {
|
|
28
|
-
return Bundle.EMPTY;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
package expo.modules.camera.events;
|
|
2
|
-
|
|
3
|
-
import android.os.Bundle;
|
|
4
|
-
import androidx.core.util.Pools;
|
|
5
|
-
|
|
6
|
-
import expo.modules.core.interfaces.services.EventEmitter;
|
|
7
|
-
|
|
8
|
-
import expo.modules.camera.CameraViewManager;
|
|
9
|
-
import expo.modules.interfaces.facedetector.FaceDetectorInterface;
|
|
10
|
-
|
|
11
|
-
public class FaceDetectionErrorEvent extends EventEmitter.BaseEvent {
|
|
12
|
-
private static final Pools.SynchronizedPool<FaceDetectionErrorEvent> EVENTS_POOL = new Pools.SynchronizedPool<>(3);
|
|
13
|
-
private FaceDetectorInterface mFaceDetector;
|
|
14
|
-
|
|
15
|
-
private FaceDetectionErrorEvent() {
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
public static FaceDetectionErrorEvent obtain(FaceDetectorInterface faceDetector) {
|
|
19
|
-
FaceDetectionErrorEvent event = EVENTS_POOL.acquire();
|
|
20
|
-
if (event == null) {
|
|
21
|
-
event = new FaceDetectionErrorEvent();
|
|
22
|
-
}
|
|
23
|
-
event.init(faceDetector);
|
|
24
|
-
return event;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
private void init(FaceDetectorInterface faceDetector) {
|
|
28
|
-
mFaceDetector = faceDetector;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
@Override
|
|
32
|
-
public short getCoalescingKey() {
|
|
33
|
-
return 0;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
@Override
|
|
37
|
-
public String getEventName() {
|
|
38
|
-
return CameraViewManager.Events.EVENT_ON_MOUNT_ERROR.toString();
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
public Bundle getEventBody() {
|
|
42
|
-
Bundle map = new Bundle();
|
|
43
|
-
map.putBoolean("isOperational", isFaceDetectorOperational());
|
|
44
|
-
return map;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
private boolean isFaceDetectorOperational() {
|
|
48
|
-
return mFaceDetector != null;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
package expo.modules.camera.events;
|
|
2
|
-
|
|
3
|
-
import android.os.Bundle;
|
|
4
|
-
import androidx.core.util.Pools;
|
|
5
|
-
|
|
6
|
-
import java.util.List;
|
|
7
|
-
|
|
8
|
-
import expo.modules.core.interfaces.services.EventEmitter;
|
|
9
|
-
import expo.modules.camera.CameraViewManager;
|
|
10
|
-
|
|
11
|
-
public class FacesDetectedEvent extends EventEmitter.BaseEvent {
|
|
12
|
-
private static final Pools.SynchronizedPool<FacesDetectedEvent> EVENTS_POOL =
|
|
13
|
-
new Pools.SynchronizedPool<>(3);
|
|
14
|
-
|
|
15
|
-
private List<Bundle> mFaces;
|
|
16
|
-
private int mViewTag;
|
|
17
|
-
|
|
18
|
-
private FacesDetectedEvent() {}
|
|
19
|
-
|
|
20
|
-
public static FacesDetectedEvent obtain(int viewTag, List<Bundle> faces) {
|
|
21
|
-
FacesDetectedEvent event = EVENTS_POOL.acquire();
|
|
22
|
-
if (event == null) {
|
|
23
|
-
event = new FacesDetectedEvent();
|
|
24
|
-
}
|
|
25
|
-
event.init(viewTag, faces);
|
|
26
|
-
return event;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
private void init(int viewTag, List<Bundle> faces) {
|
|
30
|
-
mViewTag = viewTag;
|
|
31
|
-
mFaces = faces;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* note(@sjchmiela)
|
|
36
|
-
* Should events about detected faces coalesce, the best strategy will be
|
|
37
|
-
* to ensure that events with different faces count are always being transmitted.
|
|
38
|
-
*/
|
|
39
|
-
@Override
|
|
40
|
-
public short getCoalescingKey() {
|
|
41
|
-
if (mFaces.size() > Short.MAX_VALUE) {
|
|
42
|
-
return Short.MAX_VALUE;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return (short) mFaces.size();
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
@Override
|
|
49
|
-
public String getEventName() {
|
|
50
|
-
return CameraViewManager.Events.EVENT_ON_FACES_DETECTED.toString();
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
@Override
|
|
54
|
-
public Bundle getEventBody() {
|
|
55
|
-
Bundle event = new Bundle();
|
|
56
|
-
event.putString("type", "face");
|
|
57
|
-
Bundle[] bundle = new Bundle[mFaces.size()];
|
|
58
|
-
mFaces.toArray(bundle);
|
|
59
|
-
event.putParcelableArray("faces", bundle);
|
|
60
|
-
event.putInt("target", mViewTag);
|
|
61
|
-
return event;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
package expo.modules.camera.events;
|
|
2
|
-
|
|
3
|
-
import android.os.Bundle;
|
|
4
|
-
import androidx.core.util.Pools;
|
|
5
|
-
|
|
6
|
-
import expo.modules.core.interfaces.services.EventEmitter;
|
|
7
|
-
import expo.modules.camera.CameraViewManager;
|
|
8
|
-
|
|
9
|
-
public class PictureSavedEvent extends EventEmitter.BaseEvent {
|
|
10
|
-
private static final Pools.SynchronizedPool<PictureSavedEvent> EVENTS_POOL =
|
|
11
|
-
new Pools.SynchronizedPool<>(3);
|
|
12
|
-
|
|
13
|
-
private Bundle mResponse;
|
|
14
|
-
|
|
15
|
-
private PictureSavedEvent() {}
|
|
16
|
-
|
|
17
|
-
public static PictureSavedEvent obtain(Bundle response) {
|
|
18
|
-
PictureSavedEvent event = EVENTS_POOL.acquire();
|
|
19
|
-
if (event == null) {
|
|
20
|
-
event = new PictureSavedEvent();
|
|
21
|
-
}
|
|
22
|
-
event.init(response);
|
|
23
|
-
return event;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
private void init(Bundle response) {
|
|
27
|
-
mResponse = response;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
@Override
|
|
31
|
-
public short getCoalescingKey() {
|
|
32
|
-
short fallback = -1;
|
|
33
|
-
Bundle data = mResponse.getBundle("data");
|
|
34
|
-
if (data == null || !data.containsKey("uri")) {
|
|
35
|
-
return fallback;
|
|
36
|
-
}
|
|
37
|
-
String uri = data.getString("uri");
|
|
38
|
-
if (uri == null) {
|
|
39
|
-
return fallback;
|
|
40
|
-
}
|
|
41
|
-
return (short) (uri.hashCode() % Short.MAX_VALUE);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
@Override
|
|
45
|
-
public String getEventName() {
|
|
46
|
-
return CameraViewManager.Events.EVENT_ON_PICTURE_SAVED.toString();
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
@Override
|
|
50
|
-
public Bundle getEventBody() {
|
|
51
|
-
return mResponse;
|
|
52
|
-
}
|
|
53
|
-
}
|