| import {FillLightMode, ImageCapture, ImageCaptureReceiver, MeteringMode, RedEyeReduction} from '/gen/media/capture/mojom/image_capture.mojom.m.js'; |
| |
| self.ImageCaptureTest = (() => { |
| // Class that mocks ImageCapture interface defined in |
| // https://cs.chromium.org/chromium/src/media/capture/mojom/image_capture.mojom |
| class MockImageCapture { |
| constructor() { |
| this.interceptor_ = |
| new MojoInterfaceInterceptor(ImageCapture.$interfaceName); |
| this.interceptor_.oninterfacerequest = |
| e => this.receiver_.$.bindHandle(e.handle); |
| this.interceptor_.start(); |
| |
| this.state_ = { |
| state: { |
| supportedWhiteBalanceModes: [ |
| MeteringMode.SINGLE_SHOT, |
| MeteringMode.CONTINUOUS |
| ], |
| currentWhiteBalanceMode: MeteringMode.CONTINUOUS, |
| supportedExposureModes: [ |
| MeteringMode.MANUAL, |
| MeteringMode.SINGLE_SHOT, |
| MeteringMode.CONTINUOUS |
| ], |
| currentExposureMode: MeteringMode.MANUAL, |
| supportedFocusModes: [ |
| MeteringMode.MANUAL, |
| MeteringMode.SINGLE_SHOT |
| ], |
| currentFocusMode: MeteringMode.MANUAL, |
| pointsOfInterest: [{ |
| x: 0.4, |
| y: 0.6 |
| }], |
| |
| exposureCompensation: { |
| min: -200.0, |
| max: 200.0, |
| current: 33.0, |
| step: 33.0 |
| }, |
| exposureTime: { |
| min: 100.0, |
| max: 100000.0, |
| current: 1000.0, |
| step: 100.0 |
| }, |
| colorTemperature: { |
| min: 2500.0, |
| max: 6500.0, |
| current: 6000.0, |
| step: 1000.0 |
| }, |
| iso: { |
| min: 100.0, |
| max: 12000.0, |
| current: 400.0, |
| step: 1.0 |
| }, |
| |
| brightness: { |
| min: 1.0, |
| max: 10.0, |
| current: 5.0, |
| step: 1.0 |
| }, |
| contrast: { |
| min: 2.0, |
| max: 9.0, |
| current: 5.0, |
| step: 1.0 |
| }, |
| saturation: { |
| min: 3.0, |
| max: 8.0, |
| current: 6.0, |
| step: 1.0 |
| }, |
| sharpness: { |
| min: 4.0, |
| max: 7.0, |
| current: 7.0, |
| step: 1.0 |
| }, |
| |
| focusDistance: { |
| min: 1.0, |
| max: 10.0, |
| current: 3.0, |
| step: 1.0 |
| }, |
| |
| pan: { |
| min: 0.0, |
| max: 10.0, |
| current: 5.0, |
| step: 2.0 |
| }, |
| |
| tilt: { |
| min: 0.0, |
| max: 10.0, |
| current: 5.0, |
| step: 2.0 |
| }, |
| |
| zoom: { |
| min: 0.0, |
| max: 10.0, |
| current: 5.0, |
| step: 5.0 |
| }, |
| |
| supportsTorch: true, |
| torch: false, |
| |
| redEyeReduction: RedEyeReduction.CONTROLLABLE, |
| height: { |
| min: 240.0, |
| max: 2448.0, |
| current: 240.0, |
| step: 2.0 |
| }, |
| width: { |
| min: 320.0, |
| max: 3264.0, |
| current: 320.0, |
| step: 3.0 |
| }, |
| fillLightMode: [FillLightMode.AUTO, FillLightMode.FLASH], |
| } |
| }; |
| this.panTiltZoomPermissionStatus_ = null; |
| this.settings_ = null; |
| this.receiver_ = new ImageCaptureReceiver(this); |
| } |
| |
| reset() { |
| this.receiver_.$.close(); |
| this.interceptor_.stop(); |
| } |
| |
| async getPhotoState(source_id) { |
| const shouldKeepPanTiltZoom = await this.isPanTiltZoomPermissionGranted(); |
| if (shouldKeepPanTiltZoom) |
| return Promise.resolve(this.state_); |
| |
| const newState = {...this.state_}; |
| newState.state.pan = {}; |
| newState.state.tilt = {}; |
| newState.state.zoom = {}; |
| return Promise.resolve(newState); |
| } |
| |
| async setOptions(source_id, settings) { |
| const isAllowedToControlPanTiltZoom = await this.isPanTiltZoomPermissionGranted(); |
| if (!isAllowedToControlPanTiltZoom && |
| (settings.hasPan || settings.hasTilt || settings.hasZoom)) { |
| return Promise.resolve({ success: false }); |
| } |
| this.settings_ = settings; |
| if (settings.hasIso) |
| this.state_.state.iso.current = settings.iso; |
| if (settings.hasHeight) |
| this.state_.state.height.current = settings.height; |
| if (settings.hasWidth) |
| this.state_.state.width.current = settings.width; |
| if (settings.hasPan) |
| this.state_.state.pan.current = settings.pan; |
| if (settings.hasTilt) |
| this.state_.state.tilt.current = settings.tilt; |
| if (settings.hasZoom) |
| this.state_.state.zoom.current = settings.zoom; |
| if (settings.hasFocusMode) |
| this.state_.state.currentFocusMode = settings.focusMode; |
| if (settings.hasFocusDistance) |
| this.state_.state.focusDistance.current = settings.focusDistance; |
| |
| if (settings.pointsOfInterest.length > 0) { |
| this.state_.state.pointsOfInterest = |
| settings.pointsOfInterest; |
| } |
| |
| if (settings.hasExposureMode) |
| this.state_.state.currentExposureMode = settings.exposureMode; |
| |
| if (settings.hasExposureCompensation) { |
| this.state_.state.exposureCompensation.current = |
| settings.exposureCompensation; |
| } |
| if (settings.hasExposureTime) { |
| this.state_.state.exposureTime.current = |
| settings.exposureTime; |
| } |
| if (settings.hasWhiteBalanceMode) { |
| this.state_.state.currentWhiteBalanceMode = |
| settings.whiteBalanceMode; |
| } |
| if (settings.hasFillLightMode) |
| this.state_.state.fillLightMode = [settings.fillLightMode]; |
| if (settings.hasRedEyeReduction) |
| this.state_.state.redEyeReduction = settings.redEyeReduction; |
| if (settings.hasColorTemperature) { |
| this.state_.state.colorTemperature.current = |
| settings.colorTemperature; |
| } |
| if (settings.hasBrightness) |
| this.state_.state.brightness.current = settings.brightness; |
| if (settings.hasContrast) |
| this.state_.state.contrast.current = settings.contrast; |
| if (settings.hasSaturation) |
| this.state_.state.saturation.current = settings.saturation; |
| if (settings.hasSharpness) |
| this.state_.state.sharpness.current = settings.sharpness; |
| |
| if (settings.hasTorch) |
| this.state_.state.torch = settings.torch; |
| |
| return Promise.resolve({ |
| success: true |
| }); |
| } |
| |
| takePhoto(source_id) { |
| return Promise.resolve({ |
| blob: { |
| mimeType: 'image/cat', |
| data: new Array(2) |
| } |
| }); |
| } |
| |
| async isPanTiltZoomPermissionGranted() { |
| if (!this.panTiltZoomPermissionStatus_) { |
| this.panTiltZoomPermissionStatus_ = await navigator.permissions.query({ |
| name: "camera", |
| panTiltZoom: true |
| }); |
| } |
| return this.panTiltZoomPermissionStatus_.state == "granted"; |
| } |
| |
| state() { |
| return this.state_.state; |
| } |
| |
| options() { |
| return this.settings_; |
| } |
| } |
| |
| let testInternal = { |
| initialized: false, |
| mockImageCapture: null |
| } |
| |
| class ImageCaptureTestChromium { |
| |
| constructor() { |
| Object.freeze(this); // Make it immutable. |
| } |
| |
| initialize() { |
| if (testInternal.initialized) |
| throw new Error('Call reset() before initialize().'); |
| |
| testInternal.mockImageCapture = new MockImageCapture; |
| testInternal.initialized = true; |
| } |
| // Resets state of image capture mocks between test runs. |
| async reset() { |
| if (!testInternal.initialized) |
| throw new Error('Call initialize() before reset().'); |
| testInternal.mockImageCapture.reset(); |
| testInternal.mockImageCapture = null; |
| testInternal.initialized = false; |
| |
| await new Promise(resolve => setTimeout(resolve, 0)); |
| } |
| mockImageCapture() { |
| return testInternal.mockImageCapture; |
| } |
| } |
| |
| return ImageCaptureTestChromium; |
| })(); |