summaryrefslogtreecommitdiffstats
path: root/toolkit/content/tests/browser/browser_resume_bkg_video_on_tab_hover.js
blob: 7dc9a8f42a2e40a0bd3b2f7623d3b53ed8475fcb (plain)
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
const PAGE =
  "https://example.com/browser/toolkit/content/tests/browser/file_silentAudioTrack.html";

async function check_video_decoding_state(args) {
  let video = content.document.getElementById("autoplay");
  if (!video) {
    ok(false, "Can't get the video element!");
  }

  let isSuspended = args.suspend;
  let reload = args.reload;

  if (reload) {
    // It is too late to register event handlers when playback is half
    // way done. Let's start playback from the beginning so we won't
    // miss any events.
    video.load();
    video.play();
  }

  let state = isSuspended ? "suspended" : "resumed";
  let event = isSuspended ? "mozentervideosuspend" : "mozexitvideosuspend";
  return new Promise(resolve => {
    video.addEventListener(
      event,
      function () {
        ok(true, `Video decoding is ${state}.`);
        resolve();
      },
      { once: true }
    );
  });
}

async function check_should_send_unselected_tab_hover_msg(browser) {
  info("did not update the value now, wait until it changes.");
  if (browser.shouldHandleUnselectedTabHover) {
    ok(
      true,
      "Should send unselected tab hover msg, someone is listening for it."
    );
    return true;
  }
  return BrowserTestUtils.waitForCondition(
    () => browser.shouldHandleUnselectedTabHover,
    "Should send unselected tab hover msg, someone is listening for it."
  );
}

async function check_should_not_send_unselected_tab_hover_msg(browser) {
  info("did not update the value now, wait until it changes.");
  return BrowserTestUtils.waitForCondition(
    () => !browser.shouldHandleUnselectedTabHover,
    "Should not send unselected tab hover msg, no one is listening for it."
  );
}

function get_video_decoding_suspend_promise(browser, reload) {
  let suspend = true;
  return SpecialPowers.spawn(
    browser,
    [{ suspend, reload }],
    check_video_decoding_state
  );
}

function get_video_decoding_resume_promise(browser) {
  let suspend = false;
  let reload = false;
  return ContentTask.spawn(
    browser,
    { suspend, reload },
    check_video_decoding_state
  );
}

/**
 * Because of bug1029451, we can't receive "mouseover" event correctly when
 * we disable non-test mouse event. Therefore, we can't synthesize mouse event
 * to simulate cursor hovering, so we temporarily use a hacky way to resume and
 * suspend video decoding.
 */
function cursor_hover_over_tab_and_resume_video_decoding(browser) {
  // TODO : simulate cursor hovering over the tab after fixing bug1029451.
  browser.unselectedTabHover(true /* hover */);
}

function cursor_leave_tab_and_suspend_video_decoding(browser) {
  // TODO : simulate cursor leaveing the tab after fixing bug1029451.
  browser.unselectedTabHover(false /* leave */);
}

add_task(async function setup_test_preference() {
  await SpecialPowers.pushPrefEnv({
    set: [
      ["media.block-autoplay-until-in-foreground", false],
      ["media.suspend-bkgnd-video.enabled", true],
      ["media.suspend-bkgnd-video.delay-ms", 0],
      ["media.resume-bkgnd-video-on-tabhover", true],
    ],
  });
});

/**
 * TODO : add the following user-level tests after fixing bug1029451.
 * test1 - only affect the unselected tab
 * test2 - only affect the tab with suspended video
 */
add_task(async function resume_and_suspend_background_video_decoding() {
  info("- open new background tab -");
  let tab = BrowserTestUtils.addTab(window.gBrowser, "about:blank");
  let browser = tab.linkedBrowser;
  await BrowserTestUtils.browserLoaded(browser);

  info("- before loading media, we shoudn't send the tab hover msg for tab -");
  await check_should_not_send_unselected_tab_hover_msg(browser);
  BrowserTestUtils.loadURIString(browser, PAGE);
  await BrowserTestUtils.browserLoaded(browser);

  info("- should suspend background video decoding -");
  await get_video_decoding_suspend_promise(browser, true);
  await check_should_send_unselected_tab_hover_msg(browser);

  info("- when cursor is hovering over the tab, resuming the video decoding -");
  let promise = get_video_decoding_resume_promise(browser);
  await cursor_hover_over_tab_and_resume_video_decoding(browser);
  await promise;
  await check_should_send_unselected_tab_hover_msg(browser);

  info("- when cursor leaves the tab, suspending the video decoding -");
  promise = get_video_decoding_suspend_promise(browser);
  await cursor_leave_tab_and_suspend_video_decoding(browser);
  await promise;
  await check_should_send_unselected_tab_hover_msg(browser);

  info("- select video's owner tab as foreground tab, should resume video -");
  promise = get_video_decoding_resume_promise(browser);
  await BrowserTestUtils.switchTab(window.gBrowser, tab);
  await promise;
  await check_should_send_unselected_tab_hover_msg(browser);

  info("- video's owner tab goes to background again, should suspend video -");
  promise = get_video_decoding_suspend_promise(browser);
  let blankTab = await BrowserTestUtils.openNewForegroundTab(
    window.gBrowser,
    "about:blank"
  );
  await promise;
  await check_should_send_unselected_tab_hover_msg(browser);

  info("- remove tabs -");
  BrowserTestUtils.removeTab(tab);
  BrowserTestUtils.removeTab(blankTab);
});