import { PermissionStatus, } from './Permissions.types';
/*
* TODO: Bacon: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia#Permissions
* Add messages to manifest like we do with iOS info.plist
*/
// https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia#Using_the_new_API_in_older_browsers
// Older browsers might not implement mediaDevices at all, so we set an empty object first
function _getUserMedia(constraints) {
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
return navigator.mediaDevices.getUserMedia(constraints);
}
// Some browsers partially implement mediaDevices. We can't just assign an object
// with getUserMedia as it would overwrite existing properties.
// Here, we will just add the getUserMedia property if it's missing.
// First get ahold of the legacy getUserMedia, if present
const getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
function () {
const error = new Error('Permission unimplemented');
error.code = 0;
error.name = 'NotAllowedError';
throw error;
};
return new Promise((resolve, reject) => {
getUserMedia.call(navigator, constraints, resolve, reject);
});
}
async function askForMediaPermissionAsync(options) {
try {
await _getUserMedia(options);
return { status: PermissionStatus.GRANTED, expires: 'never' };
}
catch ({ message }) {
// name: NotAllowedError
// code: 0
if (message === 'Permission dismissed') {
// message: Permission dismissed
return { status: PermissionStatus.UNDETERMINED, expires: 'never' };
}
else {
// TODO: Bacon: [OSX] The system could deny access to chrome.
// TODO: Bacon: add: { status: 'unimplemented' }
// message: Permission denied
return { status: PermissionStatus.DENIED, expires: 'never' };
}
}
}
async function askForMicrophonePermissionAsync() {
return await askForMediaPermissionAsync({ audio: true });
}
async function askForCameraPermissionAsync() {
return await askForMediaPermissionAsync({ video: true });
}
async function askForLocationPermissionAsync() {
return new Promise(resolve => {
navigator.geolocation.getCurrentPosition(() => resolve({ status: PermissionStatus.GRANTED, expires: 'never' }), ({ code }) => {
// https://developer.mozilla.org/en-US/docs/Web/API/PositionError/code
if (code === 1) {
resolve({ status: PermissionStatus.DENIED, expires: 'never' });
}
else {
resolve({ status: PermissionStatus.UNDETERMINED, expires: 'never' });
}
});
});
}
async function getPermissionAsync(permission, shouldAsk) {
switch (permission) {
case 'userFacingNotifications':
case 'notifications':
{
const { Notification = {} } = window;
if (Notification.requestPermission) {
let status = Notification.permission;
if (shouldAsk) {
status = await Notification.requestPermission();
}
if (!status || status === 'default') {
return { status: PermissionStatus.UNDETERMINED, expires: 'never' };
}
return { status, expires: 'never' };
}
}
break;
case 'location':
{
const { navigator = {} } = window;
if (navigator.permissions) {
const { state } = await navigator.permissions.query({ name: 'geolocation' });
if (state !== PermissionStatus.GRANTED && state !== PermissionStatus.DENIED) {
if (shouldAsk) {
return await askForLocationPermissionAsync();
}
return { status: PermissionStatus.UNDETERMINED, expires: 'never' };
}
return { status: state, expires: 'never' };
}
else if (shouldAsk) {
// TODO: Bacon: should this function as ask async when not in chrome?
return await askForLocationPermissionAsync();
}
}
break;
case 'audioRecording':
if (shouldAsk) {
return await askForMicrophonePermissionAsync();
}
else {
//TODO: Bacon: Is it possible to get this permission?
}
break;
case 'camera':
if (shouldAsk) {
return await askForCameraPermissionAsync();
}
else {
//TODO: Bacon: Is it possible to get this permission?
}
break;
default:
break;
}
return { status: PermissionStatus.UNDETERMINED, expires: 'never' };
}
export default {
get name() {
return 'ExpoPermissions';
},
async getAsync(permissionTypes) {
const results = {};
for (const permissionType of new Set(permissionTypes)) {
results[permissionType] = await getPermissionAsync(permissionType, /* shouldAsk */ false);
}
return results;
},
async askAsync(permissionTypes) {
const results = {};
for (const permissionType of new Set(permissionTypes)) {
results[permissionType] = await getPermissionAsync(permissionType, /* shouldAsk */ true);
}
return results;
},
};
//# sourceMappingURL=ExpoPermissions.web.js.map