react-native-frame-capture 1.0.1 → 1.1.0
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/FrameCapture.podspec +21 -21
- package/LICENSE +20 -20
- package/README.md +159 -158
- package/android/build.gradle +77 -77
- package/android/gradle.properties +5 -5
- package/android/src/main/AndroidManifest.xml +20 -20
- package/android/src/main/java/com/framecapture/CaptureManager.kt +1013 -831
- package/android/src/main/java/com/framecapture/Constants.kt +205 -196
- package/android/src/main/java/com/framecapture/ErrorHandler.kt +165 -165
- package/android/src/main/java/com/framecapture/FrameCaptureModule.kt +653 -653
- package/android/src/main/java/com/framecapture/OverlayRenderer.kt +423 -423
- package/android/src/main/java/com/framecapture/PermissionHandler.kt +150 -150
- package/android/src/main/java/com/framecapture/ScreenCaptureService.kt +366 -366
- package/android/src/main/java/com/framecapture/StorageManager.kt +221 -221
- package/android/src/main/java/com/framecapture/capture/BitmapProcessor.kt +157 -157
- package/android/src/main/java/com/framecapture/capture/CaptureEventEmitter.kt +150 -120
- package/android/src/main/java/com/framecapture/capture/ChangeDetector.kt +191 -0
- package/android/src/main/java/com/framecapture/models/CaptureModels.kt +343 -302
- package/android/src/main/java/com/framecapture/models/EnumsAndExtensions.kt +67 -60
- package/android/src/main/java/com/framecapture/models/OverlayModels.kt +154 -154
- package/android/src/main/java/com/framecapture/service/CaptureNotificationManager.kt +286 -286
- package/android/src/main/java/com/framecapture/storage/StorageStrategies.kt +317 -317
- package/android/src/main/java/com/framecapture/utils/ValidationUtils.kt +379 -379
- package/ios/FrameCapture.h +5 -5
- package/ios/FrameCapture.mm +21 -21
- package/lib/module/NativeFrameCapture.js.map +1 -1
- package/lib/module/constants.js +45 -0
- package/lib/module/constants.js.map +1 -1
- package/lib/module/normalize.js +10 -1
- package/lib/module/normalize.js.map +1 -1
- package/lib/module/types.js +9 -0
- package/lib/module/types.js.map +1 -1
- package/lib/module/validation.js +86 -9
- package/lib/module/validation.js.map +1 -1
- package/lib/typescript/src/NativeFrameCapture.d.ts +7 -0
- package/lib/typescript/src/NativeFrameCapture.d.ts.map +1 -1
- package/lib/typescript/src/constants.d.ts +33 -0
- package/lib/typescript/src/constants.d.ts.map +1 -1
- package/lib/typescript/src/normalize.d.ts +8 -2
- package/lib/typescript/src/normalize.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +29 -5
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/validation.d.ts.map +1 -1
- package/package.json +199 -196
- package/src/NativeFrameCapture.ts +8 -0
- package/src/constants.ts +45 -0
- package/src/normalize.ts +23 -3
- package/src/types.ts +30 -2
- package/src/validation.ts +132 -13
- package/plugin/build/index.js +0 -48
|
@@ -1,165 +1,165 @@
|
|
|
1
|
-
package com.framecapture
|
|
2
|
-
|
|
3
|
-
import android.util.Log
|
|
4
|
-
import com.facebook.react.bridge.Arguments
|
|
5
|
-
import com.facebook.react.bridge.Promise
|
|
6
|
-
import com.facebook.react.bridge.WritableMap
|
|
7
|
-
import com.framecapture.models.CaptureState
|
|
8
|
-
import com.framecapture.models.ErrorCode
|
|
9
|
-
import java.io.IOException
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Handles error classification, formatting, and reporting
|
|
13
|
-
*
|
|
14
|
-
* Provides consistent error handling across the module by:
|
|
15
|
-
* - Classifying exceptions into appropriate ErrorCode values
|
|
16
|
-
* - Formatting error details for JavaScript consumption
|
|
17
|
-
* - Coordinating error emission and cleanup
|
|
18
|
-
*
|
|
19
|
-
* Uses dependency injection for storage space and capture state checks
|
|
20
|
-
* to avoid tight coupling with other components.
|
|
21
|
-
*/
|
|
22
|
-
class ErrorHandler(
|
|
23
|
-
private val getStorageSpace: () -> Long,
|
|
24
|
-
private val getCaptureState: () -> CaptureState
|
|
25
|
-
) {
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Classifies exception into error code, message, and details
|
|
29
|
-
*
|
|
30
|
-
* Maps common exceptions to appropriate ErrorCode values and provides
|
|
31
|
-
* contextual details for debugging (e.g., available storage, current state).
|
|
32
|
-
*
|
|
33
|
-
* @param error The exception to classify
|
|
34
|
-
* @return Triple of (ErrorCode, error message, optional details map)
|
|
35
|
-
*/
|
|
36
|
-
fun classifyError(error: Exception): Triple<ErrorCode, String, Map<String, Any>?> {
|
|
37
|
-
return when (error) {
|
|
38
|
-
is SecurityException -> Triple(
|
|
39
|
-
ErrorCode.PERMISSION_DENIED,
|
|
40
|
-
"Required permission not granted: ${error.message}",
|
|
41
|
-
mapOf(Constants.ERROR_DETAIL_PERMISSION to "MEDIA_PROJECTION")
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
is IllegalStateException -> Triple(
|
|
45
|
-
ErrorCode.ALREADY_CAPTURING,
|
|
46
|
-
"Capture session is already active: ${error.message}",
|
|
47
|
-
mapOf(Constants.ERROR_DETAIL_CURRENT_STATE to getCaptureState().value)
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
is IllegalArgumentException -> Triple(
|
|
51
|
-
ErrorCode.INVALID_OPTIONS,
|
|
52
|
-
"Invalid configuration: ${error.message}",
|
|
53
|
-
null
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
is IOException -> Triple(
|
|
57
|
-
ErrorCode.STORAGE_ERROR,
|
|
58
|
-
"Failed to save frame: ${error.message}",
|
|
59
|
-
mapOf(Constants.ERROR_DETAIL_AVAILABLE_SPACE to getStorageSpace())
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
is OutOfMemoryError -> Triple(
|
|
63
|
-
ErrorCode.SYSTEM_ERROR,
|
|
64
|
-
"Out of memory during capture",
|
|
65
|
-
mapOf(Constants.ERROR_DETAIL_HEAP_SIZE to Runtime.getRuntime().maxMemory())
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
else -> Triple(
|
|
69
|
-
ErrorCode.SYSTEM_ERROR,
|
|
70
|
-
"Unexpected error: ${error.message ?: "Unknown error"}",
|
|
71
|
-
null
|
|
72
|
-
)
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Creates error map for promise rejection and event emission
|
|
78
|
-
*
|
|
79
|
-
* Formats error information into a WritableMap that can be sent to JavaScript.
|
|
80
|
-
* Handles various data types in the details map (String, Int, Long, Boolean, List).
|
|
81
|
-
*
|
|
82
|
-
* @param code Error code enum value
|
|
83
|
-
* @param message Human-readable error message
|
|
84
|
-
* @param details Optional map of additional error context
|
|
85
|
-
* @return WritableMap formatted for React Native bridge
|
|
86
|
-
*/
|
|
87
|
-
fun createErrorMap(
|
|
88
|
-
code: ErrorCode,
|
|
89
|
-
message: String,
|
|
90
|
-
details: Map<String, Any>?
|
|
91
|
-
): WritableMap {
|
|
92
|
-
return Arguments.createMap().apply {
|
|
93
|
-
putString("code", code.value)
|
|
94
|
-
putString("message", message)
|
|
95
|
-
details?.let { detailsMap ->
|
|
96
|
-
val detailsWritableMap = Arguments.createMap()
|
|
97
|
-
detailsMap.forEach { (key, value) ->
|
|
98
|
-
when (value) {
|
|
99
|
-
is String -> detailsWritableMap.putString(key, value)
|
|
100
|
-
is Int -> detailsWritableMap.putInt(key, value)
|
|
101
|
-
is Double -> detailsWritableMap.putDouble(key, value)
|
|
102
|
-
is Long -> detailsWritableMap.putDouble(key, value.toDouble())
|
|
103
|
-
is Boolean -> detailsWritableMap.putBoolean(key, value)
|
|
104
|
-
is List<*> -> {
|
|
105
|
-
val array = Arguments.createArray()
|
|
106
|
-
value.forEach { item ->
|
|
107
|
-
when (item) {
|
|
108
|
-
is String -> array.pushString(item)
|
|
109
|
-
else -> array.pushString(item.toString())
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
detailsWritableMap.putArray(key, array)
|
|
113
|
-
}
|
|
114
|
-
else -> detailsWritableMap.putString(key, value.toString())
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
putMap("details", detailsWritableMap)
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Handles error with logging, classification, and promise rejection
|
|
124
|
-
*
|
|
125
|
-
* Orchestrates the complete error handling flow:
|
|
126
|
-
* 1. Classifies the error
|
|
127
|
-
* 2. Logs for debugging
|
|
128
|
-
* 3. Performs cleanup via callback
|
|
129
|
-
* 4. Emits error event to JavaScript
|
|
130
|
-
* 5. Rejects promise if provided
|
|
131
|
-
*
|
|
132
|
-
* @param error The exception that occurred
|
|
133
|
-
* @param promise Optional promise to reject
|
|
134
|
-
* @param onEmitError Callback to emit error event
|
|
135
|
-
* @param onCleanup Callback to perform cleanup
|
|
136
|
-
*/
|
|
137
|
-
fun handleError(
|
|
138
|
-
error: Exception,
|
|
139
|
-
promise: Promise?,
|
|
140
|
-
onEmitError: (ErrorCode, String, Map<String, Any>?) -> Unit,
|
|
141
|
-
onCleanup: () -> Unit
|
|
142
|
-
) {
|
|
143
|
-
val (code, message, details) = classifyError(error)
|
|
144
|
-
|
|
145
|
-
// Log for debugging
|
|
146
|
-
Log.e(TAG, "Capture error: $message", error)
|
|
147
|
-
|
|
148
|
-
// Clean up resources on error
|
|
149
|
-
try {
|
|
150
|
-
onCleanup()
|
|
151
|
-
} catch (cleanupError: Exception) {
|
|
152
|
-
Log.e(TAG, "Error during cleanup: ${cleanupError.message}", cleanupError)
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// Emit error event
|
|
156
|
-
onEmitError(code, message, details)
|
|
157
|
-
|
|
158
|
-
// Reject promise if provided
|
|
159
|
-
promise?.reject(code.value, message, createErrorMap(code, message, details))
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
companion object {
|
|
163
|
-
private const val TAG = "ErrorHandler"
|
|
164
|
-
}
|
|
165
|
-
}
|
|
1
|
+
package com.framecapture
|
|
2
|
+
|
|
3
|
+
import android.util.Log
|
|
4
|
+
import com.facebook.react.bridge.Arguments
|
|
5
|
+
import com.facebook.react.bridge.Promise
|
|
6
|
+
import com.facebook.react.bridge.WritableMap
|
|
7
|
+
import com.framecapture.models.CaptureState
|
|
8
|
+
import com.framecapture.models.ErrorCode
|
|
9
|
+
import java.io.IOException
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Handles error classification, formatting, and reporting
|
|
13
|
+
*
|
|
14
|
+
* Provides consistent error handling across the module by:
|
|
15
|
+
* - Classifying exceptions into appropriate ErrorCode values
|
|
16
|
+
* - Formatting error details for JavaScript consumption
|
|
17
|
+
* - Coordinating error emission and cleanup
|
|
18
|
+
*
|
|
19
|
+
* Uses dependency injection for storage space and capture state checks
|
|
20
|
+
* to avoid tight coupling with other components.
|
|
21
|
+
*/
|
|
22
|
+
class ErrorHandler(
|
|
23
|
+
private val getStorageSpace: () -> Long,
|
|
24
|
+
private val getCaptureState: () -> CaptureState
|
|
25
|
+
) {
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Classifies exception into error code, message, and details
|
|
29
|
+
*
|
|
30
|
+
* Maps common exceptions to appropriate ErrorCode values and provides
|
|
31
|
+
* contextual details for debugging (e.g., available storage, current state).
|
|
32
|
+
*
|
|
33
|
+
* @param error The exception to classify
|
|
34
|
+
* @return Triple of (ErrorCode, error message, optional details map)
|
|
35
|
+
*/
|
|
36
|
+
fun classifyError(error: Exception): Triple<ErrorCode, String, Map<String, Any>?> {
|
|
37
|
+
return when (error) {
|
|
38
|
+
is SecurityException -> Triple(
|
|
39
|
+
ErrorCode.PERMISSION_DENIED,
|
|
40
|
+
"Required permission not granted: ${error.message}",
|
|
41
|
+
mapOf(Constants.ERROR_DETAIL_PERMISSION to "MEDIA_PROJECTION")
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
is IllegalStateException -> Triple(
|
|
45
|
+
ErrorCode.ALREADY_CAPTURING,
|
|
46
|
+
"Capture session is already active: ${error.message}",
|
|
47
|
+
mapOf(Constants.ERROR_DETAIL_CURRENT_STATE to getCaptureState().value)
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
is IllegalArgumentException -> Triple(
|
|
51
|
+
ErrorCode.INVALID_OPTIONS,
|
|
52
|
+
"Invalid configuration: ${error.message}",
|
|
53
|
+
null
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
is IOException -> Triple(
|
|
57
|
+
ErrorCode.STORAGE_ERROR,
|
|
58
|
+
"Failed to save frame: ${error.message}",
|
|
59
|
+
mapOf(Constants.ERROR_DETAIL_AVAILABLE_SPACE to getStorageSpace())
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
is OutOfMemoryError -> Triple(
|
|
63
|
+
ErrorCode.SYSTEM_ERROR,
|
|
64
|
+
"Out of memory during capture",
|
|
65
|
+
mapOf(Constants.ERROR_DETAIL_HEAP_SIZE to Runtime.getRuntime().maxMemory())
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
else -> Triple(
|
|
69
|
+
ErrorCode.SYSTEM_ERROR,
|
|
70
|
+
"Unexpected error: ${error.message ?: "Unknown error"}",
|
|
71
|
+
null
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Creates error map for promise rejection and event emission
|
|
78
|
+
*
|
|
79
|
+
* Formats error information into a WritableMap that can be sent to JavaScript.
|
|
80
|
+
* Handles various data types in the details map (String, Int, Long, Boolean, List).
|
|
81
|
+
*
|
|
82
|
+
* @param code Error code enum value
|
|
83
|
+
* @param message Human-readable error message
|
|
84
|
+
* @param details Optional map of additional error context
|
|
85
|
+
* @return WritableMap formatted for React Native bridge
|
|
86
|
+
*/
|
|
87
|
+
fun createErrorMap(
|
|
88
|
+
code: ErrorCode,
|
|
89
|
+
message: String,
|
|
90
|
+
details: Map<String, Any>?
|
|
91
|
+
): WritableMap {
|
|
92
|
+
return Arguments.createMap().apply {
|
|
93
|
+
putString("code", code.value)
|
|
94
|
+
putString("message", message)
|
|
95
|
+
details?.let { detailsMap ->
|
|
96
|
+
val detailsWritableMap = Arguments.createMap()
|
|
97
|
+
detailsMap.forEach { (key, value) ->
|
|
98
|
+
when (value) {
|
|
99
|
+
is String -> detailsWritableMap.putString(key, value)
|
|
100
|
+
is Int -> detailsWritableMap.putInt(key, value)
|
|
101
|
+
is Double -> detailsWritableMap.putDouble(key, value)
|
|
102
|
+
is Long -> detailsWritableMap.putDouble(key, value.toDouble())
|
|
103
|
+
is Boolean -> detailsWritableMap.putBoolean(key, value)
|
|
104
|
+
is List<*> -> {
|
|
105
|
+
val array = Arguments.createArray()
|
|
106
|
+
value.forEach { item ->
|
|
107
|
+
when (item) {
|
|
108
|
+
is String -> array.pushString(item)
|
|
109
|
+
else -> array.pushString(item.toString())
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
detailsWritableMap.putArray(key, array)
|
|
113
|
+
}
|
|
114
|
+
else -> detailsWritableMap.putString(key, value.toString())
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
putMap("details", detailsWritableMap)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Handles error with logging, classification, and promise rejection
|
|
124
|
+
*
|
|
125
|
+
* Orchestrates the complete error handling flow:
|
|
126
|
+
* 1. Classifies the error
|
|
127
|
+
* 2. Logs for debugging
|
|
128
|
+
* 3. Performs cleanup via callback
|
|
129
|
+
* 4. Emits error event to JavaScript
|
|
130
|
+
* 5. Rejects promise if provided
|
|
131
|
+
*
|
|
132
|
+
* @param error The exception that occurred
|
|
133
|
+
* @param promise Optional promise to reject
|
|
134
|
+
* @param onEmitError Callback to emit error event
|
|
135
|
+
* @param onCleanup Callback to perform cleanup
|
|
136
|
+
*/
|
|
137
|
+
fun handleError(
|
|
138
|
+
error: Exception,
|
|
139
|
+
promise: Promise?,
|
|
140
|
+
onEmitError: (ErrorCode, String, Map<String, Any>?) -> Unit,
|
|
141
|
+
onCleanup: () -> Unit
|
|
142
|
+
) {
|
|
143
|
+
val (code, message, details) = classifyError(error)
|
|
144
|
+
|
|
145
|
+
// Log for debugging
|
|
146
|
+
Log.e(TAG, "Capture error: $message", error)
|
|
147
|
+
|
|
148
|
+
// Clean up resources on error
|
|
149
|
+
try {
|
|
150
|
+
onCleanup()
|
|
151
|
+
} catch (cleanupError: Exception) {
|
|
152
|
+
Log.e(TAG, "Error during cleanup: ${cleanupError.message}", cleanupError)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Emit error event
|
|
156
|
+
onEmitError(code, message, details)
|
|
157
|
+
|
|
158
|
+
// Reject promise if provided
|
|
159
|
+
promise?.reject(code.value, message, createErrorMap(code, message, details))
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
companion object {
|
|
163
|
+
private const val TAG = "ErrorHandler"
|
|
164
|
+
}
|
|
165
|
+
}
|