mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Merge autoland to m-c, a=merge
This commit is contained in:
commit
8a8c8d9816
@ -547,7 +547,7 @@
|
||||
</div>
|
||||
<div id="errorDescriptionsContainer">
|
||||
<div id="ed_generic">&generic.longDesc;</div>
|
||||
<div id="ed_captivePortal">&captivePortal.longDesc;</div>
|
||||
<div id="ed_captivePortal">&captivePortal.longDesc2;</div>
|
||||
<div id="ed_dnsNotFound">&dnsNotFound.longDesc;</div>
|
||||
<div id="ed_fileNotFound">&fileNotFound.longDesc;</div>
|
||||
<div id="ed_fileAccessDenied">&fileAccessDenied.longDesc;</div>
|
||||
@ -616,7 +616,7 @@
|
||||
|
||||
<div id="certErrorAndCaptivePortalButtonContainer" class="button-container">
|
||||
<button id="returnButton" class="primary" autocomplete="off" autofocus="true">&returnToPreviousPage.label;</button>
|
||||
<button id="openPortalLoginPageButton" class="primary" autocomplete="off" autofocus="true">&openPortalLoginPage.label;</button>
|
||||
<button id="openPortalLoginPageButton" class="primary" autocomplete="off" autofocus="true">&openPortalLoginPage.label2;</button>
|
||||
<div class="button-spacer"></div>
|
||||
<button id="advancedButton" autocomplete="off" autofocus="true">&advanced.label;</button>
|
||||
</div>
|
||||
|
@ -192,7 +192,7 @@ var CaptivePortalWatcher = {
|
||||
_showNotification() {
|
||||
let buttons = [
|
||||
{
|
||||
label: this._browserBundle.GetStringFromName("captivePortal.showLoginPage"),
|
||||
label: this._browserBundle.GetStringFromName("captivePortal.showLoginPage2"),
|
||||
callback: () => {
|
||||
this.ensureCaptivePortalTab();
|
||||
|
||||
@ -203,7 +203,7 @@ var CaptivePortalWatcher = {
|
||||
},
|
||||
];
|
||||
|
||||
let message = this._browserBundle.GetStringFromName("captivePortal.infoMessage2");
|
||||
let message = this._browserBundle.GetStringFromName("captivePortal.infoMessage3");
|
||||
|
||||
let closeHandler = (aEventName) => {
|
||||
if (aEventName != "removed") {
|
||||
|
@ -452,6 +452,19 @@
|
||||
onpopupshowing="if (!this.parentNode._placesView)
|
||||
new PlacesMenu(event, 'place:folder=UNFILED_BOOKMARKS');"/>
|
||||
</menu>
|
||||
<menu id="menu_mobileBookmarks"
|
||||
class="menu-iconic bookmark-item"
|
||||
label="&mobileBookmarksCmd.label;"
|
||||
hidden="true"
|
||||
container="true">
|
||||
<menupopup id="mobileBookmarksFolderPopup"
|
||||
#ifndef XP_MACOSX
|
||||
placespopup="true"
|
||||
#endif
|
||||
context="placesContext"
|
||||
onpopupshowing="if (!this.parentNode._placesView)
|
||||
new PlacesMenu(event, 'place:folder=MOBILE_BOOKMARKS');"/>
|
||||
</menu>
|
||||
<menuseparator id="bookmarksMenuItemsSeparator"/>
|
||||
<!-- Bookmarks menu items -->
|
||||
</menupopup>
|
||||
|
@ -1342,6 +1342,7 @@ var BookmarkingUI = {
|
||||
return;
|
||||
}
|
||||
|
||||
this._initMobileBookmarks(document.getElementById("BMB_mobileBookmarks"));
|
||||
this._initRecentBookmarks(document.getElementById("BMB_recentBookmarks"),
|
||||
"subviewbutton");
|
||||
|
||||
@ -1380,6 +1381,28 @@ var BookmarkingUI = {
|
||||
|
||||
RECENTLY_BOOKMARKED_PREF: "browser.bookmarks.showRecentlyBookmarked",
|
||||
|
||||
// Set by sync after syncing bookmarks successfully once.
|
||||
MOBILE_BOOKMARKS_PREF: "browser.bookmarks.showMobileBookmarks",
|
||||
|
||||
_shouldShowMobileBookmarks() {
|
||||
try {
|
||||
return Services.prefs.getBoolPref(this.MOBILE_BOOKMARKS_PREF);
|
||||
} catch (e) {}
|
||||
// No pref set (or invalid pref set), look for a mobile bookmarks left pane query.
|
||||
const organizerQueryAnno = "PlacesOrganizer/OrganizerQuery";
|
||||
const mobileBookmarksAnno = "MobileBookmarks";
|
||||
let shouldShow = PlacesUtils.annotations.getItemsWithAnnotation(organizerQueryAnno, {}).filter(
|
||||
id => PlacesUtils.annotations.getItemAnnotation(id, organizerQueryAnno) == mobileBookmarksAnno
|
||||
).length > 0;
|
||||
// Sync will change this pref if/when it adds a mobile bookmarks query.
|
||||
Services.prefs.setBoolPref(this.MOBILE_BOOKMARKS_PREF, shouldShow);
|
||||
return shouldShow;
|
||||
},
|
||||
|
||||
_initMobileBookmarks(mobileMenuItem) {
|
||||
mobileMenuItem.hidden = !this._shouldShowMobileBookmarks();
|
||||
},
|
||||
|
||||
_initRecentBookmarks(aHeaderItem, aExtraCSSClass) {
|
||||
this._populateRecentBookmarks(aHeaderItem, aExtraCSSClass);
|
||||
|
||||
@ -1710,6 +1733,7 @@ var BookmarkingUI = {
|
||||
|
||||
this._updateBookmarkPageMenuItem();
|
||||
PlacesCommandHook.updateBookmarkAllTabsCommand();
|
||||
this._initMobileBookmarks(document.getElementById("menu_mobileBookmarks"));
|
||||
this._initRecentBookmarks(document.getElementById("menu_recentBookmarks"));
|
||||
},
|
||||
|
||||
|
@ -6246,12 +6246,12 @@ var IndexedDBPromptHelper = {
|
||||
}
|
||||
];
|
||||
|
||||
PopupNotifications.show(browser, topic, message,
|
||||
this._notificationIcon, mainAction,
|
||||
secondaryActions, {
|
||||
persistent: true,
|
||||
hideClose: true,
|
||||
});
|
||||
PopupNotifications.show(
|
||||
browser, topic, message, this._notificationIcon, mainAction, secondaryActions,
|
||||
{
|
||||
persistent: true,
|
||||
hideClose: !Services.prefs.getBoolPref("privacy.permissionPrompts.showCloseButton"),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -883,6 +883,19 @@
|
||||
new PlacesMenu(event, 'place:folder=UNFILED_BOOKMARKS',
|
||||
PlacesUIUtils.getViewForNode(this.parentNode.parentNode).options);"/>
|
||||
</menu>
|
||||
<menu id="BMB_mobileBookmarks"
|
||||
class="menu-iconic bookmark-item subviewbutton"
|
||||
label="&bookmarksMenuButton.mobile.label;"
|
||||
hidden="true"
|
||||
container="true">
|
||||
<menupopup id="BMB_mobileBookmarksPopup"
|
||||
placespopup="true"
|
||||
context="placesContext"
|
||||
onpopupshowing="if (!this.parentNode._placesView)
|
||||
new PlacesMenu(event, 'place:folder=MOBILE_BOOKMARKS',
|
||||
PlacesUIUtils.getViewForNode(this.parentNode.parentNode).options);"/>
|
||||
</menu>
|
||||
|
||||
<menuseparator/>
|
||||
<!-- Bookmarks menu items will go here -->
|
||||
<menuitem id="BMB_bookmarksShowAll"
|
||||
|
@ -198,10 +198,32 @@ var tests = [
|
||||
ok(this.notifyObj.dismissalCallbackTriggered, "dismissal callback triggered");
|
||||
this.notification.remove();
|
||||
ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
|
||||
ok(!this.notifyObj.secondaryActionClicked, "secondary action not clicked");
|
||||
}
|
||||
},
|
||||
// Test that notification close button calls secondary action instead of
|
||||
// dismissal callback if privacy.permissionPrompts.showCloseButton is set.
|
||||
{ id: "Test#10",
|
||||
run() {
|
||||
Preferences.set("privacy.permissionPrompts.showCloseButton", true);
|
||||
this.notifyObj = new BasicNotification(this.id);
|
||||
this.notification = showNotification(this.notifyObj);
|
||||
},
|
||||
onShown(popup) {
|
||||
checkPopup(popup, this.notifyObj);
|
||||
let notification = popup.childNodes[0];
|
||||
EventUtils.synthesizeMouseAtCenter(notification.closebutton, {});
|
||||
},
|
||||
onHidden(popup) {
|
||||
ok(!this.notifyObj.dismissalCallbackTriggered, "dismissal callback not triggered");
|
||||
ok(this.notifyObj.secondaryActionClicked, "secondary action clicked");
|
||||
Preferences.reset("privacy.permissionPrompts.showCloseButton");
|
||||
this.notification.remove();
|
||||
ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
|
||||
}
|
||||
},
|
||||
// Test notification when chrome is hidden
|
||||
{ id: "Test#10",
|
||||
{ id: "Test#11",
|
||||
run() {
|
||||
window.locationbar.visible = false;
|
||||
this.notifyObj = new BasicNotification(this.id);
|
||||
|
@ -48,8 +48,10 @@ browser/chrome/devtools/modules/devtools/client/projecteditor/lib/helpers/readdi
|
||||
browser/chrome/devtools/modules/devtools/client/shared/frame-script-utils.js
|
||||
browser/chrome/devtools/modules/devtools/client/shared/theme-switching.js
|
||||
browser/chrome/devtools/modules/devtools/client/themes/common.css
|
||||
browser/chrome/devtools/modules/devtools/client/themes/toolbars.css
|
||||
browser/chrome/devtools/modules/devtools/client/themes/variables.css
|
||||
browser/chrome/devtools/skin/common.css
|
||||
browser/chrome/devtools/skin/toolbars.css
|
||||
browser/chrome/devtools/skin/images/command-scratchpad.svg
|
||||
browser/chrome/devtools/skin/images/controls.png
|
||||
browser/chrome/devtools/skin/images/controls@2x.png
|
||||
|
@ -184,6 +184,7 @@ These should match what Safari and other Apple applications use on OS X Lion. --
|
||||
<!ENTITY showAllBookmarks2.label "Show All Bookmarks">
|
||||
<!ENTITY recentBookmarks.label "Recently Bookmarked">
|
||||
<!ENTITY otherBookmarksCmd.label "Other Bookmarks">
|
||||
<!ENTITY mobileBookmarksCmd.label "Mobile Bookmarks">
|
||||
<!ENTITY bookmarksToolbarChevron.tooltip "Show more bookmarks">
|
||||
<!ENTITY showRecentlyBookmarked.label "Show Recently Bookmarked">
|
||||
<!ENTITY showRecentlyBookmarked.accesskey "h">
|
||||
@ -245,6 +246,7 @@ These should match what Safari and other Apple applications use on OS X Lion. --
|
||||
|
||||
<!ENTITY bookmarksMenuButton.label "Bookmarks">
|
||||
<!ENTITY bookmarksMenuButton.other.label "Other Bookmarks">
|
||||
<!ENTITY bookmarksMenuButton.mobile.label "Mobile Bookmarks">
|
||||
<!ENTITY viewBookmarksSidebar2.label "View Bookmarks Sidebar">
|
||||
<!ENTITY viewBookmarksToolbar.label "View Bookmarks Toolbar">
|
||||
|
||||
|
@ -846,14 +846,14 @@ decoder.noHWAcceleration.message = To improve video quality, you may need to ins
|
||||
decoder.noPulseAudio.message = To play audio, you may need to install the required PulseAudio software.
|
||||
decoder.unsupportedLibavcodec.message = libavcodec may be vulnerable or is not supported, and should be updated to play video.
|
||||
|
||||
# LOCALIZATION NOTE (captivePortal.infoMessage2):
|
||||
# LOCALIZATION NOTE (captivePortal.infoMessage3):
|
||||
# Shown in a notification bar when we detect a captive portal is blocking network access
|
||||
# and requires the user to log in before browsing.
|
||||
captivePortal.infoMessage2 = This network may require you to log in to use the internet.
|
||||
# LOCALIZATION NOTE (captivePortal.showLoginPage):
|
||||
captivePortal.infoMessage3 = You must log in to this network before you can access the Internet.
|
||||
# LOCALIZATION NOTE (captivePortal.showLoginPage2):
|
||||
# The label for a button shown in the info bar in all tabs except the login page tab.
|
||||
# The button shows the portal login page tab when clicked.
|
||||
captivePortal.showLoginPage = Show Login Page
|
||||
captivePortal.showLoginPage2 = Open Network Login Page
|
||||
|
||||
permissions.remove.tooltip = Clear this permission and ask again
|
||||
|
||||
|
@ -52,11 +52,11 @@
|
||||
">
|
||||
|
||||
<!ENTITY captivePortal.title "Log in to network">
|
||||
<!ENTITY captivePortal.longDesc "
|
||||
<p>This network may require you to log in to access the internet.</p>
|
||||
<!ENTITY captivePortal.longDesc2 "
|
||||
<p>You must log in to this network before you can access the Internet.</p>
|
||||
">
|
||||
|
||||
<!ENTITY openPortalLoginPage.label "Open Login Page">
|
||||
<!ENTITY openPortalLoginPage.label2 "Open Network Login Page">
|
||||
|
||||
<!ENTITY malformedURI.title "The address isn’t valid">
|
||||
<!ENTITY malformedURI.longDesc "
|
||||
|
@ -341,9 +341,9 @@ this.PermissionPromptPrototype = {
|
||||
if (!options.hasOwnProperty("displayURI") || options.displayURI) {
|
||||
options.displayURI = this.principal.URI;
|
||||
}
|
||||
// Permission prompts are always persistent and don't have a close button.
|
||||
// Permission prompts are always persistent; the close button is controlled by a pref.
|
||||
options.persistent = true;
|
||||
options.hideClose = true;
|
||||
options.hideClose = !Services.prefs.getBoolPref("privacy.permissionPrompts.showCloseButton");
|
||||
|
||||
this.onBeforeShow();
|
||||
chromeWin.PopupNotifications.show(this.browser,
|
||||
|
@ -444,7 +444,7 @@ function prompt(aBrowser, aRequest) {
|
||||
|
||||
let options = {
|
||||
persistent: true,
|
||||
hideClose: true,
|
||||
hideClose: !Services.prefs.getBoolPref("privacy.permissionPrompts.showCloseButton"),
|
||||
checkbox: {
|
||||
label: stringBundle.getString("getUserMedia.remember"),
|
||||
checkedState: reasonForNoPermanentAllow ? {
|
||||
|
@ -1195,7 +1195,8 @@ menuitem.panel-subview-footer@menuStateActive@,
|
||||
#BMB_bookmarksPopup menupopup[placespopup=true][singleitempopup=true] > hbox > .popup-internal-box > .arrowscrollbox-scrollbox > .scrollbox-innerbox,
|
||||
/* These popups never have a footer */
|
||||
#BMB_bookmarksToolbarPopup > hbox > .popup-internal-box > .arrowscrollbox-scrollbox > .scrollbox-innerbox,
|
||||
#BMB_unsortedBookmarksPopup > hbox > .popup-internal-box > .arrowscrollbox-scrollbox > .scrollbox-innerbox {
|
||||
#BMB_unsortedBookmarksPopup > hbox > .popup-internal-box > .arrowscrollbox-scrollbox > .scrollbox-innerbox,
|
||||
#BMB_mobileBookmarksPopup > hbox > .popup-internal-box > .arrowscrollbox-scrollbox > .scrollbox-innerbox {
|
||||
/* And so they need some bottom padding: */
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
@ -214,6 +214,7 @@ Converter.prototype = {
|
||||
let baseUrl = clientBaseUrl + "jsonview/";
|
||||
let themeVarsUrl = clientBaseUrl + "themes/variables.css";
|
||||
let commonUrl = clientBaseUrl + "themes/common.css";
|
||||
let toolbarsUrl = clientBaseUrl + "themes/toolbars.css";
|
||||
|
||||
let os;
|
||||
let platform = Services.appinfo.OS;
|
||||
@ -238,6 +239,8 @@ Converter.prototype = {
|
||||
themeVarsUrl + "\">" +
|
||||
"<link rel=\"stylesheet\" type=\"text/css\" href=\"" +
|
||||
commonUrl + "\">" +
|
||||
"<link rel=\"stylesheet\" type=\"text/css\" href=\"" +
|
||||
toolbarsUrl + "\">" +
|
||||
"<link rel=\"stylesheet\" type=\"text/css\" href=\"css/main.css\">" +
|
||||
"<script data-main=\"viewer-config\" src=\"lib/require.js\"></script>" +
|
||||
"</head><body>" +
|
||||
|
@ -202,7 +202,6 @@ webconsole.close.key=CmdOrCtrl+W
|
||||
webconsole.clear.key=Ctrl+Shift+L
|
||||
webconsole.clear.keyOSX=Ctrl+L
|
||||
|
||||
|
||||
# LOCALIZATION NOTE (webconsole.menu.copyURL.label)
|
||||
# Label used for a context-menu item displayed for network message logs. Clicking on it
|
||||
# copies the URL displayed in the message to the clipboard.
|
||||
@ -239,3 +238,61 @@ webconsole.menu.copy.accesskey=C
|
||||
webconsole.menu.selectAll.label=Select all
|
||||
webconsole.menu.selectAll.accesskey=A
|
||||
|
||||
# LOCALIZATION NOTE (webconsole.clearButton.tooltip)
|
||||
# Label used for the tooltip on the clear logs button in the console top toolbar bar.
|
||||
# Clicking on it will clear the content of the console.
|
||||
webconsole.clearButton.tooltip=Clear the Web Console output
|
||||
|
||||
# LOCALIZATION NOTE (webconsole.toggleFilterButton.tooltip)
|
||||
# Label used for the tooltip on the toggle filter bar button in the console top
|
||||
# toolbar bar. Clicking on it will toggle the visibility of an additional bar which
|
||||
# contains filter buttons.
|
||||
webconsole.toggleFilterButton.tooltip=Toggle filter bar
|
||||
|
||||
# LOCALIZATION NOTE (webconsole.filterInput.placeholder)
|
||||
# Label used for for the placeholder on the filter input, in the console top toolbar.
|
||||
webconsole.filterInput.placeholder=Filter output
|
||||
|
||||
# LOCALIZATION NOTE (webconsole.errorsFilterButton.label)
|
||||
# Label used as the text of the "Errors" button in the additional filter toolbar.
|
||||
# It shows or hides error messages, either inserted in the page using
|
||||
# console.error() or as a result of a javascript error..
|
||||
webconsole.errorsFilterButton.label=Errors
|
||||
|
||||
# LOCALIZATION NOTE (webconsole.warningsFilterButton.label)
|
||||
# Label used as the text of the "Warnings" button in the additional filter toolbar.
|
||||
# It shows or hides warning messages, inserted in the page using console.warn().
|
||||
webconsole.warningsFilterButton.label=Warnings
|
||||
|
||||
# LOCALIZATION NOTE (webconsole.logsFilterButton.label)
|
||||
# Label used as the text of the "Logs" button in the additional filter toolbar.
|
||||
# It shows or hides log messages, inserted in the page using console.log().
|
||||
webconsole.logsFilterButton.label=Logs
|
||||
|
||||
# LOCALIZATION NOTE (webconsole.infoFilterButton.label)
|
||||
# Label used as the text of the "Info" button in the additional filter toolbar.
|
||||
# It shows or hides info messages, inserted in the page using console.info().
|
||||
webconsole.infoFilterButton.label=Info
|
||||
|
||||
# LOCALIZATION NOTE (webconsole.debugFilterButton.label)
|
||||
# Label used as the text of the "Debug" button in the additional filter toolbar.
|
||||
# It shows or hides debug messages, inserted in the page using console.debug().
|
||||
webconsole.debugFilterButton.label=Debug
|
||||
|
||||
# LOCALIZATION NOTE (webconsole.cssFilterButton.label)
|
||||
# Label used as the text of the "CSS" button in the additional filter toolbar.
|
||||
# It shows or hides CSS warning messages, inserted in the page by the browser
|
||||
# when there are CSS errors in the page.
|
||||
webconsole.cssFilterButton.label=CSS
|
||||
|
||||
# LOCALIZATION NOTE (webconsole.xhrFilterButton.label)
|
||||
# Label used as the text of the "XHR" button in the additional filter toolbar.
|
||||
# It shows or hides messages displayed when the page makes an XMLHttpRequest or
|
||||
# a fetch call.
|
||||
webconsole.xhrFilterButton.label=XHR
|
||||
|
||||
# LOCALIZATION NOTE (webconsole.requestsFilterButton.label)
|
||||
# Label used as the text of the "Requests" button in the additional filter toolbar.
|
||||
# It shows or hides messages displayed when the page makes a network call, for example
|
||||
# when an image or a scripts is requested.
|
||||
webconsole.requestsFilterButton.label=Requests
|
||||
|
@ -29,10 +29,6 @@
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.tabs .tabs-menu-item a {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* The tab takes entire horizontal space and individual tabs
|
||||
should stretch accordingly. Use flexbox for the behavior.
|
||||
Use also `overflow: hidden` so, 'overflow' and 'underflow'
|
||||
|
@ -30,6 +30,10 @@
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.tabs .tabs-menu-item a {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* Make sure panel content takes entire vertical space.
|
||||
(minus the height of the tab bar) */
|
||||
.tabs .panels {
|
||||
|
@ -11,5 +11,6 @@ DIRS += [
|
||||
DevToolsModules(
|
||||
'common.css',
|
||||
'splitters.css',
|
||||
'toolbars.css',
|
||||
'variables.css',
|
||||
)
|
||||
|
@ -12,9 +12,13 @@ const {
|
||||
const { connect } = require("devtools/client/shared/vendor/react-redux");
|
||||
const { getAllFilters } = require("devtools/client/webconsole/new-console-output/selectors/filters");
|
||||
const { getAllUi } = require("devtools/client/webconsole/new-console-output/selectors/ui");
|
||||
const { filterTextSet, filtersClear } = require("devtools/client/webconsole/new-console-output/actions/index");
|
||||
const { messagesClear } = require("devtools/client/webconsole/new-console-output/actions/index");
|
||||
const uiActions = require("devtools/client/webconsole/new-console-output/actions/index");
|
||||
const {
|
||||
filterTextSet,
|
||||
filtersClear,
|
||||
filterBarToggle,
|
||||
messagesClear
|
||||
} = require("devtools/client/webconsole/new-console-output/actions/index");
|
||||
const { l10n } = require("devtools/client/webconsole/new-console-output/utils/messages");
|
||||
const {
|
||||
MESSAGE_LEVEL
|
||||
} = require("../constants");
|
||||
@ -43,7 +47,7 @@ const FilterBar = createClass({
|
||||
},
|
||||
|
||||
onClickFilterBarToggle: function () {
|
||||
this.props.dispatch(uiActions.filterBarToggle());
|
||||
this.props.dispatch(filterBarToggle());
|
||||
},
|
||||
|
||||
onClickFiltersClear: function () {
|
||||
@ -62,20 +66,20 @@ const FilterBar = createClass({
|
||||
children.push(dom.div({className: "devtools-toolbar webconsole-filterbar-primary"},
|
||||
dom.button({
|
||||
className: "devtools-button devtools-clear-icon",
|
||||
title: "Clear output",
|
||||
title: l10n.getStr("webconsole.clearButton.tooltip"),
|
||||
onClick: this.onClickMessagesClear
|
||||
}),
|
||||
dom.button({
|
||||
className: "devtools-button devtools-filter-icon" + (
|
||||
filterBarVisible ? " checked" : ""),
|
||||
title: "Toggle filter bar",
|
||||
title: l10n.getStr("webconsole.toggleFilterButton.tooltip"),
|
||||
onClick: this.onClickFilterBarToggle
|
||||
}),
|
||||
dom.input({
|
||||
className: "devtools-plaininput text-filter",
|
||||
type: "search",
|
||||
value: filter.text,
|
||||
placeholder: "Filter output",
|
||||
placeholder: l10n.getStr("webconsole.filterInput.placeholder"),
|
||||
onInput: this.onSearchInput
|
||||
})
|
||||
));
|
||||
@ -85,31 +89,31 @@ const FilterBar = createClass({
|
||||
dom.div({className: "devtools-toolbar webconsole-filterbar-secondary"},
|
||||
FilterButton({
|
||||
active: filter.error,
|
||||
label: "Errors",
|
||||
label: l10n.getStr("webconsole.errorsFilterButton.label"),
|
||||
filterKey: MESSAGE_LEVEL.ERROR,
|
||||
dispatch
|
||||
}),
|
||||
FilterButton({
|
||||
active: filter.warn,
|
||||
label: "Warnings",
|
||||
label: l10n.getStr("webconsole.warningsFilterButton.label"),
|
||||
filterKey: MESSAGE_LEVEL.WARN,
|
||||
dispatch
|
||||
}),
|
||||
FilterButton({
|
||||
active: filter.log,
|
||||
label: "Logs",
|
||||
label: l10n.getStr("webconsole.logsFilterButton.label"),
|
||||
filterKey: MESSAGE_LEVEL.LOG,
|
||||
dispatch
|
||||
}),
|
||||
FilterButton({
|
||||
active: filter.info,
|
||||
label: "Info",
|
||||
label: l10n.getStr("webconsole.infoFilterButton.label"),
|
||||
filterKey: MESSAGE_LEVEL.INFO,
|
||||
dispatch
|
||||
}),
|
||||
FilterButton({
|
||||
active: filter.debug,
|
||||
label: "Debug",
|
||||
label: l10n.getStr("webconsole.debugFilterButton.label"),
|
||||
filterKey: MESSAGE_LEVEL.DEBUG,
|
||||
dispatch
|
||||
}),
|
||||
@ -118,19 +122,19 @@ const FilterBar = createClass({
|
||||
}),
|
||||
FilterButton({
|
||||
active: filter.css,
|
||||
label: "CSS",
|
||||
label: l10n.getStr("webconsole.cssFilterButton.label"),
|
||||
filterKey: "css",
|
||||
dispatch
|
||||
}),
|
||||
FilterButton({
|
||||
active: filter.netxhr,
|
||||
label: "XHR",
|
||||
label: l10n.getStr("webconsole.xhrFilterButton.label"),
|
||||
filterKey: "netxhr",
|
||||
dispatch
|
||||
}),
|
||||
FilterButton({
|
||||
active: filter.net,
|
||||
label: "Requests",
|
||||
label: l10n.getStr("webconsole.requestsFilterButton.label"),
|
||||
filterKey: "net",
|
||||
dispatch
|
||||
})
|
||||
@ -138,23 +142,6 @@ const FilterBar = createClass({
|
||||
);
|
||||
}
|
||||
|
||||
if (ui.filteredMessageVisible) {
|
||||
children.push(
|
||||
dom.div({className: "devtools-toolbar"},
|
||||
dom.span({
|
||||
className: "clear"},
|
||||
"You have filters set that may hide some results. " +
|
||||
"Learn more about our filtering syntax ",
|
||||
dom.a({}, "here"),
|
||||
"."),
|
||||
dom.button({
|
||||
className: "menu-filter-button",
|
||||
onClick: this.onClickFiltersClear
|
||||
}, "Remove filters")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
dom.div({
|
||||
className: "webconsole-filteringbar-wrapper",
|
||||
|
@ -6,7 +6,7 @@ const expect = require("expect");
|
||||
const sinon = require("sinon");
|
||||
const { render, mount } = require("enzyme");
|
||||
|
||||
const { createFactory } = require("devtools/client/shared/vendor/react");
|
||||
const { createFactory, DOM } = require("devtools/client/shared/vendor/react");
|
||||
const Provider = createFactory(require("react-redux").Provider);
|
||||
|
||||
const FilterButton = createFactory(require("devtools/client/webconsole/new-console-output/components/filter-button"));
|
||||
@ -32,7 +32,7 @@ describe("FilterBar component:", () => {
|
||||
// Clear button
|
||||
expect(toolbar.children().eq(0).attr("class"))
|
||||
.toBe("devtools-button devtools-clear-icon");
|
||||
expect(toolbar.children().eq(0).attr("title")).toBe("Clear output");
|
||||
expect(toolbar.children().eq(0).attr("title")).toBe("Clear the Web Console output");
|
||||
|
||||
// Filter bar toggle
|
||||
expect(toolbar.children().eq(1).attr("class"))
|
||||
@ -58,22 +58,28 @@ describe("FilterBar component:", () => {
|
||||
expect(getAllUi(store.getState()).filterBarVisible).toBe(true);
|
||||
|
||||
// Buttons are displayed
|
||||
const buttonProps = {
|
||||
active: true,
|
||||
dispatch: store.dispatch
|
||||
};
|
||||
const logButton = FilterButton(Object.assign({}, buttonProps,
|
||||
{ label: "Logs", filterKey: MESSAGE_LEVEL.LOG }));
|
||||
const debugButton = FilterButton(Object.assign({}, buttonProps,
|
||||
{ label: "Debug", filterKey: MESSAGE_LEVEL.DEBUG }));
|
||||
const infoButton = FilterButton(Object.assign({}, buttonProps,
|
||||
{ label: "Info", filterKey: MESSAGE_LEVEL.INFO }));
|
||||
const warnButton = FilterButton(Object.assign({}, buttonProps,
|
||||
{ label: "Warnings", filterKey: MESSAGE_LEVEL.WARN }));
|
||||
const errorButton = FilterButton(Object.assign({}, buttonProps,
|
||||
{ label: "Errors", filterKey: MESSAGE_LEVEL.ERROR }));
|
||||
let buttons = [errorButton, warnButton, logButton, infoButton, debugButton];
|
||||
expect(wrapper.contains(buttons)).toBe(true);
|
||||
const filterBtn = props => FilterButton(
|
||||
Object.assign({}, {
|
||||
active: true,
|
||||
dispatch: store.dispatch
|
||||
}, props)
|
||||
);
|
||||
|
||||
let buttons = [
|
||||
filterBtn({ label: "Errors", filterKey: MESSAGE_LEVEL.ERROR }),
|
||||
filterBtn({ label: "Warnings", filterKey: MESSAGE_LEVEL.WARN }),
|
||||
filterBtn({ label: "Logs", filterKey: MESSAGE_LEVEL.LOG }),
|
||||
filterBtn({ label: "Info", filterKey: MESSAGE_LEVEL.INFO }),
|
||||
filterBtn({ label: "Debug", filterKey: MESSAGE_LEVEL.DEBUG }),
|
||||
DOM.span({
|
||||
className: "devtools-separator",
|
||||
}),
|
||||
filterBtn({ label: "CSS", filterKey: "css" }),
|
||||
filterBtn({ label: "XHR", filterKey: "netxhr", active: false }),
|
||||
filterBtn({ label: "Requests", filterKey: "net", active: false }),
|
||||
];
|
||||
|
||||
expect(wrapper.containsAllMatchingElements(buttons)).toBe(true);
|
||||
});
|
||||
|
||||
it("fires MESSAGES_CLEAR action when clear button is clicked", () => {
|
||||
|
@ -15,6 +15,28 @@ class L10n {
|
||||
return "XHR";
|
||||
case "webConsoleMoreInfoLabel":
|
||||
return "Learn More";
|
||||
case "webconsole.clearButton.tooltip":
|
||||
return "Clear the Web Console output";
|
||||
case "webconsole.toggleFilterButton.tooltip":
|
||||
return "Toggle filter bar";
|
||||
case "webconsole.filterInput.placeholder":
|
||||
return "Filter output";
|
||||
case "webconsole.errorsFilterButton.label":
|
||||
return "Errors";
|
||||
case "webconsole.warningsFilterButton.label":
|
||||
return "Warnings";
|
||||
case "webconsole.logsFilterButton.label":
|
||||
return "Logs";
|
||||
case "webconsole.infoFilterButton.label":
|
||||
return "Info";
|
||||
case "webconsole.debugFilterButton.label":
|
||||
return "Debug";
|
||||
case "webconsole.cssFilterButton.label":
|
||||
return "CSS";
|
||||
case "webconsole.xhrFilterButton.label":
|
||||
return "XHR";
|
||||
case "webconsole.requestsFilterButton.label":
|
||||
return "Requests";
|
||||
default:
|
||||
return str;
|
||||
}
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include "mozilla/Move.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
class nsCycleCollectionTraversalCallback;
|
||||
|
||||
namespace mozilla {
|
||||
@ -110,6 +112,11 @@ public:
|
||||
{
|
||||
return !Equals(aOtherNullable);
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& aStream,
|
||||
const Nullable& aNullable) {
|
||||
return aStream << aNullable.mValue;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -2651,7 +2651,7 @@ void
|
||||
TabChild::GetDPI(float* aDPI)
|
||||
{
|
||||
*aDPI = -1.0;
|
||||
if (!mRemoteFrame) {
|
||||
if (!(mDidFakeShow || mDidSetRealShowInfo)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2668,7 +2668,7 @@ void
|
||||
TabChild::GetDefaultScale(double* aScale)
|
||||
{
|
||||
*aScale = -1.0;
|
||||
if (!mRemoteFrame) {
|
||||
if (!(mDidFakeShow || mDidSetRealShowInfo)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2685,7 +2685,7 @@ void
|
||||
TabChild::GetWidgetRounding(int32_t* aRounding)
|
||||
{
|
||||
*aRounding = 1;
|
||||
if (!mRemoteFrame) {
|
||||
if (!(mDidFakeShow || mDidSetRealShowInfo)) {
|
||||
return;
|
||||
}
|
||||
if (mRounding > 0) {
|
||||
|
@ -169,7 +169,7 @@ MediaDecoderOwner*
|
||||
MediaDecoder::ResourceCallback::GetMediaOwner() const
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return mDecoder ? mDecoder->mOwner : nullptr;
|
||||
return mDecoder ? mDecoder->GetOwner() : nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
@ -548,10 +548,10 @@ MediaDecoder::OnPlaybackEvent(MediaEventType aEvent)
|
||||
Invalidate();
|
||||
break;
|
||||
case MediaEventType::EnterVideoSuspend:
|
||||
mOwner->DispatchAsyncEvent(NS_LITERAL_STRING("mozentervideosuspend"));
|
||||
GetOwner()->DispatchAsyncEvent(NS_LITERAL_STRING("mozentervideosuspend"));
|
||||
break;
|
||||
case MediaEventType::ExitVideoSuspend:
|
||||
mOwner->DispatchAsyncEvent(NS_LITERAL_STRING("mozexitvideosuspend"));
|
||||
GetOwner()->DispatchAsyncEvent(NS_LITERAL_STRING("mozexitvideosuspend"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -568,7 +568,7 @@ MediaDecoder::OnDecoderDoctorEvent(DecoderDoctorEvent aEvent)
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
// OnDecoderDoctorEvent is disconnected at shutdown time.
|
||||
MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
|
||||
HTMLMediaElement* element = mOwner->GetMediaElement();
|
||||
HTMLMediaElement* element = GetOwner()->GetMediaElement();
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
@ -712,7 +712,7 @@ MediaDecoder::Seek(double aTime, SeekTarget::Type aSeekType, dom::Promise* aProm
|
||||
|
||||
if (mPlayState == PLAY_STATE_ENDED) {
|
||||
PinForSeek();
|
||||
ChangeState(mOwner->GetPaused() ? PLAY_STATE_PAUSED : PLAY_STATE_PLAYING);
|
||||
ChangeState(GetOwner()->GetPaused() ? PLAY_STATE_PAUSED : PLAY_STATE_PLAYING);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@ -813,12 +813,12 @@ MediaDecoder::MetadataLoaded(nsAutoPtr<MediaInfo> aInfo,
|
||||
// our new size.
|
||||
if (aEventVisibility != MediaDecoderEventVisibility::Suppressed) {
|
||||
mFiredMetadataLoaded = true;
|
||||
mOwner->MetadataLoaded(mInfo, nsAutoPtr<const MetadataTags>(aTags.forget()));
|
||||
GetOwner()->MetadataLoaded(mInfo, nsAutoPtr<const MetadataTags>(aTags.forget()));
|
||||
}
|
||||
// Invalidate() will end up calling mOwner->UpdateMediaSize with the last
|
||||
// Invalidate() will end up calling GetOwner()->UpdateMediaSize with the last
|
||||
// dimensions retrieved from the video frame container. The video frame
|
||||
// container contains more up to date dimensions than aInfo.
|
||||
// So we call Invalidate() after calling mOwner->MetadataLoaded to ensure
|
||||
// So we call Invalidate() after calling GetOwner()->MetadataLoaded to ensure
|
||||
// the media element has the latest dimensions.
|
||||
Invalidate();
|
||||
|
||||
@ -893,10 +893,10 @@ MediaDecoder::FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo,
|
||||
// that autoplay should run.
|
||||
NotifySuspendedStatusChanged();
|
||||
|
||||
// mOwner->FirstFrameLoaded() might call us back. Put it at the bottom of
|
||||
// GetOwner()->FirstFrameLoaded() might call us back. Put it at the bottom of
|
||||
// this function to avoid unexpected shutdown from reentrant calls.
|
||||
if (aEventVisibility != MediaDecoderEventVisibility::Suppressed) {
|
||||
mOwner->FirstFrameLoaded();
|
||||
GetOwner()->FirstFrameLoaded();
|
||||
}
|
||||
}
|
||||
|
||||
@ -905,7 +905,7 @@ MediaDecoder::NetworkError()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
|
||||
mOwner->NetworkError();
|
||||
GetOwner()->NetworkError();
|
||||
}
|
||||
|
||||
void
|
||||
@ -913,7 +913,7 @@ MediaDecoder::DecodeError(const MediaResult& aError)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
|
||||
mOwner->DecodeError(aError);
|
||||
GetOwner()->DecodeError(aError);
|
||||
}
|
||||
|
||||
void
|
||||
@ -935,7 +935,7 @@ MediaDecoder::OwnerHasError() const
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
|
||||
return mOwner->HasError();
|
||||
return GetOwner()->HasError();
|
||||
}
|
||||
|
||||
class MediaElementGMPCrashHelper : public GMPCrashHelper
|
||||
@ -962,8 +962,8 @@ already_AddRefed<GMPCrashHelper>
|
||||
MediaDecoder::GetCrashHelper()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return mOwner->GetMediaElement() ?
|
||||
MakeAndAddRef<MediaElementGMPCrashHelper>(mOwner->GetMediaElement()) : nullptr;
|
||||
return GetOwner()->GetMediaElement() ?
|
||||
MakeAndAddRef<MediaElementGMPCrashHelper>(GetOwner()->GetMediaElement()) : nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -997,9 +997,9 @@ MediaDecoder::PlaybackEnded()
|
||||
|
||||
ChangeState(PLAY_STATE_ENDED);
|
||||
InvalidateWithFlags(VideoFrameContainer::INVALIDATE_FORCE);
|
||||
mOwner->PlaybackEnded();
|
||||
GetOwner()->PlaybackEnded();
|
||||
|
||||
// This must be called after |mOwner->PlaybackEnded()| call above, in order
|
||||
// This must be called after |GetOwner()->PlaybackEnded()| call above, in order
|
||||
// to fire the required durationchange.
|
||||
if (IsInfinite()) {
|
||||
SetInfinite(false);
|
||||
@ -1069,7 +1069,7 @@ MediaDecoder::NotifySuspendedStatusChanged()
|
||||
MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
|
||||
if (mResource) {
|
||||
bool suspended = mResource->IsSuspendedByCache();
|
||||
mOwner->NotifySuspendedByCache(suspended);
|
||||
GetOwner()->NotifySuspendedByCache(suspended);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1079,7 +1079,7 @@ MediaDecoder::NotifyBytesDownloaded()
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
|
||||
UpdatePlaybackRate();
|
||||
mOwner->DownloadProgressed();
|
||||
GetOwner()->DownloadProgressed();
|
||||
}
|
||||
|
||||
void
|
||||
@ -1092,7 +1092,7 @@ MediaDecoder::NotifyDownloadEnded(nsresult aStatus)
|
||||
|
||||
if (aStatus == NS_BINDING_ABORTED) {
|
||||
// Download has been cancelled by user.
|
||||
mOwner->LoadAborted();
|
||||
GetOwner()->LoadAborted();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1115,7 +1115,7 @@ MediaDecoder::NotifyPrincipalChanged()
|
||||
MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
|
||||
nsCOMPtr<nsIPrincipal> newPrincipal = GetCurrentPrincipal();
|
||||
mMediaPrincipalHandle = MakePrincipalHandle(newPrincipal);
|
||||
mOwner->NotifyDecoderPrincipalChanged();
|
||||
GetOwner()->NotifyDecoderPrincipalChanged();
|
||||
}
|
||||
|
||||
void
|
||||
@ -1152,7 +1152,7 @@ MediaDecoder::OnSeekResolved()
|
||||
// Ensure logical position is updated after seek.
|
||||
UpdateLogicalPositionInternal();
|
||||
|
||||
mOwner->SeekCompleted();
|
||||
GetOwner()->SeekCompleted();
|
||||
AsyncResolveSeekDOMPromiseIfExists();
|
||||
}
|
||||
|
||||
@ -1170,7 +1170,7 @@ MediaDecoder::SeekingStarted()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
|
||||
mOwner->SeekStarted();
|
||||
GetOwner()->SeekStarted();
|
||||
}
|
||||
|
||||
void
|
||||
@ -1245,7 +1245,7 @@ MediaDecoder::DurationChanged()
|
||||
// of whether we should fire durationchange on explicit infinity.
|
||||
if (mFiredMetadataLoaded &&
|
||||
(!mozilla::IsInfinite<double>(mDuration) || mExplicitDuration.Ref().isSome())) {
|
||||
mOwner->DispatchAsyncEvent(NS_LITERAL_STRING("durationchange"));
|
||||
GetOwner()->DispatchAsyncEvent(NS_LITERAL_STRING("durationchange"));
|
||||
}
|
||||
|
||||
if (CurrentPosition() > TimeUnit::FromSeconds(mDuration).ToMicroseconds()) {
|
||||
@ -1382,7 +1382,7 @@ MediaDecoder::SetPlaybackRate(double aPlaybackRate)
|
||||
}
|
||||
|
||||
|
||||
if (oldRate == 0 && !mOwner->GetPaused()) {
|
||||
if (oldRate == 0 && !GetOwner()->GetPaused()) {
|
||||
// PlaybackRate is no longer null.
|
||||
// Restart the playback if the media was playing.
|
||||
Play();
|
||||
@ -1514,7 +1514,7 @@ MediaDecoder::FireTimeUpdate()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
|
||||
mOwner->FireTimeUpdate(true);
|
||||
GetOwner()->FireTimeUpdate(true);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1672,7 +1672,7 @@ MediaDecoder::ConstructMediaTracks()
|
||||
return;
|
||||
}
|
||||
|
||||
HTMLMediaElement* element = mOwner->GetMediaElement();
|
||||
HTMLMediaElement* element = GetOwner()->GetMediaElement();
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
@ -1705,7 +1705,7 @@ MediaDecoder::RemoveMediaTracks()
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
|
||||
|
||||
HTMLMediaElement* element = mOwner->GetMediaElement();
|
||||
HTMLMediaElement* element = GetOwner()->GetMediaElement();
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
@ -1738,32 +1738,71 @@ MediaDecoder::NextFrameBufferedStatus()
|
||||
: MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE;
|
||||
}
|
||||
|
||||
nsCString
|
||||
MediaDecoder::GetDebugInfo()
|
||||
{
|
||||
return nsPrintfCString(
|
||||
"channels=%u rate=%u hasAudio=%d hasVideo=%d mPlayState=%s mdsm=%p",
|
||||
mInfo ? mInfo->mAudio.mChannels : 0, mInfo ? mInfo->mAudio.mRate : 0,
|
||||
mInfo ? mInfo->HasAudio() : 0, mInfo ? mInfo->HasVideo() : 0,
|
||||
PlayStateStr(), GetStateMachine());
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoder::DumpDebugInfo()
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
|
||||
DUMP_LOG("metadata: channels=%u rate=%u hasAudio=%d hasVideo=%d, "
|
||||
"state: mPlayState=%s mdsm=%p",
|
||||
mInfo ? mInfo->mAudio.mChannels : 0, mInfo ? mInfo->mAudio.mRate : 0,
|
||||
mInfo ? mInfo->HasAudio() : 0, mInfo ? mInfo->HasVideo() : 0,
|
||||
PlayStateStr(), GetStateMachine());
|
||||
nsCString str = GetDebugInfo();
|
||||
|
||||
nsAutoCString str;
|
||||
GetMozDebugReaderData(str);
|
||||
if (!str.IsEmpty()) {
|
||||
DUMP_LOG("reader data:\n%s", str.get());
|
||||
nsAutoCString readerStr;
|
||||
GetMozDebugReaderData(readerStr);
|
||||
if (!readerStr.IsEmpty()) {
|
||||
str += "\nreader data:\n";
|
||||
str += readerStr;
|
||||
}
|
||||
|
||||
if (GetStateMachine()) {
|
||||
GetStateMachine()->DumpDebugInfo();
|
||||
if (!GetStateMachine()) {
|
||||
DUMP_LOG("%s", str.get());
|
||||
return;
|
||||
}
|
||||
|
||||
GetStateMachine()->RequestDebugInfo()->Then(
|
||||
AbstractThread::MainThread(), __func__,
|
||||
[this, str] (const nsACString& aString) {
|
||||
DUMP_LOG("%s", str.get());
|
||||
DUMP_LOG("%s", aString.Data());
|
||||
},
|
||||
[this, str] () {
|
||||
DUMP_LOG("%s", str.get());
|
||||
});
|
||||
}
|
||||
|
||||
RefPtr<MediaDecoder::DebugInfoPromise>
|
||||
MediaDecoder::RequestDebugInfo()
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
|
||||
|
||||
auto str = GetDebugInfo();
|
||||
if (!GetStateMachine()) {
|
||||
return DebugInfoPromise::CreateAndResolve(str, __func__);
|
||||
}
|
||||
|
||||
return GetStateMachine()->RequestDebugInfo()->Then(
|
||||
AbstractThread::MainThread(), __func__,
|
||||
[str] (const nsACString& aString) {
|
||||
nsCString result = str + nsCString("\n") + aString;
|
||||
return DebugInfoPromise::CreateAndResolve(result, __func__);
|
||||
},
|
||||
[str] () {
|
||||
return DebugInfoPromise::CreateAndResolve(str, __func__);
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoder::NotifyAudibleStateChanged()
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
|
||||
mOwner->SetAudibleState(mIsAudioDataAudible);
|
||||
GetOwner()->SetAudibleState(mIsAudioDataAudible);
|
||||
}
|
||||
|
||||
MediaMemoryTracker::MediaMemoryTracker()
|
||||
|
@ -473,7 +473,7 @@ private:
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
|
||||
mOwner->UpdateReadyState();
|
||||
GetOwner()->UpdateReadyState();
|
||||
}
|
||||
|
||||
virtual MediaDecoderOwner::NextFrameStatus NextFrameStatus() { return mNextFrameStatus; }
|
||||
@ -485,6 +485,9 @@ private:
|
||||
|
||||
virtual void DumpDebugInfo();
|
||||
|
||||
using DebugInfoPromise = MozPromise<nsCString, bool, true>;
|
||||
RefPtr<DebugInfoPromise> RequestDebugInfo();
|
||||
|
||||
protected:
|
||||
virtual ~MediaDecoder();
|
||||
|
||||
@ -552,6 +555,8 @@ protected:
|
||||
static const int DEFAULT_NEXT_FRAME_AVAILABLE_BUFFERED = 250000;
|
||||
|
||||
private:
|
||||
nsCString GetDebugInfo();
|
||||
|
||||
// Called when the metadata from the media file has been loaded by the
|
||||
// state machine. Call on the main thread only.
|
||||
void MetadataLoaded(nsAutoPtr<MediaInfo> aInfo,
|
||||
|
@ -67,24 +67,20 @@ using namespace mozilla::media;
|
||||
#undef VERBOSE_LOG
|
||||
#undef SAMPLE_LOG
|
||||
#undef DECODER_WARN
|
||||
#undef DUMP_LOG
|
||||
#undef SFMT
|
||||
#undef SLOG
|
||||
#undef SWARN
|
||||
#undef SDUMP
|
||||
|
||||
#define FMT(x, ...) "Decoder=%p " x, mDecoderID, ##__VA_ARGS__
|
||||
#define DECODER_LOG(x, ...) MOZ_LOG(gMediaDecoderLog, LogLevel::Debug, (FMT(x, ##__VA_ARGS__)))
|
||||
#define VERBOSE_LOG(x, ...) MOZ_LOG(gMediaDecoderLog, LogLevel::Verbose, (FMT(x, ##__VA_ARGS__)))
|
||||
#define SAMPLE_LOG(x, ...) MOZ_LOG(gMediaSampleLog, LogLevel::Debug, (FMT(x, ##__VA_ARGS__)))
|
||||
#define DECODER_WARN(x, ...) NS_WARNING(nsPrintfCString(FMT(x, ##__VA_ARGS__)).get())
|
||||
#define DUMP_LOG(x, ...) NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString(FMT(x, ##__VA_ARGS__)).get(), nullptr, nullptr, -1)
|
||||
|
||||
// Used by StateObject and its sub-classes
|
||||
#define SFMT(x, ...) "Decoder=%p state=%s " x, mMaster->mDecoderID, ToStateStr(GetState()), ##__VA_ARGS__
|
||||
#define SLOG(x, ...) MOZ_LOG(gMediaDecoderLog, LogLevel::Debug, (SFMT(x, ##__VA_ARGS__)))
|
||||
#define SWARN(x, ...) NS_WARNING(nsPrintfCString(SFMT(x, ##__VA_ARGS__)).get())
|
||||
#define SDUMP(x, ...) NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString(SFMT(x, ##__VA_ARGS__)).get(), nullptr, nullptr, -1)
|
||||
|
||||
// Certain constants get stored as member variables and then adjusted by various
|
||||
// scale factors on a per-decoder basis. We want to make sure to avoid using these
|
||||
@ -245,7 +241,7 @@ public:
|
||||
|
||||
virtual void HandlePlayStateChanged(MediaDecoder::PlayState aPlayState) {}
|
||||
|
||||
virtual void DumpDebugInfo() {}
|
||||
virtual nsCString GetDebugInfo() { return nsCString(); }
|
||||
|
||||
private:
|
||||
template <class S, typename R, typename... As>
|
||||
@ -744,9 +740,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void DumpDebugInfo() override
|
||||
nsCString GetDebugInfo() override
|
||||
{
|
||||
SDUMP("mIsPrerolling=%d", mIsPrerolling);
|
||||
return nsPrintfCString("mIsPrerolling=%d", mIsPrerolling);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -3654,33 +3650,32 @@ uint32_t MediaDecoderStateMachine::GetAmpleVideoFrames() const
|
||||
: std::max<uint32_t>(sVideoQueueDefaultSize, MIN_VIDEO_QUEUE_SIZE);
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::DumpDebugInfo()
|
||||
nsCString
|
||||
MediaDecoderStateMachine::GetDebugInfo()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
return nsPrintfCString(
|
||||
"GetMediaTime=%lld GetClock=%lld mMediaSink=%p "
|
||||
"state=%s mPlayState=%d mSentFirstFrameLoadedEvent=%d IsPlaying=%d "
|
||||
"mAudioStatus=%s mVideoStatus=%s mDecodedAudioEndTime=%lld mDecodedVideoEndTime=%lld "
|
||||
"mAudioCompleted=%d mVideoCompleted=%d ",
|
||||
GetMediaTime(), mMediaSink->IsStarted() ? GetClock() : -1, mMediaSink.get(),
|
||||
ToStateStr(), mPlayState.Ref(), mSentFirstFrameLoadedEvent, IsPlaying(),
|
||||
AudioRequestStatus(), VideoRequestStatus(), mDecodedAudioEndTime, mDecodedVideoEndTime,
|
||||
mAudioCompleted, mVideoCompleted)
|
||||
+ mStateObj->GetDebugInfo() + nsCString("\n")
|
||||
+ mMediaSink->GetDebugInfo();
|
||||
}
|
||||
|
||||
// It is fine to capture a raw pointer here because MediaDecoder only call
|
||||
// this function before shutdown begins.
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([this] () {
|
||||
mMediaSink->DumpDebugInfo();
|
||||
mStateObj->DumpDebugInfo();
|
||||
DUMP_LOG(
|
||||
"GetMediaTime=%lld GetClock=%lld mMediaSink=%p "
|
||||
"state=%s mPlayState=%d mSentFirstFrameLoadedEvent=%d IsPlaying=%d "
|
||||
"mAudioStatus=%s mVideoStatus=%s mDecodedAudioEndTime=%lld mDecodedVideoEndTime=%lld "
|
||||
"mAudioCompleted=%d mVideoCompleted=%d",
|
||||
GetMediaTime(), mMediaSink->IsStarted() ? GetClock() : -1, mMediaSink.get(),
|
||||
ToStateStr(), mPlayState.Ref(), mSentFirstFrameLoadedEvent, IsPlaying(),
|
||||
AudioRequestStatus(), VideoRequestStatus(), mDecodedAudioEndTime, mDecodedVideoEndTime,
|
||||
mAudioCompleted, mVideoCompleted);
|
||||
});
|
||||
|
||||
// Since the task is run asynchronously, it is possible other tasks get first
|
||||
// and change the object states before we print them. Therefore we want to
|
||||
// dispatch this task immediately without waiting for the tail dispatching
|
||||
// phase so object states are less likely to change before being printed.
|
||||
OwnerThread()->Dispatch(r.forget(),
|
||||
AbstractThread::AssertDispatchSuccess, AbstractThread::TailDispatch);
|
||||
RefPtr<MediaDecoder::DebugInfoPromise>
|
||||
MediaDecoderStateMachine::RequestDebugInfo()
|
||||
{
|
||||
using PromiseType = MediaDecoder::DebugInfoPromise;
|
||||
RefPtr<PromiseType::Private> p = new PromiseType::Private(__func__);
|
||||
OwnerThread()->Dispatch(NS_NewRunnableFunction([this, p] () {
|
||||
p->Resolve(GetDebugInfo(), __func__);
|
||||
}), AbstractThread::AssertDispatchSuccess, AbstractThread::TailDispatch);
|
||||
return p.forget();
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::AddOutputStream(ProcessedMediaStream* aStream,
|
||||
|
@ -162,7 +162,7 @@ public:
|
||||
DECODER_STATE_SHUTDOWN
|
||||
};
|
||||
|
||||
void DumpDebugInfo();
|
||||
RefPtr<MediaDecoder::DebugInfoPromise> RequestDebugInfo();
|
||||
|
||||
void AddOutputStream(ProcessedMediaStream* aStream, bool aFinishWhenEnded);
|
||||
// Remove an output stream added with AddOutputStream.
|
||||
@ -240,6 +240,8 @@ private:
|
||||
static const char* ToStr(NextFrameStatus aStatus);
|
||||
const char* ToStateStr();
|
||||
|
||||
nsCString GetDebugInfo();
|
||||
|
||||
// Functions used by assertions to ensure we're calling things
|
||||
// on the appropriate threads.
|
||||
bool OnTaskQueue() const;
|
||||
|
@ -553,11 +553,15 @@ VP8TrackEncoder::GetEncodedTrack(EncodedFrameContainer& aData)
|
||||
} else {
|
||||
// SKIP_FRAME
|
||||
// Extend the duration of the last encoded data in aData
|
||||
// because this frame will be skip.
|
||||
// because this frame will be skipped.
|
||||
VP8LOG(LogLevel::Warning, "MediaRecorder lagging behind. Skipping a frame.");
|
||||
RefPtr<EncodedFrame> last = aData.GetEncodedFrames().LastElement();
|
||||
if (last) {
|
||||
last->SetDuration(last->GetDuration() + chunk.GetDuration());
|
||||
CheckedInt64 skippedDuration = FramesToUsecs(chunk.mDuration, mTrackRate);
|
||||
if (skippedDuration.isValid() && skippedDuration.value() > 0) {
|
||||
last->SetDuration(last->GetDuration() +
|
||||
(static_cast<uint64_t>(skippedDuration.value())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -716,9 +716,12 @@ GMPParent::ReadGMPInfoFile(nsIFile* aFile)
|
||||
|
||||
#if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX)
|
||||
if (!mozilla::SandboxInfo::Get().CanSandboxMedia()) {
|
||||
printf_stderr("GMPParent::ReadGMPMetaData: Plugin \"%s\" is an EME CDM"
|
||||
" but this system can't sandbox it; not loading.\n",
|
||||
mDisplayName.get());
|
||||
nsPrintfCString msg(
|
||||
"GMPParent::ReadGMPMetaData: Plugin \"%s\" is an EME CDM"
|
||||
" but this system can't sandbox it; not loading.",
|
||||
mDisplayName.get());
|
||||
printf_stderr("%s\n", msg.get());
|
||||
LOGD("%s", msg.get());
|
||||
return GenericPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
|
||||
}
|
||||
#endif
|
||||
@ -771,6 +774,18 @@ GMPParent::ParseChromiumManifest(const nsAString& aJSON)
|
||||
mDescription = NS_ConvertUTF16toUTF8(m.mDescription);
|
||||
mVersion = NS_ConvertUTF16toUTF8(m.mVersion);
|
||||
|
||||
#if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX)
|
||||
if (!mozilla::SandboxInfo::Get().CanSandboxMedia()) {
|
||||
nsPrintfCString msg(
|
||||
"GMPParent::ParseChromiumManifest: Plugin \"%s\" is an EME CDM"
|
||||
" but this system can't sandbox it; not loading.",
|
||||
mDisplayName.get());
|
||||
printf_stderr("%s\n", msg.get());
|
||||
LOGD("%s", msg.get());
|
||||
return GenericPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCString kEMEKeySystem;
|
||||
|
||||
// We hard code a few of the settings because they can't be stored in the
|
||||
|
@ -429,6 +429,49 @@ TEST(VP8VideoTrackEncoder, NullFrameFirst)
|
||||
EXPECT_EQ(pointThree, totalDuration);
|
||||
}
|
||||
|
||||
// Test encoding a track that has to skip frames.
|
||||
TEST(VP8VideoTrackEncoder, SkippedFrames)
|
||||
{
|
||||
// Initiate VP8 encoder
|
||||
TestVP8TrackEncoder encoder;
|
||||
InitParam param = {true, 640, 480};
|
||||
encoder.TestInit(param);
|
||||
YUVBufferGenerator generator;
|
||||
generator.Init(mozilla::gfx::IntSize(640, 480));
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
VideoSegment segment;
|
||||
|
||||
// Pass 100 frames of the shortest possible duration where we don't get
|
||||
// rounding errors between input/output rate.
|
||||
for (uint32_t i = 0; i < 100; ++i) {
|
||||
segment.AppendFrame(generator.GenerateI420Image(),
|
||||
mozilla::StreamTime(90), // 1ms
|
||||
generator.GetSize(),
|
||||
PRINCIPAL_HANDLE_NONE,
|
||||
false,
|
||||
now + TimeDuration::FromMilliseconds(i));
|
||||
}
|
||||
|
||||
encoder.SetCurrentFrames(segment);
|
||||
|
||||
// End the track.
|
||||
segment.Clear();
|
||||
encoder.NotifyQueuedTrackChanges(nullptr, 0, 0, TrackEventCommand::TRACK_EVENT_ENDED, segment);
|
||||
|
||||
EncodedFrameContainer container;
|
||||
ASSERT_TRUE(NS_SUCCEEDED(encoder.GetEncodedTrack(container)));
|
||||
|
||||
EXPECT_TRUE(encoder.IsEncodingComplete());
|
||||
|
||||
// Verify total duration being 100 * 1ms = 100ms.
|
||||
uint64_t totalDuration = 0;
|
||||
for (auto& frame : container.GetEncodedFrames()) {
|
||||
totalDuration += frame->GetDuration();
|
||||
}
|
||||
const uint64_t hundredMillis = PR_USEC_PER_SEC / 10;
|
||||
EXPECT_EQ(hundredMillis, totalDuration);
|
||||
}
|
||||
|
||||
// EOS test
|
||||
TEST(VP8VideoTrackEncoder, EncodeComplete)
|
||||
{
|
||||
|
@ -22,9 +22,6 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
#undef DUMP_LOG
|
||||
#define DUMP_LOG(x, ...) NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString(x, ##__VA_ARGS__).get(), nullptr, nullptr, -1)
|
||||
|
||||
/*
|
||||
* A container class to make it easier to pass the playback info all the
|
||||
* way to DecodedStreamGraphListener from DecodedStream.
|
||||
@ -136,7 +133,7 @@ public:
|
||||
void SetPlaying(bool aPlaying);
|
||||
MediaEventSource<int64_t>& OnOutput();
|
||||
void Forget();
|
||||
void DumpDebugInfo();
|
||||
nsCString GetDebugInfo();
|
||||
|
||||
/* The following group of fields are protected by the decoder's monitor
|
||||
* and can be read or written on any thread.
|
||||
@ -229,12 +226,12 @@ DecodedStreamData::Forget()
|
||||
mListener->Forget();
|
||||
}
|
||||
|
||||
void
|
||||
DecodedStreamData::DumpDebugInfo()
|
||||
nsCString
|
||||
DecodedStreamData::GetDebugInfo()
|
||||
{
|
||||
DUMP_LOG(
|
||||
"DecodedStreamData=%p mPlaying=%d mAudioFramesWritten=%lld"
|
||||
"mNextAudioTime=%lld mNextVideoTime=%lld mHaveSentFinish=%d"
|
||||
return nsPrintfCString(
|
||||
"DecodedStreamData=%p mPlaying=%d mAudioFramesWritten=%lld "
|
||||
"mNextAudioTime=%lld mNextVideoTime=%lld mHaveSentFinish=%d "
|
||||
"mHaveSentFinishAudio=%d mHaveSentFinishVideo=%d",
|
||||
this, mPlaying, mAudioFramesWritten, mNextAudioTime, mNextVideoTime,
|
||||
mHaveSentFinish, mHaveSentFinishAudio, mHaveSentFinishVideo);
|
||||
@ -779,16 +776,14 @@ DecodedStream::DisconnectListener()
|
||||
mVideoFinishListener.Disconnect();
|
||||
}
|
||||
|
||||
void
|
||||
DecodedStream::DumpDebugInfo()
|
||||
nsCString
|
||||
DecodedStream::GetDebugInfo()
|
||||
{
|
||||
AssertOwnerThread();
|
||||
DUMP_LOG(
|
||||
return nsPrintfCString(
|
||||
"DecodedStream=%p mStartTime=%lld mLastOutputTime=%lld mPlaying=%d mData=%p",
|
||||
this, mStartTime.valueOr(-1), mLastOutputTime, mPlaying, mData.get());
|
||||
if (mData) {
|
||||
mData->DumpDebugInfo();
|
||||
}
|
||||
this, mStartTime.valueOr(-1), mLastOutputTime, mPlaying, mData.get())
|
||||
+ (mData ? nsCString("\n") + mData->GetDebugInfo() : nsCString());
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -64,7 +64,7 @@ public:
|
||||
bool IsStarted() const override;
|
||||
bool IsPlaying() const override;
|
||||
|
||||
void DumpDebugInfo() override;
|
||||
nsCString GetDebugInfo() override;
|
||||
|
||||
protected:
|
||||
virtual ~DecodedStream();
|
||||
|
@ -119,9 +119,9 @@ public:
|
||||
// Must be called after playback stopped.
|
||||
virtual void Shutdown() {}
|
||||
|
||||
// Dump debugging information to the logs.
|
||||
// Return a string containing debugging information.
|
||||
// Can be called in any phase.
|
||||
virtual void DumpDebugInfo() {}
|
||||
virtual nsCString GetDebugInfo() { return nsCString(); }
|
||||
|
||||
protected:
|
||||
virtual ~MediaSink() {}
|
||||
|
@ -13,12 +13,10 @@ namespace mozilla {
|
||||
extern LazyLogModule gMediaDecoderLog;
|
||||
|
||||
#undef FMT
|
||||
#undef DUMP_LOG
|
||||
|
||||
#define FMT(x, ...) "VideoSink=%p " x, this, ##__VA_ARGS__
|
||||
#define VSINK_LOG(x, ...) MOZ_LOG(gMediaDecoderLog, LogLevel::Debug, (FMT(x, ##__VA_ARGS__)))
|
||||
#define VSINK_LOG_V(x, ...) MOZ_LOG(gMediaDecoderLog, LogLevel::Verbose, (FMT(x, ##__VA_ARGS__)))
|
||||
#define DUMP_LOG(x, ...) NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString(FMT(x, ##__VA_ARGS__)).get(), nullptr, nullptr, -1)
|
||||
|
||||
using namespace mozilla::layers;
|
||||
|
||||
@ -473,17 +471,17 @@ VideoSink::MaybeResolveEndPromise()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VideoSink::DumpDebugInfo()
|
||||
nsCString
|
||||
VideoSink::GetDebugInfo()
|
||||
{
|
||||
AssertOwnerThread();
|
||||
DUMP_LOG(
|
||||
return nsPrintfCString(
|
||||
"IsStarted=%d IsPlaying=%d, VideoQueue: finished=%d size=%d, "
|
||||
"mVideoFrameEndTime=%lld mHasVideo=%d mVideoSinkEndRequest.Exists()=%d "
|
||||
"mEndPromiseHolder.IsEmpty()=%d",
|
||||
"mEndPromiseHolder.IsEmpty()=%d\n",
|
||||
IsStarted(), IsPlaying(), VideoQueue().IsFinished(), VideoQueue().GetSize(),
|
||||
mVideoFrameEndTime, mHasVideo, mVideoSinkEndRequest.Exists(), mEndPromiseHolder.IsEmpty());
|
||||
mAudioSink->DumpDebugInfo();
|
||||
mVideoFrameEndTime, mHasVideo, mVideoSinkEndRequest.Exists(), mEndPromiseHolder.IsEmpty())
|
||||
+ mAudioSink->GetDebugInfo();
|
||||
}
|
||||
|
||||
} // namespace media
|
||||
|
@ -68,7 +68,7 @@ public:
|
||||
|
||||
void Shutdown() override;
|
||||
|
||||
void DumpDebugInfo() override;
|
||||
nsCString GetDebugInfo() override;
|
||||
|
||||
private:
|
||||
virtual ~VideoSink();
|
||||
|
@ -61,7 +61,6 @@ Logger::printf(const char* fmt, ...)
|
||||
}
|
||||
|
||||
LazyLogModule Logger::gChromiumPRLog("chromium");
|
||||
} // namespace mozilla
|
||||
|
||||
mozilla::Logger&
|
||||
operator<<(mozilla::Logger& log, const char* s)
|
||||
@ -97,3 +96,5 @@ operator<<(mozilla::Logger& log, void* p)
|
||||
log.printf("%p", p);
|
||||
return log;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -76,8 +76,6 @@ struct EmptyLog
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
mozilla::Logger& operator<<(mozilla::Logger& log, const char* s);
|
||||
mozilla::Logger& operator<<(mozilla::Logger& log, const std::string& s);
|
||||
mozilla::Logger& operator<<(mozilla::Logger& log, int i);
|
||||
@ -90,6 +88,8 @@ const mozilla::EmptyLog& operator <<(const mozilla::EmptyLog& log, const T&)
|
||||
return log;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#ifdef NO_CHROMIUM_LOGGING
|
||||
#define CHROMIUM_LOG(info) std::stringstream()
|
||||
#define LOG_IF(info, condition) if (!(condition)) std::stringstream()
|
||||
|
@ -7,12 +7,14 @@
|
||||
#ifndef mozilla_mscom_ActivationContext_h
|
||||
#define mozilla_mscom_ActivationContext_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace mozilla {
|
||||
namespace mscom {
|
||||
|
||||
class ActivationContext
|
||||
class MOZ_RAII ActivationContext
|
||||
{
|
||||
public:
|
||||
explicit ActivationContext(HMODULE aLoadFromModule);
|
||||
@ -23,6 +25,11 @@ public:
|
||||
return mActCtx != INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
ActivationContext(const ActivationContext&) = delete;
|
||||
ActivationContext(ActivationContext&&) = delete;
|
||||
ActivationContext& operator=(const ActivationContext&) = delete;
|
||||
ActivationContext& operator=(ActivationContext&&) = delete;
|
||||
|
||||
private:
|
||||
HANDLE mActCtx;
|
||||
ULONG_PTR mActivationCookie;
|
||||
|
@ -32,35 +32,64 @@
|
||||
/* This code MUST NOT use any non-inlined internal Mozilla APIs, as it will be
|
||||
compiled into DLLs that COM may load into non-Mozilla processes! */
|
||||
|
||||
namespace {
|
||||
extern "C" {
|
||||
|
||||
// This function is defined in generated code for proxy DLLs but is not declared
|
||||
// in rpcproxy.h, so we need this typedef.
|
||||
typedef void (RPC_ENTRY *GetProxyDllInfoFnPtr)(const ProxyFileInfo*** aInfo,
|
||||
const CLSID** aId);
|
||||
// in rpcproxy.h, so we need this declaration.
|
||||
void RPC_ENTRY GetProxyDllInfo(const ProxyFileInfo*** aInfo, const CLSID** aId);
|
||||
|
||||
} // anonymous namespace
|
||||
#if defined(_MSC_VER)
|
||||
extern IMAGE_DOS_HEADER __ImageBase;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
namespace mscom {
|
||||
|
||||
static HMODULE
|
||||
GetContainingModule()
|
||||
{
|
||||
HMODULE thisModule = nullptr;
|
||||
#if defined(_MSC_VER)
|
||||
thisModule = reinterpret_cast<HMODULE>(&__ImageBase);
|
||||
#else
|
||||
if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
|
||||
GET_MODULE_HANDLE_EX_UNCHANGED_REFCOUNT,
|
||||
reinterpret_cast<LPCTSTR>(&GetContainingModule),
|
||||
&thisModule)) {
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
return thisModule;
|
||||
}
|
||||
|
||||
static bool
|
||||
GetContainingLibPath(wchar_t* aBuffer, size_t aBufferLen)
|
||||
{
|
||||
HMODULE thisModule = GetContainingModule();
|
||||
if (!thisModule) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD fileNameResult = GetModuleFileName(thisModule, aBuffer, aBufferLen);
|
||||
if (!fileNameResult || (fileNameResult == aBufferLen &&
|
||||
::GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
BuildLibPath(RegistrationFlags aFlags, wchar_t* aBuffer, size_t aBufferLen,
|
||||
const wchar_t* aLeafName)
|
||||
{
|
||||
if (aFlags == RegistrationFlags::eUseBinDirectory) {
|
||||
HMODULE thisModule = nullptr;
|
||||
if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
|
||||
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||||
reinterpret_cast<LPCTSTR>(&RegisterProxy),
|
||||
&thisModule)) {
|
||||
return false;
|
||||
}
|
||||
DWORD fileNameResult = GetModuleFileName(thisModule, aBuffer, aBufferLen);
|
||||
if (!fileNameResult || (fileNameResult == aBufferLen &&
|
||||
::GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
|
||||
if (!GetContainingLibPath(aBuffer, aBufferLen)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!PathRemoveFileSpec(aBuffer)) {
|
||||
return false;
|
||||
}
|
||||
@ -79,6 +108,74 @@ BuildLibPath(RegistrationFlags aFlags, wchar_t* aBuffer, size_t aBufferLen,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
RegisterPSClsids(const ProxyFileInfo** aProxyInfo, const CLSID* aProxyClsid)
|
||||
{
|
||||
while (*aProxyInfo) {
|
||||
const ProxyFileInfo& curInfo = **aProxyInfo;
|
||||
for (unsigned short idx = 0, size = curInfo.TableSize; idx < size; ++idx) {
|
||||
HRESULT hr = CoRegisterPSClsid(*(curInfo.pStubVtblList[idx]->header.piid),
|
||||
*aProxyClsid);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
++aProxyInfo;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
UniquePtr<RegisteredProxy>
|
||||
RegisterProxy()
|
||||
{
|
||||
const ProxyFileInfo** proxyInfo = nullptr;
|
||||
const CLSID* proxyClsid = nullptr;
|
||||
GetProxyDllInfo(&proxyInfo, &proxyClsid);
|
||||
if (!proxyInfo || !proxyClsid) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IUnknown* classObject = nullptr;
|
||||
HRESULT hr = DllGetClassObject(*proxyClsid, IID_IUnknown, (void**)&classObject);
|
||||
if (FAILED(hr)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DWORD regCookie;
|
||||
hr = CoRegisterClassObject(*proxyClsid, classObject, CLSCTX_INPROC_SERVER,
|
||||
REGCLS_MULTIPLEUSE, ®Cookie);
|
||||
if (FAILED(hr)) {
|
||||
classObject->lpVtbl->Release(classObject);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
wchar_t modulePathBuf[MAX_PATH + 1] = {0};
|
||||
if (!GetContainingLibPath(modulePathBuf, ArrayLength(modulePathBuf))) {
|
||||
CoRevokeClassObject(regCookie);
|
||||
classObject->lpVtbl->Release(classObject);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ITypeLib* typeLib = nullptr;
|
||||
hr = LoadTypeLibEx(modulePathBuf, REGKIND_NONE, &typeLib);
|
||||
MOZ_ASSERT(SUCCEEDED(hr));
|
||||
if (FAILED(hr)) {
|
||||
CoRevokeClassObject(regCookie);
|
||||
classObject->lpVtbl->Release(classObject);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// RegisteredProxy takes ownership of classObject and typeLib references
|
||||
auto result(MakeUnique<RegisteredProxy>(classObject, regCookie, typeLib));
|
||||
|
||||
if (!RegisterPSClsids(proxyInfo, proxyClsid)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
UniquePtr<RegisteredProxy>
|
||||
RegisterProxy(const wchar_t* aLeafName, RegistrationFlags aFlags)
|
||||
{
|
||||
@ -100,7 +197,7 @@ RegisterProxy(const wchar_t* aLeafName, RegistrationFlags aFlags)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto GetProxyDllInfoFn = reinterpret_cast<GetProxyDllInfoFnPtr>(
|
||||
auto GetProxyDllInfoFn = reinterpret_cast<decltype(&GetProxyDllInfo)>(
|
||||
GetProcAddress(proxyDll, "GetProxyDllInfo"));
|
||||
if (!GetProxyDllInfoFn) {
|
||||
return nullptr;
|
||||
@ -144,16 +241,8 @@ RegisterProxy(const wchar_t* aLeafName, RegistrationFlags aFlags)
|
||||
auto result(MakeUnique<RegisteredProxy>(reinterpret_cast<uintptr_t>(proxyDll.disown()),
|
||||
classObject, regCookie, typeLib));
|
||||
|
||||
while (*proxyInfo) {
|
||||
const ProxyFileInfo& curInfo = **proxyInfo;
|
||||
for (unsigned short i = 0, e = curInfo.TableSize; i < e; ++i) {
|
||||
hr = CoRegisterPSClsid(*(curInfo.pStubVtblList[i]->header.piid),
|
||||
*proxyClsid);
|
||||
if (FAILED(hr)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
++proxyInfo;
|
||||
if (!RegisterPSClsids(proxyInfo, proxyClsid)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -192,6 +281,19 @@ RegisteredProxy::RegisteredProxy(uintptr_t aModule, IUnknown* aClassObject,
|
||||
AddToRegistry(this);
|
||||
}
|
||||
|
||||
RegisteredProxy::RegisteredProxy(IUnknown* aClassObject, uint32_t aRegCookie,
|
||||
ITypeLib* aTypeLib)
|
||||
: mModule(0)
|
||||
, mClassObject(aClassObject)
|
||||
, mRegCookie(aRegCookie)
|
||||
, mTypeLib(aTypeLib)
|
||||
, mIsRegisteredInMTA(IsCurrentThreadMTA())
|
||||
{
|
||||
MOZ_ASSERT(aClassObject);
|
||||
MOZ_ASSERT(aTypeLib);
|
||||
AddToRegistry(this);
|
||||
}
|
||||
|
||||
// If we're initializing from a typelib, it doesn't matter which apartment we
|
||||
// run in, so mIsRegisteredInMTA may always be set to false in this case.
|
||||
RegisteredProxy::RegisteredProxy(ITypeLib* aTypeLib)
|
||||
|
@ -28,6 +28,8 @@ class RegisteredProxy
|
||||
public:
|
||||
RegisteredProxy(uintptr_t aModule, IUnknown* aClassObject,
|
||||
uint32_t aRegCookie, ITypeLib* aTypeLib);
|
||||
RegisteredProxy(IUnknown* aClassObject, uint32_t aRegCookie,
|
||||
ITypeLib* aTypeLib);
|
||||
explicit RegisteredProxy(ITypeLib* aTypeLib);
|
||||
RegisteredProxy(RegisteredProxy&& aOther);
|
||||
RegisteredProxy& operator=(RegisteredProxy&& aOther);
|
||||
@ -63,6 +65,10 @@ enum class RegistrationFlags
|
||||
eUseSystemDirectory
|
||||
};
|
||||
|
||||
// For our own DLL that we are currently executing in (ie, xul).
|
||||
// Assumes corresponding TLB is embedded in resources.
|
||||
UniquePtr<RegisteredProxy> RegisterProxy();
|
||||
|
||||
// For DLL files. Assumes corresponding TLB is embedded in resources.
|
||||
UniquePtr<RegisteredProxy> RegisterProxy(const wchar_t* aLeafName,
|
||||
RegistrationFlags aFlags =
|
||||
|
@ -110,9 +110,10 @@ private:
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
services::GetObserverService();
|
||||
if (observerService)
|
||||
if (observerService) {
|
||||
observerService->RemoveObserver(this, NS_IOSERVICE_OFFLINE_STATUS_TOPIC);
|
||||
observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -340,7 +341,7 @@ PeerConnectionCtx::EverySecondTelemetryCallback_m(nsITimer* timer, void *closure
|
||||
p != ctx->mPeerConnections.end(); ++p) {
|
||||
if (p->second->HasMedia()) {
|
||||
if (!queries->append(nsAutoPtr<RTCStatsQuery>(new RTCStatsQuery(true)))) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(p->second->BuildStatsQuery_m(nullptr, // all tracks
|
||||
queries->back())))) {
|
||||
|
12
mfbt/Maybe.h
12
mfbt/Maybe.h
@ -16,6 +16,7 @@
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
#include <new> // for placement new
|
||||
#include <ostream>
|
||||
#include <type_traits>
|
||||
|
||||
namespace mozilla {
|
||||
@ -452,6 +453,17 @@ public:
|
||||
::new (mStorage.addr()) T(Forward<Args>(aArgs)...);
|
||||
mIsSome = true;
|
||||
}
|
||||
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& aStream, const Maybe<T>& aMaybe)
|
||||
{
|
||||
if (aMaybe) {
|
||||
aStream << aMaybe.ref();
|
||||
} else {
|
||||
aStream << "<Nothing>";
|
||||
}
|
||||
return aStream;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width; user-scalable=0" />
|
||||
<meta charset="UTF-8" />
|
||||
|
||||
<link rel="stylesheet" href="chrome://browser/skin/config.css" type="text/css"/>
|
||||
<script type="text/javascript;version=1.8" src="chrome://browser/content/config.js"></script>
|
||||
|
@ -15,9 +15,9 @@
|
||||
"unpack": true
|
||||
},
|
||||
{
|
||||
"version": "rustc 1.15.0-beta.2 (519656798 2016-12-30) repack",
|
||||
"size": 110451636,
|
||||
"digest": "a7b34249eb4981b3b553b319515d3f333245cc0e38a631e8d0de35e130b001270783c0dd6fb58f0bf7900e3694be49453c8c23e6589996123ebddc7308d3039d",
|
||||
"version": "rustc 1.15.0-beta.4 (ad78c04a9 2017-01-18) repack",
|
||||
"size": 92947272,
|
||||
"digest": "9fdc415d422ca7fb3b8e7044e4656b60cba6697ee609f8a704423fa2fc7e5de4b7d1ce52b1abfae51d8ecc3e1a4df0a8dbae6a43c5357e3a0b6e0b055178186c",
|
||||
"algorithm": "sha512",
|
||||
"filename": "rustc.tar.xz",
|
||||
"unpack": true
|
||||
|
@ -48,9 +48,9 @@
|
||||
"unpack": true
|
||||
},
|
||||
{
|
||||
"version": "rustc 1.15.0-beta.2 (519656798 2016-12-30) repack",
|
||||
"size": 110451636,
|
||||
"digest": "a7b34249eb4981b3b553b319515d3f333245cc0e38a631e8d0de35e130b001270783c0dd6fb58f0bf7900e3694be49453c8c23e6589996123ebddc7308d3039d",
|
||||
"version": "rustc 1.15.0-beta.4 (ad78c04a9 2017-01-18) repack",
|
||||
"size": 92947272,
|
||||
"digest": "9fdc415d422ca7fb3b8e7044e4656b60cba6697ee609f8a704423fa2fc7e5de4b7d1ce52b1abfae51d8ecc3e1a4df0a8dbae6a43c5357e3a0b6e0b055178186c",
|
||||
"algorithm": "sha512",
|
||||
"filename": "rustc.tar.xz",
|
||||
"unpack": true
|
||||
|
@ -73,9 +73,9 @@
|
||||
"size": 51753660
|
||||
},
|
||||
{
|
||||
"version": "rustc 1.15.0-beta.2 (519656798 2016-12-30) repack",
|
||||
"size": 110451636,
|
||||
"digest": "a7b34249eb4981b3b553b319515d3f333245cc0e38a631e8d0de35e130b001270783c0dd6fb58f0bf7900e3694be49453c8c23e6589996123ebddc7308d3039d",
|
||||
"version": "rustc 1.15.0-beta.4 (ad78c04a9 2017-01-18) repack",
|
||||
"size": 92947272,
|
||||
"digest": "9fdc415d422ca7fb3b8e7044e4656b60cba6697ee609f8a704423fa2fc7e5de4b7d1ce52b1abfae51d8ecc3e1a4df0a8dbae6a43c5357e3a0b6e0b055178186c",
|
||||
"algorithm": "sha512",
|
||||
"filename": "rustc.tar.xz",
|
||||
"unpack": true
|
||||
|
@ -54,6 +54,7 @@ chrome.jar:
|
||||
skin/images/checkbox_unchecked_disabled.png (images/checkbox_unchecked_disabled.png)
|
||||
skin/images/checkbox_unchecked_pressed.png (images/checkbox_unchecked_pressed.png)
|
||||
skin/images/chevron.png (images/chevron.png)
|
||||
skin/images/chevron-rtl.png (images/chevron-rtl.png)
|
||||
skin/images/dropmarker.svg (images/dropmarker.svg)
|
||||
skin/images/dropmarker-right.svg (images/dropmarker-right.svg)
|
||||
skin/images/errorpage-warning.png (images/errorpage-warning.png)
|
||||
|
@ -1220,6 +1220,10 @@ pref("privacy.popups.disable_from_plugins", 2);
|
||||
|
||||
// send "do not track" HTTP header, disabled by default
|
||||
pref("privacy.donottrackheader.enabled", false);
|
||||
// If true, close buton will be shown on permission prompts
|
||||
// and for all PopupNotifications, the secondary action of
|
||||
// the popup will be called when the popup is dismissed.
|
||||
pref("privacy.permissionPrompts.showCloseButton", false);
|
||||
// Enforce tracking protection in all modes
|
||||
pref("privacy.trackingprotection.enabled", false);
|
||||
// Enforce tracking protection in Private Browsing mode
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <algorithm> // for std::min, std::max
|
||||
#include <ostream>
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/FloatingPoint.h"
|
||||
@ -279,6 +280,11 @@ public:
|
||||
return mValue != 0;
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& aStream,
|
||||
const BaseTimeDuration& aDuration) {
|
||||
return aStream << aDuration.ToMilliseconds() << " ms";
|
||||
}
|
||||
|
||||
// Return a best guess at the system's current timing resolution,
|
||||
// which might be variable. BaseTimeDurations below this order of
|
||||
// magnitude are meaningless, and those at the same order of
|
||||
|
@ -439,7 +439,7 @@ class WinArtifactJob(ArtifactJob):
|
||||
# The values correpsond to a pair of (<package regex>, <test archive regex>).
|
||||
JOB_DETAILS = {
|
||||
'android-api-15-opt': (AndroidArtifactJob, (r'(public/build/fennec-(.*)\.android-arm.apk|public/build/target\.apk)',
|
||||
r'public/build/fennec-(.*)\.common\.tests\.zip|public/build/target-(.*)\.common\.tests\.zip')),
|
||||
r'public/build/fennec-(.*)\.common\.tests\.zip|public/build/target\.common\.tests\.zip')),
|
||||
'android-api-15-debug': (AndroidArtifactJob, (r'public/build/target\.apk',
|
||||
r'public/build/target\.common\.tests\.zip')),
|
||||
'android-x86-opt': (AndroidArtifactJob, (r'public/build/target\.apk',
|
||||
|
@ -1029,6 +1029,7 @@ BookmarksTracker.prototype = {
|
||||
},
|
||||
|
||||
_ensureMobileQuery: function _ensureMobileQuery() {
|
||||
Services.prefs.setBoolPref("browser.bookmarks.showMobileBookmarks", true);
|
||||
let find = val =>
|
||||
PlacesUtils.annotations.getItemsWithAnnotation(ORGANIZERQUERY_ANNO, {}).filter(
|
||||
id => PlacesUtils.annotations.getItemAnnotation(id, ORGANIZERQUERY_ANNO) == val
|
||||
|
@ -106,7 +106,7 @@ android-api-15-nightly/opt:
|
||||
index:
|
||||
product: mobile
|
||||
job-name: android-api-15-opt
|
||||
type: nightly
|
||||
type: nightly-with-multi-l10n
|
||||
treeherder:
|
||||
platform: android-4-0-armv7-api15/opt
|
||||
symbol: tc(N)
|
||||
|
@ -38,6 +38,7 @@ linux64/opt:
|
||||
- external-media-tests
|
||||
- web-platform-tests
|
||||
- opt-only-tests
|
||||
- desktop-screenshot-capture
|
||||
- talos
|
||||
|
||||
# TODO: use 'pgo' and 'asan' labels here, instead of -pgo/opt
|
||||
|
@ -180,6 +180,9 @@ linux32-opt-tests:
|
||||
# mochitest-dt is too slow on linux32/debug
|
||||
- mochitest-devtools-chrome
|
||||
|
||||
desktop-screenshot-capture:
|
||||
- mochitest-browser-screenshots
|
||||
|
||||
android-common-tests:
|
||||
- cppunit
|
||||
- crashtest
|
||||
|
@ -433,6 +433,35 @@ mochitest-browser-chrome:
|
||||
default: legacy
|
||||
allow-software-gl-layers: false
|
||||
|
||||
mochitest-browser-screenshots:
|
||||
description: "Mochitest Browser Screenshots"
|
||||
suite: mochitest/browser-chrome-screenshots
|
||||
treeherder-symbol: tc-M(ss)
|
||||
loopback-video: true
|
||||
run-on-projects:
|
||||
by-test-platform:
|
||||
linux64/opt: ['mozilla-central', 'try']
|
||||
default: []
|
||||
e10s: true
|
||||
max-run-time: 3600
|
||||
mozharness:
|
||||
script: desktop_unittest.py
|
||||
no-read-buildbot-config: true
|
||||
config:
|
||||
by-test-platform:
|
||||
windows.*:
|
||||
- unittests/win_taskcluster_unittest.py
|
||||
macosx.*:
|
||||
- remove_executables.py
|
||||
- unittests/mac_unittest.py
|
||||
linux.*:
|
||||
- unittests/linux_unittest.py
|
||||
- remove_executables.py
|
||||
extra-options:
|
||||
- --mochitest-suite=browser-chrome-screenshots
|
||||
instance-size: legacy
|
||||
allow-software-gl-layers: false
|
||||
|
||||
mochitest-chrome:
|
||||
description: "Mochitest chrome run"
|
||||
suite: mochitest/chrome
|
||||
|
@ -1 +1 @@
|
||||
0.4.1
|
||||
0.4.2
|
||||
|
@ -57,6 +57,9 @@ def install(filename, target):
|
||||
print(' Unpacking %s...' % filename)
|
||||
subprocess.check_call(['tar', 'xf', filename])
|
||||
basename = filename.split('.tar')[0]
|
||||
# Work around bad tarball naming in 1.15 cargo packages.
|
||||
basename = basename.replace('cargo-beta', 'cargo-nightly')
|
||||
basename = basename.replace('cargo-0.16', 'cargo-nightly')
|
||||
print(' Installing %s...' % basename)
|
||||
install_cmd = [os.path.join(basename, 'install.sh')]
|
||||
install_cmd += ['--prefix=' + os.path.abspath(target)]
|
||||
@ -195,4 +198,4 @@ if __name__ == '__main__':
|
||||
repack(win64, [win64])
|
||||
repack(linux64, [linux64, linux32])
|
||||
repack(linux64, [linux64, mac64, mac32], suffix='mac-cross')
|
||||
repack(linux64, [linux64, android, android_x86], suffix='android-cross')
|
||||
repack(linux64, [linux64, android, android_x86], channel='beta', suffix='android-cross')
|
||||
|
@ -93,7 +93,7 @@ task_description_schema = Schema({
|
||||
'job-name': basestring,
|
||||
|
||||
# Type of gecko v2 index to use
|
||||
'type': Any('generic', 'nightly', 'l10n'),
|
||||
'type': Any('generic', 'nightly', 'l10n', 'nightly-with-multi-l10n'),
|
||||
|
||||
# The rank that the task will receive in the TaskCluster
|
||||
# index. A newly completed task supercedes the currently
|
||||
@ -661,11 +661,21 @@ def add_nightly_index_routes(config, task):
|
||||
for tpl in V2_NIGHTLY_TEMPLATES:
|
||||
routes.append(tpl.format(**subs))
|
||||
|
||||
# Also add routes for en-US
|
||||
task = add_l10n_index_routes(config, task, force_locale="en-US")
|
||||
|
||||
return task
|
||||
|
||||
|
||||
@index_builder('nightly-with-multi-l10n')
|
||||
def add_nightly_multi_index_routes(config, task):
|
||||
task = add_nightly_index_routes(config, task)
|
||||
task = add_l10n_index_routes(config, task, force_locale="multi")
|
||||
return task
|
||||
|
||||
|
||||
@index_builder('l10n')
|
||||
def add_l10n_index_routes(config, task):
|
||||
def add_l10n_index_routes(config, task, force_locale=None):
|
||||
index = task.get('index')
|
||||
routes = task.setdefault('routes', [])
|
||||
|
||||
@ -682,6 +692,10 @@ def add_l10n_index_routes(config, task):
|
||||
locales = task['attributes'].get('chunk_locales',
|
||||
task['attributes'].get('all_locales'))
|
||||
|
||||
if force_locale:
|
||||
# Used for en-US and multi-locale
|
||||
locales = [force_locale]
|
||||
|
||||
if not locales:
|
||||
raise Exception("Error: Unable to use l10n index for tasks without locales")
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
from marionette_driver.by import By
|
||||
from marionette_driver.errors import MoveTargetOutOfBoundsException
|
||||
|
||||
from marionette_harness import MarionetteTestCase, skip
|
||||
from marionette_harness import MarionetteTestCase, skip, skip_if_mobile
|
||||
|
||||
|
||||
class TestClickScrolling(MarionetteTestCase):
|
||||
@ -97,6 +97,7 @@ class TestClickScrolling(MarionetteTestCase):
|
||||
self.marionette.find_element(By.ID, "{}-70".format(s)).click()
|
||||
self.assertNotEqual(scroll_x, self.marionette.execute_script("return window.scrollX;"))
|
||||
|
||||
@skip_if_mobile("Bug 1293855 - Lists differ: [70, 70] != [70, 120]")
|
||||
def test_should_not_scroll_elements_if_click_point_is_in_view(self):
|
||||
test_html = self.marionette.absolute_url("element_outside_viewport.html")
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
from marionette_driver.by import By
|
||||
from marionette_driver.keys import Keys
|
||||
|
||||
from marionette_harness import MarionetteTestCase
|
||||
from marionette_harness import MarionetteTestCase, skip_if_mobile
|
||||
|
||||
|
||||
class TestText(MarionetteTestCase):
|
||||
@ -53,7 +53,7 @@ class TestText(MarionetteTestCase):
|
||||
key_reporter.send_keys("a")
|
||||
|
||||
result = self.marionette.find_element(By.ID, "result")
|
||||
self.assertTrue("press:" in result.text)
|
||||
self.assertIn("press:", result.text)
|
||||
|
||||
def test_should_fire_key_down_events(self):
|
||||
test_html = self.marionette.absolute_url("javascriptPage.html")
|
||||
@ -62,7 +62,7 @@ class TestText(MarionetteTestCase):
|
||||
key_reporter.send_keys("a")
|
||||
|
||||
result = self.marionette.find_element(By.ID, "result")
|
||||
self.assertTrue("down:" in result.text)
|
||||
self.assertIn("down:", result.text)
|
||||
|
||||
def test_should_fire_key_up_events(self):
|
||||
test_html = self.marionette.absolute_url("javascriptPage.html")
|
||||
@ -71,7 +71,7 @@ class TestText(MarionetteTestCase):
|
||||
key_reporter.send_keys("a")
|
||||
|
||||
result = self.marionette.find_element(By.ID, "result")
|
||||
self.assertTrue("up:" in result.text)
|
||||
self.assertIn("up:", result.text)
|
||||
|
||||
def test_should_type_lowercase_characters(self):
|
||||
test_html = self.marionette.absolute_url("javascriptPage.html")
|
||||
@ -183,26 +183,27 @@ class TestText(MarionetteTestCase):
|
||||
# filled, we're a letter short here
|
||||
self.assertEqual(result.text, "I like chees")
|
||||
|
||||
@skip_if_mobile("Bug 1333069 - Assertion: 'down: 40' not found in u''")
|
||||
def test_should_report_key_code_of_arrow_keys_up_down_events(self):
|
||||
test_html = self.marionette.absolute_url("javascriptPage.html")
|
||||
self.marionette.navigate(test_html)
|
||||
result = self.marionette.find_element(By.ID, "result")
|
||||
element = self.marionette.find_element(By.ID, "keyReporter")
|
||||
element.send_keys(Keys.ARROW_DOWN)
|
||||
self.assertTrue("down: 40" in result.text.strip())
|
||||
self.assertTrue("up: 40" in result.text.strip())
|
||||
self.assertIn("down: 40", result.text.strip())
|
||||
self.assertIn("up: 40", result.text.strip())
|
||||
|
||||
element.send_keys(Keys.ARROW_UP)
|
||||
self.assertTrue("down: 38" in result.text.strip())
|
||||
self.assertTrue("up: 38" in result.text.strip())
|
||||
self.assertIn("down: 38", result.text.strip())
|
||||
self.assertIn("up: 38", result.text.strip())
|
||||
|
||||
element.send_keys(Keys.ARROW_LEFT)
|
||||
self.assertTrue("down: 37" in result.text.strip())
|
||||
self.assertTrue("up: 37" in result.text.strip())
|
||||
self.assertIn("down: 37", result.text.strip())
|
||||
self.assertIn("up: 37", result.text.strip())
|
||||
|
||||
element.send_keys(Keys.ARROW_RIGHT)
|
||||
self.assertTrue("down: 39" in result.text.strip())
|
||||
self.assertTrue("up: 39" in result.text.strip())
|
||||
self.assertIn("down: 39", result.text.strip())
|
||||
self.assertIn("up: 39", result.text.strip())
|
||||
|
||||
# And leave no rubbish/printable keys in the "keyReporter"
|
||||
self.assertEqual("", element.get_property("value"))
|
||||
|
@ -322,6 +322,7 @@ def killPid(pid, log):
|
||||
except Exception as e:
|
||||
log.info("Failed to kill process %d: %s" % (pid, str(e)))
|
||||
|
||||
|
||||
if mozinfo.isWin:
|
||||
import ctypes.wintypes
|
||||
|
||||
@ -825,7 +826,6 @@ class MochitestDesktop(object):
|
||||
self.result = {}
|
||||
|
||||
self.start_script = os.path.join(here, 'start_desktop.js')
|
||||
self.disable_leak_checking = False
|
||||
|
||||
def update_mozinfo(self):
|
||||
"""walk up directories to find mozinfo.json update the info"""
|
||||
@ -1508,8 +1508,7 @@ toolbar#nav-bar {
|
||||
self.log.error(str(e))
|
||||
return None
|
||||
|
||||
if not self.disable_leak_checking:
|
||||
browserEnv["XPCOM_MEM_BLOAT_LOG"] = self.leak_report_file
|
||||
browserEnv["XPCOM_MEM_BLOAT_LOG"] = self.leak_report_file
|
||||
|
||||
try:
|
||||
gmp_path = self.getGMPPluginPath(options)
|
||||
@ -1952,13 +1951,12 @@ toolbar#nav-bar {
|
||||
args.append('-foreground')
|
||||
self.start_script_kwargs['testUrl'] = testUrl or 'about:blank'
|
||||
|
||||
if detectShutdownLeaks and not self.disable_leak_checking:
|
||||
if detectShutdownLeaks:
|
||||
shutdownLeaks = ShutdownLeaks(self.log)
|
||||
else:
|
||||
shutdownLeaks = None
|
||||
|
||||
if mozinfo.info["asan"] and (mozinfo.isLinux or mozinfo.isMac) \
|
||||
and not self.disable_leak_checking:
|
||||
if mozinfo.info["asan"] and (mozinfo.isLinux or mozinfo.isMac):
|
||||
lsanLeaks = LSANLeaks(self.log)
|
||||
else:
|
||||
lsanLeaks = None
|
||||
@ -2230,28 +2228,6 @@ toolbar#nav-bar {
|
||||
result = 1 # default value, if no tests are run.
|
||||
for d in dirs:
|
||||
print("dir: %s" % d)
|
||||
|
||||
# BEGIN LEAKCHECK HACK
|
||||
# Leak checking was broken in mochitest unnoticed for a length of time. During
|
||||
# this time, several leaks slipped through. The leak checking was fixed by bug
|
||||
# 1325148, but it couldn't land until all the regressions were also fixed or
|
||||
# backed out. Rather than waiting and risking new regressions, in the meantime
|
||||
# this code will selectively disable leak checking on flavors/directories where
|
||||
# known regressions exist. At least this way we can prevent further damage while
|
||||
# they get fixed.
|
||||
|
||||
skip_leak_conditions = []
|
||||
|
||||
for condition, reason in skip_leak_conditions:
|
||||
if condition:
|
||||
self.log.warning('WARNING | disabling leakcheck due to {}'.format(reason))
|
||||
self.disable_leak_checking = True
|
||||
break
|
||||
else:
|
||||
self.disable_leak_checking = False
|
||||
|
||||
# END LEAKCHECK HACK
|
||||
|
||||
tests_in_dir = [t for t in testsToRun if os.path.dirname(t) == d]
|
||||
|
||||
# If we are using --run-by-dir, we should not use the profile path (if) provided
|
||||
@ -2358,6 +2334,7 @@ toolbar#nav-bar {
|
||||
self.browserEnv["MOZ_LOG_FILE"] = "{}/moz-pid=%PID-uid={}.log".format(
|
||||
self.browserEnv["MOZ_UPLOAD_DIR"], str(uuid.uuid4()))
|
||||
|
||||
status = 0
|
||||
try:
|
||||
self.startServers(options, debuggerInfo)
|
||||
|
||||
@ -2417,23 +2394,25 @@ toolbar#nav-bar {
|
||||
|
||||
self.log.info("runtests.py | Running with e10s: {}".format(options.e10s))
|
||||
self.log.info("runtests.py | Running tests: start.\n")
|
||||
status = self.runApp(testURL,
|
||||
self.browserEnv,
|
||||
options.app,
|
||||
profile=self.profile,
|
||||
extraArgs=options.browserArgs,
|
||||
utilityPath=options.utilityPath,
|
||||
debuggerInfo=debuggerInfo,
|
||||
valgrindPath=valgrindPath,
|
||||
valgrindArgs=valgrindArgs,
|
||||
valgrindSuppFiles=valgrindSuppFiles,
|
||||
symbolsPath=options.symbolsPath,
|
||||
timeout=timeout,
|
||||
detectShutdownLeaks=detectShutdownLeaks,
|
||||
screenshotOnFail=options.screenshotOnFail,
|
||||
bisectChunk=options.bisectChunk,
|
||||
marionette_args=marionette_args,
|
||||
)
|
||||
ret = self.runApp(
|
||||
testURL,
|
||||
self.browserEnv,
|
||||
options.app,
|
||||
profile=self.profile,
|
||||
extraArgs=options.browserArgs,
|
||||
utilityPath=options.utilityPath,
|
||||
debuggerInfo=debuggerInfo,
|
||||
valgrindPath=valgrindPath,
|
||||
valgrindArgs=valgrindArgs,
|
||||
valgrindSuppFiles=valgrindSuppFiles,
|
||||
symbolsPath=options.symbolsPath,
|
||||
timeout=timeout,
|
||||
detectShutdownLeaks=detectShutdownLeaks,
|
||||
screenshotOnFail=options.screenshotOnFail,
|
||||
bisectChunk=options.bisectChunk,
|
||||
marionette_args=marionette_args,
|
||||
)
|
||||
status = ret or status
|
||||
except KeyboardInterrupt:
|
||||
self.log.info("runtests.py | Received keyboard interrupt.\n")
|
||||
status = -1
|
||||
@ -2735,5 +2714,6 @@ def cli(args=sys.argv[1:]):
|
||||
|
||||
return run_test_harness(parser, options)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(cli())
|
||||
|
@ -15,7 +15,9 @@ import contextlib
|
||||
import errno
|
||||
import functools
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import time
|
||||
|
||||
from mercurial.i18n import _
|
||||
from mercurial.node import hex
|
||||
@ -30,7 +32,7 @@ from mercurial import (
|
||||
util,
|
||||
)
|
||||
|
||||
testedwith = '3.6 3.7 3.8 3.9'
|
||||
testedwith = '3.7 3.8 3.9 4.0'
|
||||
minimumhgversion = '3.7'
|
||||
|
||||
cmdtable = {}
|
||||
@ -116,11 +118,13 @@ def purgewrapper(orig, ui, *args, **kwargs):
|
||||
('b', 'branch', '', 'Branch to check out'),
|
||||
('', 'purge', False, 'Whether to purge the working directory'),
|
||||
('', 'sharebase', '', 'Directory where shared repos should be placed'),
|
||||
('', 'networkattempts', 3, 'Maximum number of attempts for network '
|
||||
'operations'),
|
||||
],
|
||||
'[OPTION]... URL DEST',
|
||||
norepo=True)
|
||||
def robustcheckout(ui, url, dest, upstream=None, revision=None, branch=None,
|
||||
purge=False, sharebase=None):
|
||||
purge=False, sharebase=None, networkattempts=None):
|
||||
"""Ensure a working copy has the specified revision checked out."""
|
||||
if not revision and not branch:
|
||||
raise error.Abort('must specify one of --revision or --branch')
|
||||
@ -156,12 +160,16 @@ def robustcheckout(ui, url, dest, upstream=None, revision=None, branch=None,
|
||||
sharebase = os.path.realpath(sharebase)
|
||||
|
||||
return _docheckout(ui, url, dest, upstream, revision, branch, purge,
|
||||
sharebase)
|
||||
sharebase, networkattempts)
|
||||
|
||||
def _docheckout(ui, url, dest, upstream, revision, branch, purge, sharebase,
|
||||
networkattemptlimit, networkattempts=None):
|
||||
if not networkattempts:
|
||||
networkattempts = [1]
|
||||
|
||||
def _docheckout(ui, url, dest, upstream, revision, branch, purge, sharebase):
|
||||
def callself():
|
||||
return _docheckout(ui, url, dest, upstream, revision, branch, purge,
|
||||
sharebase)
|
||||
sharebase, networkattemptlimit, networkattempts)
|
||||
|
||||
ui.write('ensuring %s@%s is available at %s\n' % (url, revision or branch,
|
||||
dest))
|
||||
@ -217,6 +225,45 @@ def _docheckout(ui, url, dest, upstream, revision, branch, purge, sharebase):
|
||||
|
||||
# At this point we either have an existing working directory using
|
||||
# shared, pooled storage or we have nothing.
|
||||
|
||||
def handlepullabort(e):
|
||||
"""Handle an error.Abort raised during a pull.
|
||||
|
||||
Returns True if caller should call ``callself()`` to retry.
|
||||
"""
|
||||
if e.args[0] == _('repository is unrelated'):
|
||||
ui.warn('(repository is unrelated; deleting)\n')
|
||||
destvfs.rmtree(forcibly=True)
|
||||
return True
|
||||
elif e.args[0].startswith(_('stream ended unexpectedly')):
|
||||
ui.warn('%s\n' % e.args[0])
|
||||
if networkattempts[0] < networkattemptlimit:
|
||||
ui.warn('(retrying after network failure on attempt %d of %d)\n' %
|
||||
(networkattempts[0], networkattemptlimit))
|
||||
|
||||
# Do a backoff on retries to mitigate the thundering herd
|
||||
# problem. This is an exponential backoff with a multipler
|
||||
# plus random jitter thrown in for good measure.
|
||||
# With the default settings, backoffs will be:
|
||||
# 1) 2.5 - 6.5
|
||||
# 2) 5.5 - 9.5
|
||||
# 3) 11.5 - 15.5
|
||||
backoff = (2 ** networkattempts[0] - 1) * 1.5
|
||||
jittermin = ui.configint('robustcheckout', 'retryjittermin', 1000)
|
||||
jittermax = ui.configint('robustcheckout', 'retryjittermax', 5000)
|
||||
backoff += float(random.randint(jittermin, jittermax)) / 1000.0
|
||||
ui.warn('(waiting %.2fs before retry)\n' % backoff)
|
||||
time.sleep(backoff)
|
||||
|
||||
networkattempts[0] += 1
|
||||
|
||||
return True
|
||||
else:
|
||||
raise error.Abort('reached maximum number of network attempts; '
|
||||
'giving up\n')
|
||||
|
||||
return False
|
||||
|
||||
created = False
|
||||
|
||||
if not destvfs.exists():
|
||||
@ -237,6 +284,10 @@ def _docheckout(ui, url, dest, upstream, revision, branch, purge, sharebase):
|
||||
try:
|
||||
res = hg.clone(ui, {}, cloneurl, dest=dest, update=False,
|
||||
shareopts={'pool': sharebase, 'mode': 'identity'})
|
||||
except error.Abort as e:
|
||||
if handlepullabort(e):
|
||||
return callself()
|
||||
raise
|
||||
except error.RepoError as e:
|
||||
return handlerepoerror(e)
|
||||
except error.RevlogError as e:
|
||||
@ -293,11 +344,8 @@ def _docheckout(ui, url, dest, upstream, revision, branch, purge, sharebase):
|
||||
if not pullop.rheads:
|
||||
raise error.Abort('unable to pull requested revision')
|
||||
except error.Abort as e:
|
||||
if e.message == _('repository is unrelated'):
|
||||
ui.warn('(repository is unrelated; deleting)\n')
|
||||
destvfs.rmtree(forcibly=True)
|
||||
if handlepullabort(e):
|
||||
return callself()
|
||||
|
||||
raise
|
||||
except error.RepoError as e:
|
||||
return handlerepoerror(e)
|
||||
|
@ -1013,7 +1013,7 @@ LoginManagerPrompter.prototype = {
|
||||
timeout: Date.now() + 10000,
|
||||
persistWhileVisible: true,
|
||||
passwordNotificationType: type,
|
||||
hideClose: true,
|
||||
hideClose: !Services.prefs.getBoolPref("privacy.permissionPrompts.showCloseButton"),
|
||||
eventCallback(topic) {
|
||||
switch (topic) {
|
||||
case "showing":
|
||||
|
@ -468,35 +468,33 @@ Classifier::Check(const nsACString& aSpec,
|
||||
|
||||
for (uint32_t i = 0; i < cacheArray.Length(); i++) {
|
||||
LookupCache *cache = cacheArray[i];
|
||||
bool has, complete;
|
||||
bool has, fromCache;
|
||||
uint32_t matchLength;
|
||||
|
||||
rv = cache->Has(lookupHash, &has, &complete, &matchLength);
|
||||
rv = cache->Has(lookupHash, &has, &matchLength, &fromCache);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (has) {
|
||||
LookupResult *result = aResults.AppendElement();
|
||||
if (!result)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
int64_t age;
|
||||
bool found = mTableFreshness.Get(cache->TableName(), &age);
|
||||
if (!found) {
|
||||
age = 24 * 60 * 60; // just a large number
|
||||
} else {
|
||||
int64_t now = (PR_Now() / PR_USEC_PER_SEC);
|
||||
age = now - age;
|
||||
// For V2, there is no TTL for caching, so we use table freshness to
|
||||
// decide if matching a completion should trigger a gethash request or not.
|
||||
// For V4, this is done by Positive Caching & Negative Caching mechanism.
|
||||
bool confirmed = false;
|
||||
if (fromCache) {
|
||||
cache->IsHashEntryConfirmed(lookupHash, mTableFreshness,
|
||||
aFreshnessGuarantee, &confirmed);
|
||||
}
|
||||
|
||||
LOG(("Found a result in %s: %s (Age: %Lds)",
|
||||
LOG(("Found a result in %s: %s",
|
||||
cache->TableName().get(),
|
||||
complete ? "complete." : "Not complete.",
|
||||
age));
|
||||
confirmed ? "confirmed." : "Not confirmed."));
|
||||
|
||||
result->hash.complete = lookupHash;
|
||||
result->mComplete = complete;
|
||||
result->mFresh = (age < aFreshnessGuarantee);
|
||||
result->mConfirmed = confirmed;
|
||||
result->mTableName.Assign(cache->TableName());
|
||||
result->mPartialHashLength = matchLength;
|
||||
result->mPartialHashLength = confirmed ? COMPLETE_SIZE : matchLength;
|
||||
|
||||
if (LookupCache::Cast<LookupCacheV4>(cache)) {
|
||||
matchingStatistics |= PrefixMatch::eMatchV4Prefix;
|
||||
|
@ -158,7 +158,7 @@ private:
|
||||
nsTArray<nsCString> mActiveTablesCache;
|
||||
uint32_t mHashKey;
|
||||
// Stores the last time a given table was updated (seconds).
|
||||
nsDataHashtable<nsCStringHashKey, int64_t> mTableFreshness;
|
||||
TableFreshnessMap mTableFreshness;
|
||||
|
||||
// In-memory cache for the result of TableRequest. See
|
||||
// nsIUrlClassifierDBService.getTables for the format.
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsDataHashtable.h"
|
||||
|
||||
#if DEBUG
|
||||
#include "plbase64.h"
|
||||
@ -316,6 +317,8 @@ WriteTArray(nsIOutputStream* aStream, nsTArray_Impl<T, Alloc>& aArray)
|
||||
|
||||
typedef nsClassHashtable<nsUint32HashKey, nsCString> PrefixStringMap;
|
||||
|
||||
typedef nsDataHashtable<nsCStringHashKey, int64_t> TableFreshnessMap;
|
||||
|
||||
} // namespace safebrowsing
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -421,10 +421,10 @@ LookupCacheV2::ClearAll()
|
||||
|
||||
nsresult
|
||||
LookupCacheV2::Has(const Completion& aCompletion,
|
||||
bool* aHas, bool* aComplete,
|
||||
uint32_t* aMatchLength)
|
||||
bool* aHas, uint32_t* aMatchLength,
|
||||
bool* aFromCache)
|
||||
{
|
||||
*aHas = *aComplete = false;
|
||||
*aHas = *aFromCache = false;
|
||||
*aMatchLength = 0;
|
||||
|
||||
uint32_t prefix = aCompletion.ToUint32();
|
||||
@ -443,7 +443,7 @@ LookupCacheV2::Has(const Completion& aCompletion,
|
||||
if ((mGetHashCache.BinaryIndexOf(aCompletion) != nsTArray<Completion>::NoIndex) ||
|
||||
(mUpdateCompletions.BinaryIndexOf(aCompletion) != nsTArray<Completion>::NoIndex)) {
|
||||
LOG(("Complete in %s", mTableName.get()));
|
||||
*aComplete = true;
|
||||
*aFromCache = true;
|
||||
*aHas = true;
|
||||
*aMatchLength = COMPLETE_SIZE;
|
||||
}
|
||||
@ -451,6 +451,25 @@ LookupCacheV2::Has(const Completion& aCompletion,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
LookupCacheV2::IsHashEntryConfirmed(const Completion& aEntry,
|
||||
const TableFreshnessMap& aTableFreshness,
|
||||
uint32_t aFreshnessGuarantee,
|
||||
bool* aConfirmed)
|
||||
{
|
||||
int64_t age; // in seconds
|
||||
bool found = aTableFreshness.Get(mTableName, &age);
|
||||
if (!found) {
|
||||
*aConfirmed = false;
|
||||
} else {
|
||||
int64_t now = (PR_Now() / PR_USEC_PER_SEC);
|
||||
MOZ_ASSERT(age <= now);
|
||||
|
||||
// Considered completion as unsafe if its table is up-to-date.
|
||||
*aConfirmed = (now - age) < aFreshnessGuarantee;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
LookupCacheV2::Build(AddPrefixArray& aAddPrefixes,
|
||||
AddCompleteArray& aAddCompletes)
|
||||
|
@ -25,9 +25,8 @@ namespace safebrowsing {
|
||||
|
||||
class LookupResult {
|
||||
public:
|
||||
LookupResult() : mComplete(false), mNoise(false),
|
||||
mFresh(false), mProtocolConfirmed(false),
|
||||
mPartialHashLength(0) {}
|
||||
LookupResult() : mNoise(false), mProtocolConfirmed(false),
|
||||
mPartialHashLength(0), mConfirmed(false) {}
|
||||
|
||||
// The fragment that matched in the LookupCache
|
||||
union {
|
||||
@ -53,11 +52,10 @@ public:
|
||||
return hex;
|
||||
}
|
||||
|
||||
bool Confirmed() const { return (mComplete && mFresh) || mProtocolConfirmed; }
|
||||
bool Complete() const { return mComplete; }
|
||||
bool Confirmed() const { return mConfirmed || mProtocolConfirmed; }
|
||||
|
||||
// True if we have a complete match for this hash in the table.
|
||||
bool mComplete;
|
||||
bool Complete() const { return mPartialHashLength == COMPLETE_SIZE; }
|
||||
|
||||
// True if this is a noise entry, i.e. an extra entry
|
||||
// that is inserted to mask the true URL we are requesting.
|
||||
@ -66,14 +64,14 @@ public:
|
||||
// don't know the corresponding full URL.
|
||||
bool mNoise;
|
||||
|
||||
// True if we've updated this table recently-enough.
|
||||
bool mFresh;
|
||||
|
||||
bool mProtocolConfirmed;
|
||||
|
||||
nsCString mTableName;
|
||||
|
||||
uint32_t mPartialHashLength;
|
||||
|
||||
// True as long as this lookup is complete and hasn't expired.
|
||||
bool mConfirmed;
|
||||
};
|
||||
|
||||
typedef nsTArray<LookupResult> LookupResultArray;
|
||||
@ -139,8 +137,13 @@ public:
|
||||
virtual nsresult Init() = 0;
|
||||
virtual nsresult ClearPrefixes() = 0;
|
||||
virtual nsresult Has(const Completion& aCompletion,
|
||||
bool* aHas, bool* aComplete,
|
||||
uint32_t* aMatchLength) = 0;
|
||||
bool* aHas, uint32_t* aMatchLength,
|
||||
bool* aFromCache) = 0;
|
||||
|
||||
virtual void IsHashEntryConfirmed(const Completion& aEntry,
|
||||
const TableFreshnessMap& aTableFreshness,
|
||||
uint32_t aFreshnessGuarantee,
|
||||
bool* aConfirmed) = 0;
|
||||
|
||||
virtual void ClearAll();
|
||||
|
||||
@ -186,8 +189,13 @@ public:
|
||||
virtual nsresult Open() override;
|
||||
virtual void ClearAll() override;
|
||||
virtual nsresult Has(const Completion& aCompletion,
|
||||
bool* aHas, bool* aComplete,
|
||||
uint32_t* aMatchLength) override;
|
||||
bool* aHas, uint32_t* aMatchLength,
|
||||
bool* aFromCache) override;
|
||||
|
||||
virtual void IsHashEntryConfirmed(const Completion& aEntry,
|
||||
const TableFreshnessMap& aTableFreshness,
|
||||
uint32_t aFreshnessGuarantee,
|
||||
bool* aConfirmed) override;
|
||||
|
||||
nsresult Build(AddPrefixArray& aAddPrefixes,
|
||||
AddCompleteArray& aAddCompletes);
|
||||
|
@ -80,10 +80,10 @@ LookupCacheV4::Init()
|
||||
|
||||
nsresult
|
||||
LookupCacheV4::Has(const Completion& aCompletion,
|
||||
bool* aHas, bool* aComplete,
|
||||
uint32_t* aMatchLength)
|
||||
bool* aHas, uint32_t* aMatchLength,
|
||||
bool* aFromCache)
|
||||
{
|
||||
*aHas = *aComplete = false;
|
||||
*aHas = *aFromCache = false;
|
||||
*aMatchLength = 0;
|
||||
|
||||
uint32_t length = 0;
|
||||
@ -94,18 +94,29 @@ LookupCacheV4::Has(const Completion& aCompletion,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*aHas = length >= PREFIX_SIZE;
|
||||
*aComplete = length == COMPLETE_SIZE;
|
||||
*aMatchLength = length;
|
||||
|
||||
if (LOG_ENABLED()) {
|
||||
uint32_t prefix = aCompletion.ToUint32();
|
||||
LOG(("Probe in V4 %s: %X, found %d, complete %d", mTableName.get(),
|
||||
prefix, *aHas, *aComplete));
|
||||
prefix, *aHas, length == COMPLETE_SIZE));
|
||||
}
|
||||
|
||||
// TODO : Bug 1311935 - Implement v4 caching
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
LookupCacheV4::IsHashEntryConfirmed(const Completion& aEntry,
|
||||
const TableFreshnessMap& aTableFreshness,
|
||||
uint32_t aFreshnessGuarantee,
|
||||
bool* aConfirmed)
|
||||
{
|
||||
// TODO : Bug 1311935 - Implement v4 caching
|
||||
*aConfirmed = true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
LookupCacheV4::Build(PrefixStringMap& aPrefixMap)
|
||||
{
|
||||
|
@ -25,8 +25,13 @@ public:
|
||||
|
||||
virtual nsresult Init() override;
|
||||
virtual nsresult Has(const Completion& aCompletion,
|
||||
bool* aHas, bool* aComplete,
|
||||
uint32_t* aMatchLength) override;
|
||||
bool* aHas, uint32_t* aMatchLength,
|
||||
bool* aFromCache) override;
|
||||
|
||||
virtual void IsHashEntryConfirmed(const Completion& aEntry,
|
||||
const TableFreshnessMap& aTableFreshness,
|
||||
uint32_t aFreshnessGuarantee,
|
||||
bool* aConfirmed) override;
|
||||
|
||||
nsresult Build(PrefixStringMap& aPrefixMap);
|
||||
|
||||
|
@ -1012,10 +1012,9 @@ nsUrlClassifierLookupCallback::LookupComplete(nsTArray<LookupResult>* results)
|
||||
}
|
||||
} else {
|
||||
// For tables with no hash completer, a complete hash match is
|
||||
// good enough, we'll consider it fresh, even if it hasn't been updated
|
||||
// in 45 minutes.
|
||||
// good enough, we'll consider it is valid.
|
||||
if (result.Complete()) {
|
||||
result.mFresh = true;
|
||||
result.mConfirmed = true;
|
||||
LOG(("Skipping completion in a table without a valid completer (%s).",
|
||||
result.mTableName.get()));
|
||||
} else {
|
||||
|
@ -60,13 +60,13 @@ TestHasPrefix(const _Fragment& aFragment, bool aExpectedHas, bool aExpectedCompl
|
||||
nsCOMPtr<nsICryptoHash> cryptoHash = do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID);
|
||||
lookupHash.FromPlaintext(aFragment, cryptoHash);
|
||||
|
||||
bool has, complete;
|
||||
bool has, fromCache;
|
||||
uint32_t matchLength;
|
||||
nsresult rv = cache->Has(lookupHash, &has, &complete, &matchLength);
|
||||
nsresult rv = cache->Has(lookupHash, &has, &matchLength, &fromCache);
|
||||
|
||||
EXPECT_EQ(rv, NS_OK);
|
||||
EXPECT_EQ(has, aExpectedHas);
|
||||
EXPECT_EQ(complete, aExpectedComplete);
|
||||
EXPECT_EQ(matchLength == COMPLETE_SIZE, aExpectedComplete);
|
||||
|
||||
cache->ClearAll();
|
||||
});
|
||||
|
@ -716,7 +716,11 @@ PopupNotifications.prototype = {
|
||||
popupnotification.setAttribute("label", n.message);
|
||||
popupnotification.setAttribute("id", popupnotificationID);
|
||||
popupnotification.setAttribute("popupid", n.id);
|
||||
popupnotification.setAttribute("closebuttoncommand", `PopupNotifications._dismiss(event, ${TELEMETRY_STAT_DISMISSAL_CLOSE_BUTTON});`);
|
||||
if (Services.prefs.getBoolPref("privacy.permissionPrompts.showCloseButton")) {
|
||||
popupnotification.setAttribute("closebuttoncommand", "PopupNotifications._onButtonEvent(event, 'secondarybuttoncommand');");
|
||||
} else {
|
||||
popupnotification.setAttribute("closebuttoncommand", `PopupNotifications._dismiss(event, ${TELEMETRY_STAT_DISMISSAL_CLOSE_BUTTON});`);
|
||||
}
|
||||
if (n.mainAction) {
|
||||
popupnotification.setAttribute("buttonlabel", n.mainAction.label);
|
||||
popupnotification.setAttribute("buttonaccesskey", n.mainAction.accessKey);
|
||||
|
@ -485,11 +485,6 @@ audio > xul|videocontrols {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.controlsSpacer:hover {
|
||||
background-color: rgb(254,255,255);
|
||||
opacity: .4;
|
||||
}
|
||||
|
||||
@media (-moz-windows-default-theme) {
|
||||
.controlsSpacer {
|
||||
background-color: rgba(255,255,255,.4);
|
||||
|
@ -997,7 +997,7 @@ public:
|
||||
return p.forget();
|
||||
}
|
||||
|
||||
void Resolve(typename PromiseType::ResolveValueType aResolveValue,
|
||||
void Resolve(const typename PromiseType::ResolveValueType& aResolveValue,
|
||||
const char* aMethodName)
|
||||
{
|
||||
if (mMonitor) {
|
||||
@ -1007,17 +1007,33 @@ public:
|
||||
mPromise->Resolve(aResolveValue, aMethodName);
|
||||
mPromise = nullptr;
|
||||
}
|
||||
void Resolve(typename PromiseType::ResolveValueType&& aResolveValue,
|
||||
const char* aMethodName)
|
||||
{
|
||||
if (mMonitor) {
|
||||
mMonitor->AssertCurrentThreadOwns();
|
||||
}
|
||||
MOZ_ASSERT(mPromise);
|
||||
mPromise->Resolve(Move(aResolveValue), aMethodName);
|
||||
mPromise = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void ResolveIfExists(typename PromiseType::ResolveValueType aResolveValue,
|
||||
void ResolveIfExists(const typename PromiseType::ResolveValueType& aResolveValue,
|
||||
const char* aMethodName)
|
||||
{
|
||||
if (!IsEmpty()) {
|
||||
Resolve(aResolveValue, aMethodName);
|
||||
}
|
||||
}
|
||||
void ResolveIfExists(typename PromiseType::ResolveValueType&& aResolveValue,
|
||||
const char* aMethodName)
|
||||
{
|
||||
if (!IsEmpty()) {
|
||||
Resolve(Move(aResolveValue), aMethodName);
|
||||
}
|
||||
}
|
||||
|
||||
void Reject(typename PromiseType::RejectValueType aRejectValue,
|
||||
void Reject(const typename PromiseType::RejectValueType& aRejectValue,
|
||||
const char* aMethodName)
|
||||
{
|
||||
if (mMonitor) {
|
||||
@ -1027,15 +1043,31 @@ public:
|
||||
mPromise->Reject(aRejectValue, aMethodName);
|
||||
mPromise = nullptr;
|
||||
}
|
||||
void Reject(typename PromiseType::RejectValueType&& aRejectValue,
|
||||
const char* aMethodName)
|
||||
{
|
||||
if (mMonitor) {
|
||||
mMonitor->AssertCurrentThreadOwns();
|
||||
}
|
||||
MOZ_ASSERT(mPromise);
|
||||
mPromise->Reject(Move(aRejectValue), aMethodName);
|
||||
mPromise = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void RejectIfExists(typename PromiseType::RejectValueType aRejectValue,
|
||||
void RejectIfExists(const typename PromiseType::RejectValueType& aRejectValue,
|
||||
const char* aMethodName)
|
||||
{
|
||||
if (!IsEmpty()) {
|
||||
Reject(aRejectValue, aMethodName);
|
||||
}
|
||||
}
|
||||
void RejectIfExists(typename PromiseType::RejectValueType&& aRejectValue,
|
||||
const char* aMethodName)
|
||||
{
|
||||
if (!IsEmpty()) {
|
||||
Reject(Move(aRejectValue), aMethodName);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Monitor* mMonitor;
|
||||
|
Loading…
Reference in New Issue
Block a user