@chipmobilesdk/rn-camera 0.3.0 → 0.4.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.
@@ -27,6 +27,7 @@ import {
27
27
  type FileSystemBridge,
28
28
  } from '../storage/artifactStore';
29
29
  import type { AppStatus } from '../core/controller';
30
+ import { clampQuality } from '../core/captureController';
30
31
 
31
32
  export interface MemoryFileSystem extends FileSystemBridge {
32
33
  /** Seeds a file with an explicit creation time, for time-to-live tests. */
@@ -98,8 +99,15 @@ export interface TestCameraHandles {
98
99
  setAppState(status: AppStatus): void;
99
100
  /** Simulates a Settings-level permission change while running (FR-007). */
100
101
  setPermission(state: CameraPermissionState): void;
101
- /** Simulates an OS preemption such as an incoming call. */
102
- emitInterruption(): void;
102
+ /**
103
+ * Simulates the OS taking the camera away: an incoming call, another app,
104
+ * a disconnected device. A live session tears down with that code, exactly
105
+ * as the device adapter reports it (CAM-19), and the next start fails until
106
+ * `setStartError(null)` clears it.
107
+ */
108
+ emitInterruption(code?: CameraErrorCode): void;
109
+ /** Simulates the preview failing to produce frames. */
110
+ emitPermissionRequestFailure(enabled: boolean): void;
103
111
  setCaptureError(code: CameraErrorCode | null): void;
104
112
  setStartError(code: CameraErrorCode | null): void;
105
113
  /** How many times `request` showed the system prompt. */
@@ -133,12 +141,18 @@ export function createTestCamera(config: TestCameraConfig = {}): TestCameraHandl
133
141
  // identically here and on a device.
134
142
  const permissionListeners = createListenerSet<[CameraPermissionState]>();
135
143
  const appStateListeners = createListenerSet<[AppStatus]>();
144
+ const interruptionListeners = createListenerSet<[CameraErrorCode]>();
145
+ let requestThrows = false;
136
146
 
137
147
  const permissions: PermissionPort = {
138
148
  async getStatus() {
139
149
  return permission;
140
150
  },
141
151
  async request() {
152
+ if (requestThrows) {
153
+ // What a native module that cannot be reached does.
154
+ throw new Error('permission request failed');
155
+ }
142
156
  // Mirrors the real adapter: never re-prompt after a permanent denial.
143
157
  if (permission === 'deniedPermanently') {
144
158
  return permission;
@@ -154,6 +168,8 @@ export function createTestCamera(config: TestCameraConfig = {}): TestCameraHandl
154
168
  };
155
169
 
156
170
  const engine: CameraEngine = {
171
+ subscribeToInterruptions: listener => interruptionListeners.add(listener),
172
+
157
173
  async start() {
158
174
  starts += 1;
159
175
  if (startError) {
@@ -186,7 +202,8 @@ export function createTestCamera(config: TestCameraConfig = {}): TestCameraHandl
186
202
  timestamp: Date.now(),
187
203
  cameraPosition: position,
188
204
  ownership: request.destination ? 'appOwned' : 'packageTemporary',
189
- effectiveQuality: request.quality ?? 0.9,
205
+ // Clamped the way the real path clamps it, not a second copy of 0.9.
206
+ effectiveQuality: clampQuality(request.quality),
190
207
  effectiveMaxDimension:
191
208
  request.maxDimension === undefined ? unavailable() : known(request.maxDimension),
192
209
  fileSize: known(1024),
@@ -223,10 +240,15 @@ export function createTestCamera(config: TestCameraConfig = {}): TestCameraHandl
223
240
  permissionListeners.notify(state);
224
241
  },
225
242
 
226
- emitInterruption() {
227
- // An interruption behaves like the OS taking the camera away: the next
228
- // start attempt fails until the app clears it.
229
- startError = 'interrupted';
243
+ emitInterruption(code: CameraErrorCode = 'interrupted') {
244
+ // The OS took the camera away. A live session hears about it, and the
245
+ // next start attempt fails until the app clears it.
246
+ startError = code;
247
+ interruptionListeners.notify(code);
248
+ },
249
+
250
+ emitPermissionRequestFailure(enabled) {
251
+ requestThrows = enabled;
230
252
  },
231
253
 
232
254
  setCaptureError(code) {