Bug 1345403 part 5 - Test video suspend canceling; r=jwwang
authorKaku Kuo <kaku@mozilla.com>
Wed, 08 Mar 2017 21:18:13 +0800
changeset 395507 be9cfb690427c87cc94352b9848c099a99ffa112
parent 395506 850a10a1e44fa6c8bd60d44e6735f26eb3f638b7
child 395508 f64fabc72583884c9753416b17af9823a5160265
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwwang
bugs1345403
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1345403 part 5 - Test video suspend canceling; r=jwwang MozReview-Commit-ID: 99IDqpwuRIf
dom/media/test/background_video.js
dom/media/test/mochitest.ini
dom/media/test/test_background_video_cancel_suspend_taint.html
dom/media/test/test_background_video_cancel_suspend_visible.html
--- a/dom/media/test/background_video.js
+++ b/dom/media/test/background_video.js
@@ -29,86 +29,100 @@ function appendVideoToDoc(url, token, wi
   v.width = width;
   v.height = height;
   v.src = url;
   return v;
 }
 
 /**
  * @param {HTMLMediaElement} video Video element under test.
- * @returns {Promise} Promise that is resolved when video 'playing' event fires and rejected on error.
+ * @returns {Promise} Promise that is resolved when video 'playing' event fires.
  */
 function waitUntilPlaying(video) {
-  var p = once(video, 'playing', () => { ok(true, video.token + " played."); });
+  var p = once(video, 'playing', () => { ok(true, `${video.token} played.`); });
   Log(video.token, "Start playing");
   video.play();
   return p;
 }
 
 /**
  * @param {HTMLMediaElement} video Video element under test.
  * @returns {Promise} Promise which is resolved when video 'ended' event fires.
  */
 function waitUntilEnded(video) {
   Log(video.token, "Waiting for ended");
   if (video.ended) {
     ok(true, video.token + " already ended");
     return Promise.resolve();
   }
 
-  return once(video, 'ended', () => { ok(true, video.token + " ended"); });
+  return once(video, 'ended', () => { ok(true, `${video.token} ended`); });
+}
+
+/**
+ * @param {HTMLMediaElement} video Video element under test.
+ * @returns {Promise} Promise that is resolved when video decode starts
+ *                    suspend timer.
+ */
+function testSuspendTimerStartedWhenHidden(video) {
+  var p = once(video, 'mozstartvideosuspendtimer').then(() => {
+    ok(true, `${video.token} suspend begins`)
+  });
+  Log(video.token, 'Set Hidden');
+  video.setVisible(false);
+  return p;
 }
 
 /**
  * @param {HTMLMediaElement} video Video element under test.
  * @returns {Promise} Promise that is resolved when video decode suspends.
  */
 function testVideoSuspendsWhenHidden(video) {
   let p = once(video, 'mozentervideosuspend').then(() => {
-    ok(true, video.token + " suspends");
+    ok(true, `${video.token} suspends`);
   });
   Log(video.token, "Set hidden");
   video.setVisible(false);
   return p;
 }
 
 /**
  * @param {HTMLMediaElement} video Video element under test.
  * @returns {Promise} Promise that is resolved when video decode resumes.
  */
 function testVideoResumesWhenShown(video) {
   var p  = once(video, 'mozexitvideosuspend').then(() => {
-    ok(true, video.token + " resumes");
+    ok(true, `${video.token} resumes`);
   });
   Log(video.token, "Set visible");
   video.setVisible(true);
   return p;
 }
 
 /**
  * @param {HTMLVideoElement} video Video element under test.
  * @returns {Promise} Promise that is resolved if video ends and rejects if video suspends.
  */
 function checkVideoDoesntSuspend(video) {
   let p = Promise.race([
-    waitUntilEnded(video).then(() => { ok(true, video.token + ' ended before decode was suspended')}),
-    once(video, 'mozentervideosuspend', () => { Promise.reject(new Error(video.token + ' suspended')) })
+    waitUntilEnded(video).then(() => { ok(true, `${video.token} ended before decode was suspended`)}),
+    once(video, 'mozentervideosuspend', () => { Promise.reject(new Error(`${video.token} suspended`)) })
   ]);
   Log(video.token, "Set hidden.");
   video.setVisible(false);
   return p;
 }
 
 /**
  * @param {HTMLMediaElement} video Video element under test.
  * @param {number} time video current time to wait til.
  * @returns {Promise} Promise that is resolved once currentTime passes time.
  */
 function waitTil(video, time) {
-  Log(video.token, "Waiting for time to reach " + time + "s");
+  Log(video.token, `Waiting for time to reach ${time}s`);
   return new Promise(resolve => {
     video.addEventListener('timeupdate', function timeUpdateEvent() {
       if (video.currentTime > time) {
         video.removeEventListener(name, timeUpdateEvent);
         resolve();
       }
     });
   });
--- a/dom/media/test/mochitest.ini
+++ b/dom/media/test/mochitest.ini
@@ -1123,16 +1123,22 @@ tags = webvtt
 skip-if = toolkit == 'android' # android(bug 1232305)
 [test_can_play_type_wave.html]
 skip-if = android_version == '15' || android_version == '17' # android(bug 1232305)
 [test_fragment_noplay.html]
 skip-if = android_version == '15' || android_version == '17' # android(bug 1232305)
 [test_fragment_play.html]
 skip-if = android_version == '15' || android_version == '17' # bug 1335520, bug 1209318, android(bug 1232305)
 
+[test_background_video_cancel_suspend_taint.html]
+skip-if = toolkit == 'android' # bug 1346705
+tags = suspend
+[test_background_video_cancel_suspend_visible.html]
+skip-if = toolkit == 'android' # bug 1346705
+tags = suspend
 [test_background_video_no_suspend_disabled.html]
 skip-if = toolkit == 'android' # android(bug 1304480)
 tags = suspend
 [test_background_video_no_suspend_short_vid.html]
 skip-if = toolkit == 'android' # android(bug 1304480)
 tags = suspend
 [test_background_video_suspend.html]
 skip-if = toolkit == 'android' # android(bug 1304480)
new file mode 100644
--- /dev/null
+++ b/dom/media/test/test_background_video_cancel_suspend_taint.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Test Background Video Suspend Cancels (Element Taint)</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script src="manifest.js"></script>
+<script src="background_video.js"></script>
+<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
+<script type="text/javascript">
+"use strict";
+
+var manager = new MediaTestManager;
+
+/**
+ * @param {HTMLMediaElement} video Video element under test.
+ * @returns {Promise} Promise that is resolved when video decode resumes.
+ */
+function testSuspendTimerCanceledWhenTainted(video) {
+  function ended() {
+    video.removeEventListener("mozcancelvideosuspendtimer", canceled);
+    ok(false, `${video.token} ended before suspend cancels`);
+    this.ended_resolve();
+  }
+
+  function canceled() {
+    video.removeEventListener("ended", ended);
+    ok(true, `${video.token} suspend cancels`);
+    this.canceled_resolve();
+  }
+
+  let p = Promise.race([
+    new Promise((resolve) => {
+      video.ended_resolve = resolve;
+      video.addEventListener('ended', ended, { 'once': true });
+    }),
+    new Promise((resolve) => {
+      video.canceled_resolve = resolve;
+      video.addEventListener('mozcancelvideosuspendtimer', canceled, { 'once': true });
+    })
+  ]);
+
+  Log(video.token, "Mark tainted");
+
+  let c = document.createElement('canvas');
+  let g = c.getContext('2d');
+  g.drawImage(video, 0, 0, c.width, c.height);
+  ok(video.hasSuspendTaint(), 'video used with drawImage is tainted.');
+
+  return p;
+}
+
+startTest({
+  desc: 'Test Background Video Suspend Cancels (Element Taint)',
+  prefs: [
+    [ "media.test.video-suspend", true ],
+    [ "media.suspend-bkgnd-video.enabled", true ],
+    [ "media.suspend-bkgnd-video.delay-ms", 10000 ]
+  ],
+  tests: gDecodeSuspendTests,
+  runTest: (test, token) => {
+    let v = appendVideoToDoc(test.name, token);
+    manager.started(token);
+
+    waitUntilPlaying(v)
+      .then(() => testSuspendTimerStartedWhenHidden(v))
+      .then(() => testSuspendTimerCanceledWhenTainted(v))
+      .then(() => { manager.finished(token); });
+  }
+});
+</script>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/dom/media/test/test_background_video_cancel_suspend_visible.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Test Background Video Suspend Cancels (Visibility)</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script src="manifest.js"></script>
+<script src="background_video.js"></script>
+<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
+<script type="text/javascript">
+"use strict";
+
+var manager = new MediaTestManager;
+
+/**
+ * Check that making the element visible before suspend timer delay causes the
+ * the suspend timer to be canceled.
+ * @param {HTMLMediaElement} video Video element under test.
+ * @returns {Promise} Promise that is resolved when video decode resumes.
+ */
+function testSuspendTimerCanceledWhenShown(video) {
+  function ended() {
+    video.removeEventListener("mozcancelvideosuspendtimer", canceled);
+    ok(false, `${video.token} ended before suspend cancels`);
+    this.ended_resolve();
+  }
+
+  function canceled() {
+    video.removeEventListener("ended", ended);
+    ok(true, `${video.token} suspend cancels`);
+    this.canceled_resolve();
+  }
+
+  let p = Promise.race([
+    new Promise((resolve) => {
+      video.ended_resolve = resolve;
+      video.addEventListener('ended', ended, { 'once': true });
+    }),
+    new Promise((resolve) => {
+      video.canceled_resolve = resolve;
+      video.addEventListener('mozcancelvideosuspendtimer', canceled, { 'once': true });
+    })
+  ]);
+
+  Log(video.token, "Set visible");
+  video.setVisible(true);
+
+  return p;
+}
+
+startTest({
+  desc: 'Test Background Video Suspend Cancels (Visibility)',
+  prefs: [
+    [ "media.test.video-suspend", true ],
+    [ "media.suspend-bkgnd-video.enabled", true ],
+    [ "media.suspend-bkgnd-video.delay-ms", 10000 ]
+  ],
+  tests: gDecodeSuspendTests,
+  runTest: (test, token) => {
+    let v = appendVideoToDoc(test.name, token);
+    manager.started(token);
+
+    waitUntilPlaying(v)
+      .then(() => testSuspendTimerStartedWhenHidden(v))
+      .then(() => testSuspendTimerCanceledWhenShown(v))
+      .then(() => {
+        ok(true, `${v.token} finished`);
+        manager.finished(token);
+      });
+  }
+});