add wake locks to web installer

Sets wake locks during long-running operations, such as downloading and
flashing the release.

Close: https://github.com/GrapheneOS/grapheneos.org/issues/837
Test: Manual
This commit is contained in:
sandbank52641 2024-09-21 13:31:14 +02:00 committed by Daniel Micay
parent e53724dd4c
commit d0cbf321a8
2 changed files with 36 additions and 1 deletions

View File

@ -391,7 +391,7 @@ http {
}
include snippets/security-headers-base.conf;
add_header Content-Security-Policy "default-src 'none'; child-src 'self'; connect-src 'self' https://releases.grapheneos.org/; font-src 'self'; img-src 'self'; manifest-src 'self'; script-src 'self'; style-src 'self'; webrtc 'block'; form-action 'none'; frame-ancestors 'none'; base-uri 'none'" always;
add_header Permissions-Policy "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), bluetooth=(), camera=(), clipboard-read=(), clipboard-write=(), display-capture=(), document-domain=(), encrypted-media=(), fullscreen=(), gamepad=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), interest-cohort=(), keyboard-map=(), local-fonts=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), serial=(), speaker-selection=(), sync-xhr=(), xr-spatial-tracking=()" always;
add_header Permissions-Policy "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), bluetooth=(), camera=(), clipboard-read=(), clipboard-write=(), display-capture=(), document-domain=(), encrypted-media=(), fullscreen=(), gamepad=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), interest-cohort=(), keyboard-map=(), local-fonts=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(self), serial=(), speaker-selection=(), sync-xhr=(), xr-spatial-tracking=()" always;
add_header Cross-Origin-Resource-Policy "same-origin" always;
add_header Cache-Control "public, no-cache";
include snippets/preload.conf;

View File

@ -20,6 +20,36 @@ const InstallerState = {
INSTALLING_RELEASE: 0x2
};
let wakeLock = null;
const requestWakeLock = async () => {
try {
wakeLock = await navigator.wakeLock.request("screen");
console.log("Wake lock has been set");
wakeLock.addEventListener("release", async () => {
console.log("Wake lock has been released");
});
} catch (err) {
// if wake lock request fails - usually system related, such as battery
throw new Error(`${err.name}, ${err.message}`);
}
};
const releaseWakeLock = async () => {
if (wakeLock !== null) {
wakeLock.release().then(() => {
wakeLock = null;
});
}
};
// reacquires the wake lock should the visibility of the document change and the wake lock is released
document.addEventListener("visibilitychange", async () => {
if (wakeLock !== null && document.visibilityState === "visible") {
await requestWakeLock();
}
});
// This wraps XHR because getting progress updates with fetch() is overly complicated.
function fetchBlobWithProgress(url, onProgress) {
let xhr = new XMLHttpRequest();
@ -212,6 +242,7 @@ async function getLatestRelease() {
}
async function downloadRelease(setProgress) {
await requestWakeLock();
await ensureConnected(setProgress);
setProgress("Finding latest release...");
@ -227,6 +258,7 @@ async function downloadRelease(setProgress) {
});
} finally {
setInstallerState({ state: InstallerState.DOWNLOADING_RELEASE, active: false });
await releaseWakeLock();
}
setProgress(`Downloaded ${latestZip} release.`, 1.0);
}
@ -251,6 +283,7 @@ async function reconnectCallback() {
}
async function flashRelease(setProgress) {
await requestWakeLock();
await ensureConnected(setProgress);
// Need to do this again because the user may not have clicked download if
@ -297,6 +330,7 @@ async function flashRelease(setProgress) {
}
} finally {
setInstallerState({ state: InstallerState.INSTALLING_RELEASE, active: false });
await releaseWakeLock();
}
return `Flashed ${latestZip} to device.`;
@ -365,6 +399,7 @@ function addButtonHook(id, callback) {
} catch (error) {
statusCallback(`Error: ${error.message}`);
statusField.className = "error-text";
await releaseWakeLock();
// Rethrow the error so it shows up in the console
throw error;
}