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
@@ -0,0 +1,46 @@
1
+ package expo.modules.camera.events
2
+
3
+ import android.os.Bundle
4
+ import androidx.core.util.Pools
5
+
6
+ import expo.modules.camera.CameraViewManager
7
+ import expo.modules.core.interfaces.services.EventEmitter.BaseEvent
8
+
9
+ class FacesDetectedEvent private constructor() : BaseEvent() {
10
+ private lateinit var faces: List<Bundle>
11
+ private var viewTag = 0
12
+
13
+ private fun init(viewTag: Int, faces: List<Bundle>) {
14
+ this.viewTag = viewTag
15
+ this.faces = faces
16
+ }
17
+
18
+ /**
19
+ * note(@sjchmiela)
20
+ * Should events about detected faces coalesce, the best strategy will be
21
+ * to ensure that events with different faces count are always being transmitted.
22
+ */
23
+ override fun getCoalescingKey() =
24
+ if (faces.size > Short.MAX_VALUE) Short.MAX_VALUE
25
+ else faces.size.toShort()
26
+
27
+ override fun getEventName() = CameraViewManager.Events.EVENT_ON_FACES_DETECTED.toString()
28
+
29
+ override fun getEventBody() = Bundle().apply {
30
+ putString("type", "face")
31
+ putParcelableArray("faces", faces.toTypedArray())
32
+ putInt("target", viewTag)
33
+ }
34
+
35
+ companion object {
36
+ private val EVENTS_POOL = Pools.SynchronizedPool<FacesDetectedEvent>(3)
37
+ fun obtain(viewTag: Int, faces: List<Bundle>): FacesDetectedEvent {
38
+ var event = EVENTS_POOL.acquire()
39
+ if (event == null) {
40
+ event = FacesDetectedEvent()
41
+ }
42
+ event.init(viewTag, faces)
43
+ return event
44
+ }
45
+ }
46
+ }
@@ -0,0 +1,41 @@
1
+ package expo.modules.camera.events
2
+
3
+ import android.os.Bundle
4
+ import androidx.core.util.Pools
5
+
6
+ import expo.modules.camera.CameraViewManager
7
+ import expo.modules.core.interfaces.services.EventEmitter.BaseEvent
8
+
9
+ class PictureSavedEvent private constructor() : BaseEvent() {
10
+ private lateinit var response: Bundle
11
+
12
+ private fun init(response: Bundle) {
13
+ this.response = response
14
+ }
15
+
16
+ override fun getCoalescingKey(): Short {
17
+ val fallback: Short = -1
18
+ val data = response
19
+ .getBundle("data")
20
+ ?.takeIf { it.containsKey("uri") }
21
+ ?: return fallback
22
+ val uri = data.getString("uri") ?: return fallback
23
+ return (uri.hashCode() % Short.MAX_VALUE).toShort()
24
+ }
25
+
26
+ override fun getEventName() = CameraViewManager.Events.EVENT_ON_PICTURE_SAVED.toString()
27
+
28
+ override fun getEventBody() = response
29
+
30
+ companion object {
31
+ private val EVENTS_POOL = Pools.SynchronizedPool<PictureSavedEvent>(3)
32
+ fun obtain(response: Bundle): PictureSavedEvent {
33
+ var event = EVENTS_POOL.acquire()
34
+ if (event == null) {
35
+ event = PictureSavedEvent()
36
+ }
37
+ event.init(response)
38
+ return event
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,26 @@
1
+ package expo.modules.camera.tasks
2
+
3
+ import android.os.AsyncTask
4
+
5
+ import expo.modules.interfaces.barcodescanner.BarCodeScannerInterface
6
+ import expo.modules.interfaces.barcodescanner.BarCodeScannerResult
7
+
8
+ class BarCodeScannerAsyncTask(
9
+ private val delegate: BarCodeScannerAsyncTaskDelegate,
10
+ private val barCodeScanner: BarCodeScannerInterface,
11
+ private val imageData: ByteArray,
12
+ private val width: Int,
13
+ private val height: Int,
14
+ private val rotation: Int
15
+ ) : AsyncTask<Void?, Void?, BarCodeScannerResult?>() {
16
+ override fun doInBackground(vararg params: Void?) = if (!isCancelled) {
17
+ barCodeScanner.scan(imageData, width, height, rotation)
18
+ } else null
19
+
20
+ override fun onPostExecute(result: BarCodeScannerResult?) {
21
+ super.onPostExecute(result)
22
+ result?.let {
23
+ delegate.onBarCodeScanned(result)
24
+ } ?: delegate.onBarCodeScanningTaskCompleted()
25
+ }
26
+ }
@@ -0,0 +1,8 @@
1
+ package expo.modules.camera.tasks
2
+
3
+ import expo.modules.interfaces.barcodescanner.BarCodeScannerResult
4
+
5
+ interface BarCodeScannerAsyncTaskDelegate {
6
+ fun onBarCodeScanned(barCode: BarCodeScannerResult)
7
+ fun onBarCodeScanningTaskCompleted()
8
+ }
@@ -0,0 +1,10 @@
1
+ package expo.modules.camera.tasks
2
+
3
+ import android.os.Bundle
4
+ import expo.modules.interfaces.facedetector.FaceDetectorInterface
5
+
6
+ interface FaceDetectorAsyncTaskDelegate {
7
+ fun onFacesDetected(faces: List<Bundle>)
8
+ fun onFaceDetectionError(faceDetector: FaceDetectorInterface)
9
+ fun onFaceDetectingTaskCompleted()
10
+ }
@@ -0,0 +1,34 @@
1
+ package expo.modules.camera.tasks
2
+
3
+ import expo.modules.interfaces.facedetector.FaceDetectorInterface
4
+
5
+ class FaceDetectorTask(
6
+ private val mDelegate: FaceDetectorAsyncTaskDelegate,
7
+ private val mFaceDetector: FaceDetectorInterface,
8
+ private val mImageData: ByteArray,
9
+ private val mWidth: Int,
10
+ private val mHeight: Int,
11
+ private val mRotation: Int,
12
+ private val mMirrored: Boolean,
13
+ private val mScaleX: Double,
14
+ private val mScaleY: Double
15
+ ) {
16
+ fun execute() {
17
+ mFaceDetector.detectFaces(
18
+ mImageData, mWidth, mHeight, mRotation, mMirrored, mScaleX, mScaleY,
19
+ { result ->
20
+ result?.let {
21
+ mDelegate.onFacesDetected(result)
22
+ } ?: run {
23
+ mDelegate.onFaceDetectionError(mFaceDetector)
24
+ }
25
+ mDelegate.onFaceDetectingTaskCompleted()
26
+ },
27
+ { error ->
28
+ mDelegate.onFaceDetectionError(mFaceDetector)
29
+ mDelegate.onFaceDetectingTaskCompleted()
30
+ },
31
+ { skippedReason -> mDelegate.onFaceDetectingTaskCompleted() }
32
+ )
33
+ }
34
+ }
@@ -0,0 +1,7 @@
1
+ package expo.modules.camera.tasks
2
+
3
+ import android.os.Bundle
4
+
5
+ interface PictureSavedDelegate {
6
+ fun onPictureSaved(response: Bundle)
7
+ }
@@ -0,0 +1,231 @@
1
+ package expo.modules.camera.tasks
2
+
3
+ import android.content.res.Resources
4
+ import android.graphics.Bitmap
5
+ import android.graphics.BitmapFactory
6
+ import android.graphics.Matrix
7
+ import android.net.Uri
8
+ import android.os.AsyncTask
9
+ import android.os.Bundle
10
+ import android.util.Base64
11
+ import androidx.exifinterface.media.ExifInterface
12
+
13
+ import expo.modules.camera.CameraViewHelper.getExifData
14
+ import expo.modules.camera.CameraViewHelper.addExifData
15
+ import expo.modules.camera.utils.FileSystemUtils
16
+ import expo.modules.core.Promise
17
+
18
+ import java.io.ByteArrayInputStream
19
+ import java.io.ByteArrayOutputStream
20
+ import java.io.File
21
+ import java.io.FileOutputStream
22
+ import java.io.IOException
23
+ import java.lang.Exception
24
+
25
+ private const val DIRECTORY_NOT_FOUND_MSG = "Documents directory of the app could not be found."
26
+ private const val UNKNOWN_IO_EXCEPTION_MSG = "An unknown I/O exception has occurred."
27
+ private const val UNKNOWN_EXCEPTION_MSG = "An unknown exception has occurred."
28
+ private const val ERROR_TAG = "E_TAKING_PICTURE_FAILED"
29
+ private const val DIRECTORY_NAME = "Camera"
30
+ private const val EXTENSION = ".jpg"
31
+ private const val SKIP_PROCESSING_KEY = "skipProcessing"
32
+ private const val FAST_MODE_KEY = "fastMode"
33
+ private const val QUALITY_KEY = "quality"
34
+ private const val BASE64_KEY = "base64"
35
+ private const val HEIGHT_KEY = "height"
36
+ private const val WIDTH_KEY = "width"
37
+ private const val EXIF_KEY = "exif"
38
+ private const val DATA_KEY = "data"
39
+ private const val URI_KEY = "uri"
40
+ private const val ID_KEY = "id"
41
+ private const val DEFAULT_QUALITY = 1
42
+
43
+ class ResolveTakenPictureAsyncTask(
44
+ private var promise: Promise,
45
+ private var options: Map<String, Any>,
46
+ private val directory: File,
47
+ private var pictureSavedDelegate: PictureSavedDelegate
48
+ ) : AsyncTask<Void?, Void?, Bundle?>() {
49
+ private var imageData: ByteArray? = null
50
+ private var bitmap: Bitmap? = null
51
+
52
+ constructor(imageData: ByteArray?, promise: Promise, options: Map<String, Any>, directory: File, delegate: PictureSavedDelegate) : this(
53
+ promise, options, directory, delegate
54
+ ) {
55
+ this.imageData = imageData
56
+ }
57
+
58
+ constructor(bitmap: Bitmap?, promise: Promise, options: Map<String, Any>, directory: File, delegate: PictureSavedDelegate) : this(
59
+ promise, options, directory, delegate
60
+ ) {
61
+ this.bitmap = bitmap
62
+ }
63
+
64
+ private val quality: Int
65
+ get() = options[QUALITY_KEY]?.let {
66
+ val requestedQuality = (it as Number).toDouble()
67
+ (requestedQuality * 100).toInt()
68
+ } ?: DEFAULT_QUALITY * 100
69
+
70
+ override fun doInBackground(vararg params: Void?): Bundle? {
71
+ // handle SkipProcessing
72
+ if (imageData != null && isOptionEnabled(SKIP_PROCESSING_KEY)) {
73
+ return handleSkipProcessing()
74
+ }
75
+ if (bitmap == null) {
76
+ bitmap = imageData?.let { BitmapFactory.decodeByteArray(imageData, 0, it.size) }
77
+ }
78
+ try {
79
+ ByteArrayInputStream(imageData).use { inputStream ->
80
+ val response = Bundle()
81
+
82
+ val exifInterface = ExifInterface(inputStream)
83
+ // Get orientation of the image from mImageData via inputStream
84
+ val orientation = exifInterface.getAttributeInt(
85
+ ExifInterface.TAG_ORIENTATION,
86
+ ExifInterface.ORIENTATION_UNDEFINED
87
+ )
88
+
89
+ // Rotate the bitmap to the proper orientation if needed
90
+ if (orientation != ExifInterface.ORIENTATION_UNDEFINED) {
91
+ bitmap = bitmap?.let {
92
+ rotateBitmap(it, getImageRotation(orientation))
93
+ }
94
+ }
95
+
96
+ // Write Exif data to the response if requested
97
+ if (isOptionEnabled(EXIF_KEY)) {
98
+ val exifData = getExifData(exifInterface)
99
+ response.putBundle(EXIF_KEY, exifData)
100
+ }
101
+
102
+ // Upon rotating, write the image's dimensions to the response
103
+ response.apply {
104
+ putInt(WIDTH_KEY, bitmap!!.width)
105
+ putInt(HEIGHT_KEY, bitmap!!.height)
106
+ }
107
+
108
+ // Cache compressed image in imageStream
109
+ ByteArrayOutputStream().use { imageStream ->
110
+ bitmap!!.compress(Bitmap.CompressFormat.JPEG, quality, imageStream)
111
+ // Write compressed image to file in cache directory
112
+ val filePath = writeStreamToFile(imageStream)
113
+
114
+ // Save Exif data to the image if requested
115
+ if (isOptionEnabled(EXIF_KEY)) {
116
+ val exifFromFile = ExifInterface(filePath!!)
117
+ addExifData(exifFromFile, exifInterface)
118
+ }
119
+ val imageFile = File(filePath)
120
+ val fileUri = Uri.fromFile(imageFile).toString()
121
+ response.putString(URI_KEY, fileUri)
122
+
123
+ // Write base64-encoded image to the response if requested
124
+ if (isOptionEnabled(BASE64_KEY)) {
125
+ response.putString(BASE64_KEY, Base64.encodeToString(imageStream.toByteArray(), Base64.NO_WRAP))
126
+ }
127
+ }
128
+ return response
129
+ }
130
+ } catch (e: Exception) {
131
+ when (e) {
132
+ is Resources.NotFoundException -> promise.reject(ERROR_TAG, DIRECTORY_NOT_FOUND_MSG, e)
133
+ is IOException -> promise.reject(ERROR_TAG, UNKNOWN_IO_EXCEPTION_MSG, e)
134
+ else -> promise.reject(ERROR_TAG, UNKNOWN_EXCEPTION_MSG, e)
135
+ }
136
+ e.printStackTrace()
137
+ }
138
+ // An exception had to occur, promise has already been rejected. Do not try to resolve it again.
139
+ return null
140
+ }
141
+
142
+ private fun handleSkipProcessing(): Bundle? {
143
+ try {
144
+ // save byte array (it's already a JPEG)
145
+ ByteArrayOutputStream().use { imageStream ->
146
+ imageStream.write(imageData)
147
+
148
+ // write compressed image to file in cache directory
149
+ val filePath = writeStreamToFile(imageStream)
150
+ val imageFile = File(filePath)
151
+
152
+ // handle image uri
153
+ val fileUri = Uri.fromFile(imageFile).toString()
154
+
155
+ // read exif information
156
+ val exifInterface = ExifInterface(filePath!!)
157
+
158
+ return Bundle().apply {
159
+ putString(URI_KEY, fileUri)
160
+ putInt(WIDTH_KEY, exifInterface.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, -1))
161
+ putInt(HEIGHT_KEY, exifInterface.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, -1))
162
+ // handle exif request
163
+ if (isOptionEnabled(EXIF_KEY)) {
164
+ val exifData = getExifData(exifInterface)
165
+ putBundle(EXIF_KEY, exifData)
166
+ }
167
+ // handle base64
168
+ if (isOptionEnabled(BASE64_KEY)) {
169
+ putString(BASE64_KEY, Base64.encodeToString(imageData, Base64.NO_WRAP))
170
+ }
171
+ }
172
+ }
173
+ } catch (e: Exception) {
174
+ if (e is IOException) {
175
+ promise.reject(ERROR_TAG, UNKNOWN_IO_EXCEPTION_MSG, e)
176
+ } else {
177
+ promise.reject(ERROR_TAG, UNKNOWN_EXCEPTION_MSG, e)
178
+ }
179
+ e.printStackTrace()
180
+ }
181
+ // error occurred
182
+ return null
183
+ }
184
+
185
+ override fun onPostExecute(response: Bundle?) {
186
+ super.onPostExecute(response)
187
+
188
+ // If the response is not null everything went well and we can resolve the promise.
189
+ if (response != null) {
190
+ if (isOptionEnabled(FAST_MODE_KEY)) {
191
+ val wrapper = Bundle()
192
+ wrapper.putInt(ID_KEY, (options[ID_KEY] as Double).toInt())
193
+ wrapper.putBundle(DATA_KEY, response)
194
+ pictureSavedDelegate.onPictureSaved(wrapper)
195
+ } else {
196
+ promise.resolve(response)
197
+ }
198
+ }
199
+ }
200
+
201
+ // Write stream to file in cache directory
202
+ @Throws(Exception::class)
203
+ private fun writeStreamToFile(inputStream: ByteArrayOutputStream): String? {
204
+ try {
205
+ val outputPath = FileSystemUtils.generateOutputPath(directory, DIRECTORY_NAME, EXTENSION)
206
+ FileOutputStream(outputPath).use { outputStream ->
207
+ inputStream.writeTo(outputStream)
208
+ }
209
+ return outputPath
210
+ } catch (e: IOException) {
211
+ e.printStackTrace()
212
+ }
213
+ return null
214
+ }
215
+
216
+ private fun rotateBitmap(source: Bitmap, angle: Int): Bitmap {
217
+ val matrix = Matrix()
218
+ matrix.postRotate(angle.toFloat())
219
+ return Bitmap.createBitmap(source, 0, 0, source.width, source.height, matrix, true)
220
+ }
221
+
222
+ // Get rotation degrees from Exif orientation enum
223
+ private fun getImageRotation(orientation: Int) = when (orientation) {
224
+ ExifInterface.ORIENTATION_ROTATE_90 -> 90
225
+ ExifInterface.ORIENTATION_ROTATE_180 -> 180
226
+ ExifInterface.ORIENTATION_ROTATE_270 -> 270
227
+ else -> 0
228
+ }
229
+
230
+ private fun isOptionEnabled(key: String) = options[key] != null && (options[key] as Boolean)
231
+ }
@@ -0,0 +1,23 @@
1
+ package expo.modules.camera.utils
2
+
3
+ import java.io.File
4
+ import java.io.IOException
5
+ import java.util.*
6
+
7
+ object FileSystemUtils {
8
+ @Throws(IOException::class)
9
+ fun ensureDirExists(dir: File): File {
10
+ if (!(dir.isDirectory || dir.mkdirs())) {
11
+ throw IOException("Couldn't create directory '$dir'")
12
+ }
13
+ return dir
14
+ }
15
+
16
+ @Throws(IOException::class)
17
+ fun generateOutputPath(internalDirectory: File, dirName: String, extension: String): String {
18
+ val directory = File(internalDirectory.toString() + File.separator + dirName)
19
+ ensureDirExists(directory)
20
+ val filename = UUID.randomUUID().toString()
21
+ return directory.toString() + File.separator + filename + extension
22
+ }
23
+ }
@@ -0,0 +1,14 @@
1
+ package expo.modules.camera.utils
2
+
3
+ data class ImageDimensions @JvmOverloads constructor(private val mWidth: Int, private val mHeight: Int, val rotation: Int = 0, val facing: Int = -1) {
4
+ private val isLandscape: Boolean
5
+ get() = rotation % 180 == 90
6
+ val width: Int
7
+ get() = if (isLandscape) {
8
+ mHeight
9
+ } else mWidth
10
+ val height: Int
11
+ get() = if (isLandscape) {
12
+ mWidth
13
+ } else mHeight
14
+ }
@@ -9,7 +9,9 @@ function getUserMedia(constraints) {
9
9
  // with getUserMedia as it would overwrite existing properties.
10
10
  // Here, we will just add the getUserMedia property if it's missing.
11
11
  // First get ahold of the legacy getUserMedia, if present
12
- const getUserMedia = navigator.getUserMedia ||
12
+ const getUserMedia =
13
+ // TODO: this method is deprecated, migrate to https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
14
+ navigator.getUserMedia ||
13
15
  navigator.webkitGetUserMedia ||
14
16
  navigator.mozGetUserMedia ||
15
17
  function () {
@@ -1 +1 @@
1
- {"version":3,"file":"ExponentCameraManager.web.js","sourceRoot":"","sources":["../src/ExponentCameraManager.web.ts"],"names":[],"mappings":"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","sourcesContent":["import { UnavailabilityError } from 'expo-modules-core';\n\nimport {\n CameraCapturedPicture,\n CameraPictureOptions,\n CameraType,\n PermissionResponse,\n PermissionStatus,\n} from './Camera.types';\nimport { ExponentCameraRef } from './ExponentCamera.web';\nimport {\n canGetUserMedia,\n isBackCameraAvailableAsync,\n isFrontCameraAvailableAsync,\n} from './WebUserMediaManager';\n\nfunction getUserMedia(constraints: MediaStreamConstraints): Promise<MediaStream> {\n if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {\n return navigator.mediaDevices.getUserMedia(constraints);\n }\n\n // Some browsers partially implement mediaDevices. We can't just assign an object\n // with getUserMedia as it would overwrite existing properties.\n // Here, we will just add the getUserMedia property if it's missing.\n\n // First get ahold of the legacy getUserMedia, if present\n const getUserMedia =\n navigator.getUserMedia ||\n (navigator as any).webkitGetUserMedia ||\n (navigator as any).mozGetUserMedia ||\n function () {\n const error: any = new Error('Permission unimplemented');\n error.code = 0;\n error.name = 'NotAllowedError';\n throw error;\n };\n\n return new Promise((resolve, reject) => {\n getUserMedia.call(navigator, constraints, resolve, reject);\n });\n}\n\nfunction handleGetUserMediaError({ message }: { message: string }): PermissionResponse {\n // name: NotAllowedError\n // code: 0\n if (message === 'Permission dismissed') {\n return {\n status: PermissionStatus.UNDETERMINED,\n expires: 'never',\n canAskAgain: true,\n granted: false,\n };\n } else {\n // TODO: Bacon: [OSX] The system could deny access to chrome.\n // TODO: Bacon: add: { status: 'unimplemented' }\n return {\n status: PermissionStatus.DENIED,\n expires: 'never',\n canAskAgain: true,\n granted: false,\n };\n }\n}\n\nasync function handleRequestPermissionsAsync(): Promise<PermissionResponse> {\n try {\n await getUserMedia({\n video: true,\n });\n return {\n status: PermissionStatus.GRANTED,\n expires: 'never',\n canAskAgain: true,\n granted: true,\n };\n } catch ({ message }) {\n return handleGetUserMediaError({ message });\n }\n}\n\nasync function handlePermissionsQueryAsync(\n query: 'camera' | 'microphone'\n): Promise<PermissionResponse> {\n if (!navigator?.permissions?.query) {\n throw new UnavailabilityError('expo-camera', 'navigator.permissions API is not available');\n }\n\n const { state } = await navigator.permissions.query({ name: query });\n switch (state) {\n case 'prompt':\n return {\n status: PermissionStatus.UNDETERMINED,\n expires: 'never',\n canAskAgain: true,\n granted: false,\n };\n case 'granted':\n return {\n status: PermissionStatus.GRANTED,\n expires: 'never',\n canAskAgain: true,\n granted: true,\n };\n case 'denied':\n return {\n status: PermissionStatus.DENIED,\n expires: 'never',\n canAskAgain: true,\n granted: false,\n };\n }\n}\n\nexport default {\n get name(): string {\n return 'ExponentCameraManager';\n },\n get Type() {\n return {\n back: 'back',\n front: 'front',\n };\n },\n get FlashMode() {\n return {\n on: 'on',\n off: 'off',\n auto: 'auto',\n torch: 'torch',\n };\n },\n get AutoFocus() {\n return {\n on: 'on',\n off: 'off',\n auto: 'auto',\n singleShot: 'singleShot',\n };\n },\n get WhiteBalance() {\n return {\n auto: 'auto',\n continuous: 'continuous',\n manual: 'manual',\n };\n },\n get VideoQuality() {\n return {};\n },\n get VideoStabilization() {\n return {};\n },\n async isAvailableAsync(): Promise<boolean> {\n return canGetUserMedia();\n },\n async takePicture(\n options: CameraPictureOptions,\n camera: ExponentCameraRef\n ): Promise<CameraCapturedPicture> {\n return await camera.takePicture(options);\n },\n async pausePreview(camera: ExponentCameraRef): Promise<void> {\n await camera.pausePreview();\n },\n async resumePreview(camera: ExponentCameraRef): Promise<void> {\n return await camera.resumePreview();\n },\n async getAvailableCameraTypesAsync(): Promise<string[]> {\n if (!canGetUserMedia() || !navigator.mediaDevices.enumerateDevices) return [];\n\n const devices = await navigator.mediaDevices.enumerateDevices();\n\n const types: (string | null)[] = await Promise.all([\n (await isFrontCameraAvailableAsync(devices)) && CameraType.front,\n (await isBackCameraAvailableAsync()) && CameraType.back,\n ]);\n\n return types.filter(Boolean) as string[];\n },\n async getAvailablePictureSizes(ratio: string, camera: ExponentCameraRef): Promise<string[]> {\n return await camera.getAvailablePictureSizes(ratio);\n },\n /* async getSupportedRatios(camera: ExponentCameraRef): Promise<string[]> {\n // TODO: Support on web\n },\n async record(\n options?: CameraRecordingOptions,\n camera: ExponentCameraRef\n ): Promise<{ uri: string }> {\n // TODO: Support on web\n },\n async stopRecording(camera: ExponentCameraRef): Promise<void> {\n // TODO: Support on web\n }, */\n async getPermissionsAsync(): Promise<PermissionResponse> {\n return handlePermissionsQueryAsync('camera');\n },\n async requestPermissionsAsync(): Promise<PermissionResponse> {\n return handleRequestPermissionsAsync();\n },\n async getCameraPermissionsAsync(): Promise<PermissionResponse> {\n return handlePermissionsQueryAsync('camera');\n },\n async requestCameraPermissionsAsync(): Promise<PermissionResponse> {\n return handleRequestPermissionsAsync();\n },\n async getMicrophonePermissionsAsync(): Promise<PermissionResponse> {\n return handlePermissionsQueryAsync('microphone');\n },\n async requestMicrophonePermissionsAsync(): Promise<PermissionResponse> {\n try {\n await getUserMedia({\n audio: true,\n });\n return {\n status: PermissionStatus.GRANTED,\n expires: 'never',\n canAskAgain: true,\n granted: true,\n };\n } catch ({ message }) {\n return handleGetUserMediaError({ message });\n }\n },\n};\n"]}
1
+ {"version":3,"file":"ExponentCameraManager.web.js","sourceRoot":"","sources":["../src/ExponentCameraManager.web.ts"],"names":[],"mappings":"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","sourcesContent":["import { UnavailabilityError } from 'expo-modules-core';\n\nimport {\n CameraCapturedPicture,\n CameraPictureOptions,\n CameraType,\n PermissionResponse,\n PermissionStatus,\n} from './Camera.types';\nimport { ExponentCameraRef } from './ExponentCamera.web';\nimport {\n canGetUserMedia,\n isBackCameraAvailableAsync,\n isFrontCameraAvailableAsync,\n} from './WebUserMediaManager';\n\nfunction getUserMedia(constraints: MediaStreamConstraints): Promise<MediaStream> {\n if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {\n return navigator.mediaDevices.getUserMedia(constraints);\n }\n\n // Some browsers partially implement mediaDevices. We can't just assign an object\n // with getUserMedia as it would overwrite existing properties.\n // Here, we will just add the getUserMedia property if it's missing.\n\n // First get ahold of the legacy getUserMedia, if present\n const getUserMedia =\n // TODO: this method is deprecated, migrate to https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia\n navigator.getUserMedia ||\n navigator.webkitGetUserMedia ||\n navigator.mozGetUserMedia ||\n function () {\n const error: any = new Error('Permission unimplemented');\n error.code = 0;\n error.name = 'NotAllowedError';\n throw error;\n };\n\n return new Promise((resolve, reject) => {\n getUserMedia.call(navigator, constraints, resolve, reject);\n });\n}\n\nfunction handleGetUserMediaError({ message }: { message: string }): PermissionResponse {\n // name: NotAllowedError\n // code: 0\n if (message === 'Permission dismissed') {\n return {\n status: PermissionStatus.UNDETERMINED,\n expires: 'never',\n canAskAgain: true,\n granted: false,\n };\n } else {\n // TODO: Bacon: [OSX] The system could deny access to chrome.\n // TODO: Bacon: add: { status: 'unimplemented' }\n return {\n status: PermissionStatus.DENIED,\n expires: 'never',\n canAskAgain: true,\n granted: false,\n };\n }\n}\n\nasync function handleRequestPermissionsAsync(): Promise<PermissionResponse> {\n try {\n await getUserMedia({\n video: true,\n });\n return {\n status: PermissionStatus.GRANTED,\n expires: 'never',\n canAskAgain: true,\n granted: true,\n };\n } catch ({ message }) {\n return handleGetUserMediaError({ message });\n }\n}\n\nasync function handlePermissionsQueryAsync(\n query: 'camera' | 'microphone'\n): Promise<PermissionResponse> {\n if (!navigator?.permissions?.query) {\n throw new UnavailabilityError('expo-camera', 'navigator.permissions API is not available');\n }\n\n const { state } = await navigator.permissions.query({ name: query });\n switch (state) {\n case 'prompt':\n return {\n status: PermissionStatus.UNDETERMINED,\n expires: 'never',\n canAskAgain: true,\n granted: false,\n };\n case 'granted':\n return {\n status: PermissionStatus.GRANTED,\n expires: 'never',\n canAskAgain: true,\n granted: true,\n };\n case 'denied':\n return {\n status: PermissionStatus.DENIED,\n expires: 'never',\n canAskAgain: true,\n granted: false,\n };\n }\n}\n\nexport default {\n get name(): string {\n return 'ExponentCameraManager';\n },\n get Type() {\n return {\n back: 'back',\n front: 'front',\n };\n },\n get FlashMode() {\n return {\n on: 'on',\n off: 'off',\n auto: 'auto',\n torch: 'torch',\n };\n },\n get AutoFocus() {\n return {\n on: 'on',\n off: 'off',\n auto: 'auto',\n singleShot: 'singleShot',\n };\n },\n get WhiteBalance() {\n return {\n auto: 'auto',\n continuous: 'continuous',\n manual: 'manual',\n };\n },\n get VideoQuality() {\n return {};\n },\n get VideoStabilization() {\n return {};\n },\n async isAvailableAsync(): Promise<boolean> {\n return canGetUserMedia();\n },\n async takePicture(\n options: CameraPictureOptions,\n camera: ExponentCameraRef\n ): Promise<CameraCapturedPicture> {\n return await camera.takePicture(options);\n },\n async pausePreview(camera: ExponentCameraRef): Promise<void> {\n await camera.pausePreview();\n },\n async resumePreview(camera: ExponentCameraRef): Promise<void> {\n return await camera.resumePreview();\n },\n async getAvailableCameraTypesAsync(): Promise<string[]> {\n if (!canGetUserMedia() || !navigator.mediaDevices.enumerateDevices) return [];\n\n const devices = await navigator.mediaDevices.enumerateDevices();\n\n const types: (string | null)[] = await Promise.all([\n (await isFrontCameraAvailableAsync(devices)) && CameraType.front,\n (await isBackCameraAvailableAsync()) && CameraType.back,\n ]);\n\n return types.filter(Boolean) as string[];\n },\n async getAvailablePictureSizes(ratio: string, camera: ExponentCameraRef): Promise<string[]> {\n return await camera.getAvailablePictureSizes(ratio);\n },\n /* async getSupportedRatios(camera: ExponentCameraRef): Promise<string[]> {\n // TODO: Support on web\n },\n async record(\n options?: CameraRecordingOptions,\n camera: ExponentCameraRef\n ): Promise<{ uri: string }> {\n // TODO: Support on web\n },\n async stopRecording(camera: ExponentCameraRef): Promise<void> {\n // TODO: Support on web\n }, */\n async getPermissionsAsync(): Promise<PermissionResponse> {\n return handlePermissionsQueryAsync('camera');\n },\n async requestPermissionsAsync(): Promise<PermissionResponse> {\n return handleRequestPermissionsAsync();\n },\n async getCameraPermissionsAsync(): Promise<PermissionResponse> {\n return handlePermissionsQueryAsync('camera');\n },\n async requestCameraPermissionsAsync(): Promise<PermissionResponse> {\n return handleRequestPermissionsAsync();\n },\n async getMicrophonePermissionsAsync(): Promise<PermissionResponse> {\n return handlePermissionsQueryAsync('microphone');\n },\n async requestMicrophonePermissionsAsync(): Promise<PermissionResponse> {\n try {\n await getUserMedia({\n audio: true,\n });\n return {\n status: PermissionStatus.GRANTED,\n expires: 'never',\n canAskAgain: true,\n granted: true,\n };\n } catch ({ message }) {\n return handleGetUserMediaError({ message });\n }\n },\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-camera",
3
- "version": "12.0.2",
3
+ "version": "12.1.2",
4
4
  "description": "A React component that renders a preview for the device's either front or back camera. Camera's parameters like zoom, auto focus, white balance and flash mode are adjustable. With expo-camera, one can also take photos and record videos that are saved to the app's cache. Morever, the component is also capable of detecting faces and bar codes appearing on the preview.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -34,13 +34,15 @@
34
34
  "preset": "expo-module-scripts"
35
35
  },
36
36
  "dependencies": {
37
- "@expo/config-plugins": "^3.1.0",
37
+ "@expo/config-plugins": "^4.0.2",
38
38
  "@koale/useworker": "^4.0.2",
39
- "expo-modules-core": "~0.4.3",
40
- "invariant": "2.2.4"
39
+ "invariant": "^2.2.4"
41
40
  },
42
41
  "devDependencies": {
43
42
  "expo-module-scripts": "^2.0.0"
44
43
  },
45
- "gitHead": "d23e1ac491da96b51c25eb2533efcd56499ee287"
44
+ "peerDependencies": {
45
+ "expo": "*"
46
+ },
47
+ "gitHead": "43d2652ada705ed7e57801830ad935605f73b9be"
46
48
  }
@@ -1,5 +1,6 @@
1
1
  import { ConfigPlugin } from '@expo/config-plugins';
2
- export declare function setGradleMaven(buildGradle: string): string;
2
+ import { MergeResults } from '@expo/config-plugins/build/utils/generateCode';
3
+ export declare function addCameraImport(src: string): MergeResults;
3
4
  declare const _default: ConfigPlugin<void | {
4
5
  cameraPermission?: string | undefined;
5
6
  microphonePermission?: string | undefined;