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,18 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
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 =
|
|
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 =
|
|
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
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
|
56
|
+
return { contents: src, didClear: false, didMerge: false };
|
|
30
57
|
}
|
|
31
|
-
exports.setGradleMaven = setGradleMaven;
|
|
32
58
|
const withCamera = (config, { cameraPermission, microphonePermission } = {}) => {
|
|
33
|
-
|
|
34
|
-
config.
|
|
35
|
-
|
|
36
|
-
config.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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);
|
package/plugin/src/withCamera.ts
CHANGED
|
@@ -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
|
-
|
|
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 =
|
|
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
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
-
|
|
30
|
-
|
|
30
|
+
navigator.webkitGetUserMedia ||
|
|
31
|
+
navigator.mozGetUserMedia ||
|
|
31
32
|
function () {
|
|
32
33
|
const error: any = new Error('Permission unimplemented');
|
|
33
34
|
error.code = 0;
|
|
File without changes
|
|
@@ -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
|
-
}
|