| <!DOCTYPE html> |
| |
| <head> |
| <title>Cobalt WindowTimers test with freeze state</title> |
| <script src='black_box_js_test_utils.js'></script> |
| </head> |
| |
| <body> |
| <h1> |
| <span>ID element</span> |
| </h1> |
| <script> |
| |
| // Delay for setInterval (ms) |
| var kSetIntervalDelay = 600; |
| // Delay for setTimeout (ms) |
| var kSetTimeoutDelay = 800; |
| // Delay for the long setTimeout (ms) |
| var kLongSetTimeoutDelay = 13000; |
| |
| // Allowed time difference for callback expected execution time (ms) |
| // This value is quite high because in devel builds on slower devices there |
| // may occesionally be larger delays. |
| var kAllowedTimeDifference = 100; |
| |
| // Last time when the app was resumed from frozen state. |
| var resumeTime = 0; |
| // Expected execution time for interval callback |
| var expectedIntervalTime = 0; |
| // Expected execution time for timeout callback |
| var expectedTimeoutTime = 0; |
| // Expected execution time for long timeout callback |
| var expectedLongTimeoutTime = 0; |
| |
| let wasEverFrozen = false; |
| let frozen = false; |
| let eventWhileFrozen = false; |
| |
| // Callback for registering entering freeze state. |
| function freezeCallback() { |
| console.log("document.onfreeze") |
| wasEverFrozen = true; |
| frozen = true; |
| } |
| |
| // Callback for registering leaving freeze state. |
| function resumeCallback() { |
| resumeTime = performance.now(); |
| console.log("document.onresume") |
| if (!frozen) { |
| console.log('ERROR: Resuming while not frozen'); |
| notReached(); |
| } |
| if (eventWhileFrozen) { |
| console.log('ERROR: Timer callback received while frozen'); |
| notReached(); |
| } |
| frozen = false; |
| } |
| |
| function logState(prefix) { |
| console.log(prefix + ": State:" + |
| " document.visibilityState == " + document.visibilityState + |
| " document.hidden == " + document.hidden + |
| " document.hasFocus() == " + document.hasFocus()); |
| } |
| |
| function verifyNotFrozen() { |
| eventWhileFrozen |= frozen; |
| } |
| |
| function CheckTiming(expectedTime) { |
| if (expectedTime != 0) { |
| // Callbacks are allowed to execute no more than kAllowedTimeDifference |
| // before or after the expected time, except when the app was frozen, |
| // in which case it should be executed immediately when resuming, while |
| // the document is still hidden. |
| if (wasEverFrozen && resumeTime > expectedTime && document.hidden) { |
| // The callback is too late, but that is because the document was |
| // frozen. |
| return; |
| } |
| |
| if (Math.abs(performance.now() - expectedTime) > kAllowedTimeDifference) { |
| console.log('ERROR: Timer callback timing out of allowed range (' + |
| Math.round(Math.abs(performance.now() - expectedTime)) + |
| 'ms difference)'); |
| notReached(); |
| } |
| } |
| } |
| |
| function DoTimeout() { |
| verifyNotFrozen(); |
| CheckTiming(expectedTimeoutTime); |
| logState('Timeout'); |
| expectedTimeoutTime = performance.now() + kSetTimeoutDelay; |
| setTimeout(DoTimeout, kSetTimeoutDelay); |
| } |
| |
| function DoLongTimeout() { |
| verifyNotFrozen(); |
| CheckTiming(expectedLongTimeoutTime); |
| logState('Long Timeout'); |
| if (wasEverFrozen && !eventWhileFrozen) { |
| onEndTest(); |
| } |
| |
| expectedLongTimeoutTime = performance.now() + kLongSetTimeoutDelay; |
| setTimeout(DoLongTimeout, kLongSetTimeoutDelay); |
| } |
| |
| function DoInterval() {performance.now() |
| var now = performance.now(); |
| verifyNotFrozen(); |
| CheckTiming(expectedIntervalTime); |
| logState('Interval'); |
| expectedIntervalTime = now + kSetIntervalDelay; |
| } |
| |
| document.addEventListener("freeze", freezeCallback); |
| document.addEventListener("resume", resumeCallback); |
| |
| DoLongTimeout(); |
| DoTimeout(); |
| setInterval(DoInterval, kSetIntervalDelay); |
| |
| setupFinished(); |
| </script> |
| </body> |