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.
Files changed (55) hide show
  1. package/CHANGELOG.md +23 -2
  2. package/README.md +1 -1
  3. package/android/build.gradle +22 -19
  4. package/android/src/main/java/expo/modules/camera/CameraModule.kt +217 -0
  5. package/android/src/main/java/expo/modules/camera/CameraPackage.kt +10 -0
  6. package/android/src/main/java/expo/modules/camera/CameraViewHelper.kt +139 -0
  7. package/android/src/main/java/expo/modules/camera/CameraViewManager.kt +116 -0
  8. package/android/src/main/java/expo/modules/camera/Constants.kt +184 -0
  9. package/android/src/main/java/expo/modules/camera/ExpoCameraView.kt +329 -0
  10. package/android/src/main/java/expo/modules/camera/events/BarCodeScannedEvent.kt +50 -0
  11. package/android/src/main/java/expo/modules/camera/events/CameraMountErrorEvent.kt +33 -0
  12. package/android/src/main/java/expo/modules/camera/events/CameraReadyEvent.kt +23 -0
  13. package/android/src/main/java/expo/modules/camera/events/FaceDetectionErrorEvent.kt +39 -0
  14. package/android/src/main/java/expo/modules/camera/events/FacesDetectedEvent.kt +46 -0
  15. package/android/src/main/java/expo/modules/camera/events/PictureSavedEvent.kt +41 -0
  16. package/android/src/main/java/expo/modules/camera/tasks/BarCodeScannerAsyncTask.kt +26 -0
  17. package/android/src/main/java/expo/modules/camera/tasks/BarCodeScannerAsyncTaskDelegate.kt +8 -0
  18. package/android/src/main/java/expo/modules/camera/tasks/FaceDetectorAsyncTaskDelegate.kt +10 -0
  19. package/android/src/main/java/expo/modules/camera/tasks/FaceDetectorTask.kt +34 -0
  20. package/android/src/main/java/expo/modules/camera/tasks/PictureSavedDelegate.kt +7 -0
  21. package/android/src/main/java/expo/modules/camera/tasks/ResolveTakenPictureAsyncTask.kt +231 -0
  22. package/android/src/main/java/expo/modules/camera/utils/FileSystemUtils.kt +23 -0
  23. package/android/src/main/java/expo/modules/camera/utils/ImageDimensions.kt +14 -0
  24. package/build/ExponentCameraManager.web.js +3 -1
  25. package/build/ExponentCameraManager.web.js.map +1 -1
  26. package/ios/EXCamera.xcframework/ios-arm64/EXCamera.framework/EXCamera +0 -0
  27. package/ios/EXCamera.xcframework/ios-arm64/EXCamera.framework/Info.plist +0 -0
  28. package/ios/EXCamera.xcframework/ios-arm64_x86_64-simulator/EXCamera.framework/EXCamera +0 -0
  29. package/ios/EXCamera.xcframework/ios-arm64_x86_64-simulator/EXCamera.framework/Info.plist +0 -0
  30. package/package.json +7 -5
  31. package/plugin/build/withCamera.d.ts +2 -1
  32. package/plugin/build/withCamera.js +50 -30
  33. package/plugin/src/withCamera.ts +66 -27
  34. package/src/ExponentCameraManager.web.ts +3 -2
  35. package/src/{types → ts-declarations}/image-capture.d.ts +0 -0
  36. package/src/ts-declarations/lib.dom.d.ts +34 -0
  37. package/android/src/main/java/expo/modules/camera/CameraModule.java +0 -359
  38. package/android/src/main/java/expo/modules/camera/CameraPackage.java +0 -23
  39. package/android/src/main/java/expo/modules/camera/CameraViewHelper.java +0 -294
  40. package/android/src/main/java/expo/modules/camera/CameraViewManager.java +0 -142
  41. package/android/src/main/java/expo/modules/camera/ExpoCameraView.java +0 -376
  42. package/android/src/main/java/expo/modules/camera/events/BarCodeScannedEvent.java +0 -59
  43. package/android/src/main/java/expo/modules/camera/events/CameraMountErrorEvent.java +0 -38
  44. package/android/src/main/java/expo/modules/camera/events/CameraReadyEvent.java +0 -30
  45. package/android/src/main/java/expo/modules/camera/events/FaceDetectionErrorEvent.java +0 -50
  46. package/android/src/main/java/expo/modules/camera/events/FacesDetectedEvent.java +0 -63
  47. package/android/src/main/java/expo/modules/camera/events/PictureSavedEvent.java +0 -53
  48. package/android/src/main/java/expo/modules/camera/tasks/BarCodeScannerAsyncTask.java +0 -47
  49. package/android/src/main/java/expo/modules/camera/tasks/BarCodeScannerAsyncTaskDelegate.java +0 -8
  50. package/android/src/main/java/expo/modules/camera/tasks/FaceDetectorAsyncTaskDelegate.java +0 -13
  51. package/android/src/main/java/expo/modules/camera/tasks/FaceDetectorTask.java +0 -53
  52. package/android/src/main/java/expo/modules/camera/tasks/PictureSavedDelegate.java +0 -7
  53. package/android/src/main/java/expo/modules/camera/tasks/ResolveTakenPictureAsyncTask.java +0 -288
  54. package/android/src/main/java/expo/modules/camera/utils/FileSystemUtils.java +0 -21
  55. package/android/src/main/java/expo/modules/camera/utils/ImageDimensions.java +0 -64
