tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

browser_autoplay_policy_request_permission.js (8342B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/
      3 */
      4 
      5 "use strict";
      6 
      7 const { PermissionTestUtils } = ChromeUtils.importESModule(
      8  "resource://testing-common/PermissionTestUtils.sys.mjs"
      9 );
     10 
     11 const VIDEO_PAGE_URI = GetTestWebBasedURL("file_empty.html");
     12 const SAME_ORIGIN_FRAME_URI = GetTestWebBasedURL(
     13  "file_mediaplayback_frame.html"
     14 );
     15 const DIFFERENT_ORIGIN_FRAME_URI = GetTestWebBasedURL(
     16  "file_mediaplayback_frame.html",
     17  { crossOrigin: true }
     18 );
     19 
     20 const gPermissionName = "autoplay-media";
     21 
     22 function setTestingPreferences(defaultSetting) {
     23  info(`set default autoplay setting to '${defaultSetting}'`);
     24  let defaultValue =
     25    defaultSetting == "blocked"
     26      ? SpecialPowers.Ci.nsIAutoplay.BLOCKED
     27      : SpecialPowers.Ci.nsIAutoplay.ALLOWED;
     28  return SpecialPowers.pushPrefEnv({
     29    set: [
     30      ["media.autoplay.default", defaultValue],
     31      ["media.autoplay.blocking_policy", 0],
     32      ["media.autoplay.block-event.enabled", true],
     33    ],
     34  });
     35 }
     36 
     37 async function testAutoplayExistingPermission(args) {
     38  info("- Starting '" + args.name + "' -");
     39  await BrowserTestUtils.withNewTab(
     40    {
     41      gBrowser,
     42      url: VIDEO_PAGE_URI,
     43    },
     44    async browser => {
     45      let promptShowing = () =>
     46        PopupNotifications.getNotification("autoplay-media", browser);
     47 
     48      PermissionTestUtils.add(
     49        browser.currentURI,
     50        "autoplay-media",
     51        args.permission
     52      );
     53      ok(!promptShowing(), "Should not be showing permission prompt yet");
     54 
     55      await loadAutoplayVideo(browser, args);
     56      await checkVideoDidPlay(browser, args);
     57 
     58      // Reset permission.
     59      PermissionTestUtils.remove(browser.currentURI, "autoplay-media");
     60 
     61      info("- Finished '" + args.name + "' -");
     62    }
     63  );
     64 }
     65 
     66 async function testAutoplayExistingPermissionAgainstDefaultSetting(args) {
     67  await setTestingPreferences(args.defaultSetting);
     68  await testAutoplayExistingPermission(args);
     69 }
     70 
     71 // Test the simple ALLOW/BLOCK cases; when permission is already set to ALLOW,
     72 // we shoud be able to autoplay via calling play(), or via the autoplay attribute,
     73 // and when it's set to BLOCK, we should not.
     74 add_task(async () => {
     75  await setTestingPreferences("blocked" /* default setting */);
     76  await testAutoplayExistingPermission({
     77    name: "Prexisting allow permission autoplay attribute",
     78    permission: Services.perms.ALLOW_ACTION,
     79    shouldPlay: true,
     80    mode: "autoplay attribute",
     81  });
     82  await testAutoplayExistingPermission({
     83    name: "Prexisting allow permission call play",
     84    permission: Services.perms.ALLOW_ACTION,
     85    shouldPlay: true,
     86    mode: "call play",
     87  });
     88  await testAutoplayExistingPermission({
     89    name: "Prexisting block permission autoplay attribute",
     90    permission: Services.perms.DENY_ACTION,
     91    shouldPlay: false,
     92    mode: "autoplay attribute",
     93  });
     94  await testAutoplayExistingPermission({
     95    name: "Prexisting block permission call play",
     96    permission: Services.perms.DENY_ACTION,
     97    shouldPlay: false,
     98    mode: "call play",
     99  });
    100 });
    101 
    102 /**
    103 * These tests are used to ensure the autoplay setting for specific site can
    104 * always override the default autoplay setting.
    105 */
    106 add_task(async () => {
    107  await testAutoplayExistingPermissionAgainstDefaultSetting({
    108    name: "Site has prexisting allow permission but default setting is 'blocked'",
    109    permission: Services.perms.ALLOW_ACTION,
    110    defaultSetting: "blocked",
    111    shouldPlay: true,
    112    mode: "autoplay attribute",
    113  });
    114  await testAutoplayExistingPermissionAgainstDefaultSetting({
    115    name: "Site has prexisting block permission but default setting is 'allowed'",
    116    permission: Services.perms.DENY_ACTION,
    117    defaultSetting: "allowed",
    118    shouldPlay: false,
    119    mode: "autoplay attribute",
    120  });
    121 });
    122 
    123 /**
    124 * The permission of the main page's domain would determine the final autoplay
    125 * result when a page contains multiple iframes which are in the different
    126 * domain from the main pages's.
    127 * That means we would not check the permission of iframe's domain, even if it
    128 * has been set.
    129 */
    130 add_task(async function testExistingPermissionForIframe() {
    131  await setTestingPreferences("blocked" /* default setting */);
    132  await testAutoplayExistingPermissionForIframe({
    133    name: "Prexisting ALLOW for main page with same origin iframe",
    134    permissionForParent: Services.perms.ALLOW_ACTION,
    135    isIframeDifferentOrgin: true,
    136    shouldPlay: true,
    137  });
    138 
    139  await testAutoplayExistingPermissionForIframe({
    140    name: "Prexisting ALLOW for main page with different origin iframe",
    141    permissionForParent: Services.perms.ALLOW_ACTION,
    142    isIframeDifferentOrgin: false,
    143    shouldPlay: true,
    144  });
    145 
    146  await testAutoplayExistingPermissionForIframe({
    147    name: "Prexisting ALLOW for main page, prexisting DENY for different origin iframe",
    148    permissionForParent: Services.perms.ALLOW_ACTION,
    149    permissionForChild: Services.perms.DENY_ACTION,
    150    isIframeDifferentOrgin: false,
    151    shouldPlay: true,
    152  });
    153 
    154  await testAutoplayExistingPermissionForIframe({
    155    name: "Prexisting DENY for main page, prexisting ALLOW for different origin iframe",
    156    permissionForParent: Services.perms.DENY_ACTION,
    157    permissionForChild: Services.perms.ALLOW_ACTION,
    158    isIframeDifferentOrgin: false,
    159    shouldPlay: false,
    160  });
    161 });
    162 
    163 /**
    164 * The following are helper functions.
    165 */
    166 async function testAutoplayExistingPermissionForIframe(args) {
    167  info(`Start test : ${args.name}`);
    168  await BrowserTestUtils.withNewTab(
    169    {
    170      gBrowser,
    171      url: VIDEO_PAGE_URI,
    172    },
    173    async browser => {
    174      setupSitesPermission(browser, args);
    175 
    176      await createIframe(browser, args);
    177      await checkAutplayInIframe(browser, args);
    178 
    179      clearSitesPermission(browser, args);
    180    }
    181  );
    182  info(`Finish test : ${args.name}`);
    183 }
    184 
    185 function setupSitesPermission(
    186  browser,
    187  {
    188    isIframeDifferentOrgin,
    189    permissionForParent,
    190    permissionForChild = Services.perms.UNKNOWN_ACTION,
    191  }
    192 ) {
    193  info(`setupSitesPermission`);
    194  // Set permission for the main page's domain
    195  setPermissionForBrowser(browser, browser.currentURI, permissionForParent);
    196  if (isIframeDifferentOrgin) {
    197    // Set permission for different domain of the iframe
    198    setPermissionForBrowser(
    199      browser,
    200      DIFFERENT_ORIGIN_FRAME_URI,
    201      permissionForChild
    202    );
    203  }
    204 }
    205 
    206 function clearSitesPermission(browser, { isIframeDifferentOrgin }) {
    207  info(`clearSitesPermission`);
    208  // Clear permission for the main page's domain
    209  setPermissionForBrowser(
    210    browser,
    211    browser.currentURI,
    212    Services.perms.UNKNOWN_ACTION
    213  );
    214  if (isIframeDifferentOrgin) {
    215    // Clear permission for different domain of the iframe
    216    setPermissionForBrowser(
    217      browser,
    218      DIFFERENT_ORIGIN_FRAME_URI,
    219      Services.perms.UNKNOWN_ACTION
    220    );
    221  }
    222 }
    223 
    224 function setPermissionForBrowser(browser, uri, permValue) {
    225  const promptShowing = () =>
    226    PopupNotifications.getNotification(gPermissionName, browser);
    227  PermissionTestUtils.add(uri, gPermissionName, permValue);
    228  ok(!promptShowing(), "Should not be showing permission prompt yet");
    229  is(
    230    PermissionTestUtils.testExactPermission(uri, gPermissionName),
    231    permValue,
    232    "Set permission correctly"
    233  );
    234 }
    235 
    236 function createIframe(browser, { isIframeDifferentOrgin }) {
    237  const iframeURL = isIframeDifferentOrgin
    238    ? DIFFERENT_ORIGIN_FRAME_URI
    239    : SAME_ORIGIN_FRAME_URI;
    240  return SpecialPowers.spawn(browser, [iframeURL], async url => {
    241    info(`Create iframe and wait until it finsihes loading`);
    242    const iframe = content.document.createElement("iframe");
    243    iframe.src = url;
    244    content.document.body.appendChild(iframe);
    245    await new Promise(r => (iframe.onload = r));
    246  });
    247 }
    248 
    249 function checkAutplayInIframe(browser, args) {
    250  return SpecialPowers.spawn(browser, [args], async ({ shouldPlay }) => {
    251    info(`check if media in iframe can start playing`);
    252    const iframe = content.document.getElementsByTagName("iframe")[0];
    253    if (!iframe) {
    254      ok(false, `can not get the iframe!`);
    255      return;
    256    }
    257    iframe.contentWindow.postMessage("play", "*");
    258    await new Promise(r => {
    259      content.onmessage = event => {
    260        if (shouldPlay) {
    261          is(event.data, "played", `played media in iframe`);
    262        } else {
    263          is(event.data, "blocked", `blocked media in iframe`);
    264        }
    265        r();
    266      };
    267    });
    268  });
    269 }