1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
|
// META: script=/common/get-host-info.sub.js
// META: script=/common/utils.js
// META: script=/common/dispatcher/dispatcher.js
// META: script=/html/cross-origin-embedder-policy/credentialless/resources/common.js
// META: script=./resources/common.js
// A script acquiring a lock. It can be released using window.releaseLocks
const acquire_script = (key, response) => `
window.releaseLocks ||= [];
navigator.locks.request("${key}", async lock => {
send("${response}", "locked")
await new Promise(r => releaseLocks.push(r));
send("${response}", "unlocked");
});
`;
const release_script = (response) => `
for (release of releaseLocks)
release();
`;
// Assert that |context| holds |expected_keys|.
const assertHeldKeys = async (context, expected_keys) => {
const queue = token();
send(context, `
const list = await navigator.locks.query();
send("${queue}", JSON.stringify(list));
`);
const state = JSON.parse(await receive(queue));
const held = state.held.map(x => x.name);
assert_equals(held.length, expected_keys.length);
assert_array_equals(held.sort(), expected_keys.sort());
}
promise_test(async test => {
const origin = get_host_info().HTTPS_REMOTE_ORIGIN;
const key_1 = token();
const key_2 = token();
// 2 actors: A credentialless iframe and a normal one.
const iframe_credentialless = newIframeCredentialless(origin);
const iframe_normal = newIframe(origin);
const response_queue_1 = token();
const response_queue_2 = token();
// 1. Hold two different locks on both sides.
send(iframe_credentialless, acquire_script(key_1, response_queue_1));
send(iframe_normal, acquire_script(key_2, response_queue_2));
assert_equals(await receive(response_queue_1), "locked");
assert_equals(await receive(response_queue_2), "locked");
await assertHeldKeys(iframe_credentialless, [key_1]);
await assertHeldKeys(iframe_normal, [key_2]);
// 2. Try to acquire the lock with the same key on the opposite side. It
// shouldn't block, because they are partitioned.
send(iframe_credentialless , acquire_script(key_2, response_queue_1));
send(iframe_normal, acquire_script(key_1, response_queue_2));
assert_equals(await receive(response_queue_1), "locked");
assert_equals(await receive(response_queue_2), "locked");
await assertHeldKeys(iframe_credentialless, [key_1, key_2]);
await assertHeldKeys(iframe_normal, [key_1, key_2]);
// 3. Cleanup: release the 4 locks (2 on each sides).
send(iframe_credentialless, release_script(response_queue_1));
assert_equals(await receive(response_queue_1), "unlocked");
assert_equals(await receive(response_queue_1), "unlocked");
await assertHeldKeys(iframe_credentialless, []);
await assertHeldKeys(iframe_normal, [key_1, key_2]);
send(iframe_normal, release_script(response_queue_2));
assert_equals(await receive(response_queue_2), "unlocked");
assert_equals(await receive(response_queue_2), "unlocked");
await assertHeldKeys(iframe_credentialless, []);
await assertHeldKeys(iframe_normal, []);
})
|