@@ -1,18 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.setGradleMaven = void 0;
3
+ exports.addCameraImport = void 0;
4
4
  const config_plugins_1 = require("@expo/config-plugins");
5
+ const generateCode_1 = require("@expo/config-plugins/build/utils/generateCode");
5
6
  const pkg = require('expo-camera/package.json');
6
7
  const CAMERA_USAGE = 'Allow $(PRODUCT_NAME) to access your camera';
7
8
  const MICROPHONE_USAGE = 'Allow $(PRODUCT_NAME) to access your microphone';
8
9
  // Because we need the package to be added AFTER the React and Google maven packages, we create a new allprojects.
9
10
  // It's ok to have multiple allprojects.repositories, so we create a new one since it's cheaper than tokenizing
10
11
  // the existing block to find the correct place to insert our camera maven.
11
- const gradleMaven = 'allprojects { repositories { maven { url "$rootDir/../node_modules/expo-camera/android/maven" } } }';
12
+ const gradleMaven = [
13
+ `def expoCameraMavenPath = new File(["node", "--print", "require.resolve('expo-camera/package.json')"].execute(null, rootDir).text.trim(), "../android/maven")`,
14
+ `allprojects { repositories { maven { url(expoCameraMavenPath) } } }`,
15
+ ].join('\n');
12
16
  const withAndroidCameraGradle = (config) => {
13
- return config_plugins_1.withProjectBuildGradle(config, (config) => {
17
+ return (0, config_plugins_1.withProjectBuildGradle)(config, (config) => {
14
18
  if (config.modResults.language === 'groovy') {
15
- config.modResults.contents = setGradleMaven(config.modResults.contents);
19
+ config.modResults.contents = addCameraImport(config.modResults.contents).contents;
16
20
  }
17
21
  else {
18
22
  throw new Error('Cannot add camera maven gradle because the build.gradle is not groovy');
@@ -20,34 +24,50 @@ const withAndroidCameraGradle = (config) => {
20
24
  return config;
21
25
  });
22
26
  };
23
- function setGradleMaven(buildGradle) {
24
- // If this specific line is present, skip.
25
- // This also enables users in bare workflow to comment out the line to prevent expo-camera from adding it back.
26
- if (buildGradle.includes('expo-camera/android/maven')) {
27
- return buildGradle;
27
+ function addCameraImport(src) {
28
+ return appendContents({
29
+ tag: 'expo-camera-import',
30
+ src,
31
+ newSrc: gradleMaven,
32
+ comment: '//',
33
+ });
34
+ }
35
+ exports.addCameraImport = addCameraImport;
36
+ // Fork of config-plugins mergeContents, but appends the contents to the end of the file.
37
+ function appendContents({ src, newSrc, tag, comment, }) {
38
+ const header = (0, generateCode_1.createGeneratedHeaderComment)(newSrc, tag, comment);
39
+ if (!src.includes(header)) {
40
+ // Ensure the old generated contents are removed.
41
+ const sanitizedTarget = (0, generateCode_1.removeGeneratedContents)(src, tag);
42
+ const contentsToAdd = [
43
+ // @something
44
+ header,
45
+ // contents
46
+ newSrc,
47
+ // @end
48
+ `${comment} @generated end ${tag}`,
49
+ ].join('\n');
50
+ return {
51
+ contents: sanitizedTarget !== null && sanitizedTarget !== void 0 ? sanitizedTarget : src + contentsToAdd,
52
+ didMerge: true,
53
+ didClear: !!sanitizedTarget,
54
+ };
28
55
  }
29
- return buildGradle + `\n${gradleMaven}\n`;
56
+ return { contents: src, didClear: false, didMerge: false };
30
57
  }
31
- exports.setGradleMaven = setGradleMaven;
32
58
  const withCamera = (config, { cameraPermission, microphonePermission } = {}) => {
33
- if (!config.ios)
34
- config.ios = {};
35
- if (!config.ios.infoPlist)
36
- config.ios.infoPlist = {};
37
- config.ios.infoPlist.NSCameraUsageDescription =
38
- cameraPermission || config.ios.infoPlist.NSCameraUsageDescription || CAMERA_USAGE;
39
- config.ios.infoPlist.NSMicrophoneUsageDescription =
40
- microphonePermission || config.ios.infoPlist.NSMicrophoneUsageDescription || MICROPHONE_USAGE;
41
- return config_plugins_1.withPlugins(config, [
42
- [
43
- config_plugins_1.AndroidConfig.Permissions.withPermissions,
44
- [
45
- 'android.permission.CAMERA',
46
- // Optional
47
- 'android.permission.RECORD_AUDIO',
48
- ],
49
- ],
50
- withAndroidCameraGradle,
59
+ config = (0, config_plugins_1.withInfoPlist)(config, (config) => {
60
+ config.modResults.NSCameraUsageDescription =
61
+ cameraPermission || config.modResults.NSCameraUsageDescription || CAMERA_USAGE;
62
+ config.modResults.NSMicrophoneUsageDescription =
63
+ microphonePermission || config.modResults.NSMicrophoneUsageDescription || MICROPHONE_USAGE;
64
+ return config;
65
+ });
66
+ config = config_plugins_1.AndroidConfig.Permissions.withPermissions(config, [
67
+ 'android.permission.CAMERA',
68
+ // Optional
69
+ 'android.permission.RECORD_AUDIO',
51
70
  ]);
71
+ return withAndroidCameraGradle(config);
52
72
  };
53
- exports.default = config_plugins_1.createRunOncePlugin(withCamera, pkg.name, pkg.version);
73
+ exports.default = (0, config_plugins_1.createRunOncePlugin)(withCamera, pkg.name, pkg.version);
@@ -1,10 +1,15 @@
1
1
  import {
2
- withPlugins,
3
2
  AndroidConfig,
4
3
  withProjectBuildGradle,
5
4
  ConfigPlugin,
6
5
  createRunOncePlugin,
6
+ withInfoPlist,
7
7
  } from '@expo/config-plugins';
8
+ import {
9
+ createGeneratedHeaderComment,
10
+ MergeResults,
11
+ removeGeneratedContents,
12
+ } from '@expo/config-plugins/build/utils/generateCode';
8
13
 
9
14
  const pkg = require('expo-camera/package.json');
10
15
 
@@ -14,13 +19,15 @@ const MICROPHONE_USAGE = 'Allow $(PRODUCT_NAME) to access your microphone';
14
19
  // Because we need the package to be added AFTER the React and Google maven packages, we create a new allprojects.
15
20
  // It's ok to have multiple allprojects.repositories, so we create a new one since it's cheaper than tokenizing
16
21
  // the existing block to find the correct place to insert our camera maven.
17
- const gradleMaven =
18
- 'allprojects { repositories { maven { url "$rootDir/../node_modules/expo-camera/android/maven" } } }';
22
+ const gradleMaven = [
23
+ `def expoCameraMavenPath = new File(["node", "--print", "require.resolve('expo-camera/package.json')"].execute(null, rootDir).text.trim(), "../android/maven")`,
24
+ `allprojects { repositories { maven { url(expoCameraMavenPath) } } }`,
25
+ ].join('\n');
19
26
 
20
27
  const withAndroidCameraGradle: ConfigPlugin = (config) => {
21
28
  return withProjectBuildGradle(config, (config) => {
22
29
  if (config.modResults.language === 'groovy') {
23
- config.modResults.contents = setGradleMaven(config.modResults.contents);
30
+ config.modResults.contents = addCameraImport(config.modResults.contents).contents;
24
31
  } else {
25
32
  throw new Error('Cannot add camera maven gradle because the build.gradle is not groovy');
26
33
  }
@@ -28,38 +35,70 @@ const withAndroidCameraGradle: ConfigPlugin = (config) => {
28
35
  });
29
36
  };
30
37
 
31
- export function setGradleMaven(buildGradle: string): string {
32
- // If this specific line is present, skip.
33
- // This also enables users in bare workflow to comment out the line to prevent expo-camera from adding it back.
34
- if (buildGradle.includes('expo-camera/android/maven')) {
35
- return buildGradle;
36
- }
38
+ export function addCameraImport(src: string): MergeResults {
39
+ return appendContents({
40
+ tag: 'expo-camera-import',
41
+ src,
42
+ newSrc: gradleMaven,
43
+ comment: '//',
44
+ });
45
+ }
46
+
47
+ // Fork of config-plugins mergeContents, but appends the contents to the end of the file.
48
+ function appendContents({
49
+ src,
50
+ newSrc,
51
+ tag,
52
+ comment,
53
+ }: {
54
+ src: string;
55
+ newSrc: string;
56
+ tag: string;
57
+ comment: string;
58
+ }): MergeResults {
59
+ const header = createGeneratedHeaderComment(newSrc, tag, comment);
60
+ if (!src.includes(header)) {
61
+ // Ensure the old generated contents are removed.
62
+ const sanitizedTarget = removeGeneratedContents(src, tag);
63
+ const contentsToAdd = [
64
+ // @something
65
+ header,
66
+ // contents
67
+ newSrc,
68
+ // @end
69
+ `${comment} @generated end ${tag}`,
70
+ ].join('\n');
37
71
 
38
- return buildGradle + `\n${gradleMaven}\n`;
72
+ return {
73
+ contents: sanitizedTarget ?? src + contentsToAdd,
74
+ didMerge: true,
75
+ didClear: !!sanitizedTarget,
76
+ };
77
+ }
78
+ return { contents: src, didClear: false, didMerge: false };
39
79
  }
40
80
 
41
81
  const withCamera: ConfigPlugin<{
42
82
  cameraPermission?: string;
43
83
  microphonePermission?: string;
44
84
  } | void> = (config, { cameraPermission, microphonePermission } = {}) => {
45
- if (!config.ios) config.ios = {};
46
- if (!config.ios.infoPlist) config.ios.infoPlist = {};
47
- config.ios.infoPlist.NSCameraUsageDescription =
48
- cameraPermission || config.ios.infoPlist.NSCameraUsageDescription || CAMERA_USAGE;
49
- config.ios.infoPlist.NSMicrophoneUsageDescription =
50
- microphonePermission || config.ios.infoPlist.NSMicrophoneUsageDescription || MICROPHONE_USAGE;
85
+ config = withInfoPlist(config, (config) => {
86
+ config.modResults.NSCameraUsageDescription =
87
+ cameraPermission || config.modResults.NSCameraUsageDescription || CAMERA_USAGE;
51
88
 
52
- return withPlugins(config, [
53
- [
54
- AndroidConfig.Permissions.withPermissions,
55
- [
56
- 'android.permission.CAMERA',
57
- // Optional
58
- 'android.permission.RECORD_AUDIO',
59
- ],
60
- ],
61
- withAndroidCameraGradle,
89
+ config.modResults.NSMicrophoneUsageDescription =
90
+ microphonePermission || config.modResults.NSMicrophoneUsageDescription || MICROPHONE_USAGE;
91
+
92
+ return config;
93
+ });
94
+
95
+ config = AndroidConfig.Permissions.withPermissions(config, [
96
+ 'android.permission.CAMERA',
97
+ // Optional
98
+ 'android.permission.RECORD_AUDIO',
62
99
  ]);
100
+
101
+ return withAndroidCameraGradle(config);
63
102
  };
64
103
 
65
104
  export default createRunOncePlugin(withCamera, pkg.name, pkg.version);
@@ -25,9 +25,10 @@ function getUserMedia(constraints: MediaStreamConstraints): Promise<MediaStream>
25
25
 
26
26
  // First get ahold of the legacy getUserMedia, if present
27
27
  const getUserMedia =
28
+ // TODO: this method is deprecated, migrate to https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
28
29
  navigator.getUserMedia ||
29
- (navigator as any).webkitGetUserMedia ||
30
- (navigator as any).mozGetUserMedia ||
30
+ navigator.webkitGetUserMedia ||
31
+ navigator.mozGetUserMedia ||
31
32
  function () {
32
33
  const error: any = new Error('Permission unimplemented');
33
34
  error.code = 0;
@@ -0,0 +1,34 @@
1
+ // Expose this file as a module (see https://stackoverflow.com/a/59499895/4337317)
2
+ export {};
3
+
4
+ /**
5
+ * Handle deprecations and missing typings that not available in the main lib.dom.d.ts file.
6
+ */
7
+ declare global {
8
+ type GetUserMediaFunctionType = (
9
+ constraints: MediaStreamConstraints,
10
+ successCallback: () => MediaStream,
11
+ failureCallback: () => DOMException
12
+ ) => undefined;
13
+ interface Navigator {
14
+ /**
15
+ * This method has been deprecated: https://developer.mozilla.org/en-US/docs/Web/API/Navigator/getUserMedia
16
+ * TODO: migrate to https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
17
+ */
18
+ getUserMedia?: GetUserMediaFunctionType;
19
+ webkitGetUserMedia?: GetUserMediaFunctionType;
20
+ mozGetUserMedia?: GetUserMediaFunctionType;
21
+ }
22
+
23
+ type PermissionNameWithAdditionalValues = PermissionName | 'camera' | 'microphone';
24
+
25
+ // TODO: remove once "microphone" name is added to the PermissionName union type exposed by the main lib.dom.d.ts file.
26
+ interface Permissions {
27
+ // Replace original PermissionDescriptor with our own that includes missing permission names (e.g. "microphone")
28
+ query(permissionDesc: PermissionDescriptorWithAdditionalValues): Promise<PermissionStatus>;
29
+ }
30
+
31
+ interface PermissionDescriptorWithAdditionalValues {
32
+ name: PermissionNameWithAdditionalValues;
33
+ }
34
+ }
@@ -1,359 +0,0 @@
1
- package expo.modules.camera;
2
-
3
- import android.Manifest;
4
- import android.content.Context;
5
- import android.graphics.Bitmap;
6
- import android.os.Build;
7
-
8
- import com.google.android.cameraview.AspectRatio;
9
- import com.google.android.cameraview.Constants;
10
- import com.google.android.cameraview.Size;
11
-
12
- import expo.modules.core.ExportedModule;
13
- import expo.modules.core.ModuleRegistry;
14
- import expo.modules.core.Promise;
15
- import expo.modules.core.interfaces.ExpoMethod;
16
- import expo.modules.core.interfaces.services.UIManager;
17
-
18
- import java.io.File;
19
- import java.util.ArrayList;
20
- import java.util.Collections;
21
- import java.util.HashMap;
22
- import java.util.List;
23
- import java.util.Map;
24
- import java.util.Set;
25
- import java.util.SortedSet;
26
-
27
- import expo.modules.camera.tasks.ResolveTakenPictureAsyncTask;
28
- import expo.modules.interfaces.permissions.Permissions;
29
-
30
- public class CameraModule extends ExportedModule {
31
- private static final String TAG = "ExponentCameraModule";
32
- private static final String ERROR_TAG = "E_CAMERA";
33
- private ModuleRegistry mModuleRegistry;
34
-
35
- static final int VIDEO_2160P = 0;
36
- static final int VIDEO_1080P = 1;
37
- static final int VIDEO_720P = 2;
38
- static final int VIDEO_480P = 3;
39
- static final int VIDEO_4x3 = 4;
40
-
41
- public CameraModule(Context context) {
42
- super(context);
43
- }
44
-
45
- @Override
46
- public void onCreate(ModuleRegistry moduleRegistry) {
47
- mModuleRegistry = moduleRegistry;
48
- }
49
-
50
- @Override
51
- public String getName() {
52
- return TAG;
53
- }
54
-
55
- @Override
56
- public Map<String, Object> getConstants() {
57
- return Collections.unmodifiableMap(new HashMap<String, Object>() {
58
- {
59
- put("Type", getTypeConstants());
60
- put("FlashMode", getFlashModeConstants());
61
- put("AutoFocus", getAutoFocusConstants());
62
- put("WhiteBalance", getWhiteBalanceConstants());
63
- put("VideoQuality", getVideoQualityConstants());
64
- put("FaceDetection", Collections.unmodifiableMap(new HashMap<>()));
65
- }
66
-
67
- private Map<String, Object> getTypeConstants() {
68
- return Collections.unmodifiableMap(new HashMap<String, Object>() {
69
- {
70
- put("front", Constants.FACING_FRONT);
71
- put("back", Constants.FACING_BACK);
72
- }
73
- });
74
- }
75
-
76
- private Map<String, Object> getFlashModeConstants() {
77
- return Collections.unmodifiableMap(new HashMap<String, Object>() {
78
- {
79
- put("off", Constants.FLASH_OFF);
80
- put("on", Constants.FLASH_ON);
81
- put("auto", Constants.FLASH_AUTO);
82
- put("torch", Constants.FLASH_TORCH);
83
- }
84
- });
85
- }
86
-
87
- private Map<String, Object> getAutoFocusConstants() {
88
- return Collections.unmodifiableMap(new HashMap<String, Object>() {
89
- {
90
- put("on", true);
91
- put("off", false);
92
- }
93
- });
94
- }
95
-
96
- private Map<String, Object> getWhiteBalanceConstants() {
97
- return Collections.unmodifiableMap(new HashMap<String, Object>() {
98
- {
99
- put("auto", Constants.WB_AUTO);
100
- put("cloudy", Constants.WB_CLOUDY);
101
- put("sunny", Constants.WB_SUNNY);
102
- put("shadow", Constants.WB_SHADOW);
103
- put("fluorescent", Constants.WB_FLUORESCENT);
104
- put("incandescent", Constants.WB_INCANDESCENT);
105
- }
106
- });
107
- }
108
-
109
- private Map<String, Object> getVideoQualityConstants() {
110
- return Collections.unmodifiableMap(new HashMap<String, Object>() {
111
- {
112
- put("2160p", VIDEO_2160P);
113
- put("1080p", VIDEO_1080P);
114
- put("720p", VIDEO_720P);
115
- put("480p", VIDEO_480P);
116
- put("4:3", VIDEO_4x3);
117
- }
118
- });
119
- }
120
- });
121
- }
122
-
123
- @ExpoMethod
124
- public void pausePreview(final int viewTag, final Promise promise) {
125
- addUIBlock(viewTag, new UIManager.UIBlock<ExpoCameraView>() {
126
- @Override
127
- public void resolve(ExpoCameraView view) {
128
- try {
129
- if (view.isCameraOpened()) {
130
- view.pausePreview();
131
- }
132
- } catch (Exception e) {
133
- promise.reject(ERROR_TAG, "pausePreview -- exception occurred -- " + e.getMessage(), e);
134
- }
135
- }
136
-
137
- @Override
138
- public void reject(Throwable throwable) {
139
- promise.reject(ERROR_TAG, throwable);
140
- }
141
- });
142
- }
143
-
144
- @ExpoMethod
145
- public void resumePreview(final int viewTag, final Promise promise) {
146
- addUIBlock(viewTag, new UIManager.UIBlock<ExpoCameraView>() {
147
- @Override
148
- public void resolve(ExpoCameraView view) {
149
- try {
150
- if (view.isCameraOpened()) {
151
- view.resumePreview();
152
- }
153
- } catch (Exception e) {
154
- promise.reject(ERROR_TAG, "resumePreview -- exception occurred -- " + e.getMessage(), e);
155
- }
156
- }
157
-
158
- @Override
159
- public void reject(Throwable throwable) {
160
- promise.reject(ERROR_TAG, throwable);
161
- }
162
- });
163
- }
164
-
165
- @ExpoMethod
166
- public void takePicture(final Map<String, Object> options, final int viewTag, final Promise promise) {
167
- final File cacheDirectory = getContext().getCacheDir();
168
- addUIBlock(viewTag, new UIManager.UIBlock<ExpoCameraView>() {
169
- @Override
170
- public void resolve(ExpoCameraView view) {
171
- if (!Build.FINGERPRINT.contains("generic")) {
172
- if (view.isCameraOpened()) {
173
- view.takePicture(options, promise, cacheDirectory);
174
- } else {
175
- promise.reject("E_CAMERA_UNAVAILABLE", "Camera is not running");
176
- }
177
- } else {
178
- Bitmap image = CameraViewHelper.generateSimulatorPhoto(view.getWidth(), view.getHeight());
179
- new ResolveTakenPictureAsyncTask(image, promise, options, cacheDirectory, view).execute();
180
- }
181
- }
182
-
183
- @Override
184
- public void reject(Throwable throwable) {
185
- promise.reject(ERROR_TAG, throwable);
186
- }
187
- });
188
- }
189
-
190
- @ExpoMethod
191
- public void record(final Map<String, Object> options, final int viewTag, final Promise promise) {
192
- Permissions permissionsManager = mModuleRegistry.getModule(Permissions.class);
193
- if (permissionsManager == null) {
194
- promise.reject("E_NO_PERMISSIONS", "Permissions module is null. Are you sure all the installed Expo modules are properly linked?");
195
- return;
196
- }
197
- if (permissionsManager.hasGrantedPermissions(Manifest.permission.RECORD_AUDIO)) {
198
- final File cacheDirectory = getContext().getCacheDir();
199
- addUIBlock(viewTag, new UIManager.UIBlock<ExpoCameraView>() {
200
- @Override
201
- public void resolve(ExpoCameraView view) {
202
- if (view.isCameraOpened()) {
203
- view.record(options, promise, cacheDirectory);
204
- } else {
205
- promise.reject("E_CAMERA_UNAVAILABLE", "Camera is not running");
206
- }
207
- }
208
-
209
- @Override
210
- public void reject(Throwable throwable) {
211
- promise.reject(ERROR_TAG, throwable);
212
- }
213
- });
214
- } else {
215
- promise.reject(new SecurityException("User rejected audio permissions"));
216
- }
217
- }
218
-
219
- @ExpoMethod
220
- public void stopRecording(final int viewTag, final Promise promise) {
221
- addUIBlock(viewTag, new UIManager.UIBlock<ExpoCameraView>() {
222
- @Override
223
- public void resolve(ExpoCameraView view) {
224
- if (view.isCameraOpened()) {
225
- view.stopRecording();
226
- promise.resolve(true);
227
- } else {
228
- promise.reject(ERROR_TAG, "Camera is not open");
229
- }
230
- }
231
-
232
- @Override
233
- public void reject(Throwable throwable) {
234
- promise.reject(ERROR_TAG, throwable);
235
- }
236
- });
237
- }
238
-
239
- @ExpoMethod
240
- public void getSupportedRatios(final int viewTag, final Promise promise) {
241
- addUIBlock(viewTag, new UIManager.UIBlock<ExpoCameraView>() {
242
- @Override
243
- public void resolve(ExpoCameraView view) {
244
- if (view.isCameraOpened()) {
245
- Set<AspectRatio> ratios = view.getSupportedAspectRatios();
246
- List<String> supportedRatios = new ArrayList<>(ratios.size());
247
- for (AspectRatio ratio : ratios) {
248
- supportedRatios.add(ratio.toString());
249
- }
250
- promise.resolve(supportedRatios);
251
- } else {
252
- promise.reject(ERROR_TAG, "Camera is not running");
253
- }
254
- }
255
-
256
- @Override
257
- public void reject(Throwable throwable) {
258
- promise.reject(ERROR_TAG, throwable);
259
- }
260
- });
261
- }
262
-
263
- @ExpoMethod
264
- public void getAvailablePictureSizes(final String ratio, final int viewTag, final Promise promise) {
265
- addUIBlock(viewTag, new UIManager.UIBlock<ExpoCameraView>() {
266
- @Override
267
- public void resolve(ExpoCameraView view) {
268
- if (view.isCameraOpened()) {
269
- try {
270
- SortedSet<Size> sizes = view.getAvailablePictureSizes(AspectRatio.parse(ratio));
271
- List<String> result = new ArrayList<>(sizes.size());
272
- for (Size size : sizes) {
273
- result.add(size.toString());
274
- }
275
- promise.resolve(result);
276
- } catch (Exception e) {
277
- promise.reject(ERROR_TAG, "getAvailablePictureSizes -- unexpected error -- " + e.getMessage(), e);
278
- }
279
- } else {
280
- promise.reject(ERROR_TAG, "Camera is not running");
281
- }
282
- }
283
-
284
- @Override
285
- public void reject(Throwable throwable) {
286
- promise.reject(ERROR_TAG, throwable);
287
- }
288
- });
289
- }
290
-
291
- private void addUIBlock(int viewTag, UIManager.UIBlock<ExpoCameraView> block) {
292
- UIManager manager = mModuleRegistry.getModule(UIManager.class);
293
- if (manager == null) {
294
- block.reject(new IllegalStateException("Implementation of " + UIManager.class.getName() + " is null. Are you sure you've included a proper Expo adapter for your platform?"));
295
- } else {
296
- manager.addUIBlock(viewTag, block, ExpoCameraView.class);
297
- }
298
- }
299
-
300
- @ExpoMethod
301
- public void requestPermissionsAsync(final Promise promise) {
302
- Permissions permissionsManager = mModuleRegistry.getModule(Permissions.class);
303
- if (permissionsManager == null) {
304
- promise.reject("E_NO_PERMISSIONS", "Permissions module is null. Are you sure all the installed Expo modules are properly linked?");
305
- return;
306
- }
307
- permissionsManager.askForPermissionsWithPromise(promise, Manifest.permission.CAMERA);
308
- }
309
-
310
- @ExpoMethod
311
- public void requestCameraPermissionsAsync(final Promise promise) {
312
- Permissions permissionsManager = mModuleRegistry.getModule(Permissions.class);
313
- if (permissionsManager == null) {
314
- promise.reject("E_NO_PERMISSIONS", "Permissions module is null. Are you sure all the installed Expo modules are properly linked?");
315
- return;
316
- }
317
- permissionsManager.askForPermissionsWithPromise(promise, Manifest.permission.CAMERA);
318
- }
319
-
320
- @ExpoMethod
321
- public void requestMicrophonePermissionsAsync(final Promise promise) {
322
- Permissions permissionsManager = mModuleRegistry.getModule(Permissions.class);
323
- if (permissionsManager == null) {
324
- promise.reject("E_NO_PERMISSIONS", "Permissions module is null. Are you sure all the installed Expo modules are properly linked?");
325
- return;
326
- }
327
- permissionsManager.askForPermissionsWithPromise(promise, Manifest.permission.RECORD_AUDIO);
328
- }
329
-
330
- @ExpoMethod
331
- public void getPermissionsAsync(final Promise promise) {
332
- Permissions permissionsManager = mModuleRegistry.getModule(Permissions.class);
333
- if (permissionsManager == null) {
334
- promise.reject("E_NO_PERMISSIONS", "Permissions module is null. Are you sure all the installed Expo modules are properly linked?");
335
- return;
336
- }
337
- permissionsManager.getPermissionsWithPromise(promise, Manifest.permission.CAMERA);
338
- }
339
-
340
- @ExpoMethod
341
- public void getCameraPermissionsAsync(final Promise promise) {
342
- Permissions permissionsManager = mModuleRegistry.getModule(Permissions.class);
343
- if (permissionsManager == null) {
344
- promise.reject("E_NO_PERMISSIONS", "Permissions module is null. Are you sure all the installed Expo modules are properly linked?");
345
- return;
346
- }
347
- permissionsManager.getPermissionsWithPromise(promise, Manifest.permission.CAMERA);
348
- }
349
-
350
- @ExpoMethod
351
- public void getMicrophonePermissionsAsync(final Promise promise) {
352
- Permissions permissionsManager = mModuleRegistry.getModule(Permissions.class);
353
- if (permissionsManager == null) {
354
- promise.reject("E_NO_PERMISSIONS", "Permissions module is null. Are you sure all the installed Expo modules are properly linked?");
355
- return;
356
- }
357
- permissionsManager.getPermissionsWithPromise(promise, Manifest.permission.RECORD_AUDIO);
358
- }
359
- }
@@ -1,23 +0,0 @@
1
-
2
- package expo.modules.camera;
3
-
4
- import android.content.Context;
5
-
6
- import java.util.Collections;
7
- import java.util.List;
8
-
9
- import expo.modules.core.ExportedModule;
10
- import expo.modules.core.BasePackage;
11
- import expo.modules.core.ViewManager;
12
-
13
- public class CameraPackage extends BasePackage {
14
- @Override
15
- public List<ExportedModule> createExportedModules(Context context) {
16
- return Collections.singletonList((ExportedModule) new CameraModule(context));
17
- }
18
-
19
- @Override
20
- public List<ViewManager> createViewManagers(Context context) {
21
- return Collections.singletonList((ViewManager) new CameraViewManager());
22
- }
23
- }