| <!DOCTYPE html> |
| <html> |
| <head> |
| <style> |
| geolocation, usermedia, camera, microphone { |
| font-size: xxx-large; |
| margin: 0px; |
| border: 0px; |
| } |
| </style> |
| </head> |
| <body> |
| <div id="parent"> |
| <geolocation id="geolocation"></geolocation> |
| <usermedia id="usermedia"></usermedia> |
| <camera id="camera"></camera> |
| <microphone id="microphone"></microphone> |
| </div> |
| <script> |
| function checkGeolocation() { |
| navigator.permissions.query({name: 'geolocation'}).then(permission => { |
| window.document.title = permission.state; |
| permission.onchange = () => { |
| window.document.title = permission.state; |
| }; |
| }); |
| } |
| |
| function getGeolocationPermissionState() { |
| navigator.permissions.query({name: 'geolocation'}).then(permission => { |
| domAutomationController.send(permission.state); |
| }); |
| } |
| |
| function getPermissionState(name) { |
| navigator.permissions.query({name: name}).then(permission => { |
| domAutomationController.send(permission.state); |
| }); |
| } |
| |
| let geolocationResolver = null; |
| const geoEl = document.getElementById('geolocation'); |
| geoEl.addEventListener('location', () => { |
| const p = geoEl.position; |
| const e = geoEl.error; |
| const count = Number(geoEl.dataset.locationCount || 0) + 1; |
| geoEl.dataset.locationCount = String(count); |
| const summary = p |
| ? `location:lat=${p.coords.latitude},lng=${p.coords.longitude},hasAcc=${p.coords.accuracy > 0},err=${Boolean(e)}` |
| : `error:code=${e ? e.code : 0}`; |
| geoEl.dataset.locationSummary = summary; |
| if (geolocationResolver) { |
| const resolve = geolocationResolver; |
| geolocationResolver = null; |
| resolve(summary); |
| } |
| }); |
| |
| function waitForGeolocationResult() { |
| if (geoEl.dataset.locationSummary) { |
| domAutomationController.send(geoEl.dataset.locationSummary); |
| } else { |
| geolocationResolver = (summary) => { |
| domAutomationController.send(summary); |
| }; |
| } |
| } |
| |
| function resetGeolocationResult() { |
| delete geoEl.dataset.locationSummary; |
| geolocationResolver = null; |
| domAutomationController.send('reset'); |
| } |
| |
| function waitForGeolocationWatchCount(minCount) { |
| const check = () => { |
| const count = Number(geoEl.dataset.locationCount || 0); |
| if (count >= minCount && geoEl.position) { |
| const p = geoEl.position; |
| domAutomationController.send( |
| `watch:lat=${p.coords.latitude},lng=${p.coords.longitude},acc=${p.coords.accuracy},err=${Boolean(geoEl.error)}`); |
| } else { |
| window.setTimeout(check, 50); |
| } |
| }; |
| check(); |
| } |
| |
| const mediaResolvers = {}; |
| |
| function recordMediaResult(el, summary) { |
| el.dataset.resultSummary = summary; |
| if (mediaResolvers[el.id]) { |
| const resolve = mediaResolvers[el.id]; |
| delete mediaResolvers[el.id]; |
| resolve(summary); |
| } |
| } |
| |
| ['usermedia', 'camera', 'microphone'].forEach(id => { |
| const el = document.getElementById(id); |
| el.addEventListener('stream', () => { |
| const s = el.stream; |
| const summary = `stream:active=${Boolean(s && s.active)},video=${s ? s.getVideoTracks().length : 0},audio=${s ? s.getAudioTracks().length : 0}`; |
| recordMediaResult(el, summary); |
| }); |
| el.addEventListener('track', () => { |
| const t = el.track; |
| const summary = `track:kind=${t ? t.kind : ''},state=${t ? t.readyState : ''}`; |
| recordMediaResult(el, summary); |
| }); |
| el.addEventListener('cancel', () => { |
| const summary = `cancel:error=${el.error ? el.error.name : ''}`; |
| recordMediaResult(el, summary); |
| }); |
| el.addEventListener('error', () => { |
| const summary = `error:name=${el.error ? el.error.name : ''}`; |
| recordMediaResult(el, summary); |
| }); |
| }); |
| |
| function waitForMediaCaptureResult(id) { |
| const el = document.getElementById(id); |
| if (el.dataset.resultSummary) { |
| domAutomationController.send(el.dataset.resultSummary); |
| } else { |
| mediaResolvers[id] = (summary) => { |
| domAutomationController.send(summary); |
| }; |
| } |
| } |
| |
| function resetMediaCaptureElement(id) { |
| const el = document.getElementById(id); |
| if (el.stream) { |
| el.stream.getTracks().forEach(t => t.stop()); |
| } |
| if (el.track) { |
| el.track.stop(); |
| } |
| delete el.dataset.resultSummary; |
| delete mediaResolvers[id]; |
| domAutomationController.send('reset'); |
| } |
| |
| document.getElementById('parent').addEventListener('promptaction', (event) => { |
| window.document.title = 'promptaction'; |
| }); |
| document.getElementById('parent').addEventListener('promptdismiss', (event) => { |
| window.document.title = 'promptdismiss'; |
| }); |
| </script> |
| </body> |
| </html> |