зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to fx-team
This commit is contained in:
Коммит
c5a0038de8
4
CLOBBER
4
CLOBBER
|
@ -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
|
|
@ -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]
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче