summaryrefslogtreecommitdiffstats
path: root/dom/media/autoplay/test/mochitest/test_autoplay_gv_play_request.html
blob: 760c452592fe5f7a9ea05b077b1c1c5acb444778 (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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
<!DOCTYPE HTML>
<html>
  <head>
    <title>GV Autoplay policy test</title>
    <script src="/tests/SimpleTest/SimpleTest.js"></script>
    <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
    <script type="text/javascript" src="manifest.js"></script>
    <script type="text/javascript" src="AutoplayTestUtils.js"></script>
  </head>
<body>
<script>

/**
 * On GeckoView, we have a different autoplay policy check than the one on other
 * platforms, which would send a request to the embedding app to ask if the
 * media can be allowed to play. We use a testing pref to simulate the response
 * from the request.
 *
 * The request has two types, audible and inaudible request. The result of the
 * audible request would only take effect on audible media, and the result of
 * inaudible request would only take effect on inaudible media.
 *
 * User activation policy still work on GeckoView, so once the page has been
 * activated, then we won't have to send the request and would allow all media
 * in that page to play.
 *
 * The following test cases contain the information which would be applied in
 * test, and the expected result of the test. For example, the following info
 * indicates that, play an [inaudible] media in the environment with [allowed]
 * [audible] request, and we expect to see it plays successfully.
 *  - muted: false,
 *  - requestType: "audible",
 *  - requestResult: "allowed",
 *  - expectedPlayResult: true,
 */
const testCases = [
  // (1) testing audible playback
  {
    name: "[audible] playback and [allowed audible request] -> allowed",
    muted: false,
    requestType: "audible",
    requestResult: "allowed",
    expectedPlayResult: true,
  },
  {
    name: "[audible] playback and [denied audible request] -> blocked",
    muted: false,
    requestType: "audible",
    requestResult: "denied",
    expectedPlayResult: false,
  },
  {
    name: "[audible] playback and [allowed inaudible request] -> blocked",
    muted: false,
    requestType: "inaudible",
    requestResult: "allowed",
    expectedPlayResult: false,
  },
  {
    name: "[audible] playback and [denied inaudible request] -> blocked",
    muted: false,
    requestType: "inaudible",
    requestResult: "denied",
    expectedPlayResult: false,
  },
  {
    name: "[audible] playback with [pending request] in [activated document] -> allowed",
    muted: false,
    requestType: "all",
    requestResult: "pending",
    activatedDocument: true,
    expectedPlayResult: true,
  },
  {
    name: "[audible] playback with [denied audible request] in [activated document] -> allowed",
    muted: false,
    requestType: "audible",
    requestResult: "allowed",
    activatedDocument: true,
    expectedPlayResult: true,
  },
  {
    name: "[audible] playback with [pending request] in [unactivated document] -> blocked",
    muted: false,
    requestType: "all",
    requestResult: "pending",
    expectedPlayResult: false,
  },
  // (2) testing inaudible playback
  {
    name: "[inaudible] playback and [allowed audible request] -> blocked",
    muted: true,
    requestType: "audible",
    requestResult: "allowed",
    expectedPlayResult: false,
  },
  {
    name: "[inaudible] playback and [denied audible request] -> blocked",
    muted: true,
    requestType: "audible",
    requestResult: "denied",
    expectedPlayResult: false,
  },
  {
    name: "[inaudible] playback and [allowed inaudible request] -> allowed",
    muted: true,
    requestType: "inaudible",
    requestResult: "allowed",
    expectedPlayResult: true,
  },
  {
    name: "[inaudible] playback and [denied inaudible request] -> blocked",
    muted: true,
    requestType: "inaudible",
    requestResult: "denied",
    expectedPlayResult: false,
  },
  {
    name: "[inaudible] playback without [pending request] in [activated document] -> allowed",
    muted: true,
    requestType: "all",
    requestResult: "pending",
    activatedDocument: true,
    expectedPlayResult: true,
  },
  {
    name: "[inaudible] playback without [denied inaudible request] in [activated document] -> allowed",
    muted: true,
    requestType: "inaudible",
    requestResult: "denied",
    activatedDocument: true,
    expectedPlayResult: true,
  },
  {
    name: "[inaudible] playback without [pending request] in [unactivated document] -> blocked",
    muted: true,
    requestType: "all",
    requestResult: "pending",
    expectedPlayResult: false,
  },
  // (3) testing playback from iframe
  {
    name: "playback from [same origin] iframe and [allowed all request]-> allowed",
    requestType: "all",
    requestResult: "allowed",
    iframe: "same-origin",
    expectedPlayResult: true,
  },
  {
    name: "playback from [same origin] iframe and [denied all request]-> blocked",
    requestType: "all",
    requestResult: "denied",
    iframe: "same-origin",
    expectedPlayResult: false,
  },
  {
    name: "playback from [cross origin] iframe and [allowed all request]-> allowed",
    requestType: "all",
    requestResult: "allowed",
    iframe: "cross-origin",
    expectedPlayResult: true,
  },
  {
    name: "playback from [cross origin] iframe and [denied all request]-> blocked",
    requestType: "all",
    requestResult: "denied",
    iframe: "cross-origin",
    expectedPlayResult: false,
  },
];

const pageURL = "file_autoplay_gv_play_request_window.html";

SimpleTest.waitForExplicitFinish();

(async function startTest() {
  for (const testCase of testCases) {
    info(`- start running test '${testCase.name}'-`);
    await setTestingPrefs(testCase);

    // Run each test in a new window to ensure they won't interfere each other
    const testPage = window.open(pageURL, "", "width=500,height=500");
    await once(testPage, "load");
    testPage.postMessage(testCase, window.origin);
    let result = await nextWindowMessage();
    is(result.data.allowedToPlay, testCase.expectedPlayResult, `allowed - ${testCase.name}`);
    is(result.data.played, testCase.expectedPlayResult, `played - ${testCase.name}`);
    testPage.close();
  }
  SimpleTest.finish();
})();

/**
 * This function would set which type of request would be explicitly allowed,
 * and the type of request we don't mention about would be pending forever.
 * E.g. `setTestingPrefs({"audible", "allow"})` will allow the audible request
 * and leave the inaudible request pending forever.
 */
async function setTestingPrefs({requestType, requestResult}) {
  let prefVal = 0;
  if (requestType == "all") {
    if (requestResult == "pending") {
      prefVal = 7;
    } else {
      prefVal = requestResult == "allowed" ? 1 : 2;
    }
  } else if (requestType == "audible") {
    prefVal = requestResult == "allowed" ? 3 : 4;
  } else if (requestType == "inaudible") {
    prefVal = requestResult == "allowed" ? 5 : 6;
  }
  info(`set testing pref to ${prefVal}`);
  await SpecialPowers.pushPrefEnv({
    set: [["media.geckoview.autoplay.request.testing", prefVal],
          ["media.geckoview.autoplay.request", true]],
  });
}

</script>
</body>
</html>