tor-browser

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

browser_global_mute_toggles.js (8970B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 const TEST_ROOT = getRootDirectory(gTestPath).replace(
      7  "chrome://mochitests/content/",
      8  "https://example.com/"
      9 );
     10 const TEST_PAGE = TEST_ROOT + "get_user_media.html";
     11 const MUTE_TOPICS = [
     12  "getUserMedia:muteVideo",
     13  "getUserMedia:unmuteVideo",
     14  "getUserMedia:muteAudio",
     15  "getUserMedia:unmuteAudio",
     16 ];
     17 
     18 add_setup(async function () {
     19  let prefs = [
     20    [PREF_PERMISSION_FAKE, true],
     21    [PREF_AUDIO_LOOPBACK, ""],
     22    [PREF_VIDEO_LOOPBACK, ""],
     23    [PREF_FAKE_STREAMS, true],
     24    [PREF_FOCUS_SOURCE, false],
     25    ["privacy.webrtc.globalMuteToggles", true],
     26  ];
     27  await SpecialPowers.pushPrefEnv({ set: prefs });
     28 });
     29 
     30 /**
     31 * Returns a Promise that resolves when the content process for
     32 * <browser> fires the right observer notification based on the
     33 * value of isMuted for the camera.
     34 *
     35 * Note: Callers must ensure that they first call
     36 * BrowserTestUtils.startObservingTopics to monitor the mute and
     37 * unmute observer notifications for this to work properly.
     38 *
     39 * @param {<xul:browser>} browser - The browser running in the content process
     40 * to be monitored.
     41 * @param {boolean} isMuted - True if the muted topic should be fired.
     42 * @returns {Promise<void>}
     43 *   Resovles when the notification fires.
     44 */
     45 function waitForCameraMuteState(browser, isMuted) {
     46  let topic = isMuted ? "getUserMedia:muteVideo" : "getUserMedia:unmuteVideo";
     47  return BrowserTestUtils.contentTopicObserved(browser.browsingContext, topic);
     48 }
     49 
     50 /**
     51 * Returns a Promise that resolves when the content process for
     52 * <browser> fires the right observer notification based on the
     53 * value of isMuted for the microphone.
     54 *
     55 * Note: Callers must ensure that they first call
     56 * BrowserTestUtils.startObservingTopics to monitor the mute and
     57 * unmute observer notifications for this to work properly.
     58 *
     59 * @param {<xul:browser>} browser - The browser running in the content process
     60 * to be monitored.
     61 * @param {boolean} isMuted - True if the muted topic should be fired.
     62 * @returns {Promise<void>}
     63 *   Resolves when the notification fires.
     64 */
     65 function waitForMicrophoneMuteState(browser, isMuted) {
     66  let topic = isMuted ? "getUserMedia:muteAudio" : "getUserMedia:unmuteAudio";
     67  return BrowserTestUtils.contentTopicObserved(browser.browsingContext, topic);
     68 }
     69 
     70 /**
     71 * Tests that the global mute toggles fire the right observer
     72 * notifications in pre-existing content processes.
     73 */
     74 add_task(async function test_notifications() {
     75  await BrowserTestUtils.withNewTab(TEST_PAGE, async browser => {
     76    let indicatorPromise = promiseIndicatorWindow();
     77 
     78    await shareDevices(browser, true /* camera */, true /* microphone */);
     79 
     80    let indicator = await indicatorPromise;
     81    let doc = indicator.document;
     82 
     83    let microphoneMute = doc.getElementById("microphone-mute-toggle");
     84    let cameraMute = doc.getElementById("camera-mute-toggle");
     85 
     86    Assert.ok(
     87      !microphoneMute.checked,
     88      "Microphone toggle should not start checked."
     89    );
     90    Assert.ok(!cameraMute.checked, "Camera toggle should not start checked.");
     91 
     92    await BrowserTestUtils.startObservingTopics(
     93      browser.browsingContext,
     94      MUTE_TOPICS
     95    );
     96 
     97    info("Muting microphone...");
     98    let microphoneMuted = waitForMicrophoneMuteState(browser, true);
     99    microphoneMute.click();
    100    await microphoneMuted;
    101    info("Microphone successfully muted.");
    102 
    103    info("Muting camera...");
    104    let cameraMuted = waitForCameraMuteState(browser, true);
    105    cameraMute.click();
    106    await cameraMuted;
    107    info("Camera successfully muted.");
    108 
    109    Assert.ok(
    110      microphoneMute.checked,
    111      "Microphone toggle should now be checked."
    112    );
    113    Assert.ok(cameraMute.checked, "Camera toggle should now be checked.");
    114 
    115    info("Unmuting microphone...");
    116    let microphoneUnmuted = waitForMicrophoneMuteState(browser, false);
    117    microphoneMute.click();
    118    await microphoneUnmuted;
    119    info("Microphone successfully unmuted.");
    120 
    121    info("Unmuting camera...");
    122    let cameraUnmuted = waitForCameraMuteState(browser, false);
    123    cameraMute.click();
    124    await cameraUnmuted;
    125    info("Camera successfully unmuted.");
    126 
    127    await BrowserTestUtils.stopObservingTopics(
    128      browser.browsingContext,
    129      MUTE_TOPICS
    130    );
    131  });
    132 });
    133 
    134 /**
    135 * Tests that if sharing stops while muted, and the indicator closes,
    136 * then the mute state is reset.
    137 */
    138 add_task(async function test_closing_indicator_resets_mute() {
    139  await BrowserTestUtils.withNewTab(TEST_PAGE, async browser => {
    140    let indicatorPromise = promiseIndicatorWindow();
    141 
    142    await shareDevices(browser, true /* camera */, true /* microphone */);
    143 
    144    let indicator = await indicatorPromise;
    145    let doc = indicator.document;
    146 
    147    let microphoneMute = doc.getElementById("microphone-mute-toggle");
    148    let cameraMute = doc.getElementById("camera-mute-toggle");
    149 
    150    Assert.ok(
    151      !microphoneMute.checked,
    152      "Microphone toggle should not start checked."
    153    );
    154    Assert.ok(!cameraMute.checked, "Camera toggle should not start checked.");
    155 
    156    await BrowserTestUtils.startObservingTopics(
    157      browser.browsingContext,
    158      MUTE_TOPICS
    159    );
    160 
    161    info("Muting microphone...");
    162    let microphoneMuted = waitForMicrophoneMuteState(browser, true);
    163    microphoneMute.click();
    164    await microphoneMuted;
    165    info("Microphone successfully muted.");
    166 
    167    info("Muting camera...");
    168    let cameraMuted = waitForCameraMuteState(browser, true);
    169    cameraMute.click();
    170    await cameraMuted;
    171    info("Camera successfully muted.");
    172 
    173    Assert.ok(
    174      microphoneMute.checked,
    175      "Microphone toggle should now be checked."
    176    );
    177    Assert.ok(cameraMute.checked, "Camera toggle should now be checked.");
    178 
    179    let allUnmuted = Promise.all([
    180      waitForMicrophoneMuteState(browser, false),
    181      waitForCameraMuteState(browser, false),
    182    ]);
    183 
    184    await closeStream();
    185    await allUnmuted;
    186 
    187    await BrowserTestUtils.stopObservingTopics(
    188      browser.browsingContext,
    189      MUTE_TOPICS
    190    );
    191  });
    192 });
    193 
    194 /**
    195 * Test that if the global mute state is set, then newly created
    196 * content processes also have their tracks muted after sending
    197 * a getUserMedia request.
    198 */
    199 add_task(async function test_new_processes() {
    200  let tab1 = await BrowserTestUtils.openNewForegroundTab({
    201    gBrowser,
    202    url: TEST_PAGE,
    203  });
    204  let browser1 = tab1.linkedBrowser;
    205 
    206  let indicatorPromise = promiseIndicatorWindow();
    207 
    208  await shareDevices(browser1, true /* camera */, true /* microphone */);
    209 
    210  let indicator = await indicatorPromise;
    211  let doc = indicator.document;
    212 
    213  let microphoneMute = doc.getElementById("microphone-mute-toggle");
    214  let cameraMute = doc.getElementById("camera-mute-toggle");
    215 
    216  Assert.ok(
    217    !microphoneMute.checked,
    218    "Microphone toggle should not start checked."
    219  );
    220  Assert.ok(!cameraMute.checked, "Camera toggle should not start checked.");
    221 
    222  await BrowserTestUtils.startObservingTopics(
    223    browser1.browsingContext,
    224    MUTE_TOPICS
    225  );
    226 
    227  info("Muting microphone...");
    228  let microphoneMuted = waitForMicrophoneMuteState(browser1, true);
    229  microphoneMute.click();
    230  await microphoneMuted;
    231  info("Microphone successfully muted.");
    232 
    233  info("Muting camera...");
    234  let cameraMuted = waitForCameraMuteState(browser1, true);
    235  cameraMute.click();
    236  await cameraMuted;
    237  info("Camera successfully muted.");
    238 
    239  // We'll make sure a new process is being launched by observing
    240  // for the ipc:content-created notification.
    241  let processLaunched = TestUtils.topicObserved("ipc:content-created");
    242 
    243  let tab2 = await BrowserTestUtils.openNewForegroundTab({
    244    gBrowser,
    245    url: TEST_PAGE,
    246    forceNewProcess: true,
    247  });
    248  let browser2 = tab2.linkedBrowser;
    249 
    250  await processLaunched;
    251 
    252  await BrowserTestUtils.startObservingTopics(
    253    browser2.browsingContext,
    254    MUTE_TOPICS
    255  );
    256 
    257  let microphoneMuted2 = waitForMicrophoneMuteState(browser2, true);
    258  let cameraMuted2 = waitForCameraMuteState(browser2, true);
    259  info("Sharing the microphone and camera from a new process.");
    260  await shareDevices(browser2, true /* camera */, true /* microphone */);
    261  await Promise.all([microphoneMuted2, cameraMuted2]);
    262 
    263  info("Unmuting microphone...");
    264  let microphoneUnmuted = Promise.all([
    265    waitForMicrophoneMuteState(browser1, false),
    266    waitForMicrophoneMuteState(browser2, false),
    267  ]);
    268  microphoneMute.click();
    269  await microphoneUnmuted;
    270  info("Microphone successfully unmuted.");
    271 
    272  info("Unmuting camera...");
    273  let cameraUnmuted = Promise.all([
    274    waitForCameraMuteState(browser1, false),
    275    waitForCameraMuteState(browser2, false),
    276  ]);
    277  cameraMute.click();
    278  await cameraUnmuted;
    279  info("Camera successfully unmuted.");
    280 
    281  await BrowserTestUtils.stopObservingTopics(
    282    browser1.browsingContext,
    283    MUTE_TOPICS
    284  );
    285 
    286  await BrowserTestUtils.stopObservingTopics(
    287    browser2.browsingContext,
    288    MUTE_TOPICS
    289  );
    290 
    291  BrowserTestUtils.removeTab(tab2);
    292  BrowserTestUtils.removeTab(tab1);
    293 });