1import { UnavailabilityError } from 'expo-modules-core';
2import { CameraType, PermissionStatus, } from './Camera.types';
3import { canGetUserMedia, isBackCameraAvailableAsync, isFrontCameraAvailableAsync, } from './WebUserMediaManager';
4function getUserMedia(constraints) {
5    if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
6        return navigator.mediaDevices.getUserMedia(constraints);
7    }
8    // Some browsers partially implement mediaDevices. We can't just assign an object
9    // with getUserMedia as it would overwrite existing properties.
10    // Here, we will just add the getUserMedia property if it's missing.
11    // First get ahold of the legacy getUserMedia, if present
12    const getUserMedia =
13    // TODO: this method is deprecated, migrate to https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
14    navigator.getUserMedia ||
15        navigator.webkitGetUserMedia ||
16        navigator.mozGetUserMedia ||
17        function () {
18            const error = new Error('Permission unimplemented');
19            error.code = 0;
20            error.name = 'NotAllowedError';
21            throw error;
22        };
23    return new Promise((resolve, reject) => {
24        getUserMedia.call(navigator, constraints, resolve, reject);
25    });
26}
27function handleGetUserMediaError({ message }) {
28    // name: NotAllowedError
29    // code: 0
30    if (message === 'Permission dismissed') {
31        return {
32            status: PermissionStatus.UNDETERMINED,
33            expires: 'never',
34            canAskAgain: true,
35            granted: false,
36        };
37    }
38    else {
39        // TODO: Bacon: [OSX] The system could deny access to chrome.
40        // TODO: Bacon: add: { status: 'unimplemented' }
41        return {
42            status: PermissionStatus.DENIED,
43            expires: 'never',
44            canAskAgain: true,
45            granted: false,
46        };
47    }
48}
49async function handleRequestPermissionsAsync() {
50    try {
51        await getUserMedia({
52            video: true,
53        });
54        return {
55            status: PermissionStatus.GRANTED,
56            expires: 'never',
57            canAskAgain: true,
58            granted: true,
59        };
60    }
61    catch ({ message }) {
62        return handleGetUserMediaError({ message });
63    }
64}
65async function handlePermissionsQueryAsync(query) {
66    if (!navigator?.permissions?.query) {
67        throw new UnavailabilityError('expo-camera', 'navigator.permissions API is not available');
68    }
69    const { state } = await navigator.permissions.query({ name: query });
70    switch (state) {
71        case 'prompt':
72            return {
73                status: PermissionStatus.UNDETERMINED,
74                expires: 'never',
75                canAskAgain: true,
76                granted: false,
77            };
78        case 'granted':
79            return {
80                status: PermissionStatus.GRANTED,
81                expires: 'never',
82                canAskAgain: true,
83                granted: true,
84            };
85        case 'denied':
86            return {
87                status: PermissionStatus.DENIED,
88                expires: 'never',
89                canAskAgain: true,
90                granted: false,
91            };
92    }
93}
94export default {
95    get name() {
96        return 'ExponentCameraManager';
97    },
98    get Type() {
99        return {
100            back: 'back',
101            front: 'front',
102        };
103    },
104    get FlashMode() {
105        return {
106            on: 'on',
107            off: 'off',
108            auto: 'auto',
109            torch: 'torch',
110        };
111    },
112    get AutoFocus() {
113        return {
114            on: 'on',
115            off: 'off',
116            auto: 'auto',
117            singleShot: 'singleShot',
118        };
119    },
120    get WhiteBalance() {
121        return {
122            auto: 'auto',
123            continuous: 'continuous',
124            manual: 'manual',
125        };
126    },
127    get VideoQuality() {
128        return {};
129    },
130    get VideoStabilization() {
131        return {};
132    },
133    async isAvailableAsync() {
134        return canGetUserMedia();
135    },
136    async takePicture(options, camera) {
137        return await camera.takePicture(options);
138    },
139    async pausePreview(camera) {
140        await camera.pausePreview();
141    },
142    async resumePreview(camera) {
143        return await camera.resumePreview();
144    },
145    async getAvailableCameraTypesAsync() {
146        if (!canGetUserMedia() || !navigator.mediaDevices.enumerateDevices)
147            return [];
148        const devices = await navigator.mediaDevices.enumerateDevices();
149        const types = await Promise.all([
150            (await isFrontCameraAvailableAsync(devices)) && CameraType.front,
151            (await isBackCameraAvailableAsync()) && CameraType.back,
152        ]);
153        return types.filter(Boolean);
154    },
155    async getAvailablePictureSizes(ratio, camera) {
156        return await camera.getAvailablePictureSizes(ratio);
157    },
158    /* async getSupportedRatios(camera: ExponentCameraRef): Promise<string[]> {
159      // TODO: Support on web
160    },
161    async record(
162      options?: CameraRecordingOptions,
163      camera: ExponentCameraRef
164    ): Promise<{ uri: string }> {
165      // TODO: Support on web
166    },
167    async stopRecording(camera: ExponentCameraRef): Promise<void> {
168      // TODO: Support on web
169    }, */
170    async getPermissionsAsync() {
171        return handlePermissionsQueryAsync('camera');
172    },
173    async requestPermissionsAsync() {
174        return handleRequestPermissionsAsync();
175    },
176    async getCameraPermissionsAsync() {
177        return handlePermissionsQueryAsync('camera');
178    },
179    async requestCameraPermissionsAsync() {
180        return handleRequestPermissionsAsync();
181    },
182    async getMicrophonePermissionsAsync() {
183        return handlePermissionsQueryAsync('microphone');
184    },
185    async requestMicrophonePermissionsAsync() {
186        try {
187            await getUserMedia({
188                audio: true,
189            });
190            return {
191                status: PermissionStatus.GRANTED,
192                expires: 'never',
193                canAskAgain: true,
194                granted: true,
195            };
196        }
197        catch ({ message }) {
198            return handleGetUserMediaError({ message });
199        }
200    },
201};
202//# sourceMappingURL=ExponentCameraManager.web.js.map