UNPKG

@fakes/media-devices

Version:

A interactive fake implementation of MediaDevices interface in the browser for testing

155 lines (154 loc) 6.67 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.UserConsentTracker = exports.RequestedMediaInput = void 0; const Deferred_1 = require("./Deferred"); const PermissionStatusFake_1 = require("./permissions/PermissionStatusFake"); var RequestedMediaInput; (function (RequestedMediaInput) { RequestedMediaInput["Microphone"] = "Microphone"; RequestedMediaInput["Camera"] = "Camera"; })(RequestedMediaInput = exports.RequestedMediaInput || (exports.RequestedMediaInput = {})); const resultingPermissionStateFor = (context, action) => { if (action === 'allow') { return 'granted'; } if (action === 'block') { return 'denied'; } context.notImplemented.call(`resultingPermissionStateFor() action: ${action}`); }; class UserConsentTracker { constructor(_context, _userConsent) { this._context = _context; this._userConsent = _userConsent; this._trackedPermissionStatus = { camera: [], microphone: [], }; this._pendingPermissionRequest = undefined; } permissionStatusFor(kind) { const permissionState = this.permissionStateFor(kind); const permissionStatus = new PermissionStatusFake_1.PermissionStatusFake(permissionState); this._trackedPermissionStatus[kind].push(permissionStatus); return permissionStatus; } setPermissionFor(kind, state) { this._userConsent[kind] = state; this._trackedPermissionStatus[kind].forEach((permissionStatus) => permissionStatus.updateTo(state)); } requestPermissionFor(permissionRequest) { if (this._pendingPermissionRequest) { this._context.notImplemented.call('There is already a pending permission request, not sure if this can happen'); } if (this.permissionGrantedFor(permissionRequest.deviceKind)) { permissionRequest.granted(); return; } if (this.permissionBlockedFor(permissionRequest.deviceKind)) { permissionRequest.blocked(); return; } this._pendingPermissionRequest = permissionRequest; } permissionStateFor(kind) { return this._userConsent[kind]; } permissionGrantedFor(deviceKind) { if (deviceKind === 'videoinput') { return this._userConsent.camera === 'granted'; } if (deviceKind === 'audioinput') { return this._userConsent.microphone === 'granted'; } this._context.notImplemented.call(`permissionGrantedFor '${deviceKind}'`); } permissionBlockedFor(deviceKind) { if (deviceKind === 'videoinput') { return this._userConsent.camera === 'denied'; } if (deviceKind === 'audioinput') { return this._userConsent.microphone === 'denied'; } this._context.notImplemented.call(`permissionGrantedFor '${deviceKind}'`); } //todo add an override for the wait time and poll interval async deviceAccessPrompt() { const deferred = new Deferred_1.Deferred(); const maximumWaitTime = 1000; const pollInterval = 100; let timeWaited = 0; let pollForPendingPermissionRequest = () => { if (this._pendingPermissionRequest) { const complete = (action) => { if (this._pendingPermissionRequest === undefined) { throw new Error('there is no pending permission request'); } const updatedPermission = resultingPermissionStateFor(this._context, action); if (this._pendingPermissionRequest.deviceKind === 'audioinput') { this._userConsent.microphone = updatedPermission; this._trackedPermissionStatus.microphone.forEach((fake) => fake.updateTo(updatedPermission)); } if (this._pendingPermissionRequest.deviceKind === 'videoinput') { this._userConsent.camera = updatedPermission; this._trackedPermissionStatus.camera.forEach((fake) => fake.updateTo(updatedPermission)); } this._pendingPermissionRequest = undefined; }; const value = this.permissionPromptFor(this._context, this._pendingPermissionRequest, complete); deferred.resolve(value); return; } if (timeWaited >= maximumWaitTime) { deferred.reject(new Error(`After waiting for ${maximumWaitTime} ms there still is no pending permission request`)); return; } timeWaited += pollInterval; // TODO add scheduler abstraction to encapsulate window access window.setTimeout(pollForPendingPermissionRequest, pollInterval); }; pollForPendingPermissionRequest(); // check with the Permission Manager if permissions where already rejected // check if there was a request for media return deferred.promise; } permissionPromptFor(context, permissionRequest, complete) { const requestedPermissions = []; if (permissionRequest.deviceKind === 'videoinput' && !this.permissionGrantedFor('videoinput')) { requestedPermissions.push(RequestedMediaInput.Camera); } if (permissionRequest.deviceKind === 'audioinput' && !this.permissionGrantedFor('audioinput')) { requestedPermissions.push(RequestedMediaInput.Microphone); } return new (class { requestedPermissions() { return requestedPermissions; } takeAction(action) { complete(action); if (action === 'allow') { permissionRequest.granted(); return; } if (action === 'block') { permissionRequest.blocked(); return; } context.notImplemented.call(`takeAction '${action}'`); } })(); } accessAllowedFor(kind) { if (kind === 'audioinput') { return this._userConsent.microphone === 'granted'; } if (kind === 'videoinput') { return this._userConsent.camera === 'granted'; } if (kind === 'audiooutput') { return this._userConsent.microphone === 'granted'; } this._context.notImplemented.call(`not sure how to implement this for ${kind}`); } } exports.UserConsentTracker = UserConsentTracker;