UNPKG

react-native-webrtc

Version:
134 lines (115 loc) 4.56 kB
import { NativeModules, Permission, PermissionsAndroid, Platform } from 'react-native'; const { WebRTCModule } = NativeModules; /** * Type declaration for a permissions descriptor. */ type PermissionDescriptor = { name: string; }; /** * Class implementing a subset of W3C's Permissions API as defined by: * https://www.w3.org/TR/permissions/ */ class Permissions { /** * Possible result values for {@link query}, in accordance with: * https://www.w3.org/TR/permissions/#status-of-a-permission */ RESULT = { DENIED: 'denied', GRANTED: 'granted', PROMPT: 'prompt' }; /** * This implementation only supports requesting these permissions, a subset * of: https://www.w3.org/TR/permissions/#permission-registry */ VALID_PERMISSIONS = [ 'camera', 'microphone' ]; _lastReq: Promise<unknown> = Promise.resolve(); /** * Helper for requesting Android permissions. On Android only one permission * can be requested at a time (unless the multi-permission API is used, * but we are not using that for symmetry with the W3C API for querying) * so we'll queue them up. * * @param perm - The requested permission from * {@link PermissionsAndroid.PERMISSIONS} * https://facebook.github.io/react-native/docs/permissionsandroid#permissions-that-require-prompting-the-user */ _requestPermissionAndroid(perm: Permission) { return new Promise(resolve => { PermissionsAndroid.request(perm).then( granted => resolve(granted === PermissionsAndroid.RESULTS.GRANTED), () => resolve(false) ); }); } /** * Validates the given permission descriptor. */ _validatePermissionDescriptior(permissionDesc) { if (typeof permissionDesc !== 'object') { throw new TypeError('Argument 1 of Permissions.query is not an object.'); } if (typeof permissionDesc.name === 'undefined') { throw new TypeError('Missing required \'name\' member of PermissionDescriptor.'); } if (this.VALID_PERMISSIONS.indexOf(permissionDesc.name) === -1) { throw new TypeError( '\'name\' member of PermissionDescriptor is not a valid value for enumeration PermissionName.' ); } } /** * Method for querying the status of a permission, according to: * https://www.w3.org/TR/permissions/#permissions-interface */ query(permissionDesc: PermissionDescriptor) { try { this._validatePermissionDescriptior(permissionDesc); } catch (e) { return Promise.reject(e); } if (Platform.OS === 'android') { const perm = permissionDesc.name === 'camera' ? PermissionsAndroid.PERMISSIONS.CAMERA : PermissionsAndroid.PERMISSIONS.RECORD_AUDIO; return new Promise(resolve => { PermissionsAndroid.check(perm).then( granted => resolve(granted ? this.RESULT.GRANTED : this.RESULT.PROMPT), () => resolve(this.RESULT.PROMPT) ); }); } else if (Platform.OS === 'ios' || Platform.OS === 'macos') { return WebRTCModule.checkPermission(permissionDesc.name); } else { return Promise.reject(new TypeError('Unsupported platform.')); } } /** * Custom method NOT defined by W3C's permissions API, which allows the * caller to request a permission. */ request(permissionDesc: PermissionDescriptor) { try { this._validatePermissionDescriptior(permissionDesc); } catch (e) { return Promise.reject(e); } if (Platform.OS === 'android') { const perm = permissionDesc.name === 'camera' ? PermissionsAndroid.PERMISSIONS.CAMERA : PermissionsAndroid.PERMISSIONS.RECORD_AUDIO; const requestPermission = () => this._requestPermissionAndroid(perm); this._lastReq = this._lastReq.then(requestPermission, requestPermission); return this._lastReq; } else if (Platform.OS === 'ios' || Platform.OS === 'macos') { return WebRTCModule.requestPermission(permissionDesc.name); } else { return Promise.reject(new TypeError('Unsupported platform.')); } } } export default new Permissions();