зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to inbound
This commit is contained in:
Коммит
6cce8278be
|
@ -188,9 +188,6 @@ pref("privacy.item.geolocation", true);
|
|||
pref("privacy.item.siteSettings", true);
|
||||
pref("privacy.item.syncAccount", true);
|
||||
|
||||
// URL to the Learn More link XXX this is the firefox one. Bug 495578 fixes this.
|
||||
pref("browser.geolocation.warning.infoURL", "http://www.mozilla.com/%LOCALE%/firefox/geolocation/");
|
||||
|
||||
// base url for the wifi geolocation network provider
|
||||
pref("geo.wifi.uri", "https://maps.googleapis.com/maps/api/browserlocation/json");
|
||||
|
||||
|
@ -342,7 +339,6 @@ pref("browser.safebrowsing.provider.0.reportMalwareURL", "http://{moz:locale}.ma
|
|||
pref("browser.safebrowsing.provider.0.reportMalwareErrorURL", "http://{moz:locale}.malware-error.mozilla.com/?hl={moz:locale}");
|
||||
|
||||
// FAQ URLs
|
||||
pref("browser.geolocation.warning.infoURL", "http://www.mozilla.com/%LOCALE%/%APP%/geolocation/");
|
||||
|
||||
// Name of the about: page contributed by safebrowsing to handle display of error
|
||||
// pages on phishing/malware hits. (bug 399233)
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e0b7c709ddc21c407ee3360d3203e9eb84535b66"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8d18b1e2fd06c84a879f99f6e8ca1f104eeacb13"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="eda08beb3ba9a159843c70ffde0f9660ec351eb9"/>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e0b7c709ddc21c407ee3360d3203e9eb84535b66"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="8d18b1e2fd06c84a879f99f6e8ca1f104eeacb13"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="96d2d00165f4561fbde62d1062706eab74b3a01f"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="e2f73049f8d52fb06cb9b5d923c1280557aa9238"/>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e0b7c709ddc21c407ee3360d3203e9eb84535b66"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8d18b1e2fd06c84a879f99f6e8ca1f104eeacb13"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="eda08beb3ba9a159843c70ffde0f9660ec351eb9"/>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"revision": "a43f6c119d80637dd3e36975e8f38b7f19b5c95c",
|
||||
"revision": "98abf6bda1c12b45389ec6bc2acd3e3e901e3163",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e0b7c709ddc21c407ee3360d3203e9eb84535b66"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8d18b1e2fd06c84a879f99f6e8ca1f104eeacb13"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e0b7c709ddc21c407ee3360d3203e9eb84535b66"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8d18b1e2fd06c84a879f99f6e8ca1f104eeacb13"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e0b7c709ddc21c407ee3360d3203e9eb84535b66"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8d18b1e2fd06c84a879f99f6e8ca1f104eeacb13"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e0b7c709ddc21c407ee3360d3203e9eb84535b66"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8d18b1e2fd06c84a879f99f6e8ca1f104eeacb13"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e0b7c709ddc21c407ee3360d3203e9eb84535b66"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="8d18b1e2fd06c84a879f99f6e8ca1f104eeacb13"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="96d2d00165f4561fbde62d1062706eab74b3a01f"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="e2f73049f8d52fb06cb9b5d923c1280557aa9238"/>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e0b7c709ddc21c407ee3360d3203e9eb84535b66"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8d18b1e2fd06c84a879f99f6e8ca1f104eeacb13"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
|
||||
|
|
|
@ -999,7 +999,7 @@ let BookmarkingUI = {
|
|||
if (widget.overflowed) {
|
||||
// Don't open a popup in the overflow popup, rather just open the Library.
|
||||
event.preventDefault();
|
||||
widget.node.removeAttribute("noautoclose");
|
||||
widget.node.removeAttribute("closemenu");
|
||||
PlacesCommandHook.showPlacesOrganizer("BookmarksMenu");
|
||||
return;
|
||||
}
|
||||
|
@ -1172,7 +1172,7 @@ let BookmarkingUI = {
|
|||
let view = document.getElementById("PanelUI-bookmarks");
|
||||
view.addEventListener("ViewShowing", this.onPanelMenuViewShowing);
|
||||
view.addEventListener("ViewHiding", this.onPanelMenuViewHiding);
|
||||
widget.node.setAttribute("noautoclose", "true");
|
||||
widget.node.setAttribute("closemenu", "none");
|
||||
PanelUI.showSubView("PanelUI-bookmarks", widget.node,
|
||||
CustomizableUI.AREA_PANEL);
|
||||
return;
|
||||
|
@ -1181,9 +1181,9 @@ let BookmarkingUI = {
|
|||
// Allow to close the panel if the page is already bookmarked, cause
|
||||
// we are going to open the edit bookmark panel.
|
||||
if (this._itemIds.length > 0)
|
||||
widget.node.removeAttribute("noautoclose");
|
||||
widget.node.removeAttribute("closemenu");
|
||||
else
|
||||
widget.node.setAttribute("noautoclose", "true");
|
||||
widget.node.setAttribute("closemenu", "none");
|
||||
}
|
||||
|
||||
// Ignore clicks on the star if we are updating its state.
|
||||
|
|
|
@ -1171,7 +1171,7 @@ SocialStatus = {
|
|||
if (inMenuPanel) {
|
||||
panel = document.getElementById("PanelUI-socialapi");
|
||||
this._attachNotificatonPanel(panel, aToolbarButton, provider);
|
||||
widget.node.setAttribute("noautoclose", "true");
|
||||
widget.node.setAttribute("closemenu", "none");
|
||||
showingEvent = "ViewShowing";
|
||||
hidingEvent = "ViewHiding";
|
||||
} else {
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
let widget = widgetGroup.forWindow(window);
|
||||
this.inMenuPanel = widgetGroup.areaType == CustomizableUI.TYPE_MENU_PANEL;
|
||||
if (this.inMenuPanel) {
|
||||
widget.node.setAttribute("noautoclose", "true");
|
||||
widget.node.setAttribute("closemenu", "none");
|
||||
return document.getElementById("PanelUI-socialapi");
|
||||
}
|
||||
return document.getAnonymousElementByAttribute(this, "anonid", "panel");
|
||||
|
|
|
@ -7,8 +7,17 @@
|
|||
<label id="customization-header">
|
||||
&customizeMode.menuAndToolbars.header;
|
||||
</label>
|
||||
<hbox id="customization-empty" hidden="true">
|
||||
<label>&customizeMode.menuAndToolbars.empty;</label>
|
||||
<label onclick="BrowserOpenAddonsMgr('addons://discovery/');"
|
||||
onkeypress="BrowserOpenAddonsMgr('addons://discovery/');"
|
||||
id="customization-more-tools"
|
||||
class="text-link">
|
||||
&customizeMode.menuAndToolbars.emptyLink;
|
||||
</label>
|
||||
</hbox>
|
||||
<vbox id="customization-palette" flex="1"/>
|
||||
<spacer flex="1"/>
|
||||
<spacer id="customization-spacer" flex="1"/>
|
||||
<hbox>
|
||||
<button id="customization-toolbar-visibility-button" label="&customizeMode.toolbars;" class="customizationmode-button" type="menu">
|
||||
<menupopup id="customization-toolbar-menu" onpopupshowing="onViewToolbarsPopupShowing(event)"/>
|
||||
|
|
|
@ -330,9 +330,15 @@ const PanelUI = {
|
|||
* so that the panel knows if and when to close itself.
|
||||
*/
|
||||
onCommandHandler: function(aEvent) {
|
||||
if (!aEvent.originalTarget.hasAttribute("noautoclose")) {
|
||||
PanelUI.hide();
|
||||
let closemenu = aEvent.originalTarget.getAttribute("closemenu");
|
||||
if (closemenu == "none") {
|
||||
return;
|
||||
}
|
||||
if (closemenu == "single") {
|
||||
this.showMainView();
|
||||
return;
|
||||
}
|
||||
this.hide();
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -1230,7 +1230,8 @@ let CustomizableUIInternal = {
|
|||
}
|
||||
// If the user hit enter/return, we don't check preventDefault - it makes sense
|
||||
// that this was prevented, but we probably still want to close the panel.
|
||||
// If consumers don't want this to happen, they should specify noautoclose.
|
||||
// If consumers don't want this to happen, they should specify the closemenu
|
||||
// attribute.
|
||||
|
||||
} else if (aEvent.type != "command") { // mouse events:
|
||||
if (aEvent.defaultPrevented || aEvent.button != 0) {
|
||||
|
@ -1243,7 +1244,7 @@ let CustomizableUIInternal = {
|
|||
}
|
||||
}
|
||||
|
||||
if (aEvent.target.getAttribute("noautoclose") == "true" ||
|
||||
if (aEvent.target.getAttribute("closemenu") == "none" ||
|
||||
aEvent.target.getAttribute("widget-type") == "view") {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -44,12 +44,12 @@ function setAttributes(aNode, aAttrs) {
|
|||
}
|
||||
}
|
||||
|
||||
function updateCombinedWidgetStyle(aNode, aArea, aModifyAutoclose) {
|
||||
function updateCombinedWidgetStyle(aNode, aArea, aModifyCloseMenu) {
|
||||
let inPanel = (aArea == CustomizableUI.AREA_PANEL);
|
||||
let cls = inPanel ? "panel-combined-button" : "toolbarbutton-1";
|
||||
let attrs = {class: cls};
|
||||
if (aModifyAutoclose) {
|
||||
attrs.noautoclose = inPanel ? true : null;
|
||||
if (aModifyCloseMenu) {
|
||||
attrs.closemenu = inPanel ? "none" : null;
|
||||
}
|
||||
for (let i = 0, l = aNode.childNodes.length; i < l; ++i) {
|
||||
if (aNode.childNodes[i].localName == "separator")
|
||||
|
@ -311,7 +311,7 @@ const CustomizableWidgets = [{
|
|||
let areaType = CustomizableUI.getAreaType(this.currentArea);
|
||||
let inPanel = areaType == CustomizableUI.TYPE_MENU_PANEL;
|
||||
let inToolbar = areaType == CustomizableUI.TYPE_TOOLBAR;
|
||||
let noautoclose = inPanel ? "true" : null;
|
||||
let closeMenu = inPanel ? "none" : null;
|
||||
let cls = inPanel ? "panel-combined-button" : "toolbarbutton-1";
|
||||
|
||||
if (!this.currentArea)
|
||||
|
@ -319,20 +319,20 @@ const CustomizableWidgets = [{
|
|||
|
||||
let buttons = [{
|
||||
id: "zoom-out-button",
|
||||
noautoclose: noautoclose,
|
||||
closemenu: closeMenu,
|
||||
command: "cmd_fullZoomReduce",
|
||||
class: cls,
|
||||
label: true,
|
||||
tooltiptext: true
|
||||
}, {
|
||||
id: "zoom-reset-button",
|
||||
noautoclose: noautoclose,
|
||||
closemenu: closeMenu,
|
||||
command: "cmd_fullZoomReset",
|
||||
class: cls,
|
||||
tooltiptext: true
|
||||
}, {
|
||||
id: "zoom-in-button",
|
||||
noautoclose: noautoclose,
|
||||
closemenu: closeMenu,
|
||||
command: "cmd_fullZoomEnlarge",
|
||||
class: cls,
|
||||
label: true,
|
||||
|
|
|
@ -48,6 +48,8 @@ function CustomizeMode(aWindow) {
|
|||
// user. Then there's the visible palette, which gets populated and displayed
|
||||
// to the user when in customizing mode.
|
||||
this.visiblePalette = this.document.getElementById(kPaletteId);
|
||||
this.paletteEmptyNotice = this.document.getElementById("customization-empty");
|
||||
this.paletteSpacer = this.document.getElementById("customization-spacer");
|
||||
};
|
||||
|
||||
CustomizeMode.prototype = {
|
||||
|
@ -228,6 +230,8 @@ CustomizeMode.prototype = {
|
|||
|
||||
// Show the palette now that the transition has finished.
|
||||
this.visiblePalette.hidden = false;
|
||||
this.paletteSpacer.hidden = true;
|
||||
this._updateEmptyPaletteNotice();
|
||||
|
||||
this._handler.isEnteringCustomizeMode = false;
|
||||
this.dispatchToolboxEvent("customizationready");
|
||||
|
@ -273,7 +277,9 @@ CustomizeMode.prototype = {
|
|||
let documentElement = document.documentElement;
|
||||
|
||||
// Hide the palette before starting the transition for increased perf.
|
||||
this.paletteSpacer.hidden = false;
|
||||
this.visiblePalette.hidden = true;
|
||||
this.paletteEmptyNotice.hidden = true;
|
||||
|
||||
this._transitioning = true;
|
||||
|
||||
|
@ -913,9 +919,15 @@ CustomizeMode.prototype = {
|
|||
_onUIChange: function() {
|
||||
this._changed = true;
|
||||
this._updateResetButton();
|
||||
this._updateEmptyPaletteNotice();
|
||||
this.dispatchToolboxEvent("customizationchange");
|
||||
},
|
||||
|
||||
_updateEmptyPaletteNotice: function() {
|
||||
let paletteItems = this.visiblePalette.getElementsByTagName("toolbarpaletteitem");
|
||||
this.paletteEmptyNotice.hidden = !!paletteItems.length;
|
||||
},
|
||||
|
||||
_updateResetButton: function() {
|
||||
let btn = this.document.getElementById("customization-reset-button");
|
||||
btn.disabled = CustomizableUI.inDefaultState;
|
||||
|
|
|
@ -37,6 +37,7 @@ skip-if = true
|
|||
[browser_918049_skipintoolbarset_dnd.js]
|
||||
[browser_923857_customize_mode_event_wrapping_during_reset.js]
|
||||
[browser_927717_customize_drag_empty_toolbar.js]
|
||||
[browser_932928_show_notice_when_palette_empty.js]
|
||||
|
||||
[browser_934113_menubar_removable.js]
|
||||
# Because this test is about the menubar, it can't be run on mac
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// There should be an advert to get more addons when the palette is empty.
|
||||
add_task(function() {
|
||||
yield startCustomizing();
|
||||
let visiblePalette = document.getElementById("customization-palette");
|
||||
let emptyPaletteNotice = document.getElementById("customization-empty");
|
||||
is(emptyPaletteNotice.hidden, true, "The empty palette notice should not be shown when there are items in the palette.");
|
||||
|
||||
while (visiblePalette.childElementCount) {
|
||||
gCustomizeMode.addToToolbar(visiblePalette.children[0]);
|
||||
}
|
||||
is(visiblePalette.childElementCount, 0, "There shouldn't be any items remaining in the visible palette.");
|
||||
is(emptyPaletteNotice.hidden, false, "The empty palette notice should be shown when there are no items in the palette.");
|
||||
|
||||
yield endCustomizing();
|
||||
yield startCustomizing();
|
||||
visiblePalette = document.getElementById("customization-palette");
|
||||
emptyPaletteNotice = document.getElementById("customization-empty");
|
||||
is(emptyPaletteNotice.hidden, false,
|
||||
"The empty palette notice should be shown when there are no items in the palette and cust. mode is re-entered.");
|
||||
|
||||
gCustomizeMode.removeFromArea(document.getElementById("wrapper-home-button"));
|
||||
is(emptyPaletteNotice.hidden, true,
|
||||
"The empty palette notice should not be shown when there is at least one item in the palette.");
|
||||
});
|
||||
|
||||
add_task(function asyncCleanup() {
|
||||
yield endCustomizing();
|
||||
yield resetCustomization();
|
||||
});
|
|
@ -3,6 +3,7 @@
|
|||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* Bug 661762 */
|
||||
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
@ -25,22 +26,15 @@ function test()
|
|||
|
||||
openScratchpad(function () {
|
||||
let sw = gScratchpadWindow;
|
||||
let {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
|
||||
|
||||
openScratchpad(function () {
|
||||
function onWebConsoleOpen(subj) {
|
||||
Services.obs.removeObserver(onWebConsoleOpen,
|
||||
"web-console-created");
|
||||
subj.QueryInterface(Ci.nsISupportsString);
|
||||
|
||||
let hud = HUDService.getHudReferenceById(subj.data);
|
||||
let target = devtools.TargetFactory.forTab(gBrowser.selectedTab);
|
||||
gDevTools.showToolbox(target, "webconsole").then((toolbox) => {
|
||||
let hud = toolbox.getCurrentPanel().hud;
|
||||
hud.jsterm.clearOutput(true);
|
||||
executeSoon(testFocus.bind(null, sw, hud));
|
||||
}
|
||||
|
||||
Services.obs.
|
||||
addObserver(onWebConsoleOpen, "web-console-created", false);
|
||||
|
||||
HUDService.toggleWebConsole();
|
||||
testFocus(sw, hud);
|
||||
});
|
||||
});
|
||||
});
|
||||
}, true);
|
||||
|
|
|
@ -142,24 +142,6 @@ HUD_SERVICE.prototype =
|
|||
return this.consoles.get(aId);
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggle the Web Console for the current tab.
|
||||
*
|
||||
* @return object
|
||||
* A promise for either the opening of the toolbox that holds the Web
|
||||
* Console, or a Promise for the closing of the toolbox.
|
||||
*/
|
||||
toggleWebConsole: function HS_toggleWebConsole()
|
||||
{
|
||||
let window = this.currentContext();
|
||||
let target = devtools.TargetFactory.forTab(window.gBrowser.selectedTab);
|
||||
let toolbox = gDevTools.getToolbox(target);
|
||||
|
||||
return toolbox && toolbox.currentToolId == "webconsole" ?
|
||||
toolbox.destroy() :
|
||||
gDevTools.showToolbox(target, "webconsole");
|
||||
},
|
||||
|
||||
/**
|
||||
* Find if there is a Web Console open for the current tab and return the
|
||||
* instance.
|
||||
|
@ -744,7 +726,7 @@ BrowserConsole.prototype = Heritage.extend(WebConsole.prototype,
|
|||
const HUDService = new HUD_SERVICE();
|
||||
|
||||
(() => {
|
||||
let methods = ["openWebConsole", "openBrowserConsole", "toggleWebConsole",
|
||||
let methods = ["openWebConsole", "openBrowserConsole",
|
||||
"toggleBrowserConsole", "getOpenWebConsole",
|
||||
"getBrowserConsole", "getHudByWindow", "getHudReferenceById"];
|
||||
for (let method of methods) {
|
||||
|
|
|
@ -115,6 +115,7 @@ support-files =
|
|||
[browser_console.js]
|
||||
[browser_console_addonsdk_loader_exception.js]
|
||||
[browser_console_clear_on_reload.js]
|
||||
[browser_console_click_focus.js]
|
||||
[browser_console_consolejsm_output.js]
|
||||
[browser_console_dead_objects.js]
|
||||
[browser_console_error_source_click.js]
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// Tests that the input field is focused when the console is opened.
|
||||
|
||||
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-console.html";
|
||||
|
||||
function test() {
|
||||
addTab(TEST_URI);
|
||||
browser.addEventListener("DOMContentLoaded", testInputFocus, false);
|
||||
}
|
||||
|
||||
function testInputFocus() {
|
||||
browser.removeEventListener("DOMContentLoaded", testInputFocus, false);
|
||||
|
||||
openConsole().then((hud) => {
|
||||
let inputNode = hud.jsterm.inputNode;
|
||||
ok(inputNode.getAttribute("focused"), "input node is focused");
|
||||
|
||||
let lostFocus = () => {
|
||||
inputNode.removeEventListener("blur", lostFocus);
|
||||
info("input node lost focus");
|
||||
}
|
||||
|
||||
inputNode.addEventListener("blur", lostFocus);
|
||||
|
||||
browser.ownerDocument.getElementById("urlbar").click();
|
||||
|
||||
ok(!inputNode.getAttribute("focused"), "input node is not focused");
|
||||
|
||||
hud.outputNode.click();
|
||||
|
||||
ok(inputNode.getAttribute("focused"), "input node is focused");
|
||||
|
||||
finishTest();
|
||||
});
|
||||
}
|
|
@ -569,6 +569,19 @@ WebConsoleFrame.prototype = {
|
|||
toolbox.on("webconsole-selected", this._onPanelSelected);
|
||||
}
|
||||
|
||||
/*
|
||||
* Focus input line whenever the output area is clicked.
|
||||
* Only focus when the target node (or parent, as in source links) is
|
||||
* not an anchor.
|
||||
*/
|
||||
this.outputNode.addEventListener("click", (e) => {
|
||||
if ((e.button == 0) &&
|
||||
(e.target.nodeName.toLowerCase() != "a") &&
|
||||
(e.target.parentNode.nodeName.toLowerCase() != "a")) {
|
||||
this.jsterm.inputNode.focus();
|
||||
}
|
||||
});
|
||||
|
||||
// Toggle the timestamp on preference change
|
||||
gDevTools.on("pref-changed", this._onToolboxPrefChanged);
|
||||
this._onToolboxPrefChanged("pref-changed", {
|
||||
|
|
|
@ -677,6 +677,8 @@ just addresses the organization to follow, e.g. "This site is run by " -->
|
|||
<!ENTITY customizeMode.tabTitle "Customize &brandShortName;">
|
||||
<!ENTITY customizeMode.menuAndToolbars.label "Menu and toolbars">
|
||||
<!ENTITY customizeMode.menuAndToolbars.header "More Tools to Add to the Menu and Toolbar">
|
||||
<!ENTITY customizeMode.menuAndToolbars.empty "Want more tools?">
|
||||
<!ENTITY customizeMode.menuAndToolbars.emptyLink "Choose from thousands of add-ons">
|
||||
<!ENTITY customizeMode.restoreDefaults "Restore Defaults">
|
||||
<!ENTITY customizeMode.toolbars "Show / Hide Toolbars">
|
||||
|
||||
|
|
|
@ -83,19 +83,25 @@ let Util = {
|
|||
aElement instanceof Ci.nsIDOMHTMLTextAreaElement);
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks whether aElement's content can be edited either if it(or any of its
|
||||
* parents) has "contenteditable" attribute set to "true" or aElement's
|
||||
* ownerDocument is in design mode.
|
||||
*/
|
||||
isEditableContent: function isEditableContent(aElement) {
|
||||
if (!aElement)
|
||||
return false;
|
||||
if (aElement.isContentEditable || aElement.designMode == "on")
|
||||
return true;
|
||||
return false;
|
||||
return !!aElement && (aElement.isContentEditable ||
|
||||
this.isOwnerDocumentInDesignMode(aElement));
|
||||
|
||||
},
|
||||
|
||||
isEditable: function isEditable(aElement) {
|
||||
if (!aElement)
|
||||
if (!aElement) {
|
||||
return false;
|
||||
if (this.isTextInput(aElement) || this.isEditableContent(aElement))
|
||||
}
|
||||
|
||||
if (this.isTextInput(aElement) || this.isEditableContent(aElement)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If a body element is editable and the body is the child of an
|
||||
// iframe or div we can assume this is an advanced HTML editor
|
||||
|
@ -106,7 +112,15 @@ let Util = {
|
|||
return true;
|
||||
}
|
||||
|
||||
return aElement.ownerDocument && aElement.ownerDocument.designMode == "on";
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks whether aElement's owner document has design mode turned on.
|
||||
*/
|
||||
isOwnerDocumentInDesignMode: function(aElement) {
|
||||
return !!aElement && !!aElement.ownerDocument &&
|
||||
aElement.ownerDocument.designMode == "on";
|
||||
},
|
||||
|
||||
isMultilineInput: function isMultilineInput(aElement) {
|
||||
|
|
|
@ -105,6 +105,8 @@ var ContextMenuHandler = {
|
|||
if (Util.isTextInput(this._target)) {
|
||||
// select all text in the input control
|
||||
this._target.select();
|
||||
} else if (Util.isEditableContent(this._target)) {
|
||||
this._target.ownerDocument.execCommand("selectAll", false);
|
||||
} else {
|
||||
// select the entire document
|
||||
content.getSelection().selectAllChildren(content.document);
|
||||
|
@ -121,7 +123,7 @@ var ContextMenuHandler = {
|
|||
} else {
|
||||
Util.dumpLn("error: target element does not support nsIDOMNSEditableElement");
|
||||
}
|
||||
} else if (this._target.isContentEditable) {
|
||||
} else if (Util.isEditableContent(this._target)) {
|
||||
try {
|
||||
this._target.ownerDocument.execCommand("paste",
|
||||
false,
|
||||
|
@ -145,7 +147,7 @@ var ContextMenuHandler = {
|
|||
} else {
|
||||
Util.dumpLn("error: target element does not support nsIDOMNSEditableElement");
|
||||
}
|
||||
} else if (this._target.isContentEditable) {
|
||||
} else if (Util.isEditableContent(this._target)) {
|
||||
try {
|
||||
this._target.ownerDocument.execCommand("cut", false);
|
||||
} catch (ex) {
|
||||
|
@ -259,7 +261,9 @@ var ContextMenuHandler = {
|
|||
break;
|
||||
}
|
||||
// is the target contentEditable (not just inheriting contentEditable)
|
||||
else if (elem.contentEditable == "true") {
|
||||
// or the entire document in designer mode.
|
||||
else if (elem.contentEditable == "true" ||
|
||||
Util.isOwnerDocumentInDesignMode(elem)) {
|
||||
this._target = elem;
|
||||
isEditableText = true;
|
||||
isText = true;
|
||||
|
|
|
@ -709,6 +709,84 @@ gTests.push({
|
|||
run: getReopenTest(sendContextMenuClickToElement, sendTap)
|
||||
});
|
||||
|
||||
gTests.push({
|
||||
desc: "Bug 947505 - Right-click in a designMode document should display a " +
|
||||
"context menu",
|
||||
run: function test() {
|
||||
info(chromeRoot + "browser_context_menu_tests_02.html");
|
||||
yield addTab(chromeRoot + "browser_context_menu_tests_02.html");
|
||||
|
||||
purgeEventQueue();
|
||||
emptyClipboard();
|
||||
ContextUI.dismiss();
|
||||
|
||||
yield waitForCondition(() => !ContextUI.navbarVisible);
|
||||
|
||||
let tabWindow = Browser.selectedTab.browser.contentWindow;
|
||||
let testSpan = tabWindow.document.getElementById("text1");
|
||||
|
||||
// Case #1: Document isn't in design mode and nothing is selected.
|
||||
tabWindow.document.designMode = "off";
|
||||
|
||||
// Simulate right mouse click to reproduce the same step as noted in the
|
||||
// appropriate bug. It's valid for non-touch case only.
|
||||
synthesizeNativeMouseRDown(Browser.selectedTab.browser, 10, 10);
|
||||
synthesizeNativeMouseRUp(Browser.selectedTab.browser, 10, 10);
|
||||
|
||||
yield waitForCondition(() => ContextUI.navbarVisible);
|
||||
|
||||
ok(ContextUI.navbarVisible, "Navbar is visible on context menu action.");
|
||||
ok(ContextUI.tabbarVisible, "Tabbar is visible on context menu action.");
|
||||
|
||||
ContextUI.dismiss();
|
||||
yield waitForCondition(() => !ContextUI.navbarVisible);
|
||||
|
||||
// Case #2: Document isn't in design mode and text is selected.
|
||||
tabWindow.getSelection().selectAllChildren(testSpan);
|
||||
|
||||
let promise = waitForEvent(tabWindow.document, "popupshown");
|
||||
sendContextMenuClickToSelection(tabWindow);
|
||||
yield promise;
|
||||
|
||||
checkContextUIMenuItemVisibility(["context-copy", "context-search"]);
|
||||
|
||||
promise = waitForEvent(document, "popuphidden");
|
||||
ContextMenuUI.hide();
|
||||
yield promise;
|
||||
|
||||
// Case #3: Document is in design mode and nothing is selected.
|
||||
tabWindow.document.designMode = "on";
|
||||
tabWindow.getSelection().removeAllRanges();
|
||||
|
||||
promise = waitForEvent(tabWindow.document, "popupshown");
|
||||
sendContextMenuClickToElement(tabWindow, testSpan);
|
||||
yield promise;
|
||||
|
||||
checkContextUIMenuItemVisibility(["context-select-all", "context-select"]);
|
||||
|
||||
promise = waitForEvent(document, "popuphidden");
|
||||
ContextMenuUI.hide();
|
||||
yield promise;
|
||||
|
||||
// Case #4: Document is in design mode and text is selected.
|
||||
tabWindow.getSelection().selectAllChildren(testSpan);
|
||||
|
||||
promise = waitForEvent(tabWindow.document, "popupshown");
|
||||
sendContextMenuClickToSelection(tabWindow);
|
||||
yield promise;
|
||||
|
||||
checkContextUIMenuItemVisibility(["context-cut", "context-copy",
|
||||
"context-select-all", "context-select",
|
||||
"context-search"]);
|
||||
|
||||
promise = waitForEvent(document, "popuphidden");
|
||||
ContextMenuUI.hide();
|
||||
yield promise;
|
||||
|
||||
Browser.closeTab(Browser.selectedTab, { forceClose: true });
|
||||
}
|
||||
});
|
||||
|
||||
function test() {
|
||||
setDevPixelEqualToPx();
|
||||
runTests();
|
||||
|
|
|
@ -3960,7 +3960,7 @@ window > chatbox {
|
|||
|
||||
%include ../shared/customizableui/customizeMode.inc.css
|
||||
|
||||
#main-window[customizing] #titlebar {
|
||||
#main-window[customize-entered] #titlebar {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "CameraControlImpl.h"
|
||||
#include "CameraCommon.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "DeviceStorageFileDescriptor.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -450,12 +451,9 @@ CameraControlImpl::TakePicture(const CameraSize& aSize, int32_t aRotation, const
|
|||
}
|
||||
|
||||
nsresult
|
||||
CameraControlImpl::StartRecording(CameraStartRecordingOptions* aOptions, nsIFile* aFolder, const nsAString& aFilename, nsICameraStartRecordingCallback* onSuccess, nsICameraErrorCallback* onError)
|
||||
CameraControlImpl::StartRecording(CameraStartRecordingOptions* aOptions, DeviceStorageFileDescriptor* aFileDescriptor, nsICameraStartRecordingCallback* onSuccess, nsICameraErrorCallback* onError)
|
||||
{
|
||||
nsCOMPtr<nsIFile> clone;
|
||||
aFolder->Clone(getter_AddRefs(clone));
|
||||
|
||||
nsCOMPtr<nsIRunnable> startRecordingTask = new StartRecordingTask(this, *aOptions, clone, aFilename, onSuccess, onError, mWindowId);
|
||||
nsCOMPtr<nsIRunnable> startRecordingTask = new StartRecordingTask(this, *aOptions, aFileDescriptor, onSuccess, onError, mWindowId);
|
||||
return mCameraThread->Dispatch(startRecordingTask, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,10 @@
|
|||
#include "DOMCameraPreview.h"
|
||||
#include "ICameraControl.h"
|
||||
#include "CameraCommon.h"
|
||||
#include "DeviceStorage.h"
|
||||
#include "DeviceStorageFileDescriptor.h"
|
||||
|
||||
class DeviceStorageFileDescriptor;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -54,7 +58,7 @@ public:
|
|||
void StopPreview();
|
||||
nsresult AutoFocus(nsICameraAutoFocusCallback* onSuccess, nsICameraErrorCallback* onError);
|
||||
nsresult TakePicture(const idl::CameraSize& aSize, int32_t aRotation, const nsAString& aFileFormat, idl::CameraPosition aPosition, uint64_t aDateTime, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError);
|
||||
nsresult StartRecording(idl::CameraStartRecordingOptions* aOptions, nsIFile* aFolder, const nsAString& aFilename, nsICameraStartRecordingCallback* onSuccess, nsICameraErrorCallback* onError);
|
||||
nsresult StartRecording(idl::CameraStartRecordingOptions* aOptions, DeviceStorageFileDescriptor *aDSFileDescriptor, nsICameraStartRecordingCallback* onSuccess, nsICameraErrorCallback* onError);
|
||||
nsresult StopRecording();
|
||||
nsresult GetPreviewStreamVideoMode(idl::CameraRecorderOptions* aOptions, nsICameraPreviewStreamCallback* onSuccess, nsICameraErrorCallback* onError);
|
||||
nsresult ReleaseHardware(nsICameraReleaseCallback* onSuccess, nsICameraErrorCallback* onError);
|
||||
|
@ -452,11 +456,15 @@ protected:
|
|||
class StartRecordingTask : public nsRunnable
|
||||
{
|
||||
public:
|
||||
StartRecordingTask(CameraControlImpl* aCameraControl, idl::CameraStartRecordingOptions aOptions, nsIFile* aFolder, const nsAString& aFilename, nsICameraStartRecordingCallback* onSuccess, nsICameraErrorCallback* onError, uint64_t aWindowId)
|
||||
StartRecordingTask(CameraControlImpl* aCameraControl,
|
||||
idl::CameraStartRecordingOptions aOptions,
|
||||
DeviceStorageFileDescriptor *aDSFileDescriptor,
|
||||
nsICameraStartRecordingCallback* onSuccess,
|
||||
nsICameraErrorCallback* onError,
|
||||
uint64_t aWindowId)
|
||||
: mCameraControl(aCameraControl)
|
||||
, mOptions(aOptions)
|
||||
, mFolder(aFolder)
|
||||
, mFilename(aFilename)
|
||||
, mDSFileDescriptor(aDSFileDescriptor)
|
||||
, mOnSuccessCb(new nsMainThreadPtrHolder<nsICameraStartRecordingCallback>(onSuccess))
|
||||
, mOnErrorCb(new nsMainThreadPtrHolder<nsICameraErrorCallback>(onError))
|
||||
, mWindowId(aWindowId)
|
||||
|
@ -491,8 +499,7 @@ public:
|
|||
|
||||
nsRefPtr<CameraControlImpl> mCameraControl;
|
||||
idl::CameraStartRecordingOptions mOptions;
|
||||
nsCOMPtr<nsIFile> mFolder;
|
||||
nsString mFilename;
|
||||
nsRefPtr<DeviceStorageFileDescriptor> mDSFileDescriptor;
|
||||
nsMainThreadPtrHandle<nsICameraStartRecordingCallback> mOnSuccessCb;
|
||||
nsMainThreadPtrHandle<nsICameraErrorCallback> mOnErrorCb;
|
||||
uint64_t mWindowId;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "nsHashPropertyBag.h"
|
||||
#include "nsThread.h"
|
||||
#include "DeviceStorage.h"
|
||||
#include "DeviceStorageFileDescriptor.h"
|
||||
#include "mozilla/dom/CameraControlBinding.h"
|
||||
#include "mozilla/dom/TabChild.h"
|
||||
#include "mozilla/MediaManager.h"
|
||||
|
@ -349,13 +350,12 @@ nsDOMCameraControl::StartRecording(JSContext* aCx,
|
|||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(onSuccess, "no onSuccess handler passed");
|
||||
mozilla::idl::CameraStartRecordingOptions options;
|
||||
|
||||
// Default values, until the dictionary parser can handle them.
|
||||
options.rotation = 0;
|
||||
options.maxFileSizeBytes = 0;
|
||||
options.maxVideoLengthMs = 0;
|
||||
aRv = options.Init(aCx, aOptions.address());
|
||||
mOptions.rotation = 0;
|
||||
mOptions.maxFileSizeBytes = 0;
|
||||
mOptions.maxVideoLengthMs = 0;
|
||||
aRv = mOptions.Init(aCx, aOptions.address());
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
@ -375,13 +375,53 @@ nsDOMCameraControl::StartRecording(JSContext* aCx,
|
|||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIFile> folder;
|
||||
aRv = storageArea.GetRootDirectoryForFile(filename, getter_AddRefs(folder));
|
||||
nsCOMPtr<nsIDOMDOMRequest> request;
|
||||
mDSFileDescriptor = new DeviceStorageFileDescriptor();
|
||||
aRv = storageArea.CreateFileDescriptor(filename, mDSFileDescriptor.get(),
|
||||
getter_AddRefs(request));
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
}
|
||||
aRv = mCameraControl->StartRecording(&options, folder, filename, onSuccess,
|
||||
onError.WasPassed() ? onError.Value() : nullptr);
|
||||
|
||||
mOnSuccessCb = onSuccess;
|
||||
mOnErrorCb = onError.WasPassed() ? onError.Value() : nullptr;
|
||||
|
||||
request->AddEventListener(NS_LITERAL_STRING("success"), this, false);
|
||||
request->AddEventListener(NS_LITERAL_STRING("error"), this, false);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMCameraControl::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
nsString eventType;
|
||||
aEvent->GetType(eventType);
|
||||
ErrorResult rv;
|
||||
|
||||
if ((eventType.EqualsLiteral("success")) &&
|
||||
mDSFileDescriptor->mFileDescriptor.IsValid()) {
|
||||
|
||||
rv = mCameraControl->StartRecording(&mOptions,
|
||||
mDSFileDescriptor.get(),
|
||||
mOnSuccessCb.get(),
|
||||
mOnErrorCb.get());
|
||||
if (!rv.Failed()) {
|
||||
return rv.ErrorCode();
|
||||
}
|
||||
|
||||
// An error happened. Fall through and call the error callback.
|
||||
}
|
||||
|
||||
// We're already be on the main thread, so go ahead and call the
|
||||
// error callback directly.
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mOnErrorCb &&
|
||||
nsDOMCameraManager::IsWindowStillActive(mWindow->WindowID())) {
|
||||
mOnErrorCb->HandleEvent(NS_LITERAL_STRING("FAILURE"));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "nsCOMPtr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "DictionaryHelpers.h"
|
||||
#include "ICameraControl.h"
|
||||
#include "DOMCameraPreview.h"
|
||||
|
@ -16,6 +17,7 @@
|
|||
#include "AudioChannelAgent.h"
|
||||
#include "nsProxyRelease.h"
|
||||
#include "nsHashPropertyBag.h"
|
||||
#include "DeviceStorage.h"
|
||||
|
||||
class nsDOMDeviceStorage;
|
||||
class nsPIDOMWindow;
|
||||
|
@ -28,11 +30,12 @@ template<typename T> class Optional;
|
|||
class ErrorResult;
|
||||
|
||||
// Main camera control.
|
||||
class nsDOMCameraControl MOZ_FINAL : public nsISupports,
|
||||
class nsDOMCameraControl MOZ_FINAL : public nsIDOMEventListener,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_NSIDOMEVENTLISTENER
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMCameraControl)
|
||||
|
||||
nsDOMCameraControl(uint32_t aCameraId, nsIThread* aCameraThread,
|
||||
|
@ -107,6 +110,11 @@ private:
|
|||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
|
||||
nsresult NotifyRecordingStatusChange(const nsString& aMsg);
|
||||
|
||||
mozilla::idl::CameraStartRecordingOptions mOptions;
|
||||
nsRefPtr<DeviceStorageFileDescriptor> mDSFileDescriptor;
|
||||
nsCOMPtr<nsICameraStartRecordingCallback> mOnSuccessCb;
|
||||
nsCOMPtr<nsICameraErrorCallback> mOnErrorCb;
|
||||
|
||||
protected:
|
||||
/* additional members */
|
||||
nsRefPtr<ICameraControl> mCameraControl; // non-DOM camera control
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "GonkRecorderProfiles.h"
|
||||
#include "GonkCameraControl.h"
|
||||
#include "CameraCommon.h"
|
||||
#include "DeviceStorageFileDescriptor.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -1023,7 +1024,7 @@ nsGonkCameraControl::TakePictureImpl(TakePictureTask* aTakePicture)
|
|||
// is meant to be stored as a local time. Since we are given seconds from
|
||||
// Epoch GMT, we use localtime_r() to handle the conversion.
|
||||
time_t time = aTakePicture->mDateTime;
|
||||
if (time != aTakePicture->mDateTime) {
|
||||
if ((uint64_t)time != aTakePicture->mDateTime) {
|
||||
DOM_CAMERA_LOGE("picture date/time '%llu' is too far in the future\n", aTakePicture->mDateTime);
|
||||
} else {
|
||||
struct tm t;
|
||||
|
@ -1097,42 +1098,24 @@ nsGonkCameraControl::StartRecordingImpl(StartRecordingTask* aStartRecording)
|
|||
* The camera app needs to provide the file extension '.3gp' for now.
|
||||
* See bug 795202.
|
||||
*/
|
||||
nsCOMPtr<nsIFile> filename = aStartRecording->mFolder;
|
||||
filename->AppendRelativePath(aStartRecording->mFilename);
|
||||
|
||||
nsString fullpath;
|
||||
filename->GetPath(fullpath);
|
||||
|
||||
nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(vs, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIVolume> vol;
|
||||
nsresult rv = vs->GetVolumeByPath(fullpath, getter_AddRefs(vol));
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_INVALID_ARG);
|
||||
|
||||
nsString volName;
|
||||
vol->GetName(volName);
|
||||
|
||||
mVideoFile = new DeviceStorageFile(NS_LITERAL_STRING("videos"),
|
||||
volName,
|
||||
aStartRecording->mFilename);
|
||||
|
||||
nsAutoCString nativeFilename;
|
||||
filename->GetNativePath(nativeFilename);
|
||||
DOM_CAMERA_LOGI("Video filename is '%s'\n", nativeFilename.get());
|
||||
nsRefPtr<DeviceStorageFileDescriptor> dsfd = aStartRecording->mDSFileDescriptor;
|
||||
NS_ENSURE_TRUE(dsfd, NS_ERROR_FAILURE);
|
||||
nsAutoString fullPath;
|
||||
mVideoFile = dsfd->mDSFile;
|
||||
mVideoFile->GetFullPath(fullPath);
|
||||
DOM_CAMERA_LOGI("Video filename is '%s'\n",
|
||||
NS_LossyConvertUTF16toASCII(fullPath).get());
|
||||
|
||||
if (!mVideoFile->IsSafePath()) {
|
||||
DOM_CAMERA_LOGE("Invalid video file name\n");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ScopedClose fd(open(nativeFilename.get(), O_RDWR | O_CREAT, 0644));
|
||||
if (fd < 0) {
|
||||
DOM_CAMERA_LOGE("Couldn't create file '%s': (%d) %s\n", nativeFilename.get(), errno, strerror(errno));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
rv = SetupRecording(fd, aStartRecording->mOptions.rotation, aStartRecording->mOptions.maxFileSizeBytes, aStartRecording->mOptions.maxVideoLengthMs);
|
||||
nsresult rv;
|
||||
rv = SetupRecording(dsfd->mFileDescriptor.PlatformHandle(),
|
||||
aStartRecording->mOptions.rotation,
|
||||
aStartRecording->mOptions.maxFileSizeBytes,
|
||||
aStartRecording->mOptions.maxVideoLengthMs);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (mRecorder->start() != OK) {
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "DictionaryHelpers.h"
|
||||
#include "CameraCommon.h"
|
||||
|
||||
class DeviceStorageFileDescriptor;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class DOMCameraPreview;
|
||||
|
@ -25,7 +27,7 @@ public:
|
|||
virtual void StopPreview() = 0;
|
||||
virtual nsresult AutoFocus(nsICameraAutoFocusCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
|
||||
virtual nsresult TakePicture(const idl::CameraSize& aSize, int32_t aRotation, const nsAString& aFileFormat, idl::CameraPosition aPosition, uint64_t aDateTime, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
|
||||
virtual nsresult StartRecording(idl::CameraStartRecordingOptions* aOptions, nsIFile* aFolder, const nsAString& aFilename, nsICameraStartRecordingCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
|
||||
virtual nsresult StartRecording(idl::CameraStartRecordingOptions* aOptions, DeviceStorageFileDescriptor *aFileDescriptor, nsICameraStartRecordingCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
|
||||
virtual nsresult StopRecording() = 0;
|
||||
virtual nsresult GetPreviewStreamVideoMode(idl::CameraRecorderOptions* aOptions, nsICameraPreviewStreamCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
|
||||
virtual nsresult ReleaseHardware(nsICameraReleaseCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "nsDOMEventTargetHelper.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "DOMRequest.h"
|
||||
#include "mozilla/dom/DOMRequest.h"
|
||||
|
||||
#define DEVICESTORAGE_PICTURES "pictures"
|
||||
#define DEVICESTORAGE_VIDEOS "videos"
|
||||
|
@ -23,6 +23,7 @@
|
|||
#define DEVICESTORAGE_SDCARD "sdcard"
|
||||
#define DEVICESTORAGE_CRASHES "crashes"
|
||||
|
||||
class DeviceStorageFile;
|
||||
class nsIInputStream;
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -31,6 +32,9 @@ class DeviceStorageEnumerationParameters;
|
|||
class DOMCursor;
|
||||
class DOMRequest;
|
||||
} // namespace dom
|
||||
namespace ipc {
|
||||
class FileDescriptor;
|
||||
}
|
||||
} // namespace mozilla
|
||||
|
||||
class DeviceStorageFile MOZ_FINAL
|
||||
|
@ -102,6 +106,7 @@ public:
|
|||
|
||||
nsresult CalculateSizeAndModifiedDate();
|
||||
nsresult CalculateMimeType();
|
||||
nsresult CreateFileDescriptor(mozilla::ipc::FileDescriptor& aFileDescriptor);
|
||||
|
||||
private:
|
||||
void Init();
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 sw=2 et tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef DeviceStorageFileDescriptor_h
|
||||
#define DeviceStorageFileDescriptor_h
|
||||
|
||||
#include "mozilla/ipc/FileDescriptor.h"
|
||||
|
||||
class DeviceStorageFileDescriptor MOZ_FINAL
|
||||
: public mozilla::RefCounted<DeviceStorageFileDescriptor>
|
||||
{
|
||||
public:
|
||||
nsRefPtr<DeviceStorageFile> mDSFile;
|
||||
mozilla::ipc::FileDescriptor mFileDescriptor;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
|
||||
#include "DeviceStorageRequestChild.h"
|
||||
#include "DeviceStorageFileDescriptor.h"
|
||||
#include "nsDeviceStorage.h"
|
||||
#include "nsDOMFile.h"
|
||||
#include "mozilla/dom/ipc/Blob.h"
|
||||
|
@ -20,11 +21,27 @@ DeviceStorageRequestChild::DeviceStorageRequestChild()
|
|||
}
|
||||
|
||||
DeviceStorageRequestChild::DeviceStorageRequestChild(DOMRequest* aRequest,
|
||||
DeviceStorageFile* aFile)
|
||||
DeviceStorageFile* aDSFile)
|
||||
: mRequest(aRequest)
|
||||
, mFile(aFile)
|
||||
, mDSFile(aDSFile)
|
||||
, mCallback(nullptr)
|
||||
{
|
||||
MOZ_ASSERT(aRequest);
|
||||
MOZ_ASSERT(aDSFile);
|
||||
MOZ_COUNT_CTOR(DeviceStorageRequestChild);
|
||||
}
|
||||
|
||||
DeviceStorageRequestChild::DeviceStorageRequestChild(DOMRequest* aRequest,
|
||||
DeviceStorageFile* aDSFile,
|
||||
DeviceStorageFileDescriptor* aDSFileDescriptor)
|
||||
: mRequest(aRequest)
|
||||
, mDSFile(aDSFile)
|
||||
, mDSFileDescriptor(aDSFileDescriptor)
|
||||
, mCallback(nullptr)
|
||||
{
|
||||
MOZ_ASSERT(aRequest);
|
||||
MOZ_ASSERT(aDSFile);
|
||||
MOZ_ASSERT(aDSFileDescriptor);
|
||||
MOZ_COUNT_CTOR(DeviceStorageRequestChild);
|
||||
}
|
||||
|
||||
|
@ -53,7 +70,7 @@ DeviceStorageRequestChild::
|
|||
case DeviceStorageResponseValue::TSuccessResponse:
|
||||
{
|
||||
nsString fullPath;
|
||||
mFile->GetFullPath(fullPath);
|
||||
mDSFile->GetFullPath(fullPath);
|
||||
AutoJSContext cx;
|
||||
JS::Rooted<JS::Value> result(cx,
|
||||
StringToJsval(mRequest->GetOwner(), fullPath));
|
||||
|
@ -61,6 +78,22 @@ DeviceStorageRequestChild::
|
|||
break;
|
||||
}
|
||||
|
||||
case DeviceStorageResponseValue::TFileDescriptorResponse:
|
||||
{
|
||||
FileDescriptorResponse r = aValue;
|
||||
|
||||
nsString fullPath;
|
||||
mDSFile->GetFullPath(fullPath);
|
||||
AutoJSContext cx;
|
||||
JS::Rooted<JS::Value> result(cx,
|
||||
StringToJsval(mRequest->GetOwner(), fullPath));
|
||||
|
||||
mDSFileDescriptor->mDSFile = mDSFile;
|
||||
mDSFileDescriptor->mFileDescriptor = r.fileDescriptor();
|
||||
mRequest->FireSuccess(result);
|
||||
break;
|
||||
}
|
||||
|
||||
case DeviceStorageResponseValue::TBlobResponse:
|
||||
{
|
||||
BlobResponse r = aValue;
|
||||
|
|
|
@ -7,12 +7,15 @@
|
|||
#define mozilla_dom_devicestorage_DeviceStorageRequestChild_h
|
||||
|
||||
#include "mozilla/dom/devicestorage/PDeviceStorageRequestChild.h"
|
||||
#include "DOMRequest.h"
|
||||
|
||||
class DeviceStorageFile;
|
||||
class DeviceStorageFileDescriptor;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class DOMRequest;
|
||||
|
||||
namespace devicestorage {
|
||||
|
||||
class DeviceStorageRequestChildCallback
|
||||
|
@ -26,6 +29,8 @@ class DeviceStorageRequestChild : public PDeviceStorageRequestChild
|
|||
public:
|
||||
DeviceStorageRequestChild();
|
||||
DeviceStorageRequestChild(DOMRequest* aRequest, DeviceStorageFile* aFile);
|
||||
DeviceStorageRequestChild(DOMRequest* aRequest, DeviceStorageFile* aFile,
|
||||
DeviceStorageFileDescriptor* aFileDescrptor);
|
||||
~DeviceStorageRequestChild();
|
||||
|
||||
void SetCallback(class DeviceStorageRequestChildCallback *aCallback);
|
||||
|
@ -34,7 +39,8 @@ public:
|
|||
|
||||
private:
|
||||
nsRefPtr<DOMRequest> mRequest;
|
||||
nsRefPtr<DeviceStorageFile> mFile;
|
||||
nsRefPtr<DeviceStorageFile> mDSFile;
|
||||
nsRefPtr<DeviceStorageFileDescriptor> mDSFileDescriptor;
|
||||
|
||||
DeviceStorageRequestChildCallback* mCallback;
|
||||
};
|
||||
|
|
|
@ -29,7 +29,7 @@ DeviceStorageRequestParent::DeviceStorageRequestParent(
|
|||
|
||||
DebugOnly<DeviceStorageUsedSpaceCache*> usedSpaceCache
|
||||
= DeviceStorageUsedSpaceCache::CreateOrGet();
|
||||
NS_ASSERTION(usedSpaceCache, "DeviceStorageUsedSpaceCache is null");
|
||||
MOZ_ASSERT(usedSpaceCache);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -53,7 +53,23 @@ DeviceStorageRequestParent::Dispatch()
|
|||
|
||||
nsCOMPtr<nsIEventTarget> target
|
||||
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
NS_ASSERTION(target, "Must have stream transport service");
|
||||
MOZ_ASSERT(target);
|
||||
target->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
break;
|
||||
}
|
||||
|
||||
case DeviceStorageParams::TDeviceStorageCreateFdParams:
|
||||
{
|
||||
DeviceStorageCreateFdParams p = mParams;
|
||||
|
||||
nsRefPtr<DeviceStorageFile> dsf =
|
||||
new DeviceStorageFile(p.type(), p.storageName(), p.relpath());
|
||||
|
||||
nsRefPtr<CancelableRunnable> r = new CreateFdEvent(this, dsf);
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target
|
||||
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(target);
|
||||
target->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
break;
|
||||
}
|
||||
|
@ -68,7 +84,7 @@ DeviceStorageRequestParent::Dispatch()
|
|||
|
||||
nsCOMPtr<nsIEventTarget> target
|
||||
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
NS_ASSERTION(target, "Must have stream transport service");
|
||||
MOZ_ASSERT(target);
|
||||
target->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
break;
|
||||
}
|
||||
|
@ -83,7 +99,7 @@ DeviceStorageRequestParent::Dispatch()
|
|||
|
||||
nsCOMPtr<nsIEventTarget> target
|
||||
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
NS_ASSERTION(target, "Must have stream transport service");
|
||||
MOZ_ASSERT(target);
|
||||
target->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
break;
|
||||
}
|
||||
|
@ -98,7 +114,7 @@ DeviceStorageRequestParent::Dispatch()
|
|||
|
||||
nsCOMPtr<nsIEventTarget> target
|
||||
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
NS_ASSERTION(target, "Must have stream transport service");
|
||||
MOZ_ASSERT(target);
|
||||
target->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
break;
|
||||
}
|
||||
|
@ -107,7 +123,7 @@ DeviceStorageRequestParent::Dispatch()
|
|||
{
|
||||
DeviceStorageUsedSpaceCache* usedSpaceCache
|
||||
= DeviceStorageUsedSpaceCache::CreateOrGet();
|
||||
NS_ASSERTION(usedSpaceCache, "DeviceStorageUsedSpaceCache is null");
|
||||
MOZ_ASSERT(usedSpaceCache);
|
||||
|
||||
DeviceStorageUsedSpaceParams p = mParams;
|
||||
|
||||
|
@ -127,7 +143,8 @@ DeviceStorageRequestParent::Dispatch()
|
|||
new DeviceStorageFile(p.type(), p.storageName());
|
||||
nsRefPtr<PostAvailableResultEvent> r
|
||||
= new PostAvailableResultEvent(this, dsf);
|
||||
NS_DispatchToMainThread(r);
|
||||
DebugOnly<nsresult> rv = NS_DispatchToMainThread(r);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -139,7 +156,8 @@ DeviceStorageRequestParent::Dispatch()
|
|||
new DeviceStorageFile(p.type(), p.storageName());
|
||||
nsRefPtr<PostFormatResultEvent> r
|
||||
= new PostFormatResultEvent(this, dsf);
|
||||
NS_DispatchToMainThread(r);
|
||||
DebugOnly<nsresult> rv = NS_DispatchToMainThread(r);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -154,7 +172,7 @@ DeviceStorageRequestParent::Dispatch()
|
|||
|
||||
nsCOMPtr<nsIEventTarget> target
|
||||
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
NS_ASSERTION(target, "Must have stream transport service");
|
||||
MOZ_ASSERT(target);
|
||||
target->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
break;
|
||||
}
|
||||
|
@ -187,6 +205,14 @@ DeviceStorageRequestParent::EnsureRequiredPermissions(
|
|||
break;
|
||||
}
|
||||
|
||||
case DeviceStorageParams::TDeviceStorageCreateFdParams:
|
||||
{
|
||||
DeviceStorageCreateFdParams p = mParams;
|
||||
type = p.type();
|
||||
requestType = DEVICE_STORAGE_REQUEST_CREATEFD;
|
||||
break;
|
||||
}
|
||||
|
||||
case DeviceStorageParams::TDeviceStorageGetParams:
|
||||
{
|
||||
DeviceStorageGetParams p = mParams;
|
||||
|
@ -312,7 +338,7 @@ DeviceStorageRequestParent::PostFreeSpaceResultEvent::
|
|||
|
||||
nsresult
|
||||
DeviceStorageRequestParent::PostFreeSpaceResultEvent::CancelableRun() {
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
FreeSpaceStorageResponse response(mFreeSpace);
|
||||
unused << mParent->Send__delete__(mParent, response);
|
||||
|
@ -334,7 +360,7 @@ DeviceStorageRequestParent::PostUsedSpaceResultEvent::
|
|||
|
||||
nsresult
|
||||
DeviceStorageRequestParent::PostUsedSpaceResultEvent::CancelableRun() {
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
UsedSpaceStorageResponse response(mUsedSpace);
|
||||
unused << mParent->Send__delete__(mParent, response);
|
||||
|
@ -352,7 +378,7 @@ DeviceStorageRequestParent::PostErrorEvent::~PostErrorEvent() {}
|
|||
|
||||
nsresult
|
||||
DeviceStorageRequestParent::PostErrorEvent::CancelableRun() {
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
ErrorResponse response(mError);
|
||||
unused << mParent->Send__delete__(mParent, response);
|
||||
|
@ -369,7 +395,7 @@ DeviceStorageRequestParent::PostSuccessEvent::~PostSuccessEvent() {}
|
|||
|
||||
nsresult
|
||||
DeviceStorageRequestParent::PostSuccessEvent::CancelableRun() {
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
SuccessResponse response;
|
||||
unused << mParent->Send__delete__(mParent, response);
|
||||
|
@ -394,7 +420,7 @@ DeviceStorageRequestParent::PostBlobSuccessEvent::~PostBlobSuccessEvent() {}
|
|||
|
||||
nsresult
|
||||
DeviceStorageRequestParent::PostBlobSuccessEvent::CancelableRun() {
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsString mime;
|
||||
CopyASCIItoUTF16(mMimeType, mime);
|
||||
|
@ -437,13 +463,54 @@ DeviceStorageRequestParent::PostEnumerationSuccessEvent::
|
|||
|
||||
nsresult
|
||||
DeviceStorageRequestParent::PostEnumerationSuccessEvent::CancelableRun() {
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
EnumerationResponse response(mStorageType, mRelPath, mPaths);
|
||||
unused << mParent->Send__delete__(mParent, response);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::CreateFdEvent::
|
||||
CreateFdEvent(DeviceStorageRequestParent* aParent,
|
||||
DeviceStorageFile* aFile)
|
||||
: CancelableRunnable(aParent)
|
||||
, mFile(aFile)
|
||||
{
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::CreateFdEvent::~CreateFdEvent()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
DeviceStorageRequestParent::CreateFdEvent::CancelableRun()
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
nsRefPtr<nsRunnable> r;
|
||||
|
||||
bool check = false;
|
||||
mFile->mFile->Exists(&check);
|
||||
if (check) {
|
||||
nsCOMPtr<PostErrorEvent> event
|
||||
= new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_EXISTS);
|
||||
return NS_DispatchToMainThread(event);
|
||||
}
|
||||
|
||||
FileDescriptor fileDescriptor;
|
||||
nsresult rv = mFile->CreateFileDescriptor(fileDescriptor);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("CreateFileDescriptor failed");
|
||||
mFile->Dump("CreateFileDescriptor failed");
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
|
||||
}
|
||||
else {
|
||||
r = new PostFileDescriptorResultEvent(mParent, fileDescriptor);
|
||||
}
|
||||
|
||||
return NS_DispatchToMainThread(r);
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::WriteFileEvent::
|
||||
WriteFileEvent(DeviceStorageRequestParent* aParent,
|
||||
DeviceStorageFile* aFile,
|
||||
|
@ -461,14 +528,13 @@ DeviceStorageRequestParent::WriteFileEvent::~WriteFileEvent()
|
|||
nsresult
|
||||
DeviceStorageRequestParent::WriteFileEvent::CancelableRun()
|
||||
{
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
nsRefPtr<nsRunnable> r;
|
||||
|
||||
if (!mInputStream) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
|
||||
NS_DispatchToMainThread(r);
|
||||
return NS_OK;
|
||||
return NS_DispatchToMainThread(r);
|
||||
}
|
||||
|
||||
bool check = false;
|
||||
|
@ -476,8 +542,7 @@ DeviceStorageRequestParent::WriteFileEvent::CancelableRun()
|
|||
if (check) {
|
||||
nsCOMPtr<PostErrorEvent> event
|
||||
= new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_EXISTS);
|
||||
NS_DispatchToMainThread(event);
|
||||
return NS_OK;
|
||||
return NS_DispatchToMainThread(event);
|
||||
}
|
||||
|
||||
nsresult rv = mFile->Write(mInputStream);
|
||||
|
@ -489,11 +554,9 @@ DeviceStorageRequestParent::WriteFileEvent::CancelableRun()
|
|||
r = new PostPathResultEvent(mParent, mFile->mPath);
|
||||
}
|
||||
|
||||
NS_DispatchToMainThread(r);
|
||||
return NS_OK;
|
||||
return NS_DispatchToMainThread(r);
|
||||
}
|
||||
|
||||
|
||||
DeviceStorageRequestParent::DeleteFileEvent::
|
||||
DeleteFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile)
|
||||
: CancelableRunnable(aParent)
|
||||
|
@ -508,7 +571,7 @@ DeviceStorageRequestParent::DeleteFileEvent::~DeleteFileEvent()
|
|||
nsresult
|
||||
DeviceStorageRequestParent::DeleteFileEvent::CancelableRun()
|
||||
{
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
mFile->Remove();
|
||||
|
||||
|
@ -523,8 +586,7 @@ DeviceStorageRequestParent::DeleteFileEvent::CancelableRun()
|
|||
r = new PostPathResultEvent(mParent, mFile->mPath);
|
||||
}
|
||||
|
||||
NS_DispatchToMainThread(r);
|
||||
return NS_OK;
|
||||
return NS_DispatchToMainThread(r);
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::FreeSpaceFileEvent::
|
||||
|
@ -542,7 +604,7 @@ DeviceStorageRequestParent::FreeSpaceFileEvent::~FreeSpaceFileEvent()
|
|||
nsresult
|
||||
DeviceStorageRequestParent::FreeSpaceFileEvent::CancelableRun()
|
||||
{
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
int64_t freeSpace = 0;
|
||||
if (mFile) {
|
||||
|
@ -551,8 +613,7 @@ DeviceStorageRequestParent::FreeSpaceFileEvent::CancelableRun()
|
|||
|
||||
nsCOMPtr<nsIRunnable> r;
|
||||
r = new PostFreeSpaceResultEvent(mParent, static_cast<uint64_t>(freeSpace));
|
||||
NS_DispatchToMainThread(r);
|
||||
return NS_OK;
|
||||
return NS_DispatchToMainThread(r);
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::UsedSpaceFileEvent::
|
||||
|
@ -570,7 +631,7 @@ DeviceStorageRequestParent::UsedSpaceFileEvent::~UsedSpaceFileEvent()
|
|||
nsresult
|
||||
DeviceStorageRequestParent::UsedSpaceFileEvent::CancelableRun()
|
||||
{
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
uint64_t picturesUsage = 0, videosUsage = 0, musicUsage = 0, totalUsage = 0;
|
||||
mFile->AccumDiskUsage(&picturesUsage, &videosUsage,
|
||||
|
@ -588,8 +649,7 @@ DeviceStorageRequestParent::UsedSpaceFileEvent::CancelableRun()
|
|||
} else {
|
||||
r = new PostUsedSpaceResultEvent(mParent, mFile->mStorageType, totalUsage);
|
||||
}
|
||||
NS_DispatchToMainThread(r);
|
||||
return NS_OK;
|
||||
return NS_DispatchToMainThread(r);
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::ReadFileEvent::
|
||||
|
@ -614,7 +674,7 @@ DeviceStorageRequestParent::ReadFileEvent::~ReadFileEvent()
|
|||
nsresult
|
||||
DeviceStorageRequestParent::ReadFileEvent::CancelableRun()
|
||||
{
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIRunnable> r;
|
||||
bool check = false;
|
||||
|
@ -622,30 +682,26 @@ DeviceStorageRequestParent::ReadFileEvent::CancelableRun()
|
|||
|
||||
if (!check) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST);
|
||||
NS_DispatchToMainThread(r);
|
||||
return NS_OK;
|
||||
return NS_DispatchToMainThread(r);
|
||||
}
|
||||
|
||||
int64_t fileSize;
|
||||
nsresult rv = mFile->mFile->GetFileSize(&fileSize);
|
||||
if (NS_FAILED(rv)) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
|
||||
NS_DispatchToMainThread(r);
|
||||
return NS_OK;
|
||||
return NS_DispatchToMainThread(r);
|
||||
}
|
||||
|
||||
PRTime modDate;
|
||||
rv = mFile->mFile->GetLastModifiedTime(&modDate);
|
||||
if (NS_FAILED(rv)) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
|
||||
NS_DispatchToMainThread(r);
|
||||
return NS_OK;
|
||||
return NS_DispatchToMainThread(r);
|
||||
}
|
||||
|
||||
r = new PostBlobSuccessEvent(mParent, mFile, static_cast<uint64_t>(fileSize),
|
||||
mMimeType, modDate);
|
||||
NS_DispatchToMainThread(r);
|
||||
return NS_OK;
|
||||
return NS_DispatchToMainThread(r);
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::EnumerateFileEvent::
|
||||
|
@ -665,7 +721,7 @@ DeviceStorageRequestParent::EnumerateFileEvent::~EnumerateFileEvent()
|
|||
nsresult
|
||||
DeviceStorageRequestParent::EnumerateFileEvent::CancelableRun()
|
||||
{
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIRunnable> r;
|
||||
if (mFile->mFile) {
|
||||
|
@ -673,8 +729,7 @@ DeviceStorageRequestParent::EnumerateFileEvent::CancelableRun()
|
|||
mFile->mFile->Exists(&check);
|
||||
if (!check) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST);
|
||||
NS_DispatchToMainThread(r);
|
||||
return NS_OK;
|
||||
return NS_DispatchToMainThread(r);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -691,8 +746,7 @@ DeviceStorageRequestParent::EnumerateFileEvent::CancelableRun()
|
|||
|
||||
r = new PostEnumerationSuccessEvent(mParent, mFile->mStorageType,
|
||||
mFile->mRootDir, values);
|
||||
NS_DispatchToMainThread(r);
|
||||
return NS_OK;
|
||||
return NS_DispatchToMainThread(r);
|
||||
}
|
||||
|
||||
|
||||
|
@ -711,13 +765,36 @@ DeviceStorageRequestParent::PostPathResultEvent::~PostPathResultEvent()
|
|||
nsresult
|
||||
DeviceStorageRequestParent::PostPathResultEvent::CancelableRun()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
SuccessResponse response;
|
||||
unused << mParent->Send__delete__(mParent, response);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::PostFileDescriptorResultEvent::
|
||||
PostFileDescriptorResultEvent(DeviceStorageRequestParent* aParent,
|
||||
const FileDescriptor& aFileDescriptor)
|
||||
: CancelableRunnable(aParent)
|
||||
, mFileDescriptor(aFileDescriptor)
|
||||
{
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::PostFileDescriptorResultEvent::
|
||||
~PostFileDescriptorResultEvent()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
DeviceStorageRequestParent::PostFileDescriptorResultEvent::CancelableRun()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
FileDescriptorResponse response(mFileDescriptor);
|
||||
unused << mParent->Send__delete__(mParent, response);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::PostAvailableResultEvent::
|
||||
PostAvailableResultEvent(DeviceStorageRequestParent* aParent,
|
||||
DeviceStorageFile* aFile)
|
||||
|
@ -734,7 +811,7 @@ DeviceStorageRequestParent::PostAvailableResultEvent::
|
|||
nsresult
|
||||
DeviceStorageRequestParent::PostAvailableResultEvent::CancelableRun()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsString state = NS_LITERAL_STRING("unavailable");
|
||||
if (mFile) {
|
||||
|
@ -762,7 +839,7 @@ DeviceStorageRequestParent::PostFormatResultEvent::
|
|||
nsresult
|
||||
DeviceStorageRequestParent::PostFormatResultEvent::CancelableRun()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsString state = NS_LITERAL_STRING("unavailable");
|
||||
if (mFile) {
|
||||
|
|
|
@ -119,6 +119,16 @@ private:
|
|||
InfallibleTArray<DeviceStorageFileValue> mPaths;
|
||||
};
|
||||
|
||||
class CreateFdEvent : public CancelableRunnable
|
||||
{
|
||||
public:
|
||||
CreateFdEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile);
|
||||
virtual ~CreateFdEvent();
|
||||
virtual nsresult CancelableRun();
|
||||
private:
|
||||
nsRefPtr<DeviceStorageFile> mFile;
|
||||
};
|
||||
|
||||
class WriteFileEvent : public CancelableRunnable
|
||||
{
|
||||
public:
|
||||
|
@ -193,6 +203,18 @@ private:
|
|||
nsString mPath;
|
||||
};
|
||||
|
||||
class PostFileDescriptorResultEvent : public CancelableRunnable
|
||||
{
|
||||
public:
|
||||
PostFileDescriptorResultEvent(DeviceStorageRequestParent* aParent,
|
||||
const FileDescriptor& aFileDescriptor);
|
||||
virtual ~PostFileDescriptorResultEvent();
|
||||
virtual nsresult CancelableRun();
|
||||
private:
|
||||
nsRefPtr<DeviceStorageFile> mFile;
|
||||
FileDescriptor mFileDescriptor;
|
||||
};
|
||||
|
||||
class PostFreeSpaceResultEvent : public CancelableRunnable
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -20,6 +20,11 @@ struct SuccessResponse
|
|||
{
|
||||
};
|
||||
|
||||
struct FileDescriptorResponse
|
||||
{
|
||||
FileDescriptor fileDescriptor;
|
||||
};
|
||||
|
||||
struct BlobResponse
|
||||
{
|
||||
PBlob blob;
|
||||
|
@ -62,6 +67,7 @@ union DeviceStorageResponseValue
|
|||
{
|
||||
ErrorResponse;
|
||||
SuccessResponse;
|
||||
FileDescriptorResponse;
|
||||
BlobResponse;
|
||||
EnumerationResponse;
|
||||
FreeSpaceStorageResponse;
|
||||
|
|
|
@ -8,6 +8,7 @@ TEST_DIRS += ['test', 'ipc']
|
|||
|
||||
EXPORTS += [
|
||||
'DeviceStorage.h',
|
||||
'DeviceStorageFileDescriptor.h',
|
||||
'nsDeviceStorage.h',
|
||||
]
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -52,7 +52,8 @@ enum DeviceStorageRequestType {
|
|||
DEVICE_STORAGE_REQUEST_FREE_SPACE,
|
||||
DEVICE_STORAGE_REQUEST_USED_SPACE,
|
||||
DEVICE_STORAGE_REQUEST_AVAILABLE,
|
||||
DEVICE_STORAGE_REQUEST_FORMAT
|
||||
DEVICE_STORAGE_REQUEST_FORMAT,
|
||||
DEVICE_STORAGE_REQUEST_CREATEFD
|
||||
};
|
||||
|
||||
class DeviceStorageUsedSpaceCache MOZ_FINAL
|
||||
|
@ -90,8 +91,8 @@ public:
|
|||
|
||||
void Invalidate(const nsAString& aStorageName)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(mIOThread, "Null mIOThread!");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mIOThread);
|
||||
|
||||
nsRefPtr<InvalidateRunnable> r = new InvalidateRunnable(this, aStorageName);
|
||||
mIOThread->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
|
@ -99,8 +100,8 @@ public:
|
|||
|
||||
void Dispatch(nsIRunnable* aRunnable)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(mIOThread, "Null mIOThread!");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mIOThread);
|
||||
|
||||
mIOThread->Dispatch(aRunnable, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,12 @@ interface nsIDOMDeviceStorageChangeEvent;
|
|||
interface nsIDOMEventListener;
|
||||
interface nsIFile;
|
||||
|
||||
[scriptable, uuid(7c1b2305-0f14-4c07-8a8a-359eeb850068), builtinclass]
|
||||
%{C++
|
||||
class DeviceStorageFileDescriptor;
|
||||
%}
|
||||
[ptr] native DeviceStorageFdPtr(DeviceStorageFileDescriptor);
|
||||
|
||||
[scriptable, uuid(8b724547-3c78-4244-969a-f00a1f4ae0c3), builtinclass]
|
||||
interface nsIDOMDeviceStorage : nsIDOMEventTarget
|
||||
{
|
||||
[implicit_jscontext] attribute jsval onchange;
|
||||
|
@ -34,5 +39,8 @@ interface nsIDOMDeviceStorage : nsIDOMEventTarget
|
|||
// for storing new files.
|
||||
readonly attribute bool default;
|
||||
|
||||
[noscript] nsIFile getRootDirectoryForFile(in DOMString aName);
|
||||
// Note: aFileDescriptor is reference counted, which is why we're using
|
||||
// a pointer rather than a reference.
|
||||
[noscript] nsIDOMDOMRequest createFileDescriptor(in DOMString aName,
|
||||
in DeviceStorageFdPtr aFileDescriptor);
|
||||
};
|
||||
|
|
|
@ -94,6 +94,13 @@ struct DeviceStorageAddParams
|
|||
PBlob blob;
|
||||
};
|
||||
|
||||
struct DeviceStorageCreateFdParams
|
||||
{
|
||||
nsString type;
|
||||
nsString storageName;
|
||||
nsString relpath;
|
||||
};
|
||||
|
||||
struct DeviceStorageGetParams
|
||||
{
|
||||
nsString type;
|
||||
|
@ -120,6 +127,7 @@ struct DeviceStorageEnumerationParams
|
|||
union DeviceStorageParams
|
||||
{
|
||||
DeviceStorageAddParams;
|
||||
DeviceStorageCreateFdParams;
|
||||
DeviceStorageGetParams;
|
||||
DeviceStorageDeleteParams;
|
||||
DeviceStorageEnumerationParams;
|
||||
|
|
|
@ -51,7 +51,12 @@ public class FormAssistPopup extends RelativeLayout implements GeckoEventListene
|
|||
private double mY;
|
||||
private double mW;
|
||||
private double mH;
|
||||
private boolean mIsAutoComplete = true;
|
||||
|
||||
private enum PopupType {
|
||||
AUTOCOMPLETE,
|
||||
VALIDATIONMESSAGE;
|
||||
}
|
||||
private PopupType mPopupType;
|
||||
|
||||
private static int sAutoCompleteMinWidth = 0;
|
||||
private static int sAutoCompleteRowHeight = 0;
|
||||
|
@ -208,7 +213,8 @@ public class FormAssistPopup extends RelativeLayout implements GeckoEventListene
|
|||
return false;
|
||||
}
|
||||
|
||||
mIsAutoComplete = isAutoComplete;
|
||||
mPopupType = (isAutoComplete ?
|
||||
PopupType.AUTOCOMPLETE : PopupType.VALIDATIONMESSAGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -227,9 +233,9 @@ public class FormAssistPopup extends RelativeLayout implements GeckoEventListene
|
|||
|
||||
// Hide/show the appropriate popup contents
|
||||
if (mAutoCompleteList != null)
|
||||
mAutoCompleteList.setVisibility(mIsAutoComplete ? VISIBLE : GONE);
|
||||
mAutoCompleteList.setVisibility((mPopupType == PopupType.AUTOCOMPLETE) ? VISIBLE : GONE);
|
||||
if (mValidationMessage != null)
|
||||
mValidationMessage.setVisibility(mIsAutoComplete ? GONE : VISIBLE);
|
||||
mValidationMessage.setVisibility((mPopupType == PopupType.AUTOCOMPLETE) ? GONE : VISIBLE);
|
||||
|
||||
if (sAutoCompleteMinWidth == 0) {
|
||||
Resources res = mContext.getResources();
|
||||
|
@ -255,7 +261,7 @@ public class FormAssistPopup extends RelativeLayout implements GeckoEventListene
|
|||
|
||||
// For autocomplete suggestions, if the input is smaller than the screen-width,
|
||||
// shrink the popup's width. Otherwise, keep it as FILL_PARENT.
|
||||
if (mIsAutoComplete && (left + width) < viewport.width) {
|
||||
if ((mPopupType == PopupType.AUTOCOMPLETE) && (left + width) < viewport.width) {
|
||||
popupWidth = left < 0 ? left + width : width;
|
||||
|
||||
// Ensure the popup has a minimum width.
|
||||
|
@ -269,14 +275,14 @@ public class FormAssistPopup extends RelativeLayout implements GeckoEventListene
|
|||
}
|
||||
|
||||
int popupHeight;
|
||||
if (mIsAutoComplete)
|
||||
if (mPopupType == PopupType.AUTOCOMPLETE)
|
||||
popupHeight = sAutoCompleteRowHeight * mAutoCompleteList.getAdapter().getCount();
|
||||
else
|
||||
popupHeight = sValidationMessageHeight;
|
||||
|
||||
int popupTop = top + height;
|
||||
|
||||
if (!mIsAutoComplete) {
|
||||
if (mPopupType == PopupType.VALIDATIONMESSAGE) {
|
||||
mValidationMessageText.setLayoutParams(sValidationTextLayoutNormal);
|
||||
mValidationMessageArrow.setVisibility(VISIBLE);
|
||||
mValidationMessageArrowInverted.setVisibility(GONE);
|
||||
|
@ -299,7 +305,7 @@ public class FormAssistPopup extends RelativeLayout implements GeckoEventListene
|
|||
popupHeight = top;
|
||||
}
|
||||
|
||||
if (!mIsAutoComplete) {
|
||||
if (mPopupType == PopupType.VALIDATIONMESSAGE) {
|
||||
mValidationMessageText.setLayoutParams(sValidationTextLayoutInverted);
|
||||
mValidationMessageArrow.setVisibility(GONE);
|
||||
mValidationMessageArrowInverted.setVisibility(VISIBLE);
|
||||
|
|
|
@ -158,7 +158,6 @@
|
|||
ALLOW_SYSCALL(readlink), \
|
||||
ALLOW_SYSCALL(getsockname), \
|
||||
ALLOW_SYSCALL(recvmsg), \
|
||||
ALLOW_SYSCALL(uname), \
|
||||
/* duplicate rt_sigaction in SECCOMP_WHITELIST_PROFILING */ \
|
||||
ALLOW_SYSCALL(rt_sigaction), \
|
||||
ALLOW_SYSCALL(getuid), \
|
||||
|
@ -268,6 +267,9 @@
|
|||
/* linux desktop is not as performance critical as B2G */ \
|
||||
/* we can place desktop syscalls at the end */ \
|
||||
SECCOMP_WHITELIST_DESKTOP_LINUX \
|
||||
/* nsSystemInfo uses uname (and we cache an instance, so */ \
|
||||
/* the info remains present even if we block the syscall) */ \
|
||||
ALLOW_SYSCALL(uname), \
|
||||
ALLOW_SYSCALL(exit_group), \
|
||||
ALLOW_SYSCALL(exit)
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче