Commit 26f16f3b authored by Daniel Varga's avatar Daniel Varga
Browse files

Merge autoland to mozilla-central. a=merge

parents 65f9687e fd2da88b
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -240,7 +240,13 @@ function prompt(aContentWindow, aWindowID, aCallID, aConstraints, aDevices, aSec
}

function denyGUMRequest(aData) {
  Services.obs.notifyObservers(null, "getUserMedia:response:deny", aData.callID);
  let subject;
  if (aData.noOSPermission) {
    subject = "getUserMedia:response:noOSPermission";
  } else {
    subject = "getUserMedia:response:deny";
  }
  Services.obs.notifyObservers(null, subject, aData.callID);

  if (!aData.windowID)
    return;
+4 −0
Original line number Diff line number Diff line
@@ -96,6 +96,10 @@ support-files =
  searchSuggestionEngine.xml
  searchSuggestionEngine.sjs
[browser_urlbarOneOffs_searchSuggestions.js]
support-files =
  searchSuggestionEngine.xml
  searchSuggestionEngine.sjs
[browser_urlbarOneOffs_settings.js]
support-files =
  searchSuggestionEngine.xml
  searchSuggestionEngine.sjs
+78 −0
Original line number Diff line number Diff line
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

const TEST_ENGINE_BASENAME = "searchSuggestionEngine.xml";

let gMaxResults;

add_task(async function init() {
  Services.prefs.setBoolPref("browser.urlbar.oneOffSearches", true);
  gMaxResults = Services.prefs.getIntPref("browser.urlbar.maxRichResults");

  // Add a search suggestion engine and move it to the front so that it appears
  // as the first one-off.
  let engine = await SearchTestUtils.promiseNewSearchEngine(
    getRootDirectory(gTestPath) + TEST_ENGINE_BASENAME);
  Services.search.moveEngine(engine, 0);

  registerCleanupFunction(async function() {
    await hidePopup();
    await PlacesUtils.history.clear();
  });

  await PlacesUtils.history.clear();

  let visits = [];
  for (let i = 0; i < gMaxResults; i++) {
    visits.push({
      uri: makeURI("http://example.com/browser_urlbarOneOffs.js/?" + i),
      // TYPED so that the visit shows up when the urlbar's drop-down arrow is
      // pressed.
      transition: Ci.nsINavHistoryService.TRANSITION_TYPED,
    });
  }
  await PlacesTestUtils.addVisits(visits);
});


async function selectSettings(activateFn) {
  await BrowserTestUtils.withNewTab({gBrowser, url: "about:blank"}, async browser => {
    gURLBar.focus();
    EventUtils.synthesizeKey("KEY_ArrowDown");
    await promisePopupShown(gURLBar.popup);
    await waitForAutocompleteResultAt(gMaxResults - 1);

    let promiseHidden = promisePopupHidden(gURLBar.popup);
    let prefPaneLoaded = TestUtils.topicObserved("sync-pane-loaded", () => true);

    activateFn();

    await prefPaneLoaded;
    await promiseHidden;

    Assert.equal(gBrowser.contentWindow.history.state, "paneSearch",
      "Should have opened the search preferences pane");
  });
}

add_task(async function test_open_settings_with_enter() {
  await selectSettings(() => {
    EventUtils.synthesizeKey("KEY_ArrowUp");

    Assert.equal(gURLBar.popup.oneOffSearchButtons.selectedButton.getAttribute("anonid"),
      "search-settings-compact", "Should have selected the settings button");

    EventUtils.synthesizeKey("KEY_Enter");
  });
});

add_task(async function test_open_settings_with_click() {
  await selectSettings(() => {
    gURLBar.popup.oneOffSearchButtons.settingsButton.click();
  });
});

async function hidePopup() {
  EventUtils.synthesizeKey("KEY_Escape");
  await promisePopupHidden(gURLBar.popup);
}
+3 −3
Original line number Diff line number Diff line
@@ -652,9 +652,6 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
            return;
          }

          BrowserUsageTelemetry.recordUrlbarSelectedResultMethod(
            event, this.userSelectionBehavior);

          // Determine whether to use the selected one-off search button.  In
          // one-off search buttons parlance, "selected" means that the button
          // has been navigated to via the keyboard.  So we want to use it if
@@ -673,6 +670,9 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
            return;
          }

          BrowserUsageTelemetry.recordUrlbarSelectedResultMethod(
            event, this.userSelectionBehavior);

          let where = openUILinkWhere || this._whereToOpen(event);

          let url = this.value;
+87 −5
Original line number Diff line number Diff line
@@ -23,6 +23,10 @@ XPCOMUtils.defineLazyGetter(this, "gBrandBundle", function() {
  return Services.strings.createBundle("chrome://branding/locale/brand.properties");
});

XPCOMUtils.defineLazyServiceGetter(this, "OSPermissions",
                                   "@mozilla.org/ospermissionrequest;1",
                                   "nsIOSPermissionRequest");

var webrtcUI = {
  peerConnectionBlockers: new Set(),
  emitter: new EventEmitter(),
@@ -300,6 +304,67 @@ function denyRequest(aBrowser, aRequest) {
                                            windowID: aRequest.windowID});
}

//
// Deny the request because the browser does not have access to the
// camera or microphone due to OS security restrictions. The user may
// have granted camera/microphone access to the site, but not have
// allowed the browser access in OS settings.
//
function denyRequestNoPermission(aBrowser, aRequest) {
  aBrowser.messageManager.sendAsyncMessage("webrtc:Deny",
                                           {callID: aRequest.callID,
                                            windowID: aRequest.windowID,
                                            noOSPermission: true});
}

//
// Check if we have permission to access the camera and or microphone at the
// OS level. Triggers a request to access the device if access is needed and
// the permission state has not yet been determined.
//
async function checkOSPermission(camNeeded, micNeeded) {
  let camStatus = {}, micStatus = {};
  OSPermissions.getMediaCapturePermissionState(camStatus, micStatus);
  if (camNeeded) {
    let camPermission = camStatus.value;
    let camAccessible = await checkAndGetOSPermission(camPermission,
      OSPermissions.requestVideoCapturePermission);
    if (!camAccessible) {
      return false;
    }
  }
  if (micNeeded) {
    let micPermission = micStatus.value;
    let micAccessible = await checkAndGetOSPermission(micPermission,
      OSPermissions.requestAudioCapturePermission);
    if (!micAccessible) {
      return false;
    }
  }
  return true;
}

//
// Given a device's permission, return true if the device is accessible. If
// the device's permission is not yet determined, request access to the device.
// |requestPermissionFunc| must return a promise that resolves with true
// if the device is accessible and false otherwise.
//
async function checkAndGetOSPermission(devicePermission,
                                       requestPermissionFunc) {
  if (devicePermission == OSPermissions.PERMISSION_STATE_DENIED ||
      devicePermission == OSPermissions.PERMISSION_STATE_RESTRICTED) {
    return false;
  }
  if (devicePermission == OSPermissions.PERMISSION_STATE_NOTDETERMINED) {
    let deviceAllowed = await requestPermissionFunc();
    if (!deviceAllowed) {
      return false;
    }
  }
  return true;
}

function getHostOrExtensionName(uri, href) {
  let host;
  try {
@@ -517,10 +582,19 @@ function prompt(aBrowser, aRequest) {
          browser._devicePermissionURIs = browser._devicePermissionURIs || [];
          browser._devicePermissionURIs.push(uri);

          let camNeeded = videoDevices.length > 0;
          let micNeeded = audioDevices.length > 0;
          checkOSPermission(camNeeded, micNeeded).then((havePermission) => {
            if (havePermission) {
              let mm = browser.messageManager;
              mm.sendAsyncMessage("webrtc:Allow", {callID: aRequest.callID,
                                                   windowID: aRequest.windowID,
                                                   devices: allowedDevices});
            } else {
              denyRequestNoPermission(browser, aRequest);
            }
          });

          this.remove();
          return true;
        }
@@ -717,7 +791,7 @@ function prompt(aBrowser, aRequest) {
      if (!sharingAudio)
        listDevices(micMenupopup, audioDevices);

      this.mainAction.callback = function(aState) {
      this.mainAction.callback = async function(aState) {
        let remember = aState && aState.checkboxChecked;
        let allowedDevices = [];
        let perms = Services.perms;
@@ -784,6 +858,14 @@ function prompt(aBrowser, aRequest) {
          aBrowser._devicePermissionURIs.push(uri);
        }

        let camNeeded = videoDevices.length > 0;
        let micNeeded = audioDevices.length > 0;
        let havePermission = await checkOSPermission(camNeeded, micNeeded);
        if (!havePermission) {
          denyRequestNoPermission(notification.browser, aRequest);
          return;
        }

        let mm = notification.browser.messageManager;
        mm.sendAsyncMessage("webrtc:Allow", {callID: aRequest.callID,
                                             windowID: aRequest.windowID,
Loading