Merge mozilla-central to fx-team

This commit is contained in:
Carsten "Tomcat" Book 2014-07-10 15:15:52 +02:00
Родитель 1bda00a462 61f33624c3
Коммит c5a0038de8
375 изменённых файлов: 9828 добавлений и 9080 удалений

Просмотреть файл

@ -22,6 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1033481 - Use a .mozbuild file rather than a .mk in
m/a/tests/background/junit3 -- doesn't clean the classes* directory
when moving from in APK to in JAR building.
Bug 1024707 - It seems like changing 3 uuids is just too much!

Просмотреть файл

@ -167,7 +167,7 @@ endif
endif
default all::
$(call BUILDSTATUS,TIERS export $(if $(COMPILE_ENVIRONMENT),$(if $(MOZ_PSEUDO_DERECURSE),compile ))libs tools $(if $(MOZ_AUTOMATION),$(MOZ_AUTOMATION_TIERS)))
$(call BUILDSTATUS,TIERS export $(if $(COMPILE_ENVIRONMENT),compile )libs tools $(if $(MOZ_AUTOMATION),$(MOZ_AUTOMATION_TIERS)))
include $(topsrcdir)/config/rules.mk
@ -309,11 +309,9 @@ config/export:
endif
ifdef MOZ_PSEUDO_DERECURSE
# Interdependencies for parallel export.
js/xpconnect/src/export: dom/bindings/export xpcom/xpidl/export
accessible/xpcom/export: xpcom/xpidl/export
ifdef ENABLE_CLANG_PLUGIN
js/src/export config/export: build/clang-plugin/export
endif
endif

Просмотреть файл

@ -459,6 +459,18 @@ pref("services.push.retryBaseInterval", 5000);
pref("services.push.pingInterval", 1800000); // 30 minutes
// How long before a DOMRequest errors as timeout
pref("services.push.requestTimeout", 10000);
pref("services.push.pingInterval.default", 180000);// 3 min
pref("services.push.pingInterval.mobile", 180000); // 3 min
pref("services.push.pingInterval.wifi", 180000); // 3 min
// Adaptive ping
pref("services.push.adaptive.enabled", true);
pref("services.push.adaptive.lastGoodPingInterval", 180000);// 3 min
pref("services.push.adaptive.lastGoodPingInterval.mobile", 180000);// 3 min
pref("services.push.adaptive.lastGoodPingInterval.wifi", 180000);// 3 min
// Valid gap between the biggest good ping and the bad ping
pref("services.push.adaptive.gap", 60000); // 1 minute
// We limit the ping to this maximum value
pref("services.push.adaptive.upperLimit", 1740000); // 29 min
// enable udp wakeup support
pref("services.push.udp.wakeupEnabled", true);
// This value should be the prefix to be added to the current PDP context[1]

Просмотреть файл

@ -14,6 +14,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "FxAccountsMgmtService",
"resource://gre/modules/FxAccountsMgmtService.jsm",
"FxAccountsMgmtService");
XPCOMUtils.defineLazyModuleGetter(this, "FxAccountsManager",
"resource://gre/modules/FxAccountsManager.jsm");
// At end of test, restore original state
const ORIGINAL_AUTH_URI = Services.prefs.getCharPref("identity.fxaccounts.auth.uri");
let { SystemAppProxy } = Cu.import("resource://gre/modules/FxAccountsMgmtService.jsm");
@ -158,6 +161,22 @@ add_test(function test_invalidEmailCase_signIn() {
});
});
add_test(function testHandleGetAssertionError_defaultCase() {
do_test_pending();
FxAccountsManager.getAssertion(null).then(
success => {
// getAssertion should throw with invalid audience
ok(false);
},
reason => {
equal("INVALID_AUDIENCE", reason.error);
do_test_finished();
run_next_test();
}
)
});
// End of tests
// Utility functions follow

Просмотреть файл

@ -19,7 +19,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="4e4e579b4b1e35f863ed43ef6ba840f49bfd761c"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="09642e74e250fbc62db860c808ef188628fca55d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

Просмотреть файл

@ -17,7 +17,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="4e4e579b4b1e35f863ed43ef6ba840f49bfd761c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="09642e74e250fbc62db860c808ef188628fca55d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ee6e7320bb83409ebd4685fbd87a8ae033704182"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="276ce45e78b09c4a4ee643646f691d22804754c1">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="4e4e579b4b1e35f863ed43ef6ba840f49bfd761c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="09642e74e250fbc62db860c808ef188628fca55d"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -19,7 +19,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="4e4e579b4b1e35f863ed43ef6ba840f49bfd761c"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="09642e74e250fbc62db860c808ef188628fca55d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

Просмотреть файл

@ -17,7 +17,7 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="4e4e579b4b1e35f863ed43ef6ba840f49bfd761c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="09642e74e250fbc62db860c808ef188628fca55d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ee6e7320bb83409ebd4685fbd87a8ae033704182"/>

Просмотреть файл

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "158fb07e2e4939dddee026a33a05d65e38bb0e67",
"revision": "056dbe15b2aac2b252a119c211a85cb14165aa81",
"repo_path": "/integration/gaia-central"
}

Просмотреть файл

@ -17,7 +17,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="4e4e579b4b1e35f863ed43ef6ba840f49bfd761c"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="09642e74e250fbc62db860c808ef188628fca55d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -15,7 +15,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="4e4e579b4b1e35f863ed43ef6ba840f49bfd761c"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="09642e74e250fbc62db860c808ef188628fca55d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -17,7 +17,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="4e4e579b4b1e35f863ed43ef6ba840f49bfd761c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="09642e74e250fbc62db860c808ef188628fca55d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ee6e7320bb83409ebd4685fbd87a8ae033704182"/>

Просмотреть файл

@ -17,7 +17,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="4e4e579b4b1e35f863ed43ef6ba840f49bfd761c"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="09642e74e250fbc62db860c808ef188628fca55d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

Просмотреть файл

@ -23,7 +23,9 @@ DEFINES += -DMOZ_CHILD_PROCESS_NAME=$(MOZ_CHILD_PROCESS_NAME)
# Set MSVC dlls version to package, if any.
ifdef WIN32_REDIST_DIR
ifdef MOZ_NO_DEBUG_RTL
DEFINES += -DMOZ_MSVC_REDIST=$(_MSC_VER)
DEFINES += -DMOZ_PACKAGE_MSVC_DLLS=1
DEFINES += -DMSVC_C_RUNTIME_DLL=$(MSVC_C_RUNTIME_DLL)
DEFINES += -DMSVC_CXX_RUNTIME_DLL=$(MSVC_CXX_RUNTIME_DLL)
endif
endif

Просмотреть файл

@ -69,15 +69,9 @@
@BINPATH@/@MOZ_CHILD_PROCESS_NAME@
#endif
#ifdef XP_WIN32
#if MOZ_MSVC_REDIST == 1600
@BINPATH@/msvcp100.dll
@BINPATH@/msvcr100.dll
#elif MOZ_MSVC_REDIST == 1700
@BINPATH@/msvcp110.dll
@BINPATH@/msvcr110.dll
#elif MOZ_MSVC_REDIST == 1800
@BINPATH@/msvcp120.dll
@BINPATH@/msvcr120.dll
#if MOZ_PACKAGE_MSVC_DLLS
@BINPATH@/@MSVC_C_RUNTIME_DLL@
@BINPATH@/@MSVC_CXX_RUNTIME_DLL@
#endif
#endif
#ifdef MOZ_SHARED_MOZGLUE
@ -405,8 +399,6 @@
@BINPATH@/components/DOMWifiManager.manifest
@BINPATH@/components/DOMWifiP2pManager.js
@BINPATH@/components/DOMWifiP2pManager.manifest
@BINPATH@/components/EthernetManager.js
@BINPATH@/components/EthernetManager.manifest
@BINPATH@/components/NetworkInterfaceListService.js
@BINPATH@/components/NetworkInterfaceListService.manifest
@BINPATH@/components/NetworkManager.js

Просмотреть файл

@ -495,7 +495,10 @@ var gPluginHandler = {
if (this.getPluginUI(plugin, "submitURLOptIn").checked)
keyVals.PluginContentURL = plugin.ownerDocument.URL;
}
this.CrashSubmit.submit(pluginDumpID, { extraExtraKeyVals: keyVals });
let pluginProcessType = Services.crashmanager.PROCESS_TYPE_PLUGIN;
this.CrashSubmit.submit(pluginDumpID, { processType: pluginProcessType,
extraExtraKeyVals: keyVals });
if (browserDumpID)
this.CrashSubmit.submit(browserDumpID);
},

Просмотреть файл

@ -22,26 +22,81 @@ loop.panel = (function(_, mozL10n) {
var router;
/**
* Do not disturb panel subview.
* Availability drop down menu subview.
*/
var DoNotDisturb = React.createClass({displayName: 'DoNotDisturb',
var AvailabilityDropdown = React.createClass({displayName: 'AvailabilityDropdown',
getInitialState: function() {
return {doNotDisturb: navigator.mozLoop.doNotDisturb};
return {
doNotDisturb: navigator.mozLoop.doNotDisturb,
showMenu: false
};
},
handleCheckboxChange: function() {
showDropdownMenu: function() {
this.setState({showMenu: true});
},
hideDropdownMenu: function() {
this.setState({showMenu: false});
},
// XXX target event can either be the li, the span or the i tag
// this makes it easier to figure out the target by making a
// closure with the desired status already passed in.
changeAvailability: function(newAvailabilty) {
return function(event) {
// Note: side effect!
navigator.mozLoop.doNotDisturb = !navigator.mozLoop.doNotDisturb;
this.setState({doNotDisturb: navigator.mozLoop.doNotDisturb});
switch (newAvailabilty) {
case 'available':
this.setState({doNotDisturb: false});
navigator.mozLoop.doNotDisturb = false;
break;
case 'do-not-disturb':
this.setState({doNotDisturb: true});
navigator.mozLoop.doNotDisturb = true;
break;
}
this.hideDropdownMenu();
}.bind(this);
},
render: function() {
// XXX https://github.com/facebook/react/issues/310 for === htmlFor
var cx = React.addons.classSet;
var availabilityStatus = cx({
'status': true,
'status-dnd': this.state.doNotDisturb,
'status-available': !this.state.doNotDisturb
});
var availabilityDropdown = cx({
'dnd-menu': true,
'hide': !this.state.showMenu
});
var availabilityText = this.state.doNotDisturb ?
__("display_name_dnd_status") :
__("display_name_available_status");
return (
React.DOM.p( {className:"dnd"},
React.DOM.input( {type:"checkbox", checked:this.state.doNotDisturb,
id:"dnd-component", onChange:this.handleCheckboxChange} ),
React.DOM.label( {htmlFor:"dnd-component"}, __("do_not_disturb"))
React.DOM.div( {className:"footer component-spacer"},
React.DOM.div( {className:"do-not-disturb"},
React.DOM.p( {className:"dnd-status", onClick:this.showDropdownMenu},
React.DOM.span(null, availabilityText),
React.DOM.i( {className:availabilityStatus})
),
React.DOM.ul( {className:availabilityDropdown,
onMouseLeave:this.hideDropdownMenu},
React.DOM.li( {onClick:this.changeAvailability("available"),
className:"dnd-menu-item dnd-make-available"},
React.DOM.i( {className:"status status-available"}),
React.DOM.span(null, __("display_name_available_status"))
),
React.DOM.li( {onClick:this.changeAvailability("do-not-disturb"),
className:"dnd-menu-item dnd-make-unavailable"},
React.DOM.i( {className:"status status-dnd"}),
React.DOM.span(null, __("display_name_dnd_status"))
)
)
)
)
);
}
@ -60,7 +115,7 @@ loop.panel = (function(_, mozL10n) {
if (!this.state.seenToS) {
navigator.mozLoop.setLoopCharPref('seenToS', 'seen');
return React.DOM.p( {className:"tos",
return React.DOM.p( {className:"terms-service",
dangerouslySetInnerHTML:{__html: tosHTML}});
} else {
return React.DOM.div(null );
@ -75,9 +130,9 @@ loop.panel = (function(_, mozL10n) {
render: function() {
return (
React.DOM.div( {className:"share generate-url"},
React.DOM.div( {className:"component-spacer share generate-url"},
React.DOM.div( {className:"description"},
React.DOM.p(null, this.props.summary)
React.DOM.p( {className:"description-content"}, this.props.summary)
),
React.DOM.div( {className:"action"},
this.props.children
@ -88,61 +143,27 @@ loop.panel = (function(_, mozL10n) {
});
var CallUrlResult = React.createClass({displayName: 'CallUrlResult',
propTypes: {
callUrl: React.PropTypes.string.isRequired,
retry: React.PropTypes.func.isRequired
},
handleButtonClick: function() {
this.props.retry();
},
render: function() {
// XXX setting elem value from a state (in the callUrl input)
// makes it immutable ie read only but that is fine in our case.
// readOnly attr will suppress a warning regarding this issue
// from the react lib.
return (
PanelLayout( {summary:__("share_link_url")},
React.DOM.div( {className:"invite"},
React.DOM.input( {type:"url", value:this.props.callUrl, readOnly:"true"} ),
React.DOM.button( {onClick:this.handleButtonClick,
className:"btn btn-success"}, __("new_url"))
)
)
);
}
});
var CallUrlForm = React.createClass({displayName: 'CallUrlForm',
propTypes: {
client: React.PropTypes.object.isRequired,
notifier: React.PropTypes.object.isRequired
},
getInitialState: function() {
return {
pending: false,
disabled: true,
callUrl: false
callUrl: ''
};
},
retry: function() {
this.setState(this.getInitialState());
/**
* Returns a random 5 character string used to identify
* the conversation.
* XXX this will go away once the backend changes
*/
conversationIdentifier: function() {
return Math.random().toString(36).substring(5);
},
handleTextChange: function(event) {
this.setState({disabled: !event.currentTarget.value});
},
handleFormSubmit: function(event) {
event.preventDefault();
componentDidMount: function() {
this.setState({pending: true});
this.props.client.requestCallUrl(
this.refs.caller.getDOMNode().value, this._onCallUrlReceived);
this.props.client.requestCallUrl(this.conversationIdentifier(),
this._onCallUrlReceived);
},
_onCallUrlReceived: function(err, callUrlData) {
@ -160,30 +181,17 @@ loop.panel = (function(_, mozL10n) {
},
render: function() {
// If we have a call url, render result
if (this.state.callUrl) {
return (
CallUrlResult( {callUrl:this.state.callUrl, retry:this.retry})
);
}
// If we don't display the form
// XXX setting elem value from a state (in the callUrl input)
// makes it immutable ie read only but that is fine in our case.
// readOnly attr will suppress a warning regarding this issue
// from the react lib.
var cx = React.addons.classSet;
return (
PanelLayout( {summary:__("get_link_to_share")},
React.DOM.form( {className:"invite", onSubmit:this.handleFormSubmit},
React.DOM.input( {type:"text", name:"caller", ref:"caller", required:"required",
className:cx({'pending': this.state.pending}),
onChange:this.handleTextChange,
placeholder:__("call_identifier_textinput_placeholder")} ),
React.DOM.button( {type:"submit", className:"get-url btn btn-success",
disabled:this.state.disabled},
__("get_a_call_url")
PanelLayout( {summary:__("share_link_header_text")},
React.DOM.div( {className:"invite"},
React.DOM.input( {type:"url", value:this.state.callUrl, readOnly:"true",
className:cx({'pending': this.state.pending})} )
)
),
ToSView(null )
)
);
}
@ -201,9 +209,10 @@ loop.panel = (function(_, mozL10n) {
render: function() {
return (
React.DOM.div(null,
CallUrlForm( {client:this.props.client,
CallUrlResult( {client:this.props.client,
notifier:this.props.notifier} ),
DoNotDisturb(null )
ToSView(null ),
AvailabilityDropdown(null )
)
);
}
@ -229,7 +238,8 @@ loop.panel = (function(_, mozL10n) {
this._registerVisibilityChangeEvent();
this.on("panel:open panel:closed", this.reset, this);
this.on("panel:open panel:closed", this.clearNotifications, this);
this.on("panel:open", this.reset, this);
},
/**
@ -242,6 +252,8 @@ loop.panel = (function(_, mozL10n) {
* @link http://www.w3.org/TR/page-visibility/
*/
_registerVisibilityChangeEvent: function() {
// XXX pass in the visibility status to detect when to generate a new
// panel view
this.document.addEventListener("visibilitychange", function(event) {
this.trigger(event.currentTarget.hidden ? "panel:closed"
: "panel:open");
@ -255,6 +267,10 @@ loop.panel = (function(_, mozL10n) {
this.reset();
},
clearNotifications: function() {
this._notifier.clear();
},
/**
* Resets this router to its initial state.
*/
@ -290,8 +306,8 @@ loop.panel = (function(_, mozL10n) {
return {
init: init,
DoNotDisturb: DoNotDisturb,
CallUrlForm: CallUrlForm,
AvailabilityDropdown: AvailabilityDropdown,
CallUrlResult: CallUrlResult,
PanelView: PanelView,
PanelRouter: PanelRouter,
ToSView: ToSView

Просмотреть файл

@ -22,27 +22,82 @@ loop.panel = (function(_, mozL10n) {
var router;
/**
* Do not disturb panel subview.
* Availability drop down menu subview.
*/
var DoNotDisturb = React.createClass({
var AvailabilityDropdown = React.createClass({
getInitialState: function() {
return {doNotDisturb: navigator.mozLoop.doNotDisturb};
return {
doNotDisturb: navigator.mozLoop.doNotDisturb,
showMenu: false
};
},
handleCheckboxChange: function() {
showDropdownMenu: function() {
this.setState({showMenu: true});
},
hideDropdownMenu: function() {
this.setState({showMenu: false});
},
// XXX target event can either be the li, the span or the i tag
// this makes it easier to figure out the target by making a
// closure with the desired status already passed in.
changeAvailability: function(newAvailabilty) {
return function(event) {
// Note: side effect!
navigator.mozLoop.doNotDisturb = !navigator.mozLoop.doNotDisturb;
this.setState({doNotDisturb: navigator.mozLoop.doNotDisturb});
switch (newAvailabilty) {
case 'available':
this.setState({doNotDisturb: false});
navigator.mozLoop.doNotDisturb = false;
break;
case 'do-not-disturb':
this.setState({doNotDisturb: true});
navigator.mozLoop.doNotDisturb = true;
break;
}
this.hideDropdownMenu();
}.bind(this);
},
render: function() {
// XXX https://github.com/facebook/react/issues/310 for === htmlFor
var cx = React.addons.classSet;
var availabilityStatus = cx({
'status': true,
'status-dnd': this.state.doNotDisturb,
'status-available': !this.state.doNotDisturb
});
var availabilityDropdown = cx({
'dnd-menu': true,
'hide': !this.state.showMenu
});
var availabilityText = this.state.doNotDisturb ?
__("display_name_dnd_status") :
__("display_name_available_status");
return (
<p className="dnd">
<input type="checkbox" checked={this.state.doNotDisturb}
id="dnd-component" onChange={this.handleCheckboxChange} />
<label htmlFor="dnd-component">{__("do_not_disturb")}</label>
<div className="footer component-spacer">
<div className="do-not-disturb">
<p className="dnd-status" onClick={this.showDropdownMenu}>
<span>{availabilityText}</span>
<i className={availabilityStatus}></i>
</p>
<ul className={availabilityDropdown}
onMouseLeave={this.hideDropdownMenu}>
<li onClick={this.changeAvailability("available")}
className="dnd-menu-item dnd-make-available">
<i className="status status-available"></i>
<span>{__("display_name_available_status")}</span>
</li>
<li onClick={this.changeAvailability("do-not-disturb")}
className="dnd-menu-item dnd-make-unavailable">
<i className="status status-dnd"></i>
<span>{__("display_name_dnd_status")}</span>
</li>
</ul>
</div>
</div>
);
}
});
@ -60,7 +115,7 @@ loop.panel = (function(_, mozL10n) {
if (!this.state.seenToS) {
navigator.mozLoop.setLoopCharPref('seenToS', 'seen');
return <p className="tos"
return <p className="terms-service"
dangerouslySetInnerHTML={{__html: tosHTML}}></p>;
} else {
return <div />;
@ -75,9 +130,9 @@ loop.panel = (function(_, mozL10n) {
render: function() {
return (
<div className="share generate-url">
<div className="component-spacer share generate-url">
<div className="description">
<p>{this.props.summary}</p>
<p className="description-content">{this.props.summary}</p>
</div>
<div className="action">
{this.props.children}
@ -88,61 +143,27 @@ loop.panel = (function(_, mozL10n) {
});
var CallUrlResult = React.createClass({
propTypes: {
callUrl: React.PropTypes.string.isRequired,
retry: React.PropTypes.func.isRequired
},
handleButtonClick: function() {
this.props.retry();
},
render: function() {
// XXX setting elem value from a state (in the callUrl input)
// makes it immutable ie read only but that is fine in our case.
// readOnly attr will suppress a warning regarding this issue
// from the react lib.
return (
<PanelLayout summary={__("share_link_url")}>
<div className="invite">
<input type="url" value={this.props.callUrl} readOnly="true" />
<button onClick={this.handleButtonClick}
className="btn btn-success">{__("new_url")}</button>
</div>
</PanelLayout>
);
}
});
var CallUrlForm = React.createClass({
propTypes: {
client: React.PropTypes.object.isRequired,
notifier: React.PropTypes.object.isRequired
},
getInitialState: function() {
return {
pending: false,
disabled: true,
callUrl: false
callUrl: ''
};
},
retry: function() {
this.setState(this.getInitialState());
/**
* Returns a random 5 character string used to identify
* the conversation.
* XXX this will go away once the backend changes
*/
conversationIdentifier: function() {
return Math.random().toString(36).substring(5);
},
handleTextChange: function(event) {
this.setState({disabled: !event.currentTarget.value});
},
handleFormSubmit: function(event) {
event.preventDefault();
componentDidMount: function() {
this.setState({pending: true});
this.props.client.requestCallUrl(
this.refs.caller.getDOMNode().value, this._onCallUrlReceived);
this.props.client.requestCallUrl(this.conversationIdentifier(),
this._onCallUrlReceived);
},
_onCallUrlReceived: function(err, callUrlData) {
@ -160,30 +181,17 @@ loop.panel = (function(_, mozL10n) {
},
render: function() {
// If we have a call url, render result
if (this.state.callUrl) {
return (
<CallUrlResult callUrl={this.state.callUrl} retry={this.retry}/>
);
}
// If we don't display the form
// XXX setting elem value from a state (in the callUrl input)
// makes it immutable ie read only but that is fine in our case.
// readOnly attr will suppress a warning regarding this issue
// from the react lib.
var cx = React.addons.classSet;
return (
<PanelLayout summary={__("get_link_to_share")}>
<form className="invite" onSubmit={this.handleFormSubmit}>
<input type="text" name="caller" ref="caller" required="required"
className={cx({'pending': this.state.pending})}
onChange={this.handleTextChange}
placeholder={__("call_identifier_textinput_placeholder")} />
<button type="submit" className="get-url btn btn-success"
disabled={this.state.disabled}>
{__("get_a_call_url")}
</button>
</form>
<ToSView />
<PanelLayout summary={__("share_link_header_text")}>
<div className="invite">
<input type="url" value={this.state.callUrl} readOnly="true"
className={cx({'pending': this.state.pending})} />
</div>
</PanelLayout>
);
}
@ -201,9 +209,10 @@ loop.panel = (function(_, mozL10n) {
render: function() {
return (
<div>
<CallUrlForm client={this.props.client}
<CallUrlResult client={this.props.client}
notifier={this.props.notifier} />
<DoNotDisturb />
<ToSView />
<AvailabilityDropdown />
</div>
);
}
@ -229,7 +238,8 @@ loop.panel = (function(_, mozL10n) {
this._registerVisibilityChangeEvent();
this.on("panel:open panel:closed", this.reset, this);
this.on("panel:open panel:closed", this.clearNotifications, this);
this.on("panel:open", this.reset, this);
},
/**
@ -242,6 +252,8 @@ loop.panel = (function(_, mozL10n) {
* @link http://www.w3.org/TR/page-visibility/
*/
_registerVisibilityChangeEvent: function() {
// XXX pass in the visibility status to detect when to generate a new
// panel view
this.document.addEventListener("visibilitychange", function(event) {
this.trigger(event.currentTarget.hidden ? "panel:closed"
: "panel:open");
@ -255,6 +267,10 @@ loop.panel = (function(_, mozL10n) {
this.reset();
},
clearNotifications: function() {
this._notifier.clear();
},
/**
* Resets this router to its initial state.
*/
@ -290,8 +306,8 @@ loop.panel = (function(_, mozL10n) {
return {
init: init,
DoNotDisturb: DoNotDisturb,
CallUrlForm: CallUrlForm,
AvailabilityDropdown: AvailabilityDropdown,
CallUrlResult: CallUrlResult,
PanelView: PanelView,
PanelRouter: PanelRouter,
ToSView: ToSView

Просмотреть файл

@ -17,7 +17,7 @@ body {
padding: 0;
font-family: "Helvetica Neue", Helvetica, Arial, sans;
font-size: 14px;
background: #f2f2f2;
background: #fbfbfb;
}
button {
@ -70,7 +70,15 @@ img {
}
.btn-info {
background: #428BCA;
background: #0095dd;
}
.btn-info:hover {
background: #008acb;
}
.btn-info:active {
background: #006b9d;
}
.btn-success {

Просмотреть файл

@ -3,9 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* Panel styles */
a {
color: #0095DD;
body {
font-size: 12px;
}
.panel {
@ -14,18 +13,16 @@ a {
overflow: hidden;
}
.component-spacer {
padding: 5px 10px;
}
.spacer {
margin-bottom: 1em;
}
.share {
background: #f2f2f2;
}
.share .description {
background: #f7f7f7 url("../img/icon_32.png") no-repeat 1em 1.5em;
border-bottom: 1px solid #c3c3c3;
padding: 1em 1em 0 4em;
background: #fbfbfb;
}
.share .description .field {
@ -43,21 +40,16 @@ a {
width: 180px;
}
.description-content {
margin: .5em 0;
font-size: 1em;
font-weight: 700;
font-family: Open Sans,sans-serif;
color: #666;
}
.share .action {
clear: right;
padding: 1em;
border-top: 1px solid #fafafa;
}
.share .action p {
margin: 0 0 1em 0;
}
p.dnd {
margin: 0 10px 10px 10px;
/* The panel won't increase its height when using a bottom margin, while it
works using a padding */
padding-bottom: 10px;
}
.share .action input[type="text"],
@ -65,10 +57,13 @@ p.dnd {
border: 1px solid #ccc; /* Overriding background style for a text input (see
below) resets its borders to a weird beveled style;
defining a default 1px border solves the issue. */
font-size: .9em;
width: 65%;
padding: .5em;
margin-right: .35em;
font-size: 1em;
width: 100%;
padding: 0 10px;
margin: 5px 0;
border-radius: 2px;
outline: 0;
height: 24px;
}
.share .action input.pending {
@ -84,15 +79,102 @@ p.dnd {
padding-top: 6px;
}
.tos {
font-size: .6rem;
color: #a8a8a8;
text-align: center;
padding: 1rem;
}
/* Specific cases */
.panel #messages .alert {
margin-bottom: 0;
}
/* DnD menu */
.dnd-status {
border: 1px solid transparent;
padding: 2px 4px;
font-size: .9em;
cursor: pointer;
border-radius: 3px;
}
.dnd-status:hover {
border: 1px solid #DDD;
background: #F1F1F1;
}
.do-not-disturb {
position: relative;
}
.dnd-menu {
position: absolute;
top: -35px;
left: 10px;
background: #fdfdfd;
box-shadow: 0 1px 3px rgba(0,0,0,.3);
list-style: none;
padding: 5px;
border-radius: 2px;
}
.dnd-menu-item {
text-align: left;
margin: .3em 0;
padding: .2em .5em;
cursor: pointer;
border: 1px solid transparent;
border-radius: 2px;
font-size: 1em;
white-space: nowrap;
}
.dnd-menu-item:hover {
border: 1px solid #ccc;
background: #eee;
}
/* Status badges -- Available/Unavailable */
.status {
display: inline-block;
width: 8px;
height: 8px;
margin: 0 5px;
border-radius: 50%;
}
.status-available {
background: #6cb23e;
}
.status-dnd {
border: 1px solid #888;
}
/* Terms of Service */
.terms-service {
padding: 3px 10px 10px;
background: #FFF;
text-align: center;
opacity: .5;
transition: opacity .3s;
font-family: 'Lucida Grande', sans-serif;
font-size: .9em;
}
.terms-service a {
color: #0095dd;
}
/* Footer */
.footer {
font-size: 1em;
border-top: 1px solid #D1D1D1;
background: #EAEAEA;
color: #7F7F7F;
display: flex;
align-items: center;
margin-top: auto;
flex-direction: row;
}

Просмотреть файл

@ -145,7 +145,7 @@ describe("loop.panel", function() {
});
sinon.assert.calledOnce(router.trigger);
sinon.assert.calledWithExactly(router.trigger, "panel:open");
sinon.assert.calledWith(router.trigger, "panel:open");
});
it("should trigger panel:closed when the panel document is hidden",
@ -158,37 +158,44 @@ describe("loop.panel", function() {
});
sinon.assert.calledOnce(router.trigger);
sinon.assert.calledWithExactly(router.trigger, "panel:closed");
sinon.assert.calledWith(router.trigger, "panel:closed");
});
});
});
describe("loop.panel.DoNotDisturb", function() {
describe("loop.panel.AvailabilityDropdown", function() {
var view;
beforeEach(function() {
view = TestUtils.renderIntoDocument(loop.panel.DoNotDisturb());
view = TestUtils.renderIntoDocument(loop.panel.AvailabilityDropdown());
});
describe("Checkbox change event", function() {
describe("doNotDisturb preference change", function() {
beforeEach(function() {
navigator.mozLoop.doNotDisturb = false;
var checkbox = TestUtils.findRenderedDOMComponentWithTag(view, "input");
TestUtils.Simulate.change(checkbox);
navigator.mozLoop.doNotDisturb = true;
});
it("should toggle the value of mozLoop.doNotDisturb", function() {
expect(navigator.mozLoop.doNotDisturb).eql(true);
var availableMenuOption = view.getDOMNode()
.querySelector(".dnd-make-available");
TestUtils.Simulate.click(availableMenuOption);
expect(navigator.mozLoop.doNotDisturb).eql(false);
});
it("should update the DnD checkbox value", function() {
expect(view.getDOMNode().querySelector("input").checked).eql(true);
it("should toggle the dropdown menu", function() {
var availableMenuOption = view.getDOMNode()
.querySelector(".dnd-status span");
TestUtils.Simulate.click(availableMenuOption);
expect(view.state.showMenu).eql(true);
});
});
});
describe("loop.panel.CallUrlForm", function() {
describe("loop.panel.PanelView", function() {
var fakeClient, callUrlData, view;
beforeEach(function() {
@ -203,7 +210,7 @@ describe("loop.panel", function() {
}
};
view = TestUtils.renderIntoDocument(loop.panel.CallUrlForm({
view = TestUtils.renderIntoDocument(loop.panel.PanelView({
notifier: notifier,
client: fakeClient
}));
@ -215,69 +222,71 @@ describe("loop.panel", function() {
});
});
describe("Form submit event", function() {
function submitForm(callerValue) {
// fill caller field
TestUtils.Simulate.change(
TestUtils.findRenderedDOMComponentWithTag(view, "input"), {
target: {value: callerValue}
});
// submit form
TestUtils.Simulate.submit(
TestUtils.findRenderedDOMComponentWithTag(view, "form"));
describe("loop.panel.CallUrlResult", function() {
var fakeClient, callUrlData, view;
beforeEach(function() {
callUrlData = {
call_url: "http://call.invalid/",
expiresAt: 1000
};
fakeClient = {
requestCallUrl: function(_, cb) {
cb(null, callUrlData);
}
};
it("should reset all pending notifications", function() {
submitForm("foo");
sinon.assert.calledOnce(notifier.clear, "clear");
view = TestUtils.renderIntoDocument(loop.panel.CallUrlResult({
notifier: notifier,
client: fakeClient
}));
});
it("should request a call url to the server", function() {
fakeClient.requestCallUrl = sandbox.stub();
describe("Rendering the component should generate a call URL", function() {
submitForm("foo");
it("should make a request to requestCallUrl", function() {
sandbox.stub(fakeClient, "requestCallUrl");
var view = TestUtils.renderIntoDocument(loop.panel.CallUrlResult({
notifier: notifier,
client: fakeClient
}));
sinon.assert.calledOnce(fakeClient.requestCallUrl);
sinon.assert.calledWith(fakeClient.requestCallUrl, "foo");
sinon.assert.calledOnce(view.props.client.requestCallUrl);
sinon.assert.calledWithExactly(view.props.client.requestCallUrl,
sinon.match.string, sinon.match.func);
});
it("should set the call url form in a pending state", function() {
// Cancel requestCallUrl effect to keep the state pending
fakeClient.requestCallUrl = sandbox.stub();
submitForm("foo");
var view = TestUtils.renderIntoDocument(loop.panel.CallUrlResult({
notifier: notifier,
client: fakeClient
}));
expect(view.state.pending).eql(true);
});
it("should update state with the call url received", function() {
submitForm("foo");
expect(view.state.pending).eql(false);
expect(view.state.callUrl).eql(callUrlData.call_url);
});
it("should clear the pending state when a response is received",
function() {
submitForm("foo");
expect(view.state.pending).eql(false);
});
it("should update CallUrlResult with the call url", function() {
submitForm("foo");
var urlField = view.getDOMNode().querySelector("input[type='url']");
expect(urlField.value).eql(callUrlData.call_url);
});
it("should reset all pending notifications", function() {
submitForm("foo");
sinon.assert.calledOnce(view.props.notifier.clear);
});
@ -285,8 +294,10 @@ describe("loop.panel", function() {
fakeClient.requestCallUrl = function(_, cb) {
cb("fake error");
};
submitForm("foo");
var view = TestUtils.renderIntoDocument(loop.panel.CallUrlResult({
notifier: notifier,
client: fakeClient
}));
sinon.assert.calledOnce(notifier.errorL10n);
sinon.assert.calledWithExactly(notifier.errorL10n,
@ -320,7 +331,7 @@ describe("loop.panel", function() {
it("should render when the value of loop.seenToS is not set", function() {
var view = TestUtils.renderIntoDocument(loop.panel.ToSView());
TestUtils.findRenderedDOMComponentWithClass(view, "tos");
TestUtils.findRenderedDOMComponentWithClass(view, "terms-service");
});
it("should not render when the value of loop.seenToS is set to 'seen'",

Просмотреть файл

@ -16,8 +16,8 @@ function test_getStrings() {
// XXX This depends on the L10n values, which I'd prefer not to do, but is the
// simplest way for now.
Assert.equal(MozLoopService.getStrings("get_link_to_share"),
'{"textContent":"Get a link and invite someone to talk"}');
Assert.equal(MozLoopService.getStrings("share_link_header_text"),
'{"textContent":"Share this link to invite someone to talk:"}');
}
function run_test()

Просмотреть файл

@ -157,6 +157,29 @@ var gAdvancedPane = {
return checkbox.checked ? (this._storedSpellCheck == 2 ? 2 : 1) : 0;
},
/**
* security.OCSP.enabled is an integer value for legacy reasons.
* A value of 1 means OCSP is enabled. Any other value means it is disabled.
*/
readEnableOCSP: function ()
{
var preference = document.getElementById("security.OCSP.enabled");
// This is the case if the preference is the default value.
if (preference.value === undefined) {
return true;
}
return preference.value == 1;
},
/**
* See documentation for readEnableOCSP.
*/
writeEnableOCSP: function ()
{
var checkbox = document.getElementById("enableOCSP");
return checkbox.checked ? 1 : 0;
},
/**
* When the user toggles the layers.acceleration.disabled pref,
* sync its new value to the gfx.direct2d.disabled pref too.
@ -822,15 +845,6 @@ var gAdvancedPane = {
"", null);
},
/**
* Displays a dialog in which OCSP preferences can be configured.
*/
showOCSP: function ()
{
document.documentElement.openSubDialog("chrome://mozapps/content/preferences/ocsp.xul",
"", null);
},
/**
* Displays a dialog from which the user can manage his security devices.
*/

Просмотреть файл

@ -91,7 +91,7 @@
<preference id="browser.search.update" name="browser.search.update" type="bool"/>
<!-- Encryption tab -->
<!-- Certificates tab -->
<preference id="security.default_personal_cert" name="security.default_personal_cert" type="string"/>
<preference id="security.disable_button.openCertManager"
@ -100,6 +100,9 @@
<preference id="security.disable_button.openDeviceManager"
name="security.disable_button.openDeviceManager"
type="bool"/>
<preference id="security.OCSP.enabled"
name="security.OCSP.enabled"
type="int"/>
</preferences>
#ifdef HAVE_SHELL_SERVICE
@ -417,14 +420,20 @@
<separator/>
<checkbox id="enableOCSP"
label="&enableOCSP.label;"
accesskey="&enableOCSP.accesskey;"
onsyncfrompreference="return gAdvancedPane.readEnableOCSP();"
onsynctopreference="return gAdvancedPane.writeEnableOCSP();"
preference="security.OCSP.enabled"/>
<separator/>
<hbox>
<button id="viewCertificatesButton"
label="&viewCerts.label;" accesskey="&viewCerts.accesskey;"
oncommand="gAdvancedPane.showCertificates();"
preference="security.disable_button.openCertManager"/>
<button id="verificationButton"
label="&verify2.label;" accesskey="&verify2.accesskey;"
oncommand="gAdvancedPane.showOCSP();"/>
<button id="viewSecurityDevicesButton"
label="&viewSecurityDevices.label;" accesskey="&viewSecurityDevices.accesskey;"
oncommand="gAdvancedPane.showSecurityDevices();"

Просмотреть файл

@ -144,6 +144,28 @@ var gAdvancedPane = {
return checkbox.checked ? (this._storedSpellCheck == 2 ? 2 : 1) : 0;
},
/**
* security.OCSP.enabled is an integer value for legacy reasons.
* A value of 1 means OCSP is enabled. Any other value means it is disabled.
*/
readEnableOCSP: function ()
{
var preference = document.getElementById("security.OCSP.enabled");
// This is the case if the preference is the default value.
if (preference.value === undefined) {
return true;
}
return preference.value == 1;
},
/**
* See documentation for readEnableOCSP.
*/
writeEnableOCSP: function ()
{
var checkbox = document.getElementById("enableOCSP");
return checkbox.checked ? 1 : 0;
},
/**
* When the user toggles the layers.acceleration.disabled pref,
@ -794,16 +816,6 @@ var gAdvancedPane = {
"modal=yes", null);
},
/**
* Displays a dialog in which OCSP preferences can be configured.
*/
showOCSP: function ()
{
openDialog("chrome://mozapps/content/preferences/ocsp.xul",
"mozilla:crlmanager",
"modal=yes", null);
},
/**
* Displays a dialog from which the user can manage his security devices.
*/

Просмотреть файл

@ -107,7 +107,7 @@
name="browser.search.update"
type="bool"/>
<!-- Encryption tab -->
<!-- Certificates tab -->
<preference id="security.default_personal_cert"
name="security.default_personal_cert"
type="string"/>
@ -115,9 +115,14 @@
<preference id="security.disable_button.openCertManager"
name="security.disable_button.openCertManager"
type="bool"/>
<preference id="security.disable_button.openDeviceManager"
name="security.disable_button.openDeviceManager"
type="bool"/>
<preference id="security.OCSP.enabled"
name="security.OCSP.enabled"
type="int"/>
</preferences>
#ifdef HAVE_SHELL_SERVICE
@ -439,14 +444,20 @@
<separator/>
<checkbox id="enableOCSP"
label="&enableOCSP.label;"
accesskey="&enableOCSP.accesskey;"
onsyncfrompreference="return gAdvancedPane.readEnableOCSP();"
onsynctopreference="return gAdvancedPane.writeEnableOCSP();"
preference="security.OCSP.enabled"/>
<separator/>
<hbox>
<button id="viewCertificatesButton"
label="&viewCerts.label;" accesskey="&viewCerts.accesskey;"
oncommand="gAdvancedPane.showCertificates();"
preference="security.disable_button.openCertManager"/>
<button id="verificationButton"
label="&verify2.label;" accesskey="&verify2.accesskey;"
oncommand="gAdvancedPane.showOCSP();"/>
<button id="viewSecurityDevicesButton"
label="&viewSecurityDevices.label;" accesskey="&viewSecurityDevices.accesskey;"
oncommand="gAdvancedPane.showSecurityDevices();"

Просмотреть файл

@ -36,7 +36,6 @@
autocompletepopup="PopupAutoComplete"
autocompletesearch="search-autocomplete"
autocompletesearchparam="searchbar-history"
timeout="250"
maxrows="10"
completeselectedindex="true"
showcommentcolumn="true"
@ -536,22 +535,7 @@
<![CDATA[
// Speculatively connect to the current engine's search URI (and
// suggest URI, if different) to reduce request latency
const SUGGEST_TYPE = "application/x-suggestions+json";
var engine = this.currentEngine;
var connector =
Services.io.QueryInterface(Components.interfaces.nsISpeculativeConnect);
var searchURI = engine.getSubmission("dummy", null, "searchbar").uri;
let callbacks = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation)
.QueryInterface(Components.interfaces.nsILoadContext);
connector.speculativeConnect(searchURI, callbacks);
if (engine.supportsResponseType(SUGGEST_TYPE)) {
var suggestURI = engine.getSubmission("dummy", SUGGEST_TYPE, "searchbar").uri;
if (suggestURI.prePath != searchURI.prePath)
connector.speculativeConnect(suggestURI, callbacks);
}
this.currentEngine.speculativeConnect({window: window});
]]></handler>
</handlers>
</binding>

Просмотреть файл

@ -55,10 +55,6 @@ ifdef NSS_DISABLE_DBM
DEFINES += -DNSS_DISABLE_DBM=1
endif
ifdef _MSC_VER
DEFINES += -D_MSC_VER=$(_MSC_VER)
endif
DEFINES += -DJAREXT=
ifdef MOZ_ANGLE_RENDERER
@ -76,7 +72,9 @@ DEFINES += -DMOZ_CHILD_PROCESS_NAME=$(MOZ_CHILD_PROCESS_NAME)
# Set MSVC dlls version to package, if any.
ifdef WIN32_REDIST_DIR
ifdef MOZ_NO_DEBUG_RTL
DEFINES += -DMOZ_MSVC_REDIST=$(_MSC_VER)
DEFINES += -DMOZ_PACKAGE_MSVC_DLLS=1
DEFINES += -DMSVC_C_RUNTIME_DLL=$(MSVC_C_RUNTIME_DLL)
DEFINES += -DMSVC_CXX_RUNTIME_DLL=$(MSVC_CXX_RUNTIME_DLL)
endif
endif

Просмотреть файл

@ -85,15 +85,9 @@
#endif
#ifdef XP_WIN32
@BINPATH@/plugin-hang-ui@BIN_SUFFIX@
#if MOZ_MSVC_REDIST == 1600
@BINPATH@/msvcp100.dll
@BINPATH@/msvcr100.dll
#elif MOZ_MSVC_REDIST == 1700
@BINPATH@/msvcp110.dll
@BINPATH@/msvcr110.dll
#elif MOZ_MSVC_REDIST == 1800
@BINPATH@/msvcp120.dll
@BINPATH@/msvcr120.dll
#if MOZ_PACKAGE_MSVC_DLLS
@BINPATH@/@MSVC_C_RUNTIME_DLL@
@BINPATH@/@MSVC_CXX_RUNTIME_DLL@
#endif
#endif
#ifndef MOZ_NATIVE_ICU

Просмотреть файл

@ -4,13 +4,11 @@
# Panel Strings
get_link_to_share=Get a link and invite someone to talk
share_link_url=Share the link below with your friend to start your call!
do_not_disturb=Do not disturb
share_link_header_text=Share this link to invite someone to talk:
get_a_call_url=Get a call url
new_url=New url
call_identifier_textinput_placeholder=Identify this call
# Status text
display_name_dnd_status=Do Not Disturb
display_name_available_status=Available
unable_retrieve_url=Sorry, we were unable to retrieve a call url.
@ -38,4 +36,4 @@ connection_error_see_console_notification=Call failed; see console for details.
## part between {{..}}
legal_text_and_links=By using this product you agree to the <a \
target="_blank" href="{{terms_of_use_url}}">Terms of Use</a> and <a \
href="{{privacy_notice_url}}">Privacy Notice</a>
href="{{privacy_notice_url}}">Privacy Notice</a>.

Просмотреть файл

@ -128,9 +128,9 @@
<!ENTITY certs.auto.accesskey "S">
<!ENTITY certs.ask "Ask me every time">
<!ENTITY certs.ask.accesskey "A">
<!ENTITY enableOCSP.label "Query OCSP responder servers to confirm the current validity of certificates">
<!ENTITY enableOCSP.accesskey "Q">
<!ENTITY viewCerts.label "View Certificates">
<!ENTITY viewCerts.accesskey "C">
<!ENTITY verify2.label "Validation">
<!ENTITY verify2.accesskey "V">
<!ENTITY viewSecurityDevices.label "Security Devices">
<!ENTITY viewSecurityDevices.accesskey "D">

Просмотреть файл

@ -184,10 +184,6 @@ fi
dnl A high level macro for selecting compiler options.
AC_DEFUN([MOZ_COMPILER_OPTS],
[
if test "${MOZ_PSEUDO_DERECURSE-unset}" = unset; then
MOZ_PSEUDO_DERECURSE=1
fi
MOZ_DEBUGGING_OPTS
MOZ_RTTI
if test "$CLANG_CXX"; then

Просмотреть файл

@ -209,5 +209,3 @@ MOZ_RUN_CONFIG_STATUS()],
define([AC_CONFIG_HEADER],
[m4_fatal([Use CONFIGURE_DEFINE_FILES in moz.build files to produce header files.])
])
AC_SUBST([MOZ_PSEUDO_DERECURSE])

Просмотреть файл

@ -20,7 +20,6 @@ export
compile
Build the *compile* tier. The *compile* tier compiles all C/C++ files.
Only applies to builds with ``MOZ_PSEUDO_DERECURSE``.
libs
Build the *libs* tier. The *libs* tier performs linking and performs
@ -36,7 +35,6 @@ binaries:
build, but allows for much faster rebuilds of C/C++ code. For performance
reasons, however, it skips nss, nspr, icu and ffi. This is targeted to
improve local developer workflow when touching C/C++ code.
Only applies to builds with ``MOZ_PSEUDO_DERECURSE``.
install-manifests
Process install manifests. Install manifests handle the installation of

Просмотреть файл

@ -29,21 +29,3 @@ MACH_NO_WRITE_TIMES
If defined, mach commands will not prefix output lines with the
elapsed time since program start. This option is equivalent to
passing ``--log-no-times`` to mach.
MOZ_PSEUDO_DERECURSE
Activate an *experimental* build mode where make directory traversal
is derecursified. This mode should result in faster build times at
the expense of busted builds from time-to-time. The end goal is for
this build mode to be the default. At which time, this variable will
likely go away.
A value of ``1`` activates the mode with full optimizations.
A value of ``no-parallel-export`` activates the mode without
optimizations to the *export* tier, which are known to be slightly
buggy.
A value of ``no-skip`` activates the mode without optimizations to skip
some directories during traversal.
Values may be combined with a comma.

Просмотреть файл

@ -8,35 +8,17 @@ include $(topsrcdir)/config/rules.mk
ifdef WIN32_REDIST_DIR
ifeq (1600,$(_MSC_VER))
REDIST_FILES = \
msvcp100.dll \
msvcr100.dll \
$(MSVC_C_RUNTIME_DLL) \
$(MSVC_CXX_RUNTIME_DLL) \
$(NULL)
endif
ifeq (1700,$(_MSC_VER))
REDIST_FILES = \
msvcp110.dll \
msvcr110.dll \
$(NULL)
endif
ifeq (1800,$(_MSC_VER))
REDIST_FILES = \
msvcp120.dll \
msvcr120.dll \
$(NULL)
endif
ifdef REDIST_FILES
libs-preqs = \
$(call mkdir_deps,$(FINAL_TARGET)) \
$(NULL)
libs:: $(libs-preqs)
install --preserve-timestamps $(foreach f,$(REDIST_FILES),'$(WIN32_REDIST_DIR)'/$(f)) $(FINAL_TARGET)
endif
endif # WIN32_REDIST_DIR

Просмотреть файл

@ -64,6 +64,7 @@
#include "nsContentUtils.h"
#include "nsCxPusher.h"
#include "nsJSUtils.h"
#include "nsILoadInfo.h"
// This should be probably defined on some other place... but I couldn't find it
#define WEBAPPS_PERM_NAME "webapps-manage"
@ -265,6 +266,20 @@ nsScriptSecurityManager::GetChannelPrincipal(nsIChannel* aChannel,
}
}
// Check whether we have an nsILoadInfo that says what we should do.
nsCOMPtr<nsILoadInfo> loadInfo;
aChannel->GetLoadInfo(getter_AddRefs(loadInfo));
if (loadInfo) {
if (loadInfo->GetLoadingSandboxed()) {
return CallCreateInstance(NS_NULLPRINCIPAL_CONTRACTID, aPrincipal);
}
if (loadInfo->GetForceInheritPrincipal()) {
NS_ADDREF(*aPrincipal = loadInfo->LoadingPrincipal());
return NS_OK;
}
}
// OK, get the principal from the URI. Make sure this does the same thing
// as nsDocument::Reset and XULDocument::StartDocumentLoad.
nsCOMPtr<nsIURI> uri;

Просмотреть файл

@ -198,11 +198,6 @@ endif
CONFIG_TOOLS = $(MOZ_BUILD_ROOT)/config
AUTOCONF_TOOLS = $(topsrcdir)/build/autoconf
# Disable MOZ_PSEUDO_DERECURSE on PGO builds until it's fixed.
ifneq (,$(MOZ_PROFILE_USE)$(MOZ_PROFILE_GENERATE))
MOZ_PSEUDO_DERECURSE :=
endif
#
# Strip off the excessively long version numbers on these platforms,
# but save the version to allow multiple versions of the same base

Просмотреть файл

@ -100,7 +100,6 @@ endif
endif # !NO_DIST_INSTALL
ifdef MOZ_PSEUDO_DERECURSE
BINARIES_INSTALL_TARGETS := $(foreach category,$(INSTALL_TARGETS),$(if $(filter binaries,$($(category)_TARGET)),$(category)))
# Fill a dependency file with all the binaries installed somewhere in $(DIST)
@ -114,9 +113,4 @@ $(BINARIES_PP): Makefile $(wildcard backend.mk) $(call mkdir_deps,$(MDDEPDIR))
)\
))binaries: Makefile $(wildcard backend.mk)' | tr % '\n' > $@
else
binaries::
$(error The binaries target is not supported without MOZ_PSEUDO_DERECURSE)
endif
# EOF

Просмотреть файл

@ -22,8 +22,7 @@ endif
# make -C foo/baz
# make -C qux
# MOZ_PSEUDO_DERECURSE can have values other than 1.
ifeq (1_.,$(if $(MOZ_PSEUDO_DERECURSE),1)_$(DEPTH))
ifeq (.,$(DEPTH))
include root.mk
@ -106,6 +105,8 @@ $(addsuffix /$(CURRENT_TIER),$(filter-out config,$(CURRENT_DIRS))): config/$(CUR
endif
ifdef COMPILE_ENVIRONMENT
# Disable dependency aggregation on PGO builds because of bug 934166.
ifeq (,$(MOZ_PGO)$(MOZ_PROFILE_USE)$(MOZ_PROFILE_GENERATE))
ifneq (,$(filter libs binaries,$(CURRENT_TIER)))
# When doing a "libs" build, target_libs.mk ensures the interesting dependency data
# is available in the "binaries" stamp. Once recursion is done, aggregate all that
@ -135,6 +136,8 @@ DIST_GARBAGE += binaries-deps.mk binaries-deps
endif
endif
else
# Don't recurse if MAKELEVEL is NO_RECURSE_MAKELEVEL as defined above
@ -185,9 +188,7 @@ endif # ifdef TIERS
endif # ifeq ($(NO_RECURSE_MAKELEVEL),$(MAKELEVEL))
endif # ifeq (1_.,$(MOZ_PSEUDO_DERECURSE)_$(DEPTH))
ifdef MOZ_PSEUDO_DERECURSE
endif # ifeq (.,$(DEPTH))
ifdef COMPILE_ENVIRONMENT
@ -204,13 +205,14 @@ ALL_DEP_FILES := \
endif
binaries libs:: $(TARGETS) $(BINARIES_PP)
# Disable dependency aggregation on PGO builds because of bug 934166.
ifeq (,$(MOZ_PGO)$(MOZ_PROFILE_USE)$(MOZ_PROFILE_GENERATE))
ifneq (.,$(DEPTH))
@$(if $^,$(call py_action,link_deps,-o binaries --group-all --topsrcdir $(topsrcdir) --topobjdir $(DEPTH) --dist $(DIST) $(ALL_DEP_FILES)))
endif
endif
endif # ifdef MOZ_PSEUDO_DERECURSE
endif
recurse:
@$(RECURSED_COMMAND)

Просмотреть файл

@ -177,18 +177,20 @@ else
SHARED_LIBRARY := $(DLL_PREFIX)$(SHARED_LIBRARY_NAME)$(DLL_SUFFIX)
endif
ifdef SONAME
DSO_SONAME = $(DLL_PREFIX)$(SONAME)$(DLL_SUFFIX)
else
DSO_SONAME = $(notdir $@)
endif
EMBED_MANIFEST_AT=2
endif # MKSHLIB
endif # FORCE_SHARED_LIB
endif # LIBRARY
ifdef MKSHLIB
ifdef SONAME
DSO_SONAME = $(DLL_PREFIX)$(SONAME)$(DLL_SUFFIX)
else
DSO_SONAME = $(notdir $@)
endif
endif # MKSHLIB
ifdef FORCE_STATIC_LIB
ifndef FORCE_SHARED_LIB
SHARED_LIBRARY := $(NULL)
@ -581,10 +583,8 @@ endif
# default rule before including rules.mk
default all::
$(MAKE) export
ifdef MOZ_PSEUDO_DERECURSE
ifdef COMPILE_ENVIRONMENT
$(MAKE) compile
endif
endif
$(MAKE) libs
$(MAKE) tools

Просмотреть файл

@ -481,16 +481,24 @@ case "$target" in
if test "$_CC_MAJOR_VERSION" = "16"; then
_CC_SUITE=10
MSVS_VERSION=2010
MSVC_C_RUNTIME_DLL=msvcr100.dll
MSVC_CXX_RUNTIME_DLL=msvcp100.dll
elif test "$_CC_MAJOR_VERSION" = "17"; then
_CC_SUITE=11
MSVS_VERSION=2012
MSVC_C_RUNTIME_DLL=msvcr110.dll
MSVC_CXX_RUNTIME_DLL=msvcp110.dll
elif test "$_CC_MAJOR_VERSION" = "18"; then
_CC_SUITE=12
MSVS_VERSION=2013
MSVC_C_RUNTIME_DLL=msvcr120.dll
MSVC_CXX_RUNTIME_DLL=msvcp120.dll
else
AC_MSG_ERROR([This version ($CC_VERSION) of the MSVC compiler is unsupported. See https://developer.mozilla.org/en/Windows_Build_Prerequisites.])
fi
AC_SUBST(MSVS_VERSION)
AC_SUBST(MSVC_C_RUNTIME_DLL)
AC_SUBST(MSVC_CXX_RUNTIME_DLL)
# Disable SEH on clang-cl because it doesn't implement them yet.
if test -z "$CLANG_CL"; then

Просмотреть файл

@ -1993,20 +1993,27 @@ public:
static nsresult URIInheritsSecurityContext(nsIURI *aURI, bool *aResult);
/**
* Set the given principal as the owner of the given channel, if
* needed. aURI must be the URI of aChannel. aPrincipal may be
* null. If aSetUpForAboutBlank is true, then about:blank will get
* the principal set up on it. If aForceOwner is true, the owner
* will be set on the channel, even if the principal can be determined
* from the channel.
* The return value is whether the principal was set up as the owner
* of the channel.
* Set the given principal as the principal on the nsILoadInfo of the given
* channel, and tell the channel to inherit it if needed. aPrincipal may be
* null, in which case this method is a no-op.
*
* If aLoadingPrincipal is not null, aURI must be the URI of aChannel. If
* aInheritForAboutBlank is true, then about:blank will be told to inherit the
* principal. If aForceInherit is true, the channel will be told to inherit
* the principal no matter what, as long as the principal is not null.
*
* If aIsSandboxed is true, then aLoadingPrincipal must not be null. In this
* case, the owner on the channel, if any, will be reset to null and the
* nsILoadInfo will say the channel should be sandboxed.
*
* The return value is whether the channel was told to inherit the principal.
*/
static bool SetUpChannelOwner(nsIPrincipal* aLoadingPrincipal,
nsIChannel* aChannel,
nsIURI* aURI,
bool aSetUpForAboutBlank,
bool aForceOwner = false);
bool aInheritForAboutBlank,
bool aIsSandboxed,
bool aForceInherit);
static nsresult Btoa(const nsAString& aBinaryData,
nsAString& aAsciiBase64String);

Просмотреть файл

@ -132,8 +132,8 @@ typedef CallbackObjectHolder<NodeFilter, nsIDOMNodeFilter> NodeFilterHolder;
} // namespace mozilla
#define NS_IDOCUMENT_IID \
{ 0xc9e11955, 0xaa55, 0x49a1, \
{ 0x94, 0x29, 0x58, 0xe9, 0xbe, 0xf6, 0x79, 0x54 } }
{ 0xa45ef8f0, 0x7c5b, 0x425d, \
{ 0xa5, 0xe7, 0x11, 0x41, 0x5c, 0x41, 0x0c, 0x7a } }
// Enum for requesting a particular type of document when creating a doc
enum DocumentFlavor {
@ -851,6 +851,7 @@ public:
};
virtual nsresult LoadAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetURI) = 0;
virtual nsresult AddAdditionalStyleSheet(additionalSheetType aType, nsIStyleSheet* aSheet) = 0;
virtual void RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* sheetURI) = 0;
virtual nsIStyleSheet* FirstAdditionalAuthorSheet() = 0;

Просмотреть файл

@ -15,6 +15,7 @@
#include "nsDOMJSUtils.h"
#include "nsError.h"
#include "nsPIDOMWindow.h"
#include "mozilla/LoadInfo.h"
#include "mozilla/dom/BindingUtils.h"
using namespace mozilla;
@ -242,7 +243,10 @@ DOMParser::ParseFromStream(nsIInputStream *stream,
NS_ENSURE_STATE(parserChannel);
// More principal-faking here
parserChannel->SetOwner(mOriginalPrincipal);
nsCOMPtr<nsILoadInfo> loadInfo =
new LoadInfo(mOriginalPrincipal, LoadInfo::eInheritPrincipal,
LoadInfo::eNotSandboxed);
parserChannel->SetLoadInfo(loadInfo);
if (charset) {
parserChannel->SetContentCharset(nsDependentCString(charset));

Просмотреть файл

@ -7,6 +7,7 @@
#include "mozilla/ArrayUtils.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/LoadInfo.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/dom/EventSourceBinding.h"
#include "mozilla/dom/MessageEvent.h"
@ -375,7 +376,10 @@ EventSource::OnStartRequest(nsIRequest *aRequest,
principal = do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
}
rv = httpChannel->SetOwner(principal);
nsCOMPtr<nsILoadInfo> loadInfo =
new LoadInfo(principal, LoadInfo::eInheritPrincipal,
LoadInfo::eNotSandboxed);
rv = httpChannel->SetLoadInfo(loadInfo);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIRunnable> event =

Просмотреть файл

@ -34,6 +34,7 @@
#include "mozilla/AutoRestore.h"
#include "mozilla/Base64.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/LoadInfo.h"
#include "mozilla/dom/DocumentFragment.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/HTMLMediaElement.h"
@ -6429,15 +6430,25 @@ bool
nsContentUtils::SetUpChannelOwner(nsIPrincipal* aLoadingPrincipal,
nsIChannel* aChannel,
nsIURI* aURI,
bool aSetUpForAboutBlank,
bool aForceOwner)
bool aInheritForAboutBlank,
bool aIsSandboxed,
bool aForceInherit)
{
if (!aLoadingPrincipal) {
// Nothing to do here
MOZ_ASSERT(!aIsSandboxed);
return false;
}
// If we're sandboxed, make sure to clear any owner the channel
// might already have.
if (aIsSandboxed) {
aChannel->SetOwner(nullptr);
}
// Set the loadInfo of the channel, but only tell the channel to
// inherit if it can't provide its own security context.
//
// Set the owner of the channel, but only for channels that can't
// provide their own security context.
//
// XXX: It seems wrong that the owner is ignored - even if one is
// supplied) unless the URI is javascript or data or about:blank.
// XXX: If this is ever changed, check all callers for what owners
// they're passing in. In particular, see the code and
// comments in nsDocShell::LoadURI where we fall back on
@ -6445,39 +6456,18 @@ nsContentUtils::SetUpChannelOwner(nsIPrincipal* aLoadingPrincipal,
// very wrong if this code changed anything but channels that
// can't provide their own security context!
//
// (Currently chrome URIs set the owner when they are created!
// So setting a nullptr owner would be bad!)
//
// If aForceOwner is true, the owner will be set, even for a channel that
// can provide its own security context. This is used for the HTML5 IFRAME
// sandbox attribute, so we can force the channel (and its document) to
// explicitly have a null principal.
bool inherit;
// If aForceInherit is true, we will inherit, even for a channel that
// can provide its own security context. This is used for srcdoc loads.
bool inherit = aForceInherit;
if (!inherit) {
bool uriInherits;
// We expect URIInheritsSecurityContext to return success for an
// about:blank URI, so don't call NS_IsAboutBlank() if this call fails.
// This condition needs to match the one in nsDocShell::InternalLoad where
// we're checking for things that will use the owner.
if (aForceOwner || ((NS_SUCCEEDED(URIInheritsSecurityContext(aURI, &inherit)) &&
(inherit || (aSetUpForAboutBlank && NS_IsAboutBlank(aURI)))))) {
#ifdef DEBUG
// Assert that aForceOwner is only set for null principals for non-srcdoc
// loads. (Strictly speaking not all uses of about:srcdoc would be
// srcdoc loads, but the URI is non-resolvable in cases where it is not).
if (aForceOwner) {
nsAutoCString uriStr;
aURI->GetSpec(uriStr);
if(!uriStr.EqualsLiteral("about:srcdoc") &&
!uriStr.EqualsLiteral("view-source:about:srcdoc")) {
nsCOMPtr<nsIURI> ownerURI;
nsresult rv = aLoadingPrincipal->GetURI(getter_AddRefs(ownerURI));
MOZ_ASSERT(NS_SUCCEEDED(rv) && SchemeIs(ownerURI, NS_NULLPRINCIPAL_SCHEME));
}
}
#endif
aChannel->SetOwner(aLoadingPrincipal);
return true;
}
inherit =
(NS_SUCCEEDED(URIInheritsSecurityContext(aURI, &uriInherits)) &&
(uriInherits || (aInheritForAboutBlank && NS_IsAboutBlank(aURI)))) ||
//
// file: uri special-casing
//
@ -6486,16 +6476,20 @@ nsContentUtils::SetUpChannelOwner(nsIPrincipal* aLoadingPrincipal,
// If we don't set the owner explicitly then each file: gets an owner
// based on its own codebase later.
//
if (URIIsLocalFile(aURI) && aLoadingPrincipal &&
(URIIsLocalFile(aURI) &&
NS_SUCCEEDED(aLoadingPrincipal->CheckMayLoad(aURI, false, false)) &&
// One more check here. CheckMayLoad will always return true for the
// system principal, but we do NOT want to inherit in that case.
!IsSystemPrincipal(aLoadingPrincipal)) {
aChannel->SetOwner(aLoadingPrincipal);
return true;
!IsSystemPrincipal(aLoadingPrincipal));
}
return false;
nsCOMPtr<nsILoadInfo> loadInfo =
new LoadInfo(aLoadingPrincipal,
inherit ?
LoadInfo::eInheritPrincipal : LoadInfo::eDontInheritPrincipal,
aIsSandboxed ? LoadInfo::eSandboxed : LoadInfo::eNotSandboxed);
aChannel->SetLoadInfo(loadInfo);
return inherit && !aIsSandboxed;
}
/* static */

Просмотреть файл

@ -4221,22 +4221,34 @@ nsDocument::LoadAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetUR
true, getter_AddRefs(sheet));
NS_ENSURE_SUCCESS(rv, rv);
mAdditionalSheets[aType].AppendObject(sheet);
sheet->SetOwningDocument(this);
MOZ_ASSERT(sheet->IsApplicable());
return AddAdditionalStyleSheet(aType, sheet);
}
nsresult
nsDocument::AddAdditionalStyleSheet(additionalSheetType aType, nsIStyleSheet* aSheet)
{
if (mAdditionalSheets[aType].Contains(aSheet))
return NS_ERROR_INVALID_ARG;
if (!aSheet->IsApplicable())
return NS_ERROR_INVALID_ARG;
mAdditionalSheets[aType].AppendObject(aSheet);
BeginUpdate(UPDATE_STYLE);
nsCOMPtr<nsIPresShell> shell = GetShell();
if (shell) {
nsStyleSet::sheetType type = ConvertAdditionalSheetType(aType);
shell->StyleSet()->AppendStyleSheet(type, sheet);
shell->StyleSet()->AppendStyleSheet(type, aSheet);
}
// Passing false, so documet.styleSheets.length will not be affected by
// these additional sheets.
NotifyStyleSheetAdded(sheet, false);
NotifyStyleSheetAdded(aSheet, false);
EndUpdate(UPDATE_STYLE);
return NS_OK;
}
@ -11875,6 +11887,10 @@ SizeOfStyleSheetsElementIncludingThis(nsIStyleSheet* aStyleSheet,
MallocSizeOf aMallocSizeOf,
void* aData)
{
if (!aStyleSheet->GetOwningDocument()) {
// Avoid over-reporting shared sheets.
return 0;
}
return aStyleSheet->SizeOfIncludingThis(aMallocSizeOf);
}

Просмотреть файл

@ -809,6 +809,7 @@ public:
bool aApplicable) MOZ_OVERRIDE;
virtual nsresult LoadAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetURI) MOZ_OVERRIDE;
virtual nsresult AddAdditionalStyleSheet(additionalSheetType aType, nsIStyleSheet* aSheet) MOZ_OVERRIDE;
virtual void RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* sheetURI) MOZ_OVERRIDE;
virtual nsIStyleSheet* FirstAdditionalAuthorSheet() MOZ_OVERRIDE;

Просмотреть файл

@ -15,8 +15,10 @@
#include "mozilla/dom/MediaSource.h"
#include "nsIMemoryReporter.h"
#include "mozilla/Preferences.h"
#include "mozilla/LoadInfo.h"
using mozilla::dom::DOMFileImpl;
using mozilla::LoadInfo;
// -----------------------------------------------------------------------
// Hash table
@ -506,8 +508,6 @@ nsHostObjectProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
stream);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISupports> owner = do_QueryInterface(info->mPrincipal);
nsString type;
rv = blob->GetType(type);
NS_ENSURE_SUCCESS(rv, rv);
@ -523,7 +523,10 @@ nsHostObjectProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
rv = blob->GetSize(&size);
NS_ENSURE_SUCCESS(rv, rv);
channel->SetOwner(owner);
nsCOMPtr<nsILoadInfo> loadInfo =
new mozilla::LoadInfo(info->mPrincipal, LoadInfo::eInheritPrincipal,
LoadInfo::eNotSandboxed);
channel->SetLoadInfo(loadInfo);
channel->SetOriginalURI(uri);
channel->SetContentType(NS_ConvertUTF16toUTF8(type));
channel->SetContentLength(size);

Просмотреть файл

@ -2367,18 +2367,11 @@ nsObjectLoadingContent::OpenChannel()
// Set up the channel's principal and such, like nsDocShell::DoURILoad does.
// If the content being loaded should be sandboxed with respect to origin we
// create a new null principal here. nsContentUtils::SetUpChannelOwner is
// used with a flag to force it to be set as the channel owner.
nsCOMPtr<nsIPrincipal> ownerPrincipal;
uint32_t sandboxFlags = doc->GetSandboxFlags();
if (sandboxFlags & SANDBOXED_ORIGIN) {
ownerPrincipal = do_CreateInstance("@mozilla.org/nullprincipal;1");
} else {
// Not sandboxed - we allow the content to assume its natural owner.
ownerPrincipal = thisContent->NodePrincipal();
}
nsContentUtils::SetUpChannelOwner(ownerPrincipal, chan, mURI, true,
sandboxFlags & SANDBOXED_ORIGIN);
// tell SetUpChannelOwner that.
nsContentUtils::SetUpChannelOwner(thisContent->NodePrincipal(), chan, mURI,
true,
doc->GetSandboxFlags() & SANDBOXED_ORIGIN,
false);
nsCOMPtr<nsIScriptChannel> scriptChannel = do_QueryInterface(chan);
if (scriptChannel) {

Просмотреть файл

@ -13,6 +13,7 @@
#include "mozilla/dom/XMLHttpRequestUploadBinding.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/EventListenerManager.h"
#include "mozilla/LoadInfo.h"
#include "mozilla/MemoryReporting.h"
#include "nsDOMBlobBuilder.h"
#include "nsIDOMDocument.h"
@ -1973,7 +1974,10 @@ nsXMLHttpRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
documentPrincipal = mPrincipal;
}
channel->SetOwner(documentPrincipal);
nsCOMPtr<nsILoadInfo> loadInfo =
new LoadInfo(documentPrincipal, LoadInfo::eInheritPrincipal,
LoadInfo::eNotSandboxed);
channel->SetLoadInfo(loadInfo);
nsresult status;
request->GetStatus(&status);

Просмотреть файл

@ -2112,14 +2112,14 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
case LOCAL_GL_UNSIGNED_BYTE:
isReadTypeValid = true;
bytesPerPixel = 1*channels;
requiredDataType = js::ArrayBufferView::TYPE_UINT8;
requiredDataType = js::Scalar::Uint8;
break;
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
isReadTypeValid = true;
bytesPerPixel = 2;
requiredDataType = js::ArrayBufferView::TYPE_UINT16;
requiredDataType = js::Scalar::Uint16;
break;
case LOCAL_GL_FLOAT:
if (IsExtensionEnabled(WebGLExtensionID::WEBGL_color_buffer_float) ||
@ -2128,7 +2128,7 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
isReadTypeValid = true;
isReadTypeFloat = true;
bytesPerPixel = 4*channels;
requiredDataType = js::ArrayBufferView::TYPE_FLOAT32;
requiredDataType = js::Scalar::Float32;
}
break;
}

Просмотреть файл

@ -1202,7 +1202,7 @@ WebGLContext::ValidateTexInputData(GLenum type, int jsArrayType, WebGLTexImageFu
// First, we check for packed types
switch (type) {
case LOCAL_GL_UNSIGNED_BYTE:
validInput = (jsArrayType == -1 || jsArrayType == js::ArrayBufferView::TYPE_UINT8);
validInput = (jsArrayType == -1 || jsArrayType == js::Scalar::Uint8);
break;
case LOCAL_GL_HALF_FLOAT:
@ -1211,16 +1211,16 @@ WebGLContext::ValidateTexInputData(GLenum type, int jsArrayType, WebGLTexImageFu
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
validInput = (jsArrayType == -1 || jsArrayType == js::ArrayBufferView::TYPE_UINT16);
validInput = (jsArrayType == -1 || jsArrayType == js::Scalar::Uint16);
break;
case LOCAL_GL_UNSIGNED_INT:
case LOCAL_GL_UNSIGNED_INT_24_8:
validInput = (jsArrayType == -1 || jsArrayType == js::ArrayBufferView::TYPE_UINT32);
validInput = (jsArrayType == -1 || jsArrayType == js::Scalar::Uint32);
break;
case LOCAL_GL_FLOAT:
validInput = (jsArrayType == -1 || jsArrayType == js::ArrayBufferView::TYPE_FLOAT32);
validInput = (jsArrayType == -1 || jsArrayType == js::Scalar::Float32);
break;
default:

Просмотреть файл

@ -83,6 +83,7 @@
#include "mozilla/dom/EncodingUtils.h"
#include "mozilla/dom/FallbackEncoding.h"
#include "mozilla/LoadInfo.h"
#include "nsIEditingSession.h"
#include "nsIEditor.h"
#include "nsNodeInfoManager.h"
@ -1525,7 +1526,10 @@ nsHTMLDocument::Open(JSContext* cx,
// Set the caller principal, if any, on the channel so that we'll
// make sure to use it when we reset.
rv = channel->SetOwner(callerPrincipal);
nsCOMPtr<nsILoadInfo> loadInfo =
new LoadInfo(callerPrincipal, LoadInfo::eInheritPrincipal,
LoadInfo::eNotSandboxed);
rv = channel->SetLoadInfo(loadInfo);
if (rv.Failed()) {
return nullptr;
}
@ -2388,7 +2392,10 @@ nsHTMLDocument::CreateAndAddWyciwygChannel(void)
GetDocumentCharacterSet());
// Use our new principal
channel->SetOwner(NodePrincipal());
nsCOMPtr<nsILoadInfo> loadInfo =
new LoadInfo(NodePrincipal(), LoadInfo::eInheritPrincipal,
LoadInfo::eNotSandboxed);
channel->SetLoadInfo(loadInfo);
// Inherit load flags from the original document's channel
channel->SetLoadFlags(mLoadFlags);

Просмотреть файл

@ -813,7 +813,7 @@ public:
// Called when the backend has changed the current playback
// position. It dispatches a timeupdate event and invalidates the frame.
// This must be called on the main thread only.
void PlaybackPositionChanged();
virtual void PlaybackPositionChanged();
// Calls mElement->UpdateReadyStateForData, telling it whether we have
// data for the next frame and if we're buffering. Main thread only.

Просмотреть файл

@ -23,17 +23,17 @@ SOURCES += [
if CONFIG['MOZ_WMF']:
EXPORTS += [
'wmf/MFTDecoder.h',
'wmf/WMFAudioOutputSource.h',
'wmf/WMFAudioMFTManager.h',
'wmf/WMFDecoderModule.h',
'wmf/WMFMediaDataDecoder.h',
'wmf/WMFVideoOutputSource.h',
'wmf/WMFVideoMFTManager.h',
]
UNIFIED_SOURCES += [
'wmf/MFTDecoder.cpp',
'wmf/WMFAudioOutputSource.cpp',
'wmf/WMFAudioMFTManager.cpp',
'wmf/WMFDecoderModule.cpp',
'wmf/WMFMediaDataDecoder.cpp',
'wmf/WMFVideoOutputSource.cpp',
'wmf/WMFVideoMFTManager.cpp',
]
if CONFIG['MOZ_FFMPEG']:

Просмотреть файл

@ -21,6 +21,7 @@ namespace mozilla {
MFTDecoder::MFTDecoder()
: mMFTProvidesOutputSamples(false)
, mDiscontinuity(true)
{
memset(&mInputStreamInfo, 0, sizeof(MFT_INPUT_STREAM_INFO));
memset(&mOutputStreamInfo, 0, sizeof(MFT_OUTPUT_STREAM_INFO));
@ -237,6 +238,11 @@ MFTDecoder::Output(RefPtr<IMFSample>* aOutput)
MOZ_ASSERT(output.pSample);
if (mDiscontinuity) {
output.pSample->SetUINT32(MFSampleExtension_Discontinuity, TRUE);
mDiscontinuity = false;
}
*aOutput = output.pSample; // AddRefs
if (mMFTProvidesOutputSamples) {
// If the MFT is providing samples, we must release the sample here.
@ -277,6 +283,8 @@ MFTDecoder::Flush()
HRESULT hr = SendMFTMessage(MFT_MESSAGE_COMMAND_FLUSH, 0);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
mDiscontinuity = true;
return S_OK;
}

Просмотреть файл

@ -96,6 +96,9 @@ private:
// True if the IMFTransform allocates the samples that it returns.
bool mMFTProvidesOutputSamples;
// True if we need to mark the next sample as a discontinuity.
bool mDiscontinuity;
};
} // namespace mozilla

Просмотреть файл

@ -4,7 +4,7 @@
* 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/. */
#include "WMFAudioOutputSource.h"
#include "WMFAudioMFTManager.h"
#include "mp4_demuxer/DecoderData.h"
#include "VideoUtils.h"
#include "WMFUtils.h"
@ -66,7 +66,7 @@ AACAudioSpecificConfigToUserData(const uint8_t* aAudioSpecConfig,
aOutUserData.AppendElements(aAudioSpecConfig, aConfigLength);
}
WMFAudioOutputSource::WMFAudioOutputSource(
WMFAudioMFTManager::WMFAudioMFTManager(
const mp4_demuxer::AudioDecoderConfig& aConfig)
: mAudioChannels(aConfig.channel_count)
, mAudioBytesPerSample(aConfig.bits_per_sample / 8)
@ -75,19 +75,19 @@ WMFAudioOutputSource::WMFAudioOutputSource(
, mAudioFrameSum(0)
, mMustRecaptureAudioPosition(true)
{
MOZ_COUNT_CTOR(WMFAudioOutputSource);
MOZ_COUNT_CTOR(WMFAudioMFTManager);
AACAudioSpecificConfigToUserData(&aConfig.audio_specific_config[0],
aConfig.audio_specific_config.length(),
mUserData);
}
WMFAudioOutputSource::~WMFAudioOutputSource()
WMFAudioMFTManager::~WMFAudioMFTManager()
{
MOZ_COUNT_DTOR(WMFAudioOutputSource);
MOZ_COUNT_DTOR(WMFAudioMFTManager);
}
TemporaryRef<MFTDecoder>
WMFAudioOutputSource::Init()
WMFAudioMFTManager::Init()
{
RefPtr<MFTDecoder> decoder(new MFTDecoder());
@ -129,7 +129,7 @@ WMFAudioOutputSource::Init()
}
HRESULT
WMFAudioOutputSource::Input(mp4_demuxer::MP4Sample* aSample)
WMFAudioMFTManager::Input(mp4_demuxer::MP4Sample* aSample)
{
const uint8_t* data = reinterpret_cast<const uint8_t*>(aSample->data);
uint32_t length = aSample->size;
@ -137,7 +137,7 @@ WMFAudioOutputSource::Input(mp4_demuxer::MP4Sample* aSample)
}
HRESULT
WMFAudioOutputSource::Output(int64_t aStreamOffset,
WMFAudioMFTManager::Output(int64_t aStreamOffset,
nsAutoPtr<MediaData>& aOutData)
{
aOutData = nullptr;

Просмотреть файл

@ -15,10 +15,10 @@
namespace mozilla {
class WMFAudioOutputSource : public WMFOutputSource {
class WMFAudioMFTManager : public MFTManager {
public:
WMFAudioOutputSource(const mp4_demuxer::AudioDecoderConfig& aConfig);
~WMFAudioOutputSource();
WMFAudioMFTManager(const mp4_demuxer::AudioDecoderConfig& aConfig);
~WMFAudioMFTManager();
virtual TemporaryRef<MFTDecoder> Init() MOZ_OVERRIDE;

Просмотреть файл

@ -7,8 +7,8 @@
#include "WMF.h"
#include "WMFDecoderModule.h"
#include "WMFDecoder.h"
#include "WMFVideoOutputSource.h"
#include "WMFAudioOutputSource.h"
#include "WMFVideoMFTManager.h"
#include "WMFAudioMFTManager.h"
#include "mozilla/Preferences.h"
#include "mozilla/DebugOnly.h"
#include "WMFMediaDataDecoder.h"
@ -70,7 +70,7 @@ WMFDecoderModule::CreateH264Decoder(const mp4_demuxer::VideoDecoderConfig& aConf
MediaTaskQueue* aVideoTaskQueue,
MediaDataDecoderCallback* aCallback)
{
return new WMFMediaDataDecoder(new WMFVideoOutputSource(aConfig,
return new WMFMediaDataDecoder(new WMFVideoMFTManager(aConfig,
aLayersBackend,
aImageContainer,
sDXVAEnabled),
@ -83,7 +83,7 @@ WMFDecoderModule::CreateAACDecoder(const mp4_demuxer::AudioDecoderConfig& aConfi
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback)
{
return new WMFMediaDataDecoder(new WMFAudioOutputSource(aConfig),
return new WMFMediaDataDecoder(new WMFAudioMFTManager(aConfig),
aAudioTaskQueue,
aCallback);
}

Просмотреть файл

@ -21,12 +21,12 @@ PRLogModuleInfo* GetDemuxerLog();
namespace mozilla {
WMFMediaDataDecoder::WMFMediaDataDecoder(WMFOutputSource* aSource,
WMFMediaDataDecoder::WMFMediaDataDecoder(MFTManager* aMFTManager,
MediaTaskQueue* aTaskQueue,
MediaDataDecoderCallback* aCallback)
: mTaskQueue(aTaskQueue)
, mCallback(aCallback)
, mSource(aSource)
, mMFTManager(aMFTManager)
{
MOZ_COUNT_CTOR(WMFMediaDataDecoder);
}
@ -39,7 +39,7 @@ WMFMediaDataDecoder::~WMFMediaDataDecoder()
nsresult
WMFMediaDataDecoder::Init()
{
mDecoder = mSource->Init();
mDecoder = mMFTManager->Init();
NS_ENSURE_TRUE(mDecoder, NS_ERROR_FAILURE);
return NS_OK;
@ -67,9 +67,9 @@ WMFMediaDataDecoder::Input(mp4_demuxer::MP4Sample* aSample)
void
WMFMediaDataDecoder::ProcessDecode(mp4_demuxer::MP4Sample* aSample)
{
HRESULT hr = mSource->Input(aSample);
HRESULT hr = mMFTManager->Input(aSample);
if (FAILED(hr)) {
NS_WARNING("WMFOutputSource rejected sample");
NS_WARNING("MFTManager rejected sample");
mCallback->Error();
return;
}
@ -84,7 +84,7 @@ WMFMediaDataDecoder::ProcessOutput()
{
nsAutoPtr<MediaData> output;
HRESULT hr = S_OK;
while (SUCCEEDED(hr = mSource->Output(mLastStreamOffset, output)) &&
while (SUCCEEDED(hr = mMFTManager->Output(mLastStreamOffset, output)) &&
output) {
mCallback->Output(output.forget());
}

Просмотреть файл

@ -22,9 +22,9 @@ namespace mozilla {
// Encapsulates the initialization of the MFTDecoder appropriate for decoding
// a given stream, and the process of converting the IMFSample produced
// by the MFT into a MediaData object.
class WMFOutputSource {
class MFTManager {
public:
virtual ~WMFOutputSource() {}
virtual ~MFTManager() {}
// Creates an initializs the MFTDecoder.
// Returns nullptr on failure.
@ -46,13 +46,13 @@ public:
};
// Decodes audio and video using Windows Media Foundation. Samples are decoded
// using the MFTDecoder created by the WMFOutputSource. This class implements
// using the MFTDecoder created by the MFTManager. This class implements
// the higher-level logic that drives mapping the MFT to the async
// MediaDataDecoder interface. The specifics of decoding the exact stream
// type are handled by WMFOutputSource and the MFTDecoder it creates.
// type are handled by MFTManager and the MFTDecoder it creates.
class WMFMediaDataDecoder : public MediaDataDecoder {
public:
WMFMediaDataDecoder(WMFOutputSource* aOutputSource,
WMFMediaDataDecoder(MFTManager* aOutputSource,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback);
~WMFMediaDataDecoder();
@ -85,7 +85,7 @@ private:
MediaDataDecoderCallback* mCallback;
RefPtr<MFTDecoder> mDecoder;
nsAutoPtr<WMFOutputSource> mSource;
nsAutoPtr<MFTManager> mMFTManager;
// The last offset into the media resource that was passed into Input().
// This is used to approximate the decoder's position in the media resource.

Просмотреть файл

@ -4,7 +4,7 @@
* 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/. */
#include "WMFVideoOutputSource.h"
#include "WMFVideoMFTManager.h"
#include "MediaDecoderReader.h"
#include "WMFUtils.h"
#include "ImageContainer.h"
@ -32,7 +32,7 @@ using mozilla::layers::LayersBackend;
namespace mozilla {
WMFVideoOutputSource::WMFVideoOutputSource(
WMFVideoMFTManager::WMFVideoMFTManager(
const mp4_demuxer::VideoDecoderConfig& aConfig,
mozilla::layers::LayersBackend aLayersBackend,
mozilla::layers::ImageContainer* aImageContainer,
@ -48,12 +48,12 @@ WMFVideoOutputSource::WMFVideoOutputSource(
{
NS_ASSERTION(!NS_IsMainThread(), "Should not be on main thread.");
MOZ_ASSERT(mImageContainer);
MOZ_COUNT_CTOR(WMFVideoOutputSource);
MOZ_COUNT_CTOR(WMFVideoMFTManager);
}
WMFVideoOutputSource::~WMFVideoOutputSource()
WMFVideoMFTManager::~WMFVideoMFTManager()
{
MOZ_COUNT_DTOR(WMFVideoOutputSource);
MOZ_COUNT_DTOR(WMFVideoMFTManager);
// Ensure DXVA/D3D9 related objects are released on the main thread.
DeleteOnMainThread(mDXVA2Manager);
}
@ -69,7 +69,7 @@ public:
};
bool
WMFVideoOutputSource::InitializeDXVA()
WMFVideoMFTManager::InitializeDXVA()
{
// If we use DXVA but aren't running with a D3D layer manager then the
// readback of decoded video frames from GPU to CPU memory grinds painting
@ -90,7 +90,7 @@ WMFVideoOutputSource::InitializeDXVA()
}
TemporaryRef<MFTDecoder>
WMFVideoOutputSource::Init()
WMFVideoMFTManager::Init()
{
bool useDxva = InitializeDXVA();
@ -144,7 +144,7 @@ WMFVideoOutputSource::Init()
}
HRESULT
WMFVideoOutputSource::Input(mp4_demuxer::MP4Sample* aSample)
WMFVideoMFTManager::Input(mp4_demuxer::MP4Sample* aSample)
{
// We must prepare samples in AVC Annex B.
mp4_demuxer::AnnexB::ConvertSample(aSample, mConfig.annex_b);
@ -155,7 +155,7 @@ WMFVideoOutputSource::Input(mp4_demuxer::MP4Sample* aSample)
}
HRESULT
WMFVideoOutputSource::ConfigureVideoFrameGeometry()
WMFVideoMFTManager::ConfigureVideoFrameGeometry()
{
RefPtr<IMFMediaType> mediaType;
HRESULT hr = mDecoder->GetOutputMediaType(mediaType);
@ -216,7 +216,7 @@ WMFVideoOutputSource::ConfigureVideoFrameGeometry()
}
HRESULT
WMFVideoOutputSource::CreateBasicVideoFrame(IMFSample* aSample,
WMFVideoMFTManager::CreateBasicVideoFrame(IMFSample* aSample,
int64_t aStreamOffset,
VideoData** aOutVideoData)
{
@ -311,7 +311,7 @@ WMFVideoOutputSource::CreateBasicVideoFrame(IMFSample* aSample,
}
HRESULT
WMFVideoOutputSource::CreateD3DVideoFrame(IMFSample* aSample,
WMFVideoMFTManager::CreateD3DVideoFrame(IMFSample* aSample,
int64_t aStreamOffset,
VideoData** aOutVideoData)
{
@ -351,7 +351,7 @@ WMFVideoOutputSource::CreateD3DVideoFrame(IMFSample* aSample,
// Blocks until decoded sample is produced by the deoder.
HRESULT
WMFVideoOutputSource::Output(int64_t aStreamOffset,
WMFVideoMFTManager::Output(int64_t aStreamOffset,
nsAutoPtr<MediaData>& aOutData)
{
RefPtr<IMFSample> sample;
@ -379,7 +379,7 @@ WMFVideoOutputSource::Output(int64_t aStreamOffset,
break;
}
// Else unexpected error, assert, and bail.
NS_WARNING("WMFVideoOutputSource::Output() unexpected error");
NS_WARNING("WMFVideoMFTManager::Output() unexpected error");
return E_FAIL;
}

Просмотреть файл

@ -4,8 +4,8 @@
* 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/. */
#if !defined(WMFVideoOutputSource_h_)
#define WMFVideoOutputSource_h_
#if !defined(WMFVideoMFTManager_h_)
#define WMFVideoMFTManager_h_
#include "WMF.h"
#include "MP4Reader.h"
@ -18,13 +18,13 @@ namespace mozilla {
class DXVA2Manager;
class WMFVideoOutputSource : public WMFOutputSource {
class WMFVideoMFTManager : public MFTManager {
public:
WMFVideoOutputSource(const mp4_demuxer::VideoDecoderConfig& aConfig,
WMFVideoMFTManager(const mp4_demuxer::VideoDecoderConfig& aConfig,
mozilla::layers::LayersBackend aLayersBackend,
mozilla::layers::ImageContainer* aImageContainer,
bool aDXVAEnabled);
~WMFVideoOutputSource();
~WMFVideoMFTManager();
virtual TemporaryRef<MFTDecoder> Init() MOZ_OVERRIDE;
@ -69,4 +69,4 @@ private:
} // namespace mozilla
#endif // WMFVideoOutputSource_h_
#endif // WMFVideoMFTManager_h_

Просмотреть файл

@ -180,22 +180,28 @@ private:
int64_t mTimeThreshold;
bool mDropVideoBeforeThreshold;
bool MaybeSwitchVideoReaders() {
enum SwitchState {
SWITCHSTATE_SEEKING,
SWITCHSTATE_PLAYING
};
bool MaybeSwitchVideoReaders(SwitchState aState = SWITCHSTATE_PLAYING) {
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
MOZ_ASSERT(mActiveVideoDecoder != -1);
InitializePendingDecoders();
for (uint32_t i = mActiveVideoDecoder + 1; i < mDecoders.Length(); ++i) {
if (!mDecoders[i]->GetReader()->GetMediaInfo().HasVideo()) {
SubBufferDecoder* decoder = mDecoders[i];
if (decoder->IsDiscarded() || !decoder->GetReader()->GetMediaInfo().HasVideo()) {
continue;
}
if (mTimeThreshold >= mDecoders[i]->GetMediaStartTime()) {
if (aState == SWITCHSTATE_SEEKING || mTimeThreshold >= mDecoders[i]->GetMediaStartTime()) {
GetVideoReader()->SetIdle();
mActiveVideoDecoder = i;
MSE_DEBUG("%p MSR::DecodeVF switching to %d", this, mActiveVideoDecoder);
return true;
}
}
@ -478,7 +484,7 @@ MediaSourceReader::Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
while (!mMediaSource->ActiveSourceBuffers()->AllContainsTime(target)
&& !IsShutdown()) {
mMediaSource->WaitForData();
MaybeSwitchVideoReaders();
MaybeSwitchVideoReaders(SWITCHSTATE_SEEKING);
}
if (IsShutdown()) {

Просмотреть файл

@ -412,7 +412,7 @@ void
SourceBuffer::DiscardDecoder()
{
if (mDecoder) {
mDecoder->GetResource()->Ended();
mDecoder->SetDiscarded();
}
mDecoder = nullptr;
mDecoderInitialized = false;

Просмотреть файл

@ -21,7 +21,7 @@ public:
// of the caller to manage the memory of the MediaResource object.
SubBufferDecoder(MediaResource* aResource, MediaSourceDecoder* aParentDecoder)
: BufferDecoder(aResource), mParentDecoder(aParentDecoder), mReader(nullptr)
, mMediaDuration(-1), mMediaStartTime(0)
, mMediaDuration(-1), mMediaStartTime(0), mDiscarded(false)
{
}
@ -83,11 +83,23 @@ public:
mMediaStartTime = aMediaStartTime;
}
bool IsDiscarded()
{
return mDiscarded;
}
void SetDiscarded()
{
GetResource()->Ended();
mDiscarded = true;
}
private:
MediaSourceDecoder* mParentDecoder;
nsRefPtr<MediaDecoderReader> mReader;
int64_t mMediaDuration;
int64_t mMediaStartTime;
bool mDiscarded;
};
} // namespace mozilla

Просмотреть файл

@ -274,10 +274,16 @@ nsresult WinProcMon::QuerySystemLoad(float* load_percent)
}
#endif
class LoadStats
// Use a non-generic class name, because otherwise we can get name collisions
// with other classes in the codebase. The normal way of dealing with that is
// to put the class in an anonymous namespace, but this class is used as a
// member of RTCLoadInfo, which can't be in the anonymous namespace, so it also
// can't be in an anonymous namespace: gcc warns about that setup and this
// directory is fail-on-warnings.
class RTCLoadStats
{
public:
LoadStats() :
RTCLoadStats() :
mPrevTotalTimes(0),
mPrevCpuTimes(0),
mPrevLoad(0) {};
@ -289,11 +295,17 @@ public:
float mPrevLoad; // Previous load value.
};
class LoadInfo : public mozilla::RefCounted<LoadInfo>
// Use a non-generic class name, because otherwise we can get name collisions
// with other classes in the codebase. The normal way of dealing with that is
// to put the class in an anonymous namespace, but this class is used as a
// member of LoadInfoCollectRunner, which can't be in the anonymous namespace,
// so it also can't be in an anonymous namespace: gcc warns about that setup
// and this directory is fail-on-warnings.
class RTCLoadInfo : public mozilla::RefCounted<RTCLoadInfo>
{
public:
MOZ_DECLARE_REFCOUNTED_TYPENAME(LoadInfo)
LoadInfo(): mLoadUpdateInterval(0) {};
MOZ_DECLARE_REFCOUNTED_TYPENAME(RTCLoadInfo)
RTCLoadInfo(): mLoadUpdateInterval(0) {};
nsresult Init(int aLoadUpdateInterval);
double GetSystemLoad() { return mSystemLoad.GetLoad(); };
double GetProcessLoad() { return mProcessLoad.GetLoad(); };
@ -304,19 +316,19 @@ private:
void UpdateCpuLoad(uint64_t ticks_per_interval,
uint64_t current_total_times,
uint64_t current_cpu_times,
LoadStats* loadStat);
RTCLoadStats* loadStat);
#ifdef XP_WIN
WinProcMon mSysMon;
HANDLE mProcHandle;
int mNumProcessors;
#endif
LoadStats mSystemLoad;
LoadStats mProcessLoad;
RTCLoadStats mSystemLoad;
RTCLoadStats mProcessLoad;
uint64_t mTicksPerInterval;
int mLoadUpdateInterval;
};
nsresult LoadInfo::Init(int aLoadUpdateInterval)
nsresult RTCLoadInfo::Init(int aLoadUpdateInterval)
{
mLoadUpdateInterval = aLoadUpdateInterval;
#ifdef XP_WIN
@ -331,10 +343,10 @@ nsresult LoadInfo::Init(int aLoadUpdateInterval)
#endif
}
void LoadInfo::UpdateCpuLoad(uint64_t ticks_per_interval,
void RTCLoadInfo::UpdateCpuLoad(uint64_t ticks_per_interval,
uint64_t current_total_times,
uint64_t current_cpu_times,
LoadStats *loadStat) {
RTCLoadStats *loadStat) {
// Check if we get an inconsistent number of ticks.
if (((current_total_times - loadStat->mPrevTotalTimes)
> (ticks_per_interval * 10))
@ -366,7 +378,7 @@ void LoadInfo::UpdateCpuLoad(uint64_t ticks_per_interval,
loadStat->mPrevCpuTimes = current_cpu_times;
}
nsresult LoadInfo::UpdateSystemLoad()
nsresult RTCLoadInfo::UpdateSystemLoad()
{
#if defined(LINUX) || defined(ANDROID)
nsCOMPtr<nsIFile> procStatFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
@ -472,7 +484,7 @@ nsresult LoadInfo::UpdateSystemLoad()
#endif
}
nsresult LoadInfo::UpdateProcessLoad() {
nsresult RTCLoadInfo::UpdateProcessLoad() {
#if defined(XP_UNIX)
struct timeval tv;
gettimeofday(&tv, nullptr);
@ -518,11 +530,13 @@ nsresult LoadInfo::UpdateProcessLoad() {
return NS_OK;
}
// Note: This class can't be in the anonymous namespace, because then we can't
// declare it as a friend of LoadMonitor.
class LoadInfoCollectRunner : public nsRunnable
{
public:
LoadInfoCollectRunner(nsRefPtr<LoadMonitor> loadMonitor,
RefPtr<LoadInfo> loadInfo,
RefPtr<RTCLoadInfo> loadInfo,
nsIThread *loadInfoThread)
: mThread(loadInfoThread),
mLoadUpdateInterval(loadMonitor->mLoadUpdateInterval),
@ -571,7 +585,7 @@ public:
private:
nsCOMPtr<nsIThread> mThread;
RefPtr<LoadInfo> mLoadInfo;
RefPtr<RTCLoadInfo> mLoadInfo;
nsRefPtr<LoadMonitor> mLoadMonitor;
int mLoadUpdateInterval;
int mLoadNoiseCounter;
@ -615,11 +629,11 @@ LoadMonitor::Init(nsRefPtr<LoadMonitor> &self)
{
LOG(("Initializing LoadMonitor"));
RefPtr<LoadInfo> load_info = new LoadInfo();
RefPtr<RTCLoadInfo> load_info = new RTCLoadInfo();
nsresult rv = load_info->Init(mLoadUpdateInterval);
if (NS_FAILED(rv)) {
LOG(("LoadInfo::Init error"));
LOG(("RTCLoadInfo::Init error"));
return rv;
}

Просмотреть файл

@ -61,6 +61,7 @@ skip-if = true
[test_pointer-events-3.xhtml]
[test_pointer-events-4.xhtml]
[test_pointer-events-5.xhtml]
[test_pointer-events-6.xhtml]
[test_scientific.html]
[test_selectSubString.xhtml]
[test_stroke-linecap-hit-testing.xhtml]

Просмотреть файл

@ -0,0 +1,70 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=500174
-->
<head>
<title>Test pointer events for clip-path on non-SVG elements</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body onload="run()">
<script class="testbody" type="text/javascript">
<![CDATA[
SimpleTest.waitForExplicitFinish();
function run()
{
var div = document.getElementById("div");
// Get the coords of the origin of the SVG canvas:
var originX = div.offsetLeft;
var originY = div.offsetTop;
var elementFromPoint;
elementFromPoint = document.elementFromPoint(originX + 18, originY + 30);
isnot(elementFromPoint, div, 'Outside left edge of clipped area');
elementFromPoint = document.elementFromPoint(originX + 22, originY + 30);
is(elementFromPoint, div, 'Inside left edge of clipped area');
elementFromPoint = document.elementFromPoint(originX + 30, originY + 18);
isnot(elementFromPoint, div, 'Outside top edge of clipped area');
elementFromPoint = document.elementFromPoint(originX + 30, originY + 22);
is(elementFromPoint, div, 'Inside top edge of clipped area');
elementFromPoint = document.elementFromPoint(originX + 42, originY + 30);
isnot(elementFromPoint, div, 'Outside right edge of clipped area');
elementFromPoint = document.elementFromPoint(originX + 38, originY + 30);
is(elementFromPoint, div, 'Inside right edge of clipped area');
elementFromPoint = document.elementFromPoint(originX + 30, originY + 42);
isnot(elementFromPoint, div, 'Outside bottom edge of clipped area');
elementFromPoint = document.elementFromPoint(originX + 30, originY + 38);
is(elementFromPoint, div, 'Inside bottom edge of clipped area');
SimpleTest.finish();
}
]]>
</script>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=500174">Mozilla Bug 500174</a>
<p id="display"></p>
<div id="content">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" id="svg">
<defs>
<clipPath id="clip">
<rect x="20" y="20" width="20" height="20"/>
</clipPath>
</defs>
</svg>
<div id="div" style="width:100px; height:100px; clip-path:url(#clip)"></div>
</div>
<pre id="test">
</pre>
</body>
</html>

Просмотреть файл

@ -89,6 +89,7 @@
#include "mozilla/dom/ProcessingInstruction.h"
#include "mozilla/dom/XULDocumentBinding.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/LoadInfo.h"
#include "mozilla/Preferences.h"
#include "nsTextNode.h"
#include "nsJSUtils.h"
@ -2829,7 +2830,10 @@ XULDocument::LoadOverlayInternal(nsIURI* aURI, bool aIsDynamic,
// that the overlay's JSObjects etc end up being created
// with the right principal and in the correct
// compartment.
channel->SetOwner(NodePrincipal());
nsCOMPtr<nsILoadInfo> loadInfo =
new LoadInfo(NodePrincipal(), LoadInfo::eInheritPrincipal,
LoadInfo::eNotSandboxed);
channel->SetLoadInfo(loadInfo);
rv = channel->AsyncOpen(listener, nullptr);
}

Просмотреть файл

@ -0,0 +1,59 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 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/. */
#include "mozilla/LoadInfo.h"
#include "mozilla/Assertions.h"
#include "nsISupportsImpl.h"
#include "nsISupportsUtils.h"
namespace mozilla {
LoadInfo::LoadInfo(nsIPrincipal* aPrincipal,
InheritType aInheritPrincipal,
SandboxType aSandboxed)
: mPrincipal(aPrincipal)
, mInheritPrincipal(aInheritPrincipal == eInheritPrincipal &&
aSandboxed != eSandboxed)
, mSandboxed(aSandboxed == eSandboxed)
{
MOZ_ASSERT(aPrincipal);
}
LoadInfo::~LoadInfo()
{
}
NS_IMPL_ISUPPORTS(LoadInfo, nsILoadInfo)
NS_IMETHODIMP
LoadInfo::GetLoadingPrincipal(nsIPrincipal** aPrincipal)
{
NS_ADDREF(*aPrincipal = mPrincipal);
return NS_OK;
}
nsIPrincipal*
LoadInfo::LoadingPrincipal()
{
return mPrincipal;
}
NS_IMETHODIMP
LoadInfo::GetForceInheritPrincipal(bool* aInheritPrincipal)
{
*aInheritPrincipal = mInheritPrincipal;
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::GetLoadingSandboxed(bool* aLoadingSandboxed)
{
*aLoadingSandboxed = mSandboxed;
return NS_OK;
}
} // namespace mozilla

54
docshell/base/LoadInfo.h Normal file
Просмотреть файл

@ -0,0 +1,54 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 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 mozilla_LoadInfo_h
#define mozilla_LoadInfo_h
#include "nsIPrincipal.h"
#include "nsILoadInfo.h"
namespace mozilla {
/**
* Class that provides an nsILoadInfo implementation.
*/
class LoadInfo MOZ_FINAL : public nsILoadInfo
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSILOADINFO
enum InheritType
{
eInheritPrincipal,
eDontInheritPrincipal
};
enum SandboxType
{
eSandboxed,
eNotSandboxed
};
// aPrincipal MUST NOT BE NULL. If aSandboxed is eSandboxed, the
// value passed for aInheritPrincipal will be ignored and
// eDontInheritPrincipal will be used instead.
LoadInfo(nsIPrincipal* aPrincipal,
InheritType aInheritPrincipal,
SandboxType aSandboxed);
private:
~LoadInfo();
nsCOMPtr<nsIPrincipal> mPrincipal;
bool mInheritPrincipal;
bool mSandboxed;
};
} // namespace mozilla
#endif // mozilla_LoadInfo_h

Просмотреть файл

@ -20,6 +20,7 @@ XPIDL_SOURCES += [
'nsIDownloadHistory.idl',
'nsIGlobalHistory2.idl',
'nsILoadContext.idl',
'nsILoadInfo.idl',
'nsIMarkupDocumentViewer.idl',
'nsIPrivacyTransitionObserver.idl',
'nsIReflowObserver.idl',
@ -45,10 +46,12 @@ EXPORTS += [
EXPORTS.mozilla += [
'IHistory.h',
'LoadContext.h',
'LoadInfo.h',
]
UNIFIED_SOURCES += [
'LoadContext.cpp',
'LoadInfo.cpp',
'nsAboutRedirector.cpp',
'nsDefaultURIFixup.cpp',
'nsDocShellEditorData.cpp',

Просмотреть файл

@ -101,6 +101,7 @@
#include "nsITimer.h"
#include "nsISHistoryInternal.h"
#include "nsIPrincipal.h"
#include "nsNullPrincipal.h"
#include "nsISHEntry.h"
#include "nsIWindowWatcher.h"
#include "nsIPromptFactory.h"
@ -168,6 +169,7 @@
#include "nsCxPusher.h"
#include "nsIChannelPolicy.h"
#include "nsIContentSecurityPolicy.h"
#include "nsILoadInfo.h"
#include "nsSandboxFlags.h"
#include "nsXULAppAPI.h"
#include "nsDOMNavigationTiming.h"
@ -10006,21 +10008,9 @@ nsDocShell::DoURILoad(nsIURI * aURI,
}
}
nsCOMPtr<nsIPrincipal> ownerPrincipal;
// If the content being loaded should be sandboxed with respect to origin
// we need to create a new null principal here, and then tell
// nsContentUtils::SetUpChannelOwner to force it to be set as the
// channel owner.
if (mSandboxFlags & SANDBOXED_ORIGIN) {
ownerPrincipal = do_CreateInstance("@mozilla.org/nullprincipal;1");
} else {
// Not sandboxed - we allow the content to assume its natural owner.
ownerPrincipal = do_QueryInterface(aOwner);
}
nsCOMPtr<nsIPrincipal> ownerPrincipal = do_QueryInterface(aOwner);
nsContentUtils::SetUpChannelOwner(ownerPrincipal, channel, aURI, true,
(mSandboxFlags & SANDBOXED_ORIGIN) ||
mSandboxFlags & SANDBOXED_ORIGIN,
isSrcdoc);
nsCOMPtr<nsIScriptChannel> scriptChannel = do_QueryInterface(channel);
@ -11091,6 +11081,21 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel,
discardLayoutState = ShouldDiscardLayoutState(httpChannel);
}
aChannel->GetOwner(getter_AddRefs(owner));
if (!owner) {
nsCOMPtr<nsILoadInfo> loadInfo;
aChannel->GetLoadInfo(getter_AddRefs(loadInfo));
if (loadInfo) {
// For now keep storing just the principal in the SHEntry.
if (loadInfo->GetLoadingSandboxed()) {
owner = do_CreateInstance(NS_NULLPRINCIPAL_CONTRACTID, &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} else if (loadInfo->GetForceInheritPrincipal()) {
owner = loadInfo->LoadingPrincipal();
}
}
}
}
//Title is set in nsDocShell::SetTitle()

Просмотреть файл

@ -0,0 +1,42 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: ft=cpp tw=78 sw=2 et ts=2 sts=2 cin
* 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/. */
#include "nsISupports.idl"
interface nsIPrincipal;
/**
* An nsILoadOwner represents per-load information about who started the load.
*/
[scriptable, builtinclass, uuid(046db047-a1c1-4519-8ec7-99f3054bc9ac)]
interface nsILoadInfo : nsISupports
{
/**
* loadingPrincipal is the principal that started the load. Will
* never be null.
*/
readonly attribute nsIPrincipal loadingPrincipal;
/**
* A C++-friendly version of loadingPrincipal.
*/
[noscript, notxpcom, nostdcall, binaryname(LoadingPrincipal)]
nsIPrincipal binaryLoadingPrincipal();
/**
* If forceInheritPrincipal is true, the data coming from the channel should
* use loadingPrincipal for its principal, even when the data is loaded over
* http:// or another protocol that would normally use a URI-based principal.
* This attribute will never be true when loadingSandboxed is true.
*/
[infallible] readonly attribute boolean forceInheritPrincipal;
/**
* If loadingSandboxed is true, the data coming from the channel is
* being loaded sandboxed, so it should have a nonce origin and
* hence should use a NullPrincipal.
*/
[infallible] readonly attribute boolean loadingSandboxed;
};

Просмотреть файл

@ -15,8 +15,6 @@
using mozilla::dom::ContentChild;
using namespace js::ArrayBufferView;
namespace mozilla {
namespace dom {
@ -67,13 +65,13 @@ Crypto::GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray,
// Throw if the wrong type of ArrayBufferView is passed in
// (Part of the Web Crypto API spec)
switch (JS_GetArrayBufferViewType(view)) {
case TYPE_INT8:
case TYPE_UINT8:
case TYPE_UINT8_CLAMPED:
case TYPE_INT16:
case TYPE_UINT16:
case TYPE_INT32:
case TYPE_UINT32:
case js::Scalar::Int8:
case js::Scalar::Uint8:
case js::Scalar::Uint8Clamped:
case js::Scalar::Int16:
case js::Scalar::Uint16:
case js::Scalar::Int32:
case js::Scalar::Uint32:
break;
default:
aRv.Throw(NS_ERROR_DOM_TYPE_MISMATCH_ERR);

Просмотреть файл

@ -1515,6 +1515,25 @@ Navigator::GetFeature(const nsAString& aName)
return p.forget();
} // hardware.memory
#endif
// Hardcoded manifest features. Some are still b2g specific.
const char manifestFeatures[][64] = {
"manifest.origin"
, "manifest.redirects"
#ifdef MOZ_B2G
, "manifest.chrome.navigation"
, "manifest.precompile"
#endif
};
nsAutoCString feature = NS_ConvertUTF16toUTF8(aName);
for (uint32_t i = 0; i < MOZ_ARRAY_LENGTH(manifestFeatures); i++) {
if (feature.Equals(manifestFeatures[i])) {
p->MaybeResolve(true);
return p.forget();
}
}
// resolve with <undefined> because the feature name is not supported
p->MaybeResolve(JS::UndefinedHandleValue);

Просмотреть файл

@ -161,6 +161,7 @@ LOCAL_INCLUDES += [
'/content/base/src',
'/content/html/document/src',
'/content/xul/document/src',
'/layout/base',
'/layout/generic',
'/layout/style',
'/layout/xul',

Просмотреть файл

@ -90,6 +90,8 @@
#include "GeckoProfiler.h"
#include "mozilla/Preferences.h"
#include "nsIContentIterator.h"
#include "nsIDOMStyleSheet.h"
#include "nsIStyleSheet.h"
#include "nsContentPermissionHelper.h"
#ifdef XP_WIN
@ -3367,6 +3369,28 @@ nsDOMWindowUtils::LoadSheet(nsIURI *aSheetURI, uint32_t aSheetType)
return doc->LoadAdditionalStyleSheet(type, aSheetURI);
}
NS_IMETHODIMP
nsDOMWindowUtils::AddSheet(nsIDOMStyleSheet *aSheet, uint32_t aSheetType)
{
MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
NS_ENSURE_ARG_POINTER(aSheet);
NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
aSheetType == USER_SHEET ||
aSheetType == AUTHOR_SHEET);
nsCOMPtr<nsIDocument> doc = GetDocument();
NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
nsIDocument::additionalSheetType type = convertSheetType(aSheetType);
nsCOMPtr<nsIStyleSheet> sheet = do_QueryInterface(aSheet);
NS_ENSURE_TRUE(sheet, NS_ERROR_FAILURE);
if (sheet->GetOwningDocument()) {
return NS_ERROR_INVALID_ARG;
}
return doc->AddAdditionalStyleSheet(type, sheet);
}
NS_IMETHODIMP
nsDOMWindowUtils::RemoveSheet(nsIURI *aSheetURI, uint32_t aSheetType)
{
@ -3642,7 +3666,7 @@ HandlingUserInputHelper::Destruct()
return NS_OK;
}
}
} // unnamed namespace
NS_IMETHODIMP
nsDOMWindowUtils::SetHandlingUserInput(bool aHandlingUserInput,

Просмотреть файл

@ -38,7 +38,7 @@ function testSupported() {
ok(typeof mem === 'undefined', "hardware.memory is not support on this platform");
}
SimpleTest.finish();
runNextTest();
},function(mem) {
ok(false, "The Promise should not be rejected");
@ -49,17 +49,56 @@ function testNotSupported() {
var tv;
navigator.getFeature("hardware.tv").then(function(tv) {
ok(typeof tv === 'undefined', "Resolve the Promise with undefined value (hardware.tv)");
testSupported();
runNextTest();
},function(tv) {
ok(false, "The Promise should not be rejected")
});
}
function createManifestTest(aFeature) {
return function() {
var res;
navigator.getFeature(aFeature).then(function(res) {
ok(res === true, "Resolve the Promise with 'true' for " + aFeature);
runNextTest();
},function(tv) {
ok(false, "The Promise should not be rejected")
});
}
}
var currentTest = -1;
var tests = [
testNotSupported,
testSupported,
createManifestTest("manifest.origin"),
createManifestTest("manifest.redirects")
];
function runNextTest() {
currentTest++;
if (currentTest < tests.length) {
tests[currentTest]();
} else {
SimpleTest.finish();
}
}
info("About to run " + tests.length + " tests");
SpecialPowers.pushPermissions([
{type: "feature-detection", allow: 1, context: document}
], function() {
ok('getFeature' in navigator, "navigator.getFeature should exist");
testNotSupported();
// B2G specific manifest features.
// Touching navigator before pushPermissions makes it fail.
if (!navigator.userAgent.contains("Android") &&
/Mobile|Tablet/.test(navigator.userAgent)) {
info("Adding B2G specific tests");
tests.push(createManifestTest("manifest.chrome.navigation"));
tests.push(createManifestTest("manifest.precompile"));
}
runNextTest();
ok(true, "Test DONE");
});

Просмотреть файл

@ -173,6 +173,10 @@ DOMInterfaces = {
'nativeType': 'mozilla::dom::bluetooth::BluetoothDiscoveryHandle',
},
'BluetoothClassOfDevice': {
'nativeType': 'mozilla::dom::bluetooth::BluetoothClassOfDevice',
},
'CameraCapabilities': {
'nativeType': 'mozilla::dom::CameraCapabilities',
'headerFile': 'DOMCameraCapabilities.h'

Просмотреть файл

@ -0,0 +1,105 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/. */
#include "BluetoothClassOfDevice.h"
#include "mozilla/dom/BluetoothClassOfDeviceBinding.h"
#include "nsThreadUtils.h"
USING_BLUETOOTH_NAMESPACE
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(BluetoothClassOfDevice, mOwnerWindow)
NS_IMPL_CYCLE_COLLECTING_ADDREF(BluetoothClassOfDevice)
NS_IMPL_CYCLE_COLLECTING_RELEASE(BluetoothClassOfDevice)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BluetoothClassOfDevice)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
/*
* Class of Device(CoD): 32-bit unsigned integer
*
* 31 24 23 13 12 8 7 2 1 0
* | | Major | Major | Minor | |
* | | service | device | device | |
* | | class | class | class | |
* | |<- 11 ->|<- 5 ->|<- 6 ->| |
*
* https://www.bluetooth.org/en-us/specification/assigned-numbers/baseband
*/
// Bit 23 ~ Bit 13: Major service class
#define GET_MAJOR_SERVICE_CLASS(cod) (((cod) & 0xffe000) >> 13)
// Bit 12 ~ Bit 8: Major device class
#define GET_MAJOR_DEVICE_CLASS(cod) (((cod) & 0x1f00) >> 8)
// Bit 7 ~ Bit 2: Minor device class
#define GET_MINOR_DEVICE_CLASS(cod) (((cod) & 0xfc) >> 2)
BluetoothClassOfDevice::BluetoothClassOfDevice(nsPIDOMWindow* aOwner)
: mOwnerWindow(aOwner)
{
MOZ_ASSERT(aOwner);
SetIsDOMBinding();
Reset();
}
BluetoothClassOfDevice::~BluetoothClassOfDevice()
{}
void
BluetoothClassOfDevice::Reset()
{
mMajorServiceClass = 0x1; // LIMITED_DISCOVERABILITY
mMajorDeviceClass = 0x1F; // UNCATEGORIZED
mMinorDeviceClass = 0;
}
bool
BluetoothClassOfDevice::Equals(const uint32_t aValue)
{
return (mMajorServiceClass == GET_MAJOR_SERVICE_CLASS(aValue) &&
mMajorDeviceClass == GET_MAJOR_DEVICE_CLASS(aValue) &&
mMinorDeviceClass == GET_MINOR_DEVICE_CLASS(aValue));
}
uint32_t
BluetoothClassOfDevice::ToUint32()
{
return (mMajorServiceClass & 0x7ff) << 13 |
(mMajorDeviceClass & 0x1f) << 8 |
(mMinorDeviceClass & 0x3f) << 2;
}
void
BluetoothClassOfDevice::Update(const uint32_t aValue)
{
mMajorServiceClass = GET_MAJOR_SERVICE_CLASS(aValue);
mMajorDeviceClass = GET_MAJOR_DEVICE_CLASS(aValue);
mMinorDeviceClass = GET_MINOR_DEVICE_CLASS(aValue);
BT_API2_LOGR("aValue %x => majorService %x majorDevice %x minorDevice %x",
aValue, mMajorServiceClass, mMajorDeviceClass, mMinorDeviceClass);
}
// static
already_AddRefed<BluetoothClassOfDevice>
BluetoothClassOfDevice::Create(nsPIDOMWindow* aOwner)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aOwner);
nsRefPtr<BluetoothClassOfDevice> cod = new BluetoothClassOfDevice(aOwner);
return cod.forget();
}
JSObject*
BluetoothClassOfDevice::WrapObject(JSContext* aCx)
{
return BluetoothClassOfDeviceBinding::Wrap(aCx, this);
}

Просмотреть файл

@ -0,0 +1,92 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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 mozilla_dom_bluetooth_bluetoothclassofdevice_h
#define mozilla_dom_bluetooth_bluetoothclassofdevice_h
#include "BluetoothCommon.h"
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
#include "nsCycleCollectionParticipant.h"
#include "nsPIDOMWindow.h"
#include "nsWrapperCache.h"
struct JSContext;
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothClassOfDevice MOZ_FINAL : public nsISupports,
public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(BluetoothClassOfDevice)
static already_AddRefed<BluetoothClassOfDevice>
Create(nsPIDOMWindow* aOwner);
uint16_t MajorServiceClass() const
{
return mMajorServiceClass;
}
uint8_t MajorDeviceClass() const
{
return mMajorDeviceClass;
}
uint8_t MinorDeviceClass() const
{
return mMinorDeviceClass;
}
/**
* Compare whether CoD equals to CoD value.
*
* @param aValue [in] CoD value to compare
*/
bool Equals(const uint32_t aValue);
/**
* Convert CoD to uint32_t CoD value.
*
* TODO: Remove this function once we replace uint32_t cod value with
* BluetoothClassOfDevice in BluetoothProfileController.
*/
uint32_t ToUint32();
/**
* Update CoD.
*
* @param aValue [in] CoD value to update
*/
void Update(const uint32_t aValue);
nsPIDOMWindow* GetParentObject() const
{
return mOwnerWindow;
}
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
private:
BluetoothClassOfDevice(nsPIDOMWindow* aOwner);
~BluetoothClassOfDevice();
/**
* Reset CoD to default value.
*/
void Reset();
uint16_t mMajorServiceClass;
uint8_t mMajorDeviceClass;
uint8_t mMinorDeviceClass;
nsCOMPtr<nsPIDOMWindow> mOwnerWindow;
};
END_BLUETOOTH_NAMESPACE
#endif // mozilla_dom_bluetooth_bluetoothclassofdevice_h

Просмотреть файл

@ -27,19 +27,19 @@ BEGIN_BLUETOOTH_NAMESPACE
*/
// Bit 23 ~ Bit 13: Major service class
#define GET_MAJOR_SERVICE_CLASS(cod) ((cod & 0xffe000) >> 13)
#define GET_MAJOR_SERVICE_CLASS(cod) (((cod) & 0xffe000) >> 13)
// Bit 12 ~ Bit 8: Major device class
#define GET_MAJOR_DEVICE_CLASS(cod) ((cod & 0x1f00) >> 8)
#define GET_MAJOR_DEVICE_CLASS(cod) (((cod) & 0x1f00) >> 8)
// Bit 7 ~ Bit 2: Minor device class
#define GET_MINOR_DEVICE_CLASS(cod) ((cod & 0xfc) >> 2)
#define GET_MINOR_DEVICE_CLASS(cod) (((cod) & 0xfc) >> 2)
// Audio: Major service class = 0x100 (Bit 21 is set)
#define HAS_AUDIO(cod) (cod & 0x200000)
#define HAS_AUDIO(cod) ((cod) & 0x200000)
// Rendering: Major service class = 0x20 (Bit 18 is set)
#define HAS_RENDERING(cod) (cod & 0x40000)
#define HAS_RENDERING(cod) ((cod) & 0x40000)
// Peripheral: Major device class = 0x5
#define IS_PERIPHERAL(cod) (GET_MAJOR_DEVICE_CLASS(cod) == 0x5)

Просмотреть файл

@ -7,6 +7,7 @@
if CONFIG['MOZ_B2G_BT']:
SOURCES += [
'BluetoothAdapter.cpp',
'BluetoothClassOfDevice.cpp',
'BluetoothDevice.cpp',
'BluetoothDiscoveryHandle.cpp',
'BluetoothHidManager.cpp',
@ -93,6 +94,7 @@ EXPORTS.mozilla.dom.bluetooth.ipc += [
EXPORTS.mozilla.dom.bluetooth += [
'BluetoothAdapter.h',
'BluetoothClassOfDevice.h',
'BluetoothCommon.h',
'BluetoothDevice.h',
'BluetoothDiscoveryHandle.h',

Просмотреть файл

@ -128,7 +128,7 @@ TouchEvent::Touches()
WidgetTouchEvent* touchEvent = mEvent->AsTouchEvent();
if (mEvent->message == NS_TOUCH_END || mEvent->message == NS_TOUCH_CANCEL) {
// for touchend events, remove any changed touches from the touches array
WidgetTouchEvent::TouchArray unchangedTouches;
WidgetTouchEvent::AutoTouchArray unchangedTouches;
const WidgetTouchEvent::TouchArray& touches = touchEvent->touches;
for (uint32_t i = 0; i < touches.Length(); ++i) {
if (!touches[i]->mChanged) {
@ -147,7 +147,7 @@ TouchList*
TouchEvent::TargetTouches()
{
if (!mTargetTouches) {
nsTArray< nsRefPtr<Touch> > targetTouches;
WidgetTouchEvent::AutoTouchArray targetTouches;
WidgetTouchEvent* touchEvent = mEvent->AsTouchEvent();
const WidgetTouchEvent::TouchArray& touches = touchEvent->touches;
for (uint32_t i = 0; i < touches.Length(); ++i) {
@ -169,7 +169,7 @@ TouchList*
TouchEvent::ChangedTouches()
{
if (!mChangedTouches) {
nsTArray< nsRefPtr<Touch> > changedTouches;
WidgetTouchEvent::AutoTouchArray changedTouches;
WidgetTouchEvent* touchEvent = mEvent->AsTouchEvent();
const WidgetTouchEvent::TouchArray& touches = touchEvent->touches;
for (uint32_t i = 0; i < touches.Length(); ++i) {

Просмотреть файл

@ -10,8 +10,8 @@
#include "mozilla/dom/UIEvent.h"
#include "mozilla/Attributes.h"
#include "mozilla/EventForwards.h"
#include "mozilla/TouchEvents.h"
#include "nsJSEnvironment.h"
#include "nsTArray.h"
#include "nsWrapperCache.h"
class nsAString;
@ -33,7 +33,7 @@ public:
nsJSContext::LikelyShortLivingObjectCreated();
}
TouchList(nsISupports* aParent,
const nsTArray<nsRefPtr<Touch> >& aTouches)
const WidgetTouchEvent::TouchArray& aTouches)
: mParent(aParent)
, mPoints(aTouches)
{
@ -78,7 +78,7 @@ protected:
~TouchList() {}
nsCOMPtr<nsISupports> mParent;
nsTArray<nsRefPtr<Touch> > mPoints;
WidgetTouchEvent::TouchArray mPoints;
};
class TouchEvent : public UIEvent

Просмотреть файл

@ -35,6 +35,7 @@ interface nsIDOMNodeList;
interface nsIDOMElement;
interface nsIDOMHTMLCanvasElement;
interface nsIDOMEvent;
interface nsIDOMStyleSheet;
interface nsITransferable;
interface nsIQueryContentEventResult;
interface nsIDOMWindow;
@ -50,7 +51,7 @@ interface nsITranslationNodeList;
interface nsIJSRAIIHelper;
interface nsIContentPermissionRequest;
[scriptable, uuid(ca202fa7-7b8f-4814-acc3-a8545f67320b)]
[scriptable, uuid(0ef9e8bb-b934-4f6b-ae05-e98774d8d3d3)]
interface nsIDOMWindowUtils : nsISupports {
/**
@ -1563,15 +1564,22 @@ interface nsIDOMWindowUtils : nsISupports {
*
* Sheets added via this API take effect immediately on the document.
*/
void loadSheet(in nsIURI sheetURI,
in unsigned long type);
void loadSheet(in nsIURI sheetURI, in unsigned long type);
/**
* Adds a style sheet to the list of additional style sheets of the document.
*
* Style sheets can be preloaded with nsIStyleSheetService.preloadSheet.
*
* Sheets added via this API take effect immediately on the document.
*/
void addSheet(in nsIDOMStyleSheet sheet, in unsigned long type);
/**
* Remove the document style sheet at |sheetURI| from the list of additional
* style sheets of the document. The removal takes effect immediately.
*/
void removeSheet(in nsIURI sheetURI,
in unsigned long type);
void removeSheet(in nsIURI sheetURI, in unsigned long type);
/**
* Returns true if a user input is being handled.
@ -1641,8 +1649,10 @@ interface nsIDOMWindowUtils : nsISupports {
AString getOMTAStyle(in nsIDOMElement aElement, in AString aProperty);
/**
* If we are currently handling user input, this informs the event state
* manager. Remember to call destruct() on the return value!
* If aHandlingInput is true, this informs the event state manager that
* we're handling user input. Otherwise, this is a no-op (as by default
* we're not handling user input).
* Remember to call destruct() on the return value!
* See also nsIDOMWindowUtils::isHandlingUserInput.
*/
nsIJSRAIIHelper setHandlingUserInput(in boolean aHandlingInput);

Просмотреть файл

@ -41,6 +41,7 @@
#include "nsIDOMWindow.h"
#include "nsIDOMWindowUtils.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsILoadInfo.h"
#include "nsIPromptFactory.h"
#include "nsIURI.h"
#include "nsIWebBrowserChrome.h"
@ -2185,6 +2186,16 @@ public:
}
NS_IMETHOD GetOwner(nsISupports**) NO_IMPL
NS_IMETHOD SetOwner(nsISupports*) NO_IMPL
NS_IMETHOD GetLoadInfo(nsILoadInfo** aLoadInfo)
{
NS_IF_ADDREF(*aLoadInfo = mLoadInfo);
return NS_OK;
}
NS_IMETHOD SetLoadInfo(nsILoadInfo* aLoadInfo)
{
mLoadInfo = aLoadInfo;
return NS_OK;
}
NS_IMETHOD GetNotificationCallbacks(nsIInterfaceRequestor** aRequestor)
{
NS_ADDREF(*aRequestor = this);
@ -2237,6 +2248,7 @@ protected:
nsCOMPtr<nsIURI> mUri;
uint64_t mCallbackId;
nsCOMPtr<Element> mElement;
nsCOMPtr<nsILoadInfo> mLoadInfo;
};
NS_IMPL_ISUPPORTS(FakeChannel, nsIChannel, nsIAuthPromptCallback,

Просмотреть файл

@ -18,7 +18,6 @@ XPIDL_SOURCES += [
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
XPIDL_SOURCES += [
'nsIDOMNetworkStatsManager.idl',
'nsIEthernetManager.idl',
'nsINetworkStatsServiceProxy.idl',
]

Просмотреть файл

@ -1,137 +0,0 @@
/* 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/. */
#include "nsISupports.idl"
[scriptable, function, uuid(2a3ad56c-edc0-439f-8aae-900b331ddf49)]
interface nsIEthernetManagerCallback : nsISupports
{
/**
* Callback function used to report the success of different operations.
*
* @param success
* Boolean value indicates the success of an operation.
* @prarm message
* Message reported in the end of operation.
*/
void notify(in boolean success, in DOMString message);
};
[scriptable, function, uuid(1746e7dd-92d4-43fa-8ef4-bc13d0b60353)]
interface nsIEthernetManagerScanCallback : nsISupports
{
/**
* Callback function used to report the result of scan function.
*
* @param list
* List of available ethernet interfaces.
*/
void notify(in jsval list);
};
/**
* An internal idl provides control to ethernet interfaces.
*/
[scriptable, uuid(a96441dd-36b3-4f7f-963b-2c032e28a039)]
interface nsIEthernetManager : nsISupports
{
/**
* List of exisiting interface name.
*/
readonly attribute jsval interfaceList;
/**
* Scan available ethernet interfaces on device.
*
* @param callback
* Callback function.
*/
void scan(in nsIEthernetManagerScanCallback callback);
/**
* Add a new interface to the interface list.
*
* @param ifname
* Interface name. Should be the form of "eth*".
* @param callback
* Callback function.
*/
void addInterface(in DOMString ifname,
in nsIEthernetManagerCallback callback);
/**
* Remove an existing interface from the interface list.
*
* @param ifname
* Interface name.
* @param Callback
* Callback function.
*/
void removeInterface(in DOMString ifname,
in nsIEthernetManagerCallback callback);
/**
* Update a conifg of an existing interface in the interface list.
*
* @param ifname
* Interface name.
* @param config
* .ip: ip address.
* .prefixLength: mask length.
* .gateway: gateway.
* .dnses: dnses.
* .httpProxyHost: http proxy host.
* .httpProxyPort: http porxy port.
* .ipMode: ip mode, can be 'dhcp' or 'static'.
* @param callback
* Callback function.
*/
void updateInterfaceConfig(in DOMString ifname,
in jsval config,
in nsIEthernetManagerCallback callback);
/**
* Enable networking of an existing interface in the interface list.
*
* @param ifname
* Interface name.
* @param callback
* Callback function.
*/
void enable(in DOMString ifname,
in nsIEthernetManagerCallback callback);
/**
* Disable networking of an existing interface in the interface list.
*
* @param ifname
* Interface name.
* @param callback
* Callback function.
*/
void disable(in DOMString ifname,
in nsIEthernetManagerCallback callback);
/**
* Make an existing interface connect to network.
*
* @param ifname
* Interface name.
* @param callback
* Callback function.
*/
void connect(in DOMString ifname,
in nsIEthernetManagerCallback callback);
/**
* Disconnect a connected interface in the interface list.
*
* @param ifname
* Interface name.
* @param callback
* Callback function.
*/
void disconnect(in DOMString ifname,
in nsIEthernetManagerCallback callback);
};

Просмотреть файл

@ -1,619 +0,0 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* 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";
const DEBUG = false;
function debug(s) {
if (DEBUG) {
dump("-*- EthernetManager: " + s + "\n");
}
}
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
const TOPIC_INTERFACE_STATE_CHANGED = "network-interface-state-changed";
const ETHERNET_NETWORK_IFACE_PREFIX = "eth";
const DEFAULT_ETHERNET_NETWORK_IFACE = "eth0";
const INTERFACE_IPADDR_NULL = "0.0.0.0";
const INTERFACE_GATEWAY_NULL = "0.0.0.0";
const INTERFACE_PREFIX_NULL = 0;
const INTERFACE_MACADDR_NULL = "00:00:00:00:00:00";
const NETWORK_INTERFACE_UP = "up";
const NETWORK_INTERFACE_DOWN = "down";
const IP_MODE_DHCP = "dhcp";
const IP_MODE_STATIC = "static";
XPCOMUtils.defineLazyServiceGetter(this, "gNetworkManager",
"@mozilla.org/network/manager;1",
"nsINetworkManager");
XPCOMUtils.defineLazyServiceGetter(this, "gNetworkService",
"@mozilla.org/network/service;1",
"nsINetworkService");
// nsINetworkInterface
function EthernetInterface(attr) {
this.state = attr.state;
this.type = attr.type;
this.name = attr.name;
this.ipMode = attr.ipMode;
this.ips = [attr.ip];
this.prefixLengths = [attr.prefixLength];
this.gateways = [attr.gateway];
this.dnses = attr.dnses;
this.httpProxyHost = "";
this.httpProxyPort = 0;
}
EthernetInterface.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInterface]),
updateConfig: function(config) {
debug("Interface " + this.name + " updateConfig " + JSON.stringify(config));
this.state = (config.state != undefined) ?
config.state : this.state;
this.ips = (config.ip != undefined) ? [config.ip] : this.ips;
this.prefixLengths = (config.prefixLength != undefined) ?
[config.prefixLength] : this.prefixLengths;
this.gateways = (config.gateway != undefined) ?
[config.gateway] : this.gateways;
this.dnses = (config.dnses != undefined) ? config.dnses : this.dnses;
this.httpProxyHost = (config.httpProxyHost != undefined) ?
config.httpProxyHost : this.httpProxyHost;
this.httpProxyPort = (config.httpProxyPort != undefined) ?
config.httpProxyPort : this.httpProxyPort;
this.ipMode = (config.ipMode != undefined) ?
config.ipMode : this.ipMode;
},
getAddresses: function(ips, prefixLengths) {
ips.value = this.ips.slice();
prefixLengths.value = this.prefixLengths.slice();
return this.ips.length;
},
getGateways: function(count) {
if (count) {
count.value = this.gateways.length;
}
return this.gateways.slice();
},
getDnses: function(count) {
if (count) {
count.value = this.dnses.length;
}
return this.dnses.slice();
}
};
// nsIEthernetManager
/*
* Network state transition diagram
*
* ---------- enable --------- connect ----------- disconnect --------------
* | Disabled | -----> | Enabled | -------> | Connected | <----------> | Disconnected |
* ---------- --------- ----------- connect --------------
* ^ | | |
* | disable | | |
* -----------------------------------------------------------------------
*/
function EthernetManager() {
debug("EthernetManager start");
// Interface list.
this.ethernetInterfaces = {};
// Used to memorize last connection information.
this.lastStaticConfig = {};
Services.obs.addObserver(this, "xpcom-shutdown", false);
}
EthernetManager.prototype = {
classID: Components.ID("a96441dd-36b3-4f7f-963b-2c032e28a039"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIEthernetManager]),
ethernetInterfaces: null,
lastStaticConfig: null,
observer: function(subject, topic, data) {
switch (topic) {
case "xpcom-shutdown":
debug("xpcom-shutdown");
this._shutdown();
Services.obs.removeObserver(this, "xpcom-shutdown");
break;
}
},
_shutdown: function() {
debug("shuting down.");
(function onRemove(ifnameList) {
if (!ifnameList.length) {
return;
}
let ifname = ifnameList.shift();
this.removeInterface(ifname, { notify: onRemove.bind(this, ifnameList) });
}).call(this, Object.keys(this.ethernetInterfaces));
},
get interfaceList() {
return Object.keys(this.ethernetInterfaces);
},
scan: function(callback) {
debug("scan");
gNetworkService.getInterfaces(function(success, list) {
let ethList = [];
if (!success) {
if (callback) {
callback.notify(ethList);
}
return;
}
for (let i = 0; i < list.length; i++) {
debug("Found interface " + list[i]);
if (!list[i].startsWith(ETHERNET_NETWORK_IFACE_PREFIX)) {
continue;
}
ethList.push(list[i]);
}
if (callback) {
callback.notify(ethList);
}
});
},
addInterface: function(ifname, callback) {
debug("addInterfaces " + ifname);
if (!ifname || !ifname.startsWith(ETHERNET_NETWORK_IFACE_PREFIX)) {
if (callback) {
callback.notify(false, "Invalid interface.");
}
return;
}
if (this.ethernetInterfaces[ifname]) {
if (callback) {
callback.notify(true, "Interface already exists.");
}
return;
}
gNetworkService.getInterfaceConfig(ifname, function(success, result) {
if (!success) {
if (callback) {
callback.notify(false, "Netd error.");
}
return;
}
// Since the operation may still succeed with an invalid interface name,
// check the mac address as well.
if (result.macAddr == INTERFACE_MACADDR_NULL) {
if (callback) {
callback.notify(false, "Interface not found.");
}
return;
}
this.ethernetInterfaces[ifname] = new EthernetInterface({
state: result.link == NETWORK_INTERFACE_UP ?
Ci.nsINetworkInterface.NETWORK_STATE_DISABLED :
Ci.nsINetworkInterface.NETWORK_STATE_ENABLED,
name: ifname,
type: Ci.nsINetworkInterface.NETWORK_TYPE_ETHERNET,
ip: result.ip,
prefixLength: result.prefix,
ipMode: IP_MODE_DHCP
});
// Register the interface to NetworkManager.
gNetworkManager.registerNetworkInterface(this.ethernetInterfaces[ifname]);
debug("Add interface " + ifname + " success with " +
JSON.stringify(this.ethernetInterfaces[ifname]));
if (callback) {
callback.notify(true, "ok");
}
}.bind(this));
},
removeInterface: function(ifname, callback) {
debug("removeInterface");
if (!ifname || !ifname.startsWith(ETHERNET_NETWORK_IFACE_PREFIX)) {
if (callback) {
callback.notify(false, "Invalid interface.");
}
return;
}
if (!this.ethernetInterfaces[ifname]) {
if (callback) {
callback.notify(true, "Interface does not exist.");
}
return;
}
// Make sure interface is disable before removing.
this.disable(ifname, { notify: function(success, message) {
// Unregister the interface from NetworkManager and also remove it from
// the interface list.
gNetworkManager.unregisterNetworkInterface(this.ethernetInterfaces[ifname]);
delete this.ethernetInterfaces[ifname];
debug("Remove interface " + ifname + " success.");
if (callback) {
callback.notify(true, "ok");
}
}.bind(this)});
},
updateInterfaceConfig: function(ifname, config, callback) {
debug("interfaceConfigUpdate with " + ifname);
this._ensureIfname(ifname, callback, function(iface) {
if (!config) {
if (callback) {
callback.notify(false, "No config to update.");
}
return;
}
// Network state can not be modified externally.
if (config.state) {
delete config.state;
}
let currentIpMode = iface.ipMode;
// Update config.
this.ethernetInterfaces[iface.name].updateConfig(config);
// Do not automatically re-connect if the interface is not in connected
// state.
if (iface.state != Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED) {
if (callback) {
callback.notify(true, "ok");
}
return;
}
let newIpMode = this.ethernetInterfaces[iface.name].ipMode;
if (newIpMode == IP_MODE_STATIC) {
this._setStaticIP(iface.name, callback);
return;
}
if ((currentIpMode == IP_MODE_STATIC) && (newIpMode == IP_MODE_DHCP)) {
gNetworkService.stopDhcp(iface.name);
// Clear the current network settings before do dhcp request, otherwise
// dhcp settings could fail.
this.disconnect(iface.name, { notify: function(success, message) {
if (!success) {
if (callback) {
callback.notify("Disconnect failed.");
}
return;
}
this._runDhcp(iface.name, callback);
}.bind(this) });
return;
}
if (callback) {
callback.notify(true, "ok");
}
}.bind(this));
},
enable: function(ifname, callback) {
debug("enable with " + ifname);
this._ensureIfname(ifname, callback, function(iface) {
// Interface can be only enabled in the state of disabled.
if (iface.state != Ci.nsINetworkInterface.NETWORK_STATE_DISABLED) {
if (callback) {
callback.notify(true, "already enabled.");
}
return;
}
let ips = {};
let prefixLengths = {};
iface.getAddresses(ips, prefixLengths);
let config = { ifname: iface.name,
ip: ips.value[0],
prefix: prefixLengths.value[0],
link: NETWORK_INTERFACE_UP };
gNetworkService.setInterfaceConfig(config, function(success) {
if (!success) {
if (callback) {
callback.notify(false, "Netd Error.");
}
return;
}
this.ethernetInterfaces[iface.name].updateConfig({
state: Ci.nsINetworkInterface.NETWORK_STATE_ENABLED
});
debug("Interface " + iface.name + " enable success.");
if (callback) {
callback.notify(true, "ok");
}
}.bind(this));
}.bind(this));
},
disable: function(ifname, callback) {
debug("disable with " + ifname);
this._ensureIfname(ifname, callback, function(iface) {
if (iface.state == Ci.nsINetworkInterface.NETWORK_STATE_DISABLED) {
if (callback) {
callback.notify(true, "Interface is already disabled.");
}
return;
}
if (iface.state == Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED) {
gNetworkService.stopDhcp(iface.name);
}
let ips = {};
let prefixLengths = {};
iface.getAddresses(ips, prefixLengths);
let config = { ifname: iface.name,
ip: ips.value[0],
prefix: prefixLengths.value[0],
link: NETWORK_INTERFACE_DOWN };
gNetworkService.setInterfaceConfig(config, function(success) {
if (!success) {
if (callback) {
callback.notify(false, "Netd Error.");
}
return;
}
this.ethernetInterfaces[iface.name].updateConfig({
state: Ci.nsINetworkInterface.NETWORK_STATE_DISABLED
});
debug("Disable interface " + iface.name + " success.");
if (callback) {
callback.notify(true, "ok");
}
}.bind(this));
}.bind(this));
},
connect: function(ifname, callback) {
debug("connect wtih " + ifname);
this._ensureIfname(ifname, callback, function(iface) {
// Interface can only be connected in the state of enabled or
// disconnected.
if (iface.state == Ci.nsINetworkInterface.NETWORK_STATE_DISABLED ||
iface.state == Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED) {
if (callback) {
callback.notify(true, "Interface " + ifname + " is not available or "
+ " already connected.");
}
return;
}
if (iface.ipMode == IP_MODE_DHCP) {
this._runDhcp(iface.name, callback);
return;
}
if (iface.ipMode == IP_MODE_STATIC) {
if (this._checkConfigNull(iface) && this.lastStaticConfig[iface.name]) {
debug("connect with lastStaticConfig " +
JSON.stringify(this.lastStaticConfig[iface.name]));
this.ethernetInterfaces[iface.name].updateConfig(
this.lastStaticConfig[iface.name]);
}
this._setStaticIP(iface.name, callback);
return;
}
if (callback) {
callback.notify(false, "Ip mode is wrong or not set.");
}
}.bind(this));
},
disconnect: function(ifname, callback) {
debug("disconnect");
this._ensureIfname(ifname, callback, function(iface) {
// Interface can be only disconnected in the state of connected.
if (iface.state != Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED) {
if (callback) {
callback.notify(true, "interface is already disconnected");
}
return;
}
let config = { ifname: iface.name,
ip: INTERFACE_IPADDR_NULL,
prefix: INTERFACE_PREFIX_NULL,
link: NETWORK_INTERFACE_UP };
gNetworkService.setInterfaceConfig(config, function(success) {
if (!success) {
if (callback) {
callback.notify(false, "Netd error.");
}
return;
}
// Stop dhcp daemon.
gNetworkService.stopDhcp(iface.name);
this.ethernetInterfaces[iface.name].updateConfig({
state: Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED,
ip: INTERFACE_IPADDR_NULL,
prefixLength: INTERFACE_PREFIX_NULL,
gateway: INTERFACE_GATEWAY_NULL
});
Services.obs.notifyObservers(this.ethernetInterfaces[iface.name],
TOPIC_INTERFACE_STATE_CHANGED,
null);
debug("Disconnect interface " + iface.name + " success.");
if (callback) {
callback.notify(true, "ok");
}
}.bind(this));
}.bind(this));
},
_checkConfigNull: function(iface) {
let ips = {};
let prefixLengths = {};
let gateways = iface.getGateways();
iface.getAddresses(ips, prefixLengths);
if (ips.value[0] == INTERFACE_IPADDR_NULL &&
prefixLengths.value[0] == INTERFACE_PREFIX_NULL &&
gateways[0] == INTERFACE_GATEWAY_NULL) {
return true;
}
return false;
},
_ensureIfname: function(ifname, callback, func) {
// If no given ifname, use the default one.
if (!ifname) {
ifname = DEFAULT_ETHERNET_NETWORK_IFACE;
}
let iface = this.ethernetInterfaces[ifname];
if (!iface) {
if (callback) {
callback.notify(true, "Interface " + ifname + " is not available.");
}
return;
}
func.call(this, iface);
},
_runDhcp: function(ifname, callback) {
debug("runDhcp with " + ifname);
if (!this.ethernetInterfaces[ifname]) {
callback.notify(false, "Invalid interface.");
return
}
gNetworkService.runDhcp(ifname, function(success, result) {
if (!success) {
callback.notify(false, "Dhcp failed.");
return;
}
debug("Dhcp success with " + JSON.stringify(result));
// Clear last static network information when connecting with dhcp mode.
if (this.lastStaticConfig[ifname]) {
this.lastStaticConfig[ifname] = null;
}
this.ethernetInterfaces[ifname].updateConfig({
state: Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED,
ip: result.ip,
gateway: result.gateway,
prefixLength: result.prefix,
dnses: [result.dns1, result.dns2]
});
Services.obs.notifyObservers(this.ethernetInterfaces[ifname],
TOPIC_INTERFACE_STATE_CHANGED,
null);
debug("Connect interface " + ifname + "with dhcp success.");
callback.notify(true, "ok");
}.bind(this));
},
_setStaticIP: function(ifname, callback) {
let iface = this.ethernetInterfaces[ifname];
if (!iface) {
callback.notify(false, "Invalid interface.");
return;
}
let ips = {};
let prefixLengths = {};
iface.getAddresses(ips, prefixLengths);
let config = { ifname: iface.name,
ip: ips.value[0],
prefix: prefixLengths.value[0],
link: NETWORK_INTERFACE_UP };
gNetworkService.setInterfaceConfig(config, function(success) {
if (!success) {
callback.notify(false, "Netd Error.");
return;
}
// Keep the lastest static network information.
let ips = {};
let prefixLengths = {};
let gateways = iface.getGateways();
iface.getAddresses(ips, prefixLengths);
this.lastStaticConfig[iface.name] = {
ip: ips.value[0],
prefixLength: prefixLengths.value[0],
gateway: gateways[0]
};
this.ethernetInterfaces[ifname].updateConfig({
state: Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED,
});
Services.obs.notifyObservers(this.ethernetInterfaces[ifname],
TOPIC_INTERFACE_STATE_CHANGED,
null);
debug("Connect interface " + ifname + "with static ip success.");
callback.notify(true, "ok");
}.bind(this));
},
}
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([EthernetManager]);

Просмотреть файл

@ -1,2 +0,0 @@
component {a96441dd-36b3-4f7f-963b-2c032e28a039} EthernetManager.js
contract @mozilla.org/ethernetManager;1 {a96441dd-36b3-4f7f-963b-2c032e28a039}

Просмотреть файл

@ -44,8 +44,6 @@ EXTRA_PP_COMPONENTS += [
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
EXTRA_COMPONENTS += [
'EthernetManager.js',
'EthernetManager.manifest',
'NetworkStatsManager.js',
'NetworkStatsManager.manifest',
'NetworkStatsServiceProxy.js',

Просмотреть файл

@ -1,551 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
let Promise = SpecialPowers.Cu.import("resource://gre/modules/Promise.jsm").Promise;
const ETHERNET_MANAGER_CONTRACT_ID = "@mozilla.org/ethernetManager;1";
const INTERFACE_UP = "UP";
const INTERFACE_DOWN = "DOWN";
let gTestSuite = (function() {
let suite = {};
// Private member variables of the returned object |suite|.
let ethernetManager = SpecialPowers.Cc[ETHERNET_MANAGER_CONTRACT_ID]
.getService(SpecialPowers.Ci.nsIEthernetManager);
let pendingEmulatorShellCount = 0;
/**
* Send emulator shell command with safe guard.
*
* We should only call |finish()| after all emulator command transactions
* end, so here comes with the pending counter. Resolve when the emulator
* gives positive response, and reject otherwise.
*
* Fulfill params: an array of emulator response lines.
* Reject params: an array of emulator response lines.
*
* @param command
* A string command to be passed to emulator through its telnet console.
*
* @return A deferred promise.
*/
function runEmulatorShellSafe(command) {
let deferred = Promise.defer();
++pendingEmulatorShellCount;
runEmulatorShell(command, function(aResult) {
--pendingEmulatorShellCount;
ok(true, "Emulator shell response: " + JSON.stringify(aResult));
if (Array.isArray(aResult)) {
deferred.resolve(aResult);
} else {
deferred.reject(aResult);
}
});
return deferred.promise;
}
/**
* Get the system network conifg by the given interface name.
*
* Use shell command 'netcfg' to get the list of network cofig.
*
* Fulfill params: An object of { name, flag, ip }
*
* @parm ifname
* Interface name.
*
* @return A deferred promise.
*/
function getNetworkConfig(ifname) {
return runEmulatorShellSafe(['netcfg'])
.then(result => {
// Sample 'netcfg' output:
//
// lo UP 127.0.0.1/8 0x00000049 00:00:00:00:00:00
// eth0 UP 10.0.2.15/24 0x00001043 52:54:00:12:34:56
// eth1 DOWN 0.0.0.0/0 0x00001002 52:54:00:12:34:57
// rmnet1 DOWN 0.0.0.0/0 0x00001002 52:54:00:12:34:59
let config;
for (let i = 0; i < result.length; i++) {
let tokens = result[i].split(/\s+/);
let name = tokens[0];
let flag = tokens[1];
let ip = tokens[2].split(/\/+/)[0];
if (name == ifname) {
config = { name: name, flag: flag, ip: ip };
break;
}
}
return config;
});
}
/**
* Get the ip assigned by dhcp server of a given interface name.
*
* Get the ip from android property 'dhcp.[ifname].ipaddress'.
*
* Fulfill params: A string of ip address.
*
* @parm ifname
* Interface name.
*
* @return A deferred promise.
*/
function getDhcpIpAddr(ifname) {
return runEmulatorShellSafe(['getprop', 'dhcp.' + ifname + '.ipaddress'])
.then(function(ipAddr) {
return ipAddr[0];
});
}
/**
* Get the gateway assigned by dhcp server of a given interface name.
*
* Get the ip from android property 'dhcp.[ifname].gateway'.
*
* Fulfill params: A string of gateway.
*
* @parm ifname
* Interface name.
*
* @return A deferred promise.
*/
function getDhcpGateway(ifname) {
return runEmulatorShellSafe(['getprop', 'dhcp.' + ifname + '.gateway'])
.then(function(gateway) {
return gateway[0];
});
}
/**
* Get the default route.
*
* Use shell command 'ip route' to get the default of device.
*
* Fulfill params: An array of { name, gateway }
*
* @return A deferred promise.
*/
function getDefaultRoute() {
return runEmulatorShellSafe(['ip', 'route'])
.then(result => {
// Sample 'ip route' output:
//
// 10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15
// default via 10.0.2.2 dev eth0 metric 2
let routeInfo = [];
for (let i = 0; i < result.length; i++) {
if (!result[i].match('default')) {
continue;
}
let tokens = result[i].split(/\s+/);
let name = tokens[4];
let gateway = tokens[2];
routeInfo.push({ name: name, gateway: gateway });
}
return routeInfo;
});
}
/**
* Check a specific interface is enabled or not.
*
* @parm ifname
* Interface name.
* @parm enabled
* A boolean value used to check interface is disable or not.
*
* @return A deferred promise.
*/
function checkInterfaceIsEnabled(ifname, enabled) {
return getNetworkConfig(ifname)
.then(function(config) {
if (enabled) {
is(config.flag, INTERFACE_UP, "Interface is enabled as expectation.");
} else {
is(config.flag, INTERFACE_DOWN, "Interface is disabled as expectation.");
}
});
}
/**
* Check the ip of a specific interface is equal to given ip or not.
*
* @parm ifname
* Interface name.
* @parm ip
* Given ip address.
*
* @return A deferred promise.
*/
function checkInterfaceIpAddr(ifname, ip) {
return getNetworkConfig(ifname)
.then(function(config) {
is(config.ip, ip, "IP is right as expectation.");
});
}
/**
* Check the default gateway of a specific interface is equal to given gateway
* or not.
*
* @parm ifname
* Interface name.
* @parm gateway
* Given gateway.
*
* @return A deferred promise.
*/
function checkDefaultRoute(ifname, gateway) {
return getDefaultRoute()
.then(function(routeInfo) {
for (let i = 0; i < routeInfo.length; i++) {
if (routeInfo[i].name == ifname) {
is(routeInfo[i].gateway, gateway,
"Default gateway is right as expectation.");
return true;
}
}
if (!gateway) {
ok(true, "Default route is cleared.");
return true;
}
return false;
});
}
/**
* Check the length of interface list in EthernetManager is equal to given
* length or not.
*
* @parm length
* Given length.
*/
function checkInterfaceListLength(length) {
let list = ethernetManager.interfaceList;
is(length, list.length, "List length is equal as expectation.");
}
/**
* Check the given interface exists on device or not.
*
* @parm ifname
* Interface name.
*
* @return A deferred promise.
*/
function checkInterfaceExist(ifname) {
return scanInterfaces()
.then(list => {
let index = list.indexOf(ifname);
if (index < 0) {
throw "Interface " + ifname + " not found.";
}
ok(true, ifname + " exists.")
});
}
/**
* Scan for available ethernet interfaces.
*
* Fulfill params: A list of available interfaces found in device.
*
* @return A deferred promise.
*/
function scanInterfaces() {
let deferred = Promise.defer();
ethernetManager.scan(function onScan(list) {
deferred.resolve(list);
});
return deferred.promise;
}
/**
* Add an interface into interface list.
*
* Fulfill params: A boolean value indicates success or not.
*
* @param ifname
* Interface name.
*
* @return A deferred promise.
*/
function addInterface(ifname) {
let deferred = Promise.defer();
ethernetManager.addInterface(ifname, function onAdd(success, message) {
ok(success, "Add interface " + ifname + " success.");
is(message, "ok", "Message is as expectation.");
deferred.resolve(success);
});
return deferred.promise;
}
/**
* Remove an interface form the interface list.
*
* Fulfill params: A boolean value indicates success or not.
*
* @param ifname
* Interface name.
*
* @return A deferred promise.
*/
function removeInterface(ifname) {
let deferred = Promise.defer();
ethernetManager.removeInterface(ifname, function onRemove(success, message) {
ok(success, "Remove interface " + ifname + " success.");
is(message, "ok", "Message is as expectation.");
deferred.resolve(success);
});
return deferred.promise;
}
/**
* Enable networking of an interface in the interface list.
*
* Fulfill params: A boolean value indicates success or not.
*
* @param ifname
* Interface name.
*
* @return A deferred promise.
*/
function enableInterface(ifname) {
let deferred = Promise.defer();
ethernetManager.enable(ifname, function onEnable(success, message) {
ok(success, "Enable interface " + ifname + " success.");
is(message, "ok", "Message is as expectation.");
deferred.resolve(success);
});
return deferred.promise;
}
/**
* Disable networking of an interface in the interface list.
*
* Fulfill params: A boolean value indicates success or not.
*
* @param ifname
* Interface name.
*
* @return A deferred promise.
*/
function disableInterface(ifname) {
let deferred = Promise.defer();
ethernetManager.disable(ifname, function onDisable(success, message) {
ok(success, "Disable interface " + ifname + " success.");
is(message, "ok", "Message is as expectation.");
deferred.resolve(success);
});
return deferred.promise;
}
/**
* Make an interface connect to network.
*
* Fulfill params: A boolean value indicates success or not.
*
* @param ifname
* Interface name.
*
* @return A deferred promise.
*/
function makeInterfaceConnect(ifname) {
let deferred = Promise.defer();
ethernetManager.connect(ifname, function onConnect(success, message) {
ok(success, "Interface " + ifname + " is connected successfully.");
is(message, "ok", "Message is as expectation.");
deferred.resolve(success);
});
return deferred.promise;
}
/**
* Make an interface disconnect to network.
*
* Fulfill params: A boolean value indicates success or not.
*
* @param ifname
* Interface name.
*
* @return A deferred promise.
*/
function makeInterfaceDisconnect(ifname) {
let deferred = Promise.defer();
ethernetManager.disconnect(ifname, function onDisconnect(success, message) {
ok(success, "Interface " + ifname + " is disconnected successfully.");
is(message, "ok", "Message is as expectation.");
deferred.resolve(success);
});
return deferred.promise;
}
/**
* Update the config the an interface in the interface list.
*
* @param ifname
* Interface name.
* @param config
* .ip: ip address.
* .prefixLength: mask length.
* .gateway: gateway.
* .dnses: dnses.
* .httpProxyHost: http proxy host.
* .httpProxyPort: http porxy port.
* .usingDhcp: an boolean value indicates using dhcp or not.
*
* @return A deferred promise.
*/
function updateInterfaceConfig(ifname, config) {
let deferred = Promise.defer();
ethernetManager.updateInterfaceConfig(ifname, config,
function onUpdated(success, message) {
ok(success, "Interface " + ifname + " config is updated successfully " +
" with " + JSON.stringify(config));
is(message, "ok", "Message is as expectation.");
deferred.resolve(success);
});
return deferred.promise;
}
/**
* Wait for timeout.
*
* @param timeout
* Time in ms.
*
* @return A deferred promise.
*/
function waitForTimeout(timeout) {
let deferred = Promise.defer();
setTimeout(function() {
ok(true, "waitForTimeout " + timeout);
deferred.resolve();
}, timeout);
return deferred.promise;
}
/**
* Wait for default route of a specific interface being set and
* check.
*
* @param ifname
* Interface name.
* @param gateway
* Target gateway.
*
* @return A deferred promise.
*/
function waitForDefaultRouteSet(ifname, gateway) {
return gTestSuite.waitForTimeout(500)
.then(() => gTestSuite.checkDefaultRoute(ifname, gateway))
.then(success => {
if (success) {
ok(true, "Default route is set as expectation " + gateway);
return;
}
ok(true, "Default route is not set yet, check again. " + success);
return waitForDefaultRouteSet(ifname, gateway);
});
}
//---------------------------------------------------
// Public test suite functions
//---------------------------------------------------
suite.scanInterfaces = scanInterfaces;
suite.addInterface = addInterface;
suite.removeInterface = removeInterface;
suite.enableInterface = enableInterface;
suite.disableInterface = disableInterface;
suite.makeInterfaceConnect = makeInterfaceConnect;
suite.makeInterfaceDisconnect = makeInterfaceDisconnect;
suite.updateInterfaceConfig = updateInterfaceConfig;
suite.getDhcpIpAddr = getDhcpIpAddr;
suite.getDhcpGateway = getDhcpGateway;
suite.checkInterfaceExist = checkInterfaceExist;
suite.checkInterfaceIsEnabled = checkInterfaceIsEnabled;
suite.checkInterfaceIpAddr = checkInterfaceIpAddr;
suite.checkDefaultRoute = checkDefaultRoute;
suite.checkInterfaceListLength = checkInterfaceListLength;
suite.waitForTimeout = waitForTimeout;
suite.waitForDefaultRouteSet = waitForDefaultRouteSet;
/**
* End up the test run.
*
* Wait until all pending emulator shell commands are done and then |finish|
* will be called in the end.
*/
function cleanUp() {
waitFor(finish, function() {
return pendingEmulatorShellCount === 0;
});
}
/**
* Common test routine.
*
* Start a test with the given test case chain. The test environment will be
* settled down before the test. After the test, all the affected things will
* be restored.
*
* @param aTestCaseChain
* The test case entry point, which can be a function or a promise.
*
* @return A deferred promise.
*/
suite.doTest = function(aTestCaseChain) {
return Promise.resolve()
.then(aTestCaseChain)
.then(function onresolve() {
cleanUp();
}, function onreject(aReason) {
ok(false, 'Promise rejects during test' + (aReason ? '(' + aReason + ')' : ''));
cleanUp();
});
};
return suite;
})();

Просмотреть файл

@ -1,15 +0,0 @@
[DEFAULT]
b2g = true
browser = false
qemu = true
[test_ethernet_add_interface.js]
[test_ethernet_remove_interface.js]
[test_ethernet_enable.js]
[test_ethernet_disable.js]
[test_ethernet_connect_with_dhcp.js]
[test_ethernet_connect_with_static_ip.js]
[test_ethernet_reconnect_with_dhcp.js]
[test_ethernet_reconnect_with_static_ip.js]
[test_ethernet_ip_mode_change.js]
[test_ethernet_disconnect.js]

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше