Merge m-c to b2ginbound, a=merge

This commit is contained in:
Wes Kocher 2015-07-28 18:03:56 -07:00
commit 794fbae019
126 changed files with 1257 additions and 544 deletions

View File

@ -49,6 +49,10 @@ a11y::ProxyDestroyed(ProxyAccessible* aProxy)
{
ProxyAccessibleWrap* wrapper =
reinterpret_cast<ProxyAccessibleWrap*>(aProxy->GetWrapper());
MOZ_ASSERT(wrapper);
if (!wrapper)
return;
wrapper->Shutdown();
aProxy->SetWrapper(0);
wrapper->Release();

View File

@ -675,9 +675,6 @@ pref("dom.forms.number", true);
// implemented for b2g (bug 875751)
pref("dom.forms.color", false);
// Turns on gralloc-based direct texturing for Gonk
pref("gfx.gralloc.enabled", false);
// This preference instructs the JS engine to discard the
// source of any privileged JS after compilation. This saves
// memory, but makes things like Function.prototype.toSource()

View File

@ -6696,6 +6696,10 @@ var gIdentityHandler = {
delete this._identityIconCountryLabel;
return this._identityIconCountryLabel = document.getElementById("identity-icon-country-label");
},
get _identityIcons () {
delete this._identityIcons;
return this._identityIcons = document.getElementById("identity-icons");
},
get _identityIcon () {
delete this._identityIcon;
return this._identityIcon = document.getElementById("page-proxy-favicon");
@ -6715,12 +6719,14 @@ var gIdentityHandler = {
*/
_cacheElements : function() {
delete this._identityBox;
delete this._identityIcons;
delete this._identityIconLabel;
delete this._identityIconCountryLabel;
delete this._identityIcon;
delete this._permissionsContainer;
delete this._permissionList;
this._identityBox = document.getElementById("identity-box");
this._identityIcons = document.getElementById("identity-icons");
this._identityIconLabel = document.getElementById("identity-icon-label");
this._identityIconCountryLabel = document.getElementById("identity-icon-country-label");
this._identityIcon = document.getElementById("page-proxy-favicon");
@ -7130,7 +7136,7 @@ var gIdentityHandler = {
this._identityBox.setAttribute("open", "true");
// Now open the popup, anchored off the primary chrome element
this._identityPopup.openPopup(this._identityIcon, "bottomcenter topleft");
this._identityPopup.openPopup(this._identityIcons, "bottomcenter topleft");
},
onPopupShown(event) {

View File

@ -763,11 +763,13 @@
onclick="gIdentityHandler.handleIdentityButtonEvent(event);"
onkeypress="gIdentityHandler.handleIdentityButtonEvent(event);"
ondragstart="gIdentityHandler.onDragStart(event);">
<image id="tracking-protection-icon"/>
<image id="page-proxy-favicon"
consumeanchor="identity-box"
onclick="PageProxyClickHandler(event);"
pageproxystate="invalid"/>
<hbox id="identity-icons"
consumeanchor="identity-box">
<image id="tracking-protection-icon"/>
<image id="page-proxy-favicon"
onclick="PageProxyClickHandler(event);"
pageproxystate="invalid"/>
</hbox>
<hbox id="identity-icon-labels">
<label id="identity-icon-label" class="plain" flex="1"/>
<label id="identity-icon-country-label" class="plain"/>

View File

@ -11,6 +11,9 @@ standalone/content/libs
standalone/node_modules
# Libs we don't need to check
test/shared/vendor
# Coverage files
test/coverage
test/node_modules
# These are generated react files that we don't need to check
content/js/contacts.js
content/js/conversation.js

View File

@ -1 +1,2 @@
.module-cache
test/coverage

View File

@ -56,6 +56,17 @@ You can also run it by hand in the browser/components/loop directory:
eslint --ext .js --ext .jsx --ext .jsm .
Test coverage
=============
Initial setup
cd test
npm install
To run
npm run build-coverage
It will create a `coverage` folder under test/
Front-End Unit Tests
====================
The unit tests for Loop reside in three directories:

View File

@ -7,6 +7,7 @@ if [ "$1" == "--help" ]; then
exit 0;
fi
# Causes script to abort immediately if error code is not checked.
set -e
# Main tests
@ -22,6 +23,16 @@ if [ -x "${LOOPDIR}/${ESLINT}" ]; then
echo 'eslint run finished.'
fi
# Build tests coverage.
MISSINGDEPSMSG="\nMake sure all dependencies are up to date by running
'npm install' inside the 'browser/components/loop/test/' directory.\n"
(
cd ${LOOPDIR}/test
if ! npm run-script build-coverage ; then
echo $MISSINGDEPSMSG && exit 1
fi
)
./mach xpcshell-test ${LOOPDIR}/
./mach marionette-test ${LOOPDIR}/manifest.ini

View File

@ -256,7 +256,8 @@ loop.standaloneRoomViews = (function(mozL10n) {
mixins: [
Backbone.Events,
sharedMixins.MediaSetupMixin,
sharedMixins.RoomsAudioMixin
sharedMixins.RoomsAudioMixin,
sharedMixins.DocumentTitleMixin
],
propTypes: {
@ -306,6 +307,14 @@ loop.standaloneRoomViews = (function(mozL10n) {
* @param {Object} nextState Next state object.
*/
componentWillUpdate: function(nextProps, nextState) {
if (this.state.roomState !== ROOM_STATES.READY &&
nextState.roomState === ROOM_STATES.READY) {
this.setTitle(mozL10n.get("standalone_title_with_room_name", {
roomName: nextState.roomName || this.state.roomName,
clientShortname: mozL10n.get("clientShortname2")
}));
}
if (this.state.roomState !== ROOM_STATES.MEDIA_WAIT &&
nextState.roomState === ROOM_STATES.MEDIA_WAIT) {
this.props.dispatcher.dispatch(new sharedActions.SetupStreamElements({

View File

@ -256,7 +256,8 @@ loop.standaloneRoomViews = (function(mozL10n) {
mixins: [
Backbone.Events,
sharedMixins.MediaSetupMixin,
sharedMixins.RoomsAudioMixin
sharedMixins.RoomsAudioMixin,
sharedMixins.DocumentTitleMixin
],
propTypes: {
@ -306,6 +307,14 @@ loop.standaloneRoomViews = (function(mozL10n) {
* @param {Object} nextState Next state object.
*/
componentWillUpdate: function(nextProps, nextState) {
if (this.state.roomState !== ROOM_STATES.READY &&
nextState.roomState === ROOM_STATES.READY) {
this.setTitle(mozL10n.get("standalone_title_with_room_name", {
roomName: nextState.roomName || this.state.roomName,
clientShortname: mozL10n.get("clientShortname2")
}));
}
if (this.state.roomState !== ROOM_STATES.MEDIA_WAIT &&
nextState.roomState === ROOM_STATES.MEDIA_WAIT) {
this.props.dispatcher.dispatch(new sharedActions.SetupStreamElements({

View File

@ -115,6 +115,10 @@ room_information_failure_unsupported_browser=Your browser cannot access any info
## replaced by the brand name and {{currentStatus}} will be replaced
## by the current call status (Connecting, Ringing, etc.)
standalone_title_with_status={{clientShortname}} — {{currentStatus}}
## LOCALIZATION_NOTE(standalone_title_with_room_name): {{roomName}} will be replaced
## by the name of the conversation and {{clientShortname}} will be
## replaced by the brand name.
standalone_title_with_room_name={{roomName}} — {{clientShortname}}
status_in_conversation=In conversation
status_conversation_ended=Conversation ended
status_error=Something went wrong

View File

@ -78,6 +78,7 @@ describe("loop.conversation", function() {
});
describe("#init", function() {
var OTRestore;
beforeEach(function() {
sandbox.stub(React, "render");
sandbox.stub(document.mozL10n, "initialize");
@ -93,13 +94,14 @@ describe("loop.conversation", function() {
pathname: "/"
});
OTRestore = window.OT;
window.OT = {
overrideGuidStorage: sinon.stub()
};
});
afterEach(function() {
delete window.OT;
window.OT = OTRestore;
});
it("should initialize L10n", function() {

View File

@ -0,0 +1,67 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* eslint-env node */
module.exports = function(config) {
"use strict";
return {
// Base path that will be used to resolve all patterns (eg. files, exclude).
basePath: "../../",
// List of files / patterns to load in the browser.
files: [],
// List of files to exclude.
exclude: [
],
// Frameworks to use.
// Available frameworks: https://npmjs.org/browse/keyword/karma-adapter .
frameworks: ["mocha"],
// Test results reporter to use.
// Possible values: "dots", "progress".
// Available reporters: https://npmjs.org/browse/keyword/karma-reporter .
reporters: ["progress", "coverage"],
coverageReporter: {
type: "html",
dir: "test/coverage/"
},
// Web server port.
port: 9876,
// Enable / disable colors in the output (reporters and logs).
colors: true,
// Level of logging.
// Possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG.
logLevel: config.LOG_INFO,
// Enable / disable watching file and executing tests whenever any file changes.
autoWatch: false,
// Start these browsers
// Available browser launchers: https://npmjs.org/browse/keyword/karma-launcher .
browsers: ["Firefox"],
// Continuous Integration mode.
// If true, Karma captures browsers, runs the tests and exits.
singleRun: true,
// Capture console output.
client: {
captureConsole: true
},
plugins: [
"karma-coverage",
"karma-mocha",
"karma-firefox-launcher"
]
};
};

View File

@ -0,0 +1,61 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* eslint-env node */
module.exports = function(config) {
"use strict";
var baseConfig = require("./karma.conf.base.js")(config);
// List of files / patterns to load in the browser.
baseConfig.files = baseConfig.files.concat([
"content/libs/l10n.js",
"content/shared/libs/react-0.12.2.js",
"content/shared/libs/jquery-2.1.4.js",
"content/shared/libs/lodash-3.9.3.js",
"content/shared/libs/backbone-1.2.1.js",
"test/shared/vendor/*.js",
"test/karma/stubs.js", // Stub out DOM event listener due to races.
"content/shared/js/utils.js",
"content/shared/js/models.js",
"content/shared/js/mixins.js",
"content/shared/js/websocket.js",
"content/shared/js/actions.js",
"content/shared/js/otSdkDriver.js",
"content/shared/js/validate.js",
"content/shared/js/dispatcher.js",
"content/shared/js/store.js",
"content/shared/js/conversationStore.js",
"content/shared/js/roomStates.js",
"content/shared/js/fxOSActiveRoomStore.js",
"content/shared/js/activeRoomStore.js",
"content/shared/js/views.js",
"content/shared/js/textChatStore.js",
"content/shared/js/textChatView.js",
"content/js/feedbackViews.js",
"content/js/client.js",
"content/js/conversationAppStore.js",
"content/js/roomStore.js",
"content/js/roomViews.js",
"content/js/conversationViews.js",
"content/js/conversation.js",
"test/desktop-local/*.js"
]);
// List of files to exclude.
baseConfig.exclude = baseConfig.exclude.concat([
"test/desktop-local/panel_test.js",
"test/desktop-local/contacts_test.js"
]);
// Preprocess matching files before serving them to the browser.
// Available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor .
baseConfig.preprocessors = {
"content/js/*.js": ["coverage"]
};
baseConfig.coverageReporter.dir = "test/coverage/desktop";
config.set(baseConfig);
};

View File

@ -0,0 +1,59 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* eslint-env node */
module.exports = function(config) {
"use strict";
var baseConfig = require("./karma.conf.base.js")(config);
// List of files / patterns to load in the browser.
baseConfig.files = baseConfig.files.concat([
"standalone/content/libs/l10n-gaia-02ca67948fe8.js",
"content/shared/libs/jquery-2.1.4.js",
"content/shared/libs/lodash-3.9.3.js",
"content/shared/libs/backbone-1.2.1.js",
"content/shared/libs/react-0.12.2.js",
"content/shared/libs/sdk.js",
"test/shared/vendor/*.js",
"content/shared/js/utils.js",
"content/shared/js/store.js",
"content/shared/js/models.js",
"content/shared/js/mixins.js",
"content/shared/js/crypto.js",
"content/shared/js/websocket.js",
"content/shared/js/validate.js",
"content/shared/js/actions.js",
"content/shared/js/dispatcher.js",
"content/shared/js/otSdkDriver.js",
"content/shared/js/roomStates.js",
"content/shared/js/fxOSActiveRoomStore.js",
"content/shared/js/activeRoomStore.js",
"content/shared/js/conversationStore.js",
"content/shared/js/views.js",
"content/shared/js/textChatStore.js",
"content/shared/js/textChatView.js",
"standalone/content/js/multiplexGum.js",
"standalone/content/js/standaloneAppStore.js",
"standalone/content/js/standaloneClient.js",
"standalone/content/js/standaloneMozLoop.js",
"standalone/content/js/fxOSMarketplace.js",
"standalone/content/js/standaloneRoomViews.js",
"standalone/content/js/standaloneMetricsStore.js",
"standalone/content/js/webapp.js",
"test/shared/*.js",
"test/standalone/*.js"
]);
// Preprocess matching files before serving them to the browser.
// Available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor .
baseConfig.preprocessors = {
"content/shared/js/*.js": ["coverage"],
"standalone/content/js/*.js": ["coverage"]
};
baseConfig.coverageReporter.dir = "test/coverage/shared_standalone";
config.set(baseConfig);
};

View File

@ -0,0 +1,8 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
// Used for desktop coverage tests because triggering methods on
// DOMContentLoaded proved to lead to race conditions.
sinon.stub(document, "addEventListener");
console.log("[stubs.js] addEventListener stubbed to prevent race conditions");

View File

@ -0,0 +1,21 @@
{
"name": "FirefoxHello",
"version": "0.0.1",
"description": "Firefox Hello test coverage",
"main": "index.js",
"directories": {
"test": "test"
},
"devDependencies": {
"istanbul": "^0.3.17",
"karma": "^0.12.37",
"karma-coverage": "^0.4.2",
"karma-firefox-launcher": "^0.1.6",
"karma-mocha": "^0.2.0"
},
"scripts": {
"build-coverage-shared": "./node_modules/.bin/karma start karma/karma.coverage.shared_standalone.js",
"build-coverage-desktop": "./node_modules/.bin/karma start karma/karma.coverage.desktop.js",
"build-coverage": "npm run build-coverage-desktop && npm run build-coverage-shared"
}
}

View File

@ -11,8 +11,8 @@ describe("loop.store.ActiveRoomStore", function () {
var FAILURE_DETAILS = loop.shared.utils.FAILURE_DETAILS;
var SCREEN_SHARE_STATES = loop.shared.utils.SCREEN_SHARE_STATES;
var ROOM_INFO_FAILURES = loop.shared.utils.ROOM_INFO_FAILURES;
var sandbox, dispatcher, store, fakeMozLoop, fakeSdkDriver;
var fakeMultiplexGum;
var sandbox, dispatcher, store, fakeMozLoop, fakeSdkDriver, fakeMultiplexGum;
var standaloneMediaRestore;
beforeEach(function() {
sandbox = sinon.sandbox.create();
@ -52,9 +52,10 @@ describe("loop.store.ActiveRoomStore", function () {
};
fakeMultiplexGum = {
reset: sandbox.spy()
reset: sandbox.spy()
};
standaloneMediaRestore = loop.standaloneMedia;
loop.standaloneMedia = {
multiplexGum: fakeMultiplexGum
};
@ -67,6 +68,7 @@ describe("loop.store.ActiveRoomStore", function () {
afterEach(function() {
sandbox.restore();
loop.standaloneMedia = standaloneMediaRestore;
});
describe("#constructor", function() {

View File

@ -431,7 +431,8 @@ describe("loop.shared.mixins", function() {
doNotDisturb: true,
getAudioBlob: sinon.spy(function(name, callback) {
callback(null, new Blob([new ArrayBuffer(10)], {type: "audio/ogg"}));
})
}),
getLoopPref: sandbox.stub()
};
fakeAudio = {

View File

@ -17,6 +17,13 @@ describe("Validator", function() {
function Y(){}
describe("#validate", function() {
function mozRTCSessionDescription() {}
var mozRTC;
beforeEach(function() {
mozRTC = new mozRTCSessionDescription();
});
it("should check for a single required dependency when no option passed",
function() {
expect(create({x: Number}, {}))
@ -67,7 +74,7 @@ describe("Validator", function() {
});
it("should check for a native constructor dependency", function() {
expect(create({foo: mozRTCSessionDescription}, {foo: "x"}))
expect(create({foo: mozRTC}, {foo: "x"}))
.to.Throw(TypeError,
/invalid dependency: foo; expected mozRTCSessionDescription/);
});

View File

@ -16,6 +16,7 @@ describe("loop.standaloneRoomViews", function() {
var sharedUtils = loop.shared.utils;
var sandbox, dispatcher, activeRoomStore, dispatch;
var fakeWindow;
beforeEach(function() {
sandbox = sinon.sandbox.create();
@ -34,12 +35,30 @@ describe("loop.standaloneRoomViews", function() {
});
sandbox.useFakeTimers();
fakeWindow = {
close: sandbox.stub(),
addEventListener: function() {},
document: { addEventListener: function(){} },
setTimeout: function(callback) { callback(); }
};
loop.shared.mixins.setRootObject(fakeWindow);
sandbox.stub(navigator.mozL10n, "get", function(key, args) {
switch(key) {
case "standalone_title_with_room_name":
return args.roomName + " — " + args.clientShortname;
default:
return key;
}
});
// Prevents audio request errors in the test console.
sandbox.useFakeXMLHttpRequest();
});
afterEach(function() {
loop.shared.mixins.setRootObject(window);
sandbox.restore();
});
@ -83,6 +102,14 @@ describe("loop.standaloneRoomViews", function() {
}
describe("#componentWillUpdate", function() {
it("should set document.title to roomName and brand name when the READY state is dispatched", function() {
activeRoomStore.setStoreState({roomName: "fakeName", roomState: ROOM_STATES.INIT});
var view = mountTestComponent();
activeRoomStore.setStoreState({roomState: ROOM_STATES.READY});
expect(fakeWindow.document.title).to.equal("fakeName — clientShortname2");
});
it("should dispatch a `SetupStreamElements` action when the MEDIA_WAIT state " +
"is entered", function() {
activeRoomStore.setStoreState({roomState: ROOM_STATES.READY});

View File

@ -47,11 +47,22 @@ describe("loop.webapp", function() {
});
describe("#init", function() {
var loopConfigRestore;
beforeEach(function() {
sandbox.stub(React, "render");
loopConfigRestore = loop.config;
loop.config = {
feedbackApiUrl: "http://fake.invalid",
serverUrl: "http://fake.invalid"
};
sandbox.stub(loop.Dispatcher.prototype, "dispatch");
});
afterEach(function() {
loop.config = loopConfigRestore;
});
it("should create the WebappRootView", function() {
loop.webapp.init();

View File

@ -9,7 +9,7 @@ const { Cc, Ci, Cu, Cr } = require("chrome");
const promise = Cu.import("resource://gre/modules/Promise.jsm", {}).Promise;
const EventEmitter = require("devtools/toolkit/event-emitter");
const { CanvasFront } = require("devtools/server/actors/canvas");
const { DevToolsUtils } = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {});
const DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
function CanvasDebuggerPanel(iframeWindow, toolbox) {
this.panelWin = iframeWindow;

View File

@ -102,8 +102,10 @@ Cu.import("resource:///modules/devtools/SideMenuWidget.jsm");
Cu.import("resource:///modules/devtools/VariablesView.jsm");
Cu.import("resource:///modules/devtools/VariablesViewController.jsm");
Cu.import("resource:///modules/devtools/ViewHelpers.jsm");
const { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
const require = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools.require;
const require = devtools.require;
const DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
const promise = require("devtools/toolkit/deprecated-sync-thenables");
const Editor = require("devtools/sourceeditor/editor");
const DebuggerEditor = require("devtools/sourceeditor/debugger.js");
@ -116,12 +118,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "Task",
XPCOMUtils.defineLazyModuleGetter(this, "Parser",
"resource:///modules/devtools/Parser.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "devtools",
"resource://gre/modules/devtools/Loader.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "DevToolsUtils",
"resource://gre/modules/devtools/DevToolsUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ShortcutUtils",
"resource://gre/modules/ShortcutUtils.jsm");

View File

@ -8,7 +8,7 @@
const { Cc, Ci, Cu, Cr } = require("chrome");
const { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
const EventEmitter = require("devtools/toolkit/event-emitter");
const { DevToolsUtils } = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {});
const DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
function DebuggerPanel(iframeWindow, toolbox) {
this.panelWin = iframeWindow;

View File

@ -10,7 +10,6 @@ const JS_URL = EXAMPLE_URL + "code_math_bogus_map.js";
// This test causes an error to be logged in the console, which appears in TBPL
// logs, so we are disabling that here.
let { DevToolsUtils } = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {});
DevToolsUtils.reportingDisabled = true;
let gPanel, gDebugger, gFrames, gSources, gPrefs;

View File

@ -17,7 +17,7 @@ let { Promise: promise } = Cu.import("resource://gre/modules/devtools/deprecated
let { gDevTools } = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
let { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
let { require } = devtools;
let { DevToolsUtils } = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {});
let DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
let { BrowserToolboxProcess } = Cu.import("resource:///modules/devtools/ToolboxProcess.jsm", {});
let { DebuggerServer } = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});
let { DebuggerClient, ObjectClient } =

View File

@ -1756,6 +1756,14 @@ Toolbox.prototype = {
yield this.highlighterUtils.stopPicker();
yield this._inspector.destroy();
if (this._highlighter) {
// Note that if the toolbox is closed, this will work fine, but will fail
// in case the browser is closed and will trigger a noSuchActor message.
// We ignore the promise that |_hideBoxModel| returns, since we should still
// proceed with the rest of destruction if it fails.
// FF42+ now does the cleanup from the actor.
if (!this.highlighter.traits.autoHideOnDestroy) {
this.highlighterUtils.unhighlight();
}
yield this._highlighter.destroy();
}
if (this._selection) {

View File

@ -548,10 +548,11 @@ HTMLBreadcrumbs.prototype = {
let deferred = promise.defer();
let fallback = null;
let lastNode = null;
let moreChildren = () => {
this.walker.children(node, {
start: fallback,
start: lastNode,
maxNodes: 10,
whatToShow: Ci.nsIDOMNodeFilter.SHOW_ELEMENT
}).then(this.selectionGuard()).then(response => {
@ -563,6 +564,7 @@ HTMLBreadcrumbs.prototype = {
if (!fallback) {
fallback = node;
}
lastNode = node;
}
if (response.hasLast) {
deferred.resolve(fallback);

View File

@ -13,6 +13,7 @@ const NODES = [
{selector: "#i21", result: "i2 i21 i211 i2111"},
{selector: "#i22211", result: "i2 i22 i222 i2221 i22211"},
{selector: "#i22", result: "i2 i22 i222 i2221 i22211"},
{selector: "#i3", result: "i3 i31"},
];
add_task(function*() {

View File

@ -42,6 +42,27 @@
</div>
</div>
</article>
<article id="i3">
<link id="i31" />
<link />
<link />
<link />
<link />
<link />
<link />
<link />
<link />
<link />
<link />
<link />
<link />
<link />
<link />
<link />
<link />
<link />
<link />
</article>
<div id='pseudo-container'></div>
</body>
</html>

View File

@ -1466,11 +1466,6 @@ MarkupView.prototype = {
this._destroyer = promise.resolve();
// Note that if the toolbox is closed, this will work fine, but will fail
// in case the browser is closed and will trigger a noSuchActor message.
// We ignore the promise that |_hideBoxModel| returns, since we should still
// proceed with the rest of destruction if it fails.
this._hideBoxModel();
this._clearBriefBoxModelTimer();
this._elt.removeEventListener("click", this._onMouseClick, false);

View File

@ -8,7 +8,7 @@
const { Cc, Ci, Cu, Cr } = require("chrome");
const { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
const EventEmitter = require("devtools/toolkit/event-emitter");
const { DevToolsUtils } = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {});
const DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
function NetMonitorPanel(iframeWindow, toolbox) {
this.panelWin = iframeWindow;

View File

@ -10,7 +10,7 @@ let { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
let { Promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
let { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
let { gDevTools } = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
let { DevToolsUtils } = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {});
const DevToolsUtils = devtools.require("devtools/toolkit/DevToolsUtils");
let { DebuggerServer } = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});
let { console } = devtools.require("resource://gre/modules/devtools/Console.jsm");
let { merge } = devtools.require("sdk/util/object");

View File

@ -50,6 +50,7 @@ const Editor = require("devtools/sourceeditor/editor");
const TargetFactory = require("devtools/framework/target").TargetFactory;
const EventEmitter = require("devtools/toolkit/event-emitter");
const {DevToolsWorker} = require("devtools/toolkit/shared/worker");
const DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
const { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
@ -61,7 +62,6 @@ Cu.import("resource:///modules/devtools/gDevTools.jsm");
Cu.import("resource://gre/modules/osfile.jsm");
Cu.import("resource:///modules/devtools/ViewHelpers.jsm");
Cu.import("resource://gre/modules/reflect.jsm");
Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "VariablesView",
"resource:///modules/devtools/VariablesView.jsm");

View File

@ -9,9 +9,10 @@ const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", {});
const {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
const {console} = Cu.import("resource://gre/modules/devtools/Console.jsm", {});
const {require} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools;
const {DevToolsUtils} = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {});
const DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
const {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
let gScratchpadWindow; // Reference to the Scratchpad chrome window object
DevToolsUtils.testing = true;

View File

@ -9,7 +9,7 @@ const { Cc, Ci, Cu, Cr } = require("chrome");
const promise = Cu.import("resource://gre/modules/Promise.jsm", {}).Promise;
const EventEmitter = require("devtools/toolkit/event-emitter");
const { WebGLFront } = require("devtools/server/actors/webgl");
const { DevToolsUtils } = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {});
const DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
function ShaderEditorPanel(iframeWindow, toolbox) {
this.panelWin = iframeWindow;

View File

@ -9,7 +9,8 @@ const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
const { DevToolsUtils } = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {});
const { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
const DevToolsUtils = devtools.require("devtools/toolkit/DevToolsUtils");
XPCOMUtils.defineLazyModuleGetter(this,
"Reflect", "resource://gre/modules/reflect.jsm");

View File

@ -8,7 +8,7 @@
this.EXPORTED_SYMBOLS = ["SplitView"];
/* this must be kept in sync with CSS (ie. splitview.css) */
const LANDSCAPE_MEDIA_QUERY = "(min-width: 551px)";
const LANDSCAPE_MEDIA_QUERY = "(min-width: 701px)";
let bindings = new WeakMap();

View File

@ -43,12 +43,8 @@ box,
display: -moz-box;
}
.splitview-landscape-resizer {
cursor: ew-resize;
}
/* this is to keep in sync with SplitView.jsm's LANDSCAPE_MEDIA_QUERY */
@media (min-width: 551px) {
@media (min-width: 701px) {
.splitview-root {
-moz-box-orient: horizontal;
}
@ -79,20 +75,8 @@ ol.splitview-nav > li.splitview-filtered {
display: -moz-box;
}
.splitview-portrait-resizer {
display: none;
}
/* portrait mode */
@media (max-width: 550px) {
.splitview-landscape-splitter {
display: none;
}
.splitview-portrait-resizer {
display: -moz-box;
}
@media (max-width: 700px) {
.splitview-controller {
max-width: none;
}

View File

@ -21,13 +21,11 @@ Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource:///modules/devtools/ViewHelpers.jsm");
Cu.import("resource://gre/modules/devtools/event-emitter.js");
Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm");
const { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
const DevToolsUtils = devtools.require("devtools/toolkit/DevToolsUtils");
Cu.import("resource://gre/modules/Task.jsm");
let {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
XPCOMUtils.defineLazyModuleGetter(this, "devtools",
"resource://gre/modules/devtools/Loader.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
"resource://gre/modules/PluralForm.jsm");

View File

@ -16,7 +16,8 @@ const WIDGET_FOCUSABLE_NODES = new Set(["vbox", "hbox"]);
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Timer.jsm");
Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm");
const { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
const DevToolsUtils = devtools.require("devtools/toolkit/DevToolsUtils");
Cu.import("resource://gre/modules/devtools/event-emitter.js");
this.EXPORTED_SYMBOLS = [

View File

@ -91,7 +91,7 @@
<xul:stack id="style-editor-chrome" class="loading theme-body">
<xul:box class="splitview-root" context="sidebar-context">
<xul:box class="splitview-root devtools-responsive-container" context="sidebar-context">
<xul:box class="splitview-controller">
<xul:box class="splitview-main">
<xul:toolbar class="devtools-toolbar">
@ -125,7 +125,7 @@
</div>
</xul:box> <!-- .splitview-nav-container -->
</xul:box> <!-- .splitview-controller -->
<xul:splitter class="devtools-side-splitter splitview-landscape-splitter devtools-invisible-splitter"/>
<xul:splitter class="devtools-side-splitter devtools-invisible-splitter"/>
<xul:box class="splitview-side-details devtools-main-content"/>
<div id="splitview-templates" hidden="true">
@ -148,9 +148,6 @@
</li>
<xul:box id="splitview-tpl-details-stylesheet" class="splitview-details">
<xul:resizer class="splitview-portrait-resizer"
dir="bottom"
element="splitview-resizer-target"/>
<xul:hbox class="stylesheet-details-container">
<xul:box class="stylesheet-editor-input textbox"
data-placeholder="&editorTextbox.placeholder;"/>

View File

@ -14,7 +14,7 @@ label,
#runtime-panel-projects {
display: block;
float: left;
width: auto;
width: 100%;
text-align: left;
}

View File

@ -65,7 +65,7 @@
}
.identity-popup-section:not(:first-child) {
border-top: 1px solid rgb(229,229,229);
border-top: 1px solid ThreeDShadow;
}
#identity-popup-securityView,
@ -126,7 +126,7 @@
.identity-popup-expander > .button-box {
padding: 0;
-moz-appearance: none;
border: solid #e5e5e5;
border: solid ThreeDShadow;
border-width: 0 0 0 1px;
}
@ -209,7 +209,7 @@
}
#identity-popup-securityView-header {
border-bottom: 1px solid #e5e5e5;
border-bottom: 1px solid ThreeDShadow;
padding-bottom: 1em;
margin-bottom: 1em;
}
@ -219,7 +219,7 @@
}
#identity-popup-content-verifier {
color: #636363;
color: Graytext;
}
#identity-popup-content-owner,
@ -277,7 +277,7 @@
#identity-popup-more-info-button {
border: none;
border-top: 1px solid hsla(210,4%,10%,.14);
border-top: 1px solid ThreeDShadow;
background: transparent;
-moz-appearance: none;
margin-top: 5px;

View File

@ -140,20 +140,3 @@
min-width: 48px;
min-height: 0;
}
/* Resizers */
.splitview-portrait-resizer {
-moz-appearance: none;
background: linear-gradient(black 1px, rgba(255,255,255,0.2) 1px),
linear-gradient(hsl(210,11%,36%), hsl(210,11%,18%));
height: 12px;
background-size: 10px 2px, 100% 12px;
background-clip: content-box, border-box;
background-repeat: repeat-y, no-repeat;
background-position: center center;
padding: 2px 0;
border-top: 1px solid hsla(210,8%,5%,.5);
border-bottom: 1px solid hsla(210,8%,5%,.5);
}

View File

@ -111,6 +111,10 @@
transition: none;
}
#urlbar[pageproxystate="invalid"] > #identity-box > #identity-icons > #tracking-protection-icon {
visibility: collapse;
}
/* MAIN IDENTITY ICON */
#page-proxy-favicon {
@ -119,26 +123,26 @@
list-style-image: url(chrome://browser/skin/identity-not-secure.svg);
}
.chromeUI > #page-proxy-favicon[pageproxystate="valid"] {
.chromeUI > #identity-icons > #page-proxy-favicon[pageproxystate="valid"] {
list-style-image: url(chrome://branding/content/identity-icons-brand.svg);
}
.verifiedDomain > #page-proxy-favicon[pageproxystate="valid"],
.verifiedIdentity > #page-proxy-favicon[pageproxystate="valid"] {
.verifiedDomain > #identity-icons > #page-proxy-favicon[pageproxystate="valid"],
.verifiedIdentity > #identity-icons > #page-proxy-favicon[pageproxystate="valid"] {
list-style-image: url(chrome://browser/skin/identity-secure.svg);
}
.mixedActiveContent > #page-proxy-favicon[pageproxystate="valid"] {
.mixedActiveContent > #identity-icons > #page-proxy-favicon[pageproxystate="valid"] {
list-style-image: url(chrome://browser/skin/identity-mixed-active-loaded.svg);
}
.weakCipher > #page-proxy-favicon[pageproxystate="valid"],
.mixedDisplayContent > #page-proxy-favicon[pageproxystate="valid"],
.mixedDisplayContentLoadedActiveBlocked > #page-proxy-favicon[pageproxystate="valid"] {
.weakCipher > #identity-icons > #page-proxy-favicon[pageproxystate="valid"],
.mixedDisplayContent > #identity-icons > #page-proxy-favicon[pageproxystate="valid"],
.mixedDisplayContentLoadedActiveBlocked > #identity-icons > #page-proxy-favicon[pageproxystate="valid"] {
list-style-image: url(chrome://browser/skin/identity-mixed-passive-loaded.svg);
}
.mixedActiveBlocked > #page-proxy-favicon[pageproxystate="valid"] {
.mixedActiveBlocked > #identity-icons > #page-proxy-favicon[pageproxystate="valid"] {
list-style-image: url(chrome://browser/skin/identity-mixed-active-blocked.svg);
}
@ -146,7 +150,7 @@
opacity: 0.3;
}
#urlbar[actiontype="searchengine"] > #identity-box > #page-proxy-favicon {
#urlbar[actiontype="searchengine"] > #identity-box > #identity-icons > #page-proxy-favicon {
-moz-image-region: inherit;
list-style-image: url(chrome://global/skin/icons/autocomplete-search.svg#search-icon);
width: 16px;

View File

@ -1221,6 +1221,7 @@ toolbarbutton[constrain-size="true"][cui-areatype="toolbar"] > .toolbarbutton-ba
#urlbar,
.searchbar-textbox {
@navbarTextboxCustomBorder@
border-radius: 1px;
}
@media (-moz-os-version: windows-vista),

View File

@ -808,3 +808,4 @@ skip-if = buildapp == 'mulet' || buildapp == 'b2g'
[test_window_element_enumeration.html]
[test_referrer_redirect.html]
[test_postMessages.html]
[test_window_proto.html]

View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>Test for ...</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
test(function() {
assert_throws(new TypeError, function() {
Object.setPrototypeOf(window, Object.create(window));
}, "Setting prototype via setPrototypeOf");
assert_throws(new TypeError, function() {
window.__proto__ = Object.create(window);
}, "Setting prototype via __proto__");
}, "Setting the prototype of a window to something that has the window on its proto chain should throw");
</script>

View File

@ -14305,6 +14305,9 @@ class CallbackMember(CGNativeMember):
self.descriptorProvider,
exceptionCode=self.exceptionCode,
isCallbackReturnValue=isCallbackReturnValue,
# Allow returning a callback type that
# allows non-callable objects.
allowTreatNonCallableAsNull=True,
sourceDescription=sourceDescription),
replacements)
assignRetval = string.Template(

View File

@ -156,6 +156,13 @@ TestInterfaceJS.prototype = {
});
},
get onsomething() {
return this.__DOM_IMPL__.getEventHandler("onsomething");
},
set onsomething(val) {
this.__DOM_IMPL__.setEventHandler("onsomething", val);
}
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([TestInterfaceJS])

View File

@ -64,4 +64,6 @@ skip-if = debug == false
[test_unforgeablesonexpando.html]
[test_crossOriginWindowSymbolAccess.html]
[test_bug1123516_maplikesetlike.html]
skip-if = debug == false
skip-if = debug == false
[test_jsimplemented_eventhandler.html]
skip-if = debug == false

View File

@ -0,0 +1,47 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1186696
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1186696</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
/** Test for Bug 1186696 **/
SimpleTest.waitForExplicitFinish();
function doTest() {
var values = [ function() {}, 5, null, undefined, "some string", {} ];
while (values.length != 0) {
var value = values.pop();
var t = new TestInterfaceJS();
t.onsomething = value;
var gottenValue = t.onsomething;
if (typeof value == "object" || typeof value == "function") {
is(gottenValue, value, "Should get back the object-or-null we put in");
} else {
is(gottenValue, null, "Should get back null");
}
}
SimpleTest.finish();
}
SpecialPowers.pushPrefEnv({set: [['dom.expose_test_interfaces', true]]},
doTest);
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1186696">Mozilla Bug 1186696</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</html>

View File

@ -23,7 +23,7 @@ extern PRLogModuleInfo* gMediaDecoderLog;
// The amount of audio frames that is used to fuzz rounding errors.
static const int64_t AUDIO_FUZZ_FRAMES = 1;
AudioSink::AudioSink(MediaQueue<AudioData>& aAudioQueue,
AudioSink::AudioSink(MediaQueue<MediaData>& aAudioQueue,
int64_t aStartTime,
const AudioInfo& aInfo,
dom::AudioChannel aChannel)
@ -417,7 +417,8 @@ AudioSink::PlayFromAudioQueue()
{
AssertOnAudioThread();
NS_ASSERTION(!mAudioStream->IsPaused(), "Don't play when paused");
nsRefPtr<AudioData> audio(AudioQueue().PopFront());
nsRefPtr<AudioData> audio =
dont_AddRef(AudioQueue().PopFront().take()->As<AudioData>());
SINK_LOG_V("playing %u frames of audio at time %lld",
audio->mFrames, audio->mTime);

View File

@ -26,7 +26,7 @@ class AudioSink {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AudioSink)
AudioSink(MediaQueue<AudioData>& aAudioQueue,
AudioSink(MediaQueue<MediaData>& aAudioQueue,
int64_t aStartTime,
const AudioInfo& aInfo,
dom::AudioChannel aChannel);
@ -121,7 +121,7 @@ private:
void StartAudioStreamPlaybackIfNeeded();
void WriteSilence(uint32_t aFrames);
MediaQueue<AudioData>& AudioQueue() const {
MediaQueue<MediaData>& AudioQueue() const {
return mAudioQueue;
}
@ -136,7 +136,7 @@ private:
void AssertOnAudioThread();
void AssertNotOnAudioThread();
MediaQueue<AudioData>& mAudioQueue;
MediaQueue<MediaData>& mAudioQueue;
mutable ReentrantMonitor mMonitor;
// There members are accessed on the audio thread only.

View File

@ -184,8 +184,8 @@ OutputStreamData::Init(DecodedStream* aDecodedStream, ProcessedMediaStream* aStr
aStream->AddListener(mListener);
}
DecodedStream::DecodedStream(MediaQueue<AudioData>& aAudioQueue,
MediaQueue<VideoData>& aVideoQueue)
DecodedStream::DecodedStream(MediaQueue<MediaData>& aAudioQueue,
MediaQueue<MediaData>& aVideoQueue)
: mMonitor("DecodedStream::mMonitor")
, mPlaying(false)
, mAudioQueue(aAudioQueue)
@ -402,19 +402,21 @@ DecodedStream::InitTracks()
static void
SendStreamAudio(DecodedStreamData* aStream, int64_t aStartTime,
AudioData* aAudio, AudioSegment* aOutput,
MediaData* aData, AudioSegment* aOutput,
uint32_t aRate, double aVolume)
{
MOZ_ASSERT(aData);
AudioData* audio = aData->As<AudioData>();
// This logic has to mimic AudioSink closely to make sure we write
// the exact same silences
CheckedInt64 audioWrittenOffset = aStream->mAudioFramesWritten +
UsecsToFrames(aStartTime, aRate);
CheckedInt64 frameOffset = UsecsToFrames(aAudio->mTime, aRate);
CheckedInt64 frameOffset = UsecsToFrames(audio->mTime, aRate);
if (!audioWrittenOffset.isValid() ||
!frameOffset.isValid() ||
// ignore packet that we've already processed
frameOffset.value() + aAudio->mFrames <= audioWrittenOffset.value()) {
frameOffset.value() + audio->mFrames <= audioWrittenOffset.value()) {
return;
}
@ -431,20 +433,20 @@ SendStreamAudio(DecodedStreamData* aStream, int64_t aStartTime,
MOZ_ASSERT(audioWrittenOffset.value() >= frameOffset.value());
int64_t offset = audioWrittenOffset.value() - frameOffset.value();
size_t framesToWrite = aAudio->mFrames - offset;
size_t framesToWrite = audio->mFrames - offset;
aAudio->EnsureAudioBuffer();
nsRefPtr<SharedBuffer> buffer = aAudio->mAudioBuffer;
audio->EnsureAudioBuffer();
nsRefPtr<SharedBuffer> buffer = audio->mAudioBuffer;
AudioDataValue* bufferData = static_cast<AudioDataValue*>(buffer->Data());
nsAutoTArray<const AudioDataValue*, 2> channels;
for (uint32_t i = 0; i < aAudio->mChannels; ++i) {
channels.AppendElement(bufferData + i * aAudio->mFrames + offset);
for (uint32_t i = 0; i < audio->mChannels; ++i) {
channels.AppendElement(bufferData + i * audio->mFrames + offset);
}
aOutput->AppendFrames(buffer.forget(), channels, framesToWrite);
aStream->mAudioFramesWritten += framesToWrite;
aOutput->ApplyVolume(aVolume);
aStream->mNextAudioTime = aAudio->GetEndTime();
aStream->mNextAudioTime = audio->GetEndTime();
}
void
@ -458,7 +460,7 @@ DecodedStream::SendAudio(double aVolume, bool aIsSameOrigin)
AudioSegment output;
uint32_t rate = mInfo.mAudio.mRate;
nsAutoTArray<nsRefPtr<AudioData>,10> audio;
nsAutoTArray<nsRefPtr<MediaData>,10> audio;
TrackID audioTrackId = mInfo.mAudio.mTrackId;
SourceMediaStream* sourceStream = mData->mStream;
@ -523,7 +525,7 @@ DecodedStream::SendVideo(bool aIsSameOrigin)
VideoSegment output;
TrackID videoTrackId = mInfo.mVideo.mTrackId;
nsAutoTArray<nsRefPtr<VideoData>, 10> video;
nsAutoTArray<nsRefPtr<MediaData>, 10> video;
SourceMediaStream* sourceStream = mData->mStream;
// It's OK to hold references to the VideoData because VideoData
@ -531,7 +533,7 @@ DecodedStream::SendVideo(bool aIsSameOrigin)
mVideoQueue.GetElementsAfter(mData->mNextVideoTime, &video);
for (uint32_t i = 0; i < video.Length(); ++i) {
VideoData* v = video[i];
VideoData* v = video[i]->As<VideoData>();
if (mData->mNextVideoTime < v->mTime) {
// Write last video frame to catch up. mLastVideoImage can be null here

View File

@ -19,8 +19,7 @@
namespace mozilla {
class AudioData;
class VideoData;
class MediaData;
class AudioSegment;
class MediaStream;
class MediaInputPort;
@ -97,8 +96,8 @@ public:
class DecodedStream {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DecodedStream);
public:
DecodedStream(MediaQueue<AudioData>& aAudioQueue,
MediaQueue<VideoData>& aVideoQueue);
DecodedStream(MediaQueue<MediaData>& aAudioQueue,
MediaQueue<MediaData>& aVideoQueue);
// Mimic MDSM::StartAudioThread.
// Must be called before any calls to SendData().
@ -149,8 +148,8 @@ private:
Maybe<int64_t> mStartTime;
MediaInfo mInfo;
MediaQueue<AudioData>& mAudioQueue;
MediaQueue<VideoData>& mVideoQueue;
MediaQueue<MediaData>& mAudioQueue;
MediaQueue<MediaData>& mVideoQueue;
};
} // namespace mozilla

View File

@ -115,7 +115,7 @@ VideoData::VideoData(int64_t aOffset,
int64_t aTimecode,
IntSize aDisplay,
layers::ImageContainer::FrameID aFrameID)
: MediaData(VIDEO_DATA, aOffset, aTime, aDuration)
: MediaData(VIDEO_DATA, aOffset, aTime, aDuration, 1)
, mDisplay(aDisplay)
, mFrameID(aFrameID)
, mSentToCompositor(false)
@ -488,7 +488,7 @@ VideoData::Create(const VideoInfo& aInfo,
#define RAW_DATA_DEFAULT_SIZE 4096
MediaRawData::MediaRawData()
: MediaData(RAW_DATA)
: MediaData(RAW_DATA, 0)
, mData(nullptr)
, mSize(0)
, mCrypto(mCryptoInternal)
@ -499,7 +499,7 @@ MediaRawData::MediaRawData()
}
MediaRawData::MediaRawData(const uint8_t* aData, size_t aSize)
: MediaData(RAW_DATA)
: MediaData(RAW_DATA, 0)
, mData(nullptr)
, mSize(0)
, mCrypto(mCryptoInternal)

View File

@ -40,12 +40,14 @@ public:
MediaData(Type aType,
int64_t aOffset,
int64_t aTimestamp,
int64_t aDuration)
int64_t aDuration,
uint32_t aFrames)
: mType(aType)
, mOffset(aOffset)
, mTime(aTimestamp)
, mTimecode(aTimestamp)
, mDuration(aDuration)
, mFrames(aFrames)
, mKeyframe(false)
, mDiscontinuity(false)
{}
@ -66,6 +68,9 @@ public:
// Duration of sample, in microseconds.
int64_t mDuration;
// Amount of frames for contained data.
const uint32_t mFrames;
bool mKeyframe;
// True if this is the first sample after a gap or discontinuity in
@ -79,13 +84,29 @@ public:
mTime = mTime - aStartTime;
return mTime >= 0;
}
template <typename ReturnType>
const ReturnType* As() const
{
MOZ_ASSERT(this->mType == ReturnType::sType);
return static_cast<const ReturnType*>(this);
}
template <typename ReturnType>
ReturnType* As()
{
MOZ_ASSERT(this->mType == ReturnType::sType);
return static_cast<ReturnType*>(this);
}
protected:
explicit MediaData(Type aType)
MediaData(Type aType, uint32_t aFrames)
: mType(aType)
, mOffset(0)
, mTime(0)
, mTimecode(0)
, mDuration(0)
, mFrames(aFrames)
, mKeyframe(false)
, mDiscontinuity(false)
{}
@ -105,8 +126,7 @@ public:
AudioDataValue* aData,
uint32_t aChannels,
uint32_t aRate)
: MediaData(sType, aOffset, aTime, aDuration)
, mFrames(aFrames)
: MediaData(sType, aOffset, aTime, aDuration, aFrames)
, mChannels(aChannels)
, mRate(aRate)
, mAudioData(aData) {}
@ -128,7 +148,6 @@ public:
// If mAudioBuffer is null, creates it from mAudioData.
void EnsureAudioBuffer();
const uint32_t mFrames;
const uint32_t mChannels;
const uint32_t mRate;
// At least one of mAudioBuffer/mAudioData must be non-null.

View File

@ -540,7 +540,7 @@ nsresult MediaDecoder::InitializeStateMachine(MediaDecoder* aCloneDonor)
// set them now
SetStateMachineParameters();
return ScheduleStateMachine();
return NS_OK;
}
void MediaDecoder::SetStateMachineParameters()
@ -562,19 +562,6 @@ void MediaDecoder::SetMinimizePrerollUntilPlaybackStarts()
MOZ_DIAGNOSTIC_ASSERT(!mDecoderStateMachine);
}
nsresult MediaDecoder::ScheduleStateMachine()
{
MOZ_ASSERT(NS_IsMainThread());
if (mShuttingDown)
return NS_OK;
MOZ_ASSERT(mDecoderStateMachine);
NS_ENSURE_STATE(mDecoderStateMachine);
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
mDecoderStateMachine->ScheduleStateMachineCrossThread();
return NS_OK;
}
nsresult MediaDecoder::Play()
{
MOZ_ASSERT(NS_IsMainThread());
@ -585,7 +572,7 @@ nsresult MediaDecoder::Play()
if (mPausedForPlaybackRateNull) {
return NS_OK;
}
ScheduleStateMachine();
if (IsEnded()) {
return Seek(0, SeekTarget::PrevSyncPoint);
} else if (mPlayState == PLAY_STATE_LOADING) {
@ -1047,8 +1034,6 @@ void MediaDecoder::ChangeState(PlayState aState)
RemoveMediaTracks();
}
ScheduleStateMachine();
CancelDormantTimer();
// Start dormant timer if necessary
StartDormantTimer();

View File

@ -724,10 +724,6 @@ public:
static bool IsAppleMP3Enabled();
#endif
// Schedules the state machine to run one cycle on the shared state
// machine thread. Main thread only.
nsresult ScheduleStateMachine();
struct Statistics {
// Estimate of the current playback rate (bytes/second).
double mPlaybackRate;

View File

@ -287,13 +287,13 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
nsRefPtr<MediaDecoderStateMachine> self = this;
AudioQueue().AddPopListener(
[self] (const AudioData* aSample) {
self->OnAudioPopped(aSample);
}, mTaskQueue);
[self] (const MediaData* aSample) {
self->OnAudioPopped(aSample->As<AudioData>());
}, mTaskQueue);
VideoQueue().AddPopListener(
[self] (const VideoData* aSample) {
self->OnVideoPopped(aSample);
[self] (const MediaData* aSample) {
self->OnVideoPopped(aSample->As<VideoData>());
}, mTaskQueue);
}
@ -384,13 +384,14 @@ void MediaDecoderStateMachine::SendStreamData()
const auto clockTime = GetClock();
while (true) {
const AudioData* a = AudioQueue().PeekFront();
const MediaData* a = AudioQueue().PeekFront();
// If we discard audio samples fed to the stream immediately, we will
// keep decoding audio samples till the end and consume a lot of memory.
// Therefore we only discard those behind the stream clock to throttle
// the decoding speed.
if (a && a->mTime <= clockTime) {
nsRefPtr<AudioData> releaseMe = AudioQueue().PopFront();
nsRefPtr<MediaData> releaseMe = AudioQueue().PopFront();
continue;
}
break;
@ -1042,7 +1043,7 @@ nsresult MediaDecoderStateMachine::Init(MediaDecoderStateMachine* aCloneDonor)
nsresult rv = mReader->Init(cloneReader);
NS_ENSURE_SUCCESS(rv, rv);
ScheduleStateMachineCrossThread();
return NS_OK;
}
@ -2113,11 +2114,11 @@ MediaDecoderStateMachine::SeekCompleted()
int64_t newCurrentTime = seekTime;
// Setup timestamp state.
nsRefPtr<VideoData> video = VideoQueue().PeekFront();
nsRefPtr<MediaData> video = VideoQueue().PeekFront();
if (seekTime == Duration().ToMicroseconds()) {
newCurrentTime = seekTime;
} else if (HasAudio()) {
AudioData* audio = AudioQueue().PeekFront();
MediaData* audio = AudioQueue().PeekFront();
// Though we adjust the newCurrentTime in audio-based, and supplemented
// by video. For better UX, should NOT bind the slide position to
// the first audio data timestamp directly.
@ -2516,7 +2517,7 @@ void MediaDecoderStateMachine::RenderVideoFrames(int32_t aMaxFrames,
AssertCurrentThreadInMonitor();
VideoFrameContainer* container = mDecoder->GetVideoFrameContainer();
nsAutoTArray<nsRefPtr<VideoData>,16> frames;
nsAutoTArray<nsRefPtr<MediaData>,16> frames;
VideoQueue().GetFirstElements(aMaxFrames, &frames);
if (frames.IsEmpty() || !container) {
return;
@ -2525,7 +2526,7 @@ void MediaDecoderStateMachine::RenderVideoFrames(int32_t aMaxFrames,
nsAutoTArray<ImageContainer::NonOwningImage,16> images;
TimeStamp lastFrameTime;
for (uint32_t i = 0; i < frames.Length(); ++i) {
VideoData* frame = frames[i];
VideoData* frame = frames[i]->As<VideoData>();
frame->mSentToCompositor = true;
int64_t frameTime = frame->mTime;
@ -2562,7 +2563,7 @@ void MediaDecoderStateMachine::RenderVideoFrames(int32_t aMaxFrames,
VideoQueue().GetSize(), mReader->SizeOfVideoQueueInFrames());
}
container->SetCurrentFrames(frames[0]->mDisplay, images);
container->SetCurrentFrames(frames[0]->As<VideoData>()->mDisplay, images);
}
void MediaDecoderStateMachine::ResyncAudioClock()
@ -2666,21 +2667,21 @@ void MediaDecoderStateMachine::UpdateRenderedVideoFrames()
NS_ASSERTION(clockTime >= 0, "Should have positive clock time.");
int64_t remainingTime = AUDIO_DURATION_USECS;
if (VideoQueue().GetSize() > 0) {
nsRefPtr<VideoData> currentFrame = VideoQueue().PopFront();
nsRefPtr<MediaData> currentFrame = VideoQueue().PopFront();
int32_t framesRemoved = 0;
while (VideoQueue().GetSize() > 0) {
VideoData* nextFrame = VideoQueue().PeekFront();
MediaData* nextFrame = VideoQueue().PeekFront();
if (!IsRealTime() && nextFrame->mTime > clockTime) {
remainingTime = nextFrame->mTime - clockTime;
break;
}
++framesRemoved;
if (!currentFrame->mSentToCompositor) {
if (!currentFrame->As<VideoData>()->mSentToCompositor) {
mDecoder->NotifyDecodedFrames(0, 0, 1);
VERBOSE_LOG("discarding video frame mTime=%lld clock_time=%lld",
currentFrame->mTime, clockTime);
}
CheckTurningOffHardwareDecoder(currentFrame);
CheckTurningOffHardwareDecoder(currentFrame->As<VideoData>());
currentFrame = VideoQueue().PopFront();
}

View File

@ -406,8 +406,8 @@ protected:
void LogicalPlaybackRateChanged();
void PreservesPitchChanged();
MediaQueue<AudioData>& AudioQueue() { return mAudioQueue; }
MediaQueue<VideoData>& VideoQueue() { return mVideoQueue; }
MediaQueue<MediaData>& AudioQueue() { return mAudioQueue; }
MediaQueue<MediaData>& VideoQueue() { return mVideoQueue; }
// True if our buffers of decoded audio are not full, and we should
// decode more.
@ -879,11 +879,10 @@ private:
// Queue of audio frames. This queue is threadsafe, and is accessed from
// the audio, decoder, state machine, and main threads.
MediaQueue<AudioData> mAudioQueue;
MediaQueue<MediaData> mAudioQueue;
// Queue of video frames. This queue is threadsafe, and is accessed from
// the decoder, state machine, and main threads.
MediaQueue<VideoData> mVideoQueue;
MediaQueue<MediaData> mVideoQueue;
// The decoder monitor must be obtained before modifying this state.
// NotifyAll on the monitor must be called when the state is changed so

View File

@ -72,7 +72,7 @@ MediaSourceDecoder::Load(nsIStreamListener**, MediaDecoder*)
NS_ENSURE_SUCCESS(rv, rv);
SetStateMachineParameters();
return ScheduleStateMachine();
return NS_OK;
}
media::TimeIntervals

View File

@ -32,8 +32,14 @@ interface EventTarget {
// Mozilla extensions for use by JS-implemented event targets to
// implement on* properties.
partial interface EventTarget {
// The use of [TreatNonCallableAsNull] here is a bit of a hack: it just makes
// the codegen check whether the type involved is either
// [TreatNonCallableAsNull] or [TreatNonObjectAsNull] and if it is handle it
// accordingly. In particular, it will NOT actually treat a non-null
// non-callable object as null here.
[ChromeOnly, Throws]
void setEventHandler(DOMString type, EventHandler handler);
void setEventHandler(DOMString type,
[TreatNonCallableAsNull] EventHandler handler);
[ChromeOnly]
EventHandler getEventHandler(DOMString type);

View File

@ -12,7 +12,7 @@ dictionary TestInterfaceJSUnionableDictionary {
[JSImplementation="@mozilla.org/dom/test-interface-js;1",
Pref="dom.expose_test_interfaces",
Constructor(optional any anyArg, optional object objectArg, optional TestInterfaceJSDictionary dictionaryArg)]
interface TestInterfaceJS {
interface TestInterfaceJS : EventTarget {
readonly attribute any anyArg;
readonly attribute object objectArg;
[Cached, Pure] readonly attribute TestInterfaceJSDictionary dictionaryArg;
@ -78,4 +78,7 @@ interface TestInterfaceJS {
Promise<void> testPromiseWithThrowingChromeThenable();
Promise<void> testPromiseWithThrowingContentThenable(object thenable);
Promise<void> testPromiseWithDOMExceptionThrowingThenable();
// Event handler tests
attribute EventHandler onsomething;
};

View File

@ -1048,33 +1048,6 @@ void PadDrawTargetOutFromRegion(RefPtr<DrawTarget> drawTarget, nsIntRegion &regi
}
}
void
ClientTiledLayerBuffer::PostValidate(const nsIntRegion& aPaintRegion,
const nsIntRegion& aDirtyRegion)
{
if (gfxPrefs::TiledDrawTargetEnabled() && mMoz2DTiles.size() > 0) {
gfx::TileSet tileset;
for (size_t i = 0; i < mMoz2DTiles.size(); ++i) {
mMoz2DTiles[i].mTileOrigin -= mTilingOrigin;
}
tileset.mTiles = &mMoz2DTiles[0];
tileset.mTileCount = mMoz2DTiles.size();
RefPtr<DrawTarget> drawTarget = gfx::Factory::CreateTiledDrawTarget(tileset);
drawTarget->SetTransform(Matrix());
RefPtr<gfxContext> ctx = new gfxContext(drawTarget);
ctx->SetMatrix(
ctx->CurrentMatrix().Scale(mResolution, mResolution).Translate(ThebesPoint(-mTilingOrigin)));
mCallback(mPaintedLayer, ctx, aPaintRegion, aDirtyRegion,
DrawRegionClip::DRAW, nsIntRegion(), mCallbackData);
mMoz2DTiles.clear();
// Reset:
mTilingOrigin = IntPoint(std::numeric_limits<int32_t>::max(),
std::numeric_limits<int32_t>::max());
}
}
void
ClientTiledLayerBuffer::UnlockTile(TileClient& aTile)
{
@ -1150,9 +1123,61 @@ void ClientTiledLayerBuffer::Update(const nsIntRegion& newValidRegion,
}
}
PostValidate(aPaintRegion, aDirtyRegion);
if (gfxPrefs::TiledDrawTargetEnabled() && mMoz2DTiles.size() > 0) {
gfx::TileSet tileset;
for (size_t i = 0; i < mMoz2DTiles.size(); ++i) {
mMoz2DTiles[i].mTileOrigin -= mTilingOrigin;
}
tileset.mTiles = &mMoz2DTiles[0];
tileset.mTileCount = mMoz2DTiles.size();
RefPtr<DrawTarget> drawTarget = gfx::Factory::CreateTiledDrawTarget(tileset);
drawTarget->SetTransform(Matrix());
for (TileClient& tile : mRetainedTiles) {
RefPtr<gfxContext> ctx = new gfxContext(drawTarget);
ctx->SetMatrix(
ctx->CurrentMatrix().Scale(mResolution, mResolution).Translate(ThebesPoint(-mTilingOrigin)));
mCallback(mPaintedLayer, ctx, aPaintRegion, aDirtyRegion,
DrawRegionClip::DRAW, nsIntRegion(), mCallbackData);
mMoz2DTiles.clear();
// Reset:
mTilingOrigin = IntPoint(std::numeric_limits<int32_t>::max(),
std::numeric_limits<int32_t>::max());
}
bool edgePaddingEnabled = gfxPrefs::TileEdgePaddingEnabled();
for (uint32_t i = 0; i < mRetainedTiles.Length(); ++i) {
TileClient& tile = mRetainedTiles[i];
// Only worry about padding when not doing low-res because it simplifies
// the math and the artifacts won't be noticable
// Edge padding prevents sampling artifacts when compositing.
if (edgePaddingEnabled && mResolution == 1 &&
tile.mFrontBuffer && tile.mFrontBuffer->IsLocked()) {
const TileIntPoint tilePosition = newTiles.TilePosition(i);
IntPoint tileOffset = GetTileOffset(tilePosition);
// Strictly speakig we want the unscaled rect here, but it doesn't matter
// because we only run this code when the resolution is equal to 1.
IntRect tileRect = IntRect(tileOffset.x, tileOffset.y,
GetTileSize().width, GetTileSize().height);
nsIntRegion tileDrawRegion = IntRect(tileOffset, scaledTileSize);
tileDrawRegion.AndWith(aPaintRegion);
nsIntRegion tileValidRegion = mValidRegion;
tileValidRegion.OrWith(tileDrawRegion);
// We only need to pad out if the tile has area that's not valid
if (!tileValidRegion.Contains(tileRect)) {
tileValidRegion = tileValidRegion.Intersect(tileRect);
// translate the region into tile space and pad
tileValidRegion.MoveBy(-IntPoint(tileOffset.x, tileOffset.y));
RefPtr<DrawTarget> drawTarget = tile.mFrontBuffer->BorrowDrawTarget();
PadDrawTargetOutFromRegion(drawTarget, tileValidRegion);
}
}
UnlockTile(tile);
}
@ -1240,7 +1265,6 @@ ClientTiledLayerBuffer::ValidateTile(TileClient& aTile,
}
}
// prepare an array of Moz2D tiles that will be painted into in PostValidate
gfx::Tile moz2DTile;
RefPtr<DrawTarget> dt = backBuffer->BorrowDrawTarget();
RefPtr<DrawTarget> dtOnWhite;
@ -1326,26 +1350,6 @@ ClientTiledLayerBuffer::ValidateTile(TileClient& aTile,
aTile.mInvalidFront.Or(aTile.mInvalidFront, IntRect(copyTarget.x, copyTarget.y, copyRect.width, copyRect.height));
}
// only worry about padding when not doing low-res
// because it simplifies the math and the artifacts
// won't be noticable
if (mResolution == 1) {
IntRect unscaledTile = IntRect(aTileOrigin.x,
aTileOrigin.y,
GetTileSize().width,
GetTileSize().height);
nsIntRegion tileValidRegion = GetValidRegion();
tileValidRegion.Or(tileValidRegion, aDirtyRegion);
// We only need to pad out if the tile has area that's not valid
if (!tileValidRegion.Contains(unscaledTile)) {
tileValidRegion = tileValidRegion.Intersect(unscaledTile);
// translate the region into tile space and pad
tileValidRegion.MoveBy(-nsIntPoint(unscaledTile.x, unscaledTile.y));
PadDrawTargetOutFromRegion(drawTarget, tileValidRegion);
}
}
// The new buffer is now validated, remove the dirty region from it.
aTile.mInvalidBack.SubOut(offsetScaledDirtyRegion);
@ -1364,7 +1368,6 @@ ClientTiledLayerBuffer::ValidateTile(TileClient& aTile,
tileRegion.SubOut(GetValidRegion());
tileRegion.SubOut(aDirtyRegion); // Has now been validated
backBuffer->Unlock();
backBuffer->SetWaste(tileRegion.Area() * mResolution * mResolution);
if (createdTextureClient) {

View File

@ -277,7 +277,6 @@ struct TileClient
nsIntRegion mInvalidFront;
nsIntRegion mInvalidBack;
nsExpirationState mExpirationState;
private:
// Copies dirty pixels from the front buffer into the back buffer,
// and records the copied region in aAddPaintedRegion.
@ -469,9 +468,6 @@ protected:
const nsIntPoint& aTileRect,
const nsIntRegion& dirtyRect);
void PostValidate(const nsIntRegion& aPaintRegion,
const nsIntRegion& aDirtyRegion);
void UnlockTile(TileClient& aTile);
TileClient GetPlaceholderTile() const { return TileClient(); }

View File

@ -685,10 +685,7 @@ CompositorD3D11::DrawVRDistortion(const gfx::Rect& aRect,
mContext->PSSetShader(mAttachments->mVRDistortionPS[hmdType], nullptr, 0);
// This is the source texture SRV for the pixel shader
// XXX, um should we cache this SRV on the source?
RefPtr<ID3D11ShaderResourceView> view;
mDevice->CreateShaderResourceView(source->GetD3D11Texture(), nullptr, byRef(view));
ID3D11ShaderResourceView* srView = view;
ID3D11ShaderResourceView* srView = source->GetShaderResourceView();
mContext->PSSetShaderResources(0, 1, &srView);
gfx::IntSize vpSizeInt = mCurrentRT->GetSize();
@ -787,16 +784,7 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect,
return;
}
RefPtr<ID3D11ShaderResourceView> view;
HRESULT hr = mDevice->CreateShaderResourceView(source->GetD3D11Texture(), nullptr, byRef(view));
if (Failed(hr)) {
// XXX - There's a chance we won't be able to render anything, should we
// just crash release builds?
gfxCriticalErrorOnce(gfxCriticalError::DefaultOptions(false)) << "Failed in DrawQuad 1";
return;
}
ID3D11ShaderResourceView* srView = view;
ID3D11ShaderResourceView* srView = source->GetShaderResourceView();
mContext->PSSetShaderResources(3, 1, &srView);
const gfx::Matrix4x4& maskTransform = maskEffect->mMaskTransform;
@ -857,16 +845,7 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect,
SetPSForEffect(aEffectChain.mPrimaryEffect, maskType, texturedEffect->mTexture->GetFormat());
RefPtr<ID3D11ShaderResourceView> view;
HRESULT hr = mDevice->CreateShaderResourceView(source->GetD3D11Texture(), nullptr, byRef(view));
if (Failed(hr)) {
// XXX - There's a chance we won't be able to render anything, should we
// just crash release builds?
gfxCriticalErrorOnce(gfxCriticalError::DefaultOptions(false)) << "Failed in DrawQuad 2";
return;
}
ID3D11ShaderResourceView* srView = view;
ID3D11ShaderResourceView* srView = source->GetShaderResourceView();
mContext->PSSetShaderResources(0, 1, &srView);
if (!texturedEffect->mPremultiplied) {
@ -905,32 +884,9 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect,
TextureSourceD3D11* sourceCb = source->GetSubSource(Cb)->AsSourceD3D11();
TextureSourceD3D11* sourceCr = source->GetSubSource(Cr)->AsSourceD3D11();
HRESULT hr;
RefPtr<ID3D11ShaderResourceView> views[3];
hr = mDevice->CreateShaderResourceView(sourceY->GetD3D11Texture(),
nullptr, byRef(views[0]));
if (Failed(hr)) {
gfxCriticalErrorOnce(gfxCriticalError::DefaultOptions(false)) << "Failed in DrawQuad 3";
return;
}
hr = mDevice->CreateShaderResourceView(sourceCb->GetD3D11Texture(),
nullptr, byRef(views[1]));
if (Failed(hr)) {
gfxCriticalErrorOnce(gfxCriticalError::DefaultOptions(false)) << "Failed in DrawQuad 4";
return;
}
hr = mDevice->CreateShaderResourceView(sourceCr->GetD3D11Texture(),
nullptr, byRef(views[2]));
if (Failed(hr)) {
gfxCriticalErrorOnce(gfxCriticalError::DefaultOptions(false)) << "Failed in DrawQuad 5";
return;
}
ID3D11ShaderResourceView* srViews[3] = { views[0], views[1], views[2] };
ID3D11ShaderResourceView* srViews[3] = { sourceY->GetShaderResourceView(),
sourceCb->GetShaderResourceView(),
sourceCr->GetShaderResourceView() };
mContext->PSSetShaderResources(0, 3, srViews);
}
break;
@ -955,22 +911,8 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect,
pTexCoordRect = &effectComponentAlpha->mTextureCoords;
RefPtr<ID3D11ShaderResourceView> views[2];
HRESULT hr;
hr = mDevice->CreateShaderResourceView(sourceOnBlack->GetD3D11Texture(), nullptr, byRef(views[0]));
if (Failed(hr)) {
gfxCriticalErrorOnce(gfxCriticalError::DefaultOptions(false)) << "Failed in DrawQuad 6";
return;
}
hr = mDevice->CreateShaderResourceView(sourceOnWhite->GetD3D11Texture(), nullptr, byRef(views[1]));
if (Failed(hr)) {
gfxCriticalErrorOnce(gfxCriticalError::DefaultOptions(false)) << "Failed in DrawQuad 7";
return;
}
ID3D11ShaderResourceView* srViews[2] = { views[0], views[1] };
ID3D11ShaderResourceView* srViews[2] = { sourceOnBlack->GetShaderResourceView(),
sourceOnWhite->GetShaderResourceView() };
mContext->PSSetShaderResources(0, 2, srViews);
mContext->OMSetBlendState(mAttachments->mComponentBlendState, sBlendFactor, 0xFFFFFFFF);

View File

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* 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/. */
@ -65,6 +65,23 @@ GetTileRectD3D11(uint32_t aID, IntSize aSize, uint32_t aMaxSize)
verticalTile < (verticalTiles - 1) ? aMaxSize : aSize.height % aMaxSize);
}
ID3D11ShaderResourceView*
TextureSourceD3D11::GetShaderResourceView()
{
MOZ_ASSERT(mTexture == GetD3D11Texture(), "You need to override GetShaderResourceView if you're overriding GetD3D11Texture!");
if (!mSRV && mTexture) {
RefPtr<ID3D11Device> device;
mTexture->GetDevice(byRef(device));
HRESULT hr = device->CreateShaderResourceView(mTexture, nullptr, byRef(mSRV));
if (FAILED(hr)) {
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "[D3D11] TextureSourceD3D11:GetShaderResourceView CreateSRV failure " << gfx::hexa(hr);
return nullptr;
}
}
return mSRV;
}
DataTextureSourceD3D11::DataTextureSourceD3D11(SurfaceFormat aFormat,
CompositorD3D11* aCompositor,
TextureFlags aFlags)
@ -954,6 +971,7 @@ DataTextureSourceD3D11::Update(DataSourceSurface* aSurface,
GetRequiredTilesD3D11(mSize.height, maxSize);
mTileTextures.resize(tileCount);
mTileSRVs.resize(tileCount);
mTexture = nullptr;
for (uint32_t i = 0; i < tileCount; i++) {
@ -986,10 +1004,34 @@ DataTextureSourceD3D11::GetD3D11Texture() const
: mTexture;
}
ID3D11ShaderResourceView*
DataTextureSourceD3D11::GetShaderResourceView()
{
if (mIterating) {
if (!mTileSRVs[mCurrentTile]) {
if (!mTileTextures[mCurrentTile]) {
return nullptr;
}
RefPtr<ID3D11Device> device;
mTileTextures[mCurrentTile]->GetDevice(byRef(device));
HRESULT hr = device->CreateShaderResourceView(mTileTextures[mCurrentTile], nullptr, byRef(mTileSRVs[mCurrentTile]));
if (FAILED(hr)) {
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "[D3D11] DataTextureSourceD3D11:GetShaderResourceView CreateSRV failure " << gfx::hexa(hr);
return nullptr;
}
}
return mTileSRVs[mCurrentTile];
}
return TextureSourceD3D11::GetShaderResourceView();
}
void
DataTextureSourceD3D11::Reset()
{
mTexture = nullptr;
mTileSRVs.resize(0);
mTileTextures.resize(0);
mIsTiled = false;
mSize.width = 0;

View File

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* 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/. */
@ -154,12 +154,13 @@ public:
virtual ~TextureSourceD3D11() {}
virtual ID3D11Texture2D* GetD3D11Texture() const { return mTexture; }
virtual ID3D11ShaderResourceView* GetShaderResourceView();
protected:
virtual gfx::IntSize GetSize() const { return mSize; }
gfx::IntSize mSize;
RefPtr<ID3D11Texture2D> mTexture;
RefPtr<ID3D11ShaderResourceView> mSRV;
};
/**
@ -193,6 +194,8 @@ public:
virtual ID3D11Texture2D* GetD3D11Texture() const override;
virtual ID3D11ShaderResourceView* GetShaderResourceView() override;
virtual DataTextureSource* AsDataTextureSource() override { return this; }
virtual void DeallocateDeviceData() override { mTexture = nullptr; }
@ -227,6 +230,7 @@ protected:
void Reset();
std::vector< RefPtr<ID3D11Texture2D> > mTileTextures;
std::vector< RefPtr<ID3D11ShaderResourceView> > mTileSRVs;
RefPtr<CompositorD3D11> mCompositor;
gfx::SurfaceFormat mFormat;
TextureFlags mFlags;

View File

@ -345,6 +345,7 @@ private:
DECL_GFX_PREF(Once, "layers.tile-shrink-pool-timeout", LayersTileShrinkPoolTimeout, uint32_t, (uint32_t)1000);
DECL_GFX_PREF(Once, "layers.tiled-drawtarget.enabled", TiledDrawTargetEnabled, bool, false);
DECL_GFX_PREF(Once, "layers.tiles.adjust", LayersTilesAdjust, bool, true);
DECL_GFX_PREF(Once, "layers.tiles.edge-padding", TileEdgePaddingEnabled, bool, true);
DECL_GFX_PREF(Live, "layers.transaction.warning-ms", LayerTransactionWarning, uint32_t, 200);
DECL_GFX_PREF(Once, "layers.uniformity-info", UniformityInfo, bool, false);
DECL_GFX_PREF(Once, "layers.use-image-offscreen-surfaces", UseImageOffscreenSurfaces, bool, false);

View File

@ -623,6 +623,30 @@ class DispatchWrapper
}
};
inline RootLists&
RootListsForRootingContext(JSContext* cx)
{
return ContextFriendFields::get(cx)->roots;
}
inline RootLists&
RootListsForRootingContext(js::ContextFriendFields* cx)
{
return cx->roots;
}
inline RootLists&
RootListsForRootingContext(JSRuntime* rt)
{
return PerThreadDataFriendFields::getMainThread(rt)->roots;
}
inline RootLists&
RootListsForRootingContext(js::PerThreadDataFriendFields* pt)
{
return pt->roots;
}
} /* namespace js */
namespace JS {
@ -650,19 +674,6 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase<T>
*stack = reinterpret_cast<Rooted<void*>*>(this);
}
static js::RootLists& rootListsForRootingContext(JSContext* cx) {
return js::ContextFriendFields::get(cx)->roots;
}
static js::RootLists& rootListsForRootingContext(js::ContextFriendFields* cx) {
return cx->roots;
}
static js::RootLists& rootListsForRootingContext(JSRuntime* rt) {
return js::PerThreadDataFriendFields::getMainThread(rt)->roots;
}
static js::RootLists& rootListsForRootingContext(js::PerThreadDataFriendFields* pt) {
return pt->roots;
}
public:
template <typename RootingContext>
explicit Rooted(const RootingContext& cx
@ -670,7 +681,7 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase<T>
: ptr(js::GCMethods<T>::initial())
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
registerWithRootLists(rootListsForRootingContext(cx));
registerWithRootLists(js::RootListsForRootingContext(cx));
}
template <typename RootingContext, typename S>
@ -679,7 +690,7 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase<T>
: ptr(mozilla::Forward<S>(initial))
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
registerWithRootLists(rootListsForRootingContext(cx));
registerWithRootLists(js::RootListsForRootingContext(cx));
}
~Rooted() {
@ -993,26 +1004,32 @@ class PersistentRooted : public js::PersistentRootedBase<T>,
void registerWithRootLists(js::RootLists& roots) {
MOZ_ASSERT(!initialized());
roots.getPersistentRootedList<T>().insertBack(this);
js::ThingRootKind kind = js::RootKind<T>::rootKind();
roots.heapRoots_[kind].insertBack(reinterpret_cast<JS::PersistentRooted<void*>*>(this));
// Until marking and destruction support the full set, we assert that
// we don't try to add any unsupported types.
MOZ_ASSERT(kind == js::THING_ROOT_OBJECT ||
kind == js::THING_ROOT_SCRIPT ||
kind == js::THING_ROOT_STRING ||
kind == js::THING_ROOT_ID ||
kind == js::THING_ROOT_VALUE);
}
public:
PersistentRooted() : ptr(js::GCMethods<T>::initial()) {}
explicit PersistentRooted(JSContext* cx) {
init(cx);
template <typename RootingContext>
explicit PersistentRooted(const RootingContext& cx)
: ptr(js::GCMethods<T>::initial())
{
registerWithRootLists(js::RootListsForRootingContext(cx));
}
PersistentRooted(JSContext* cx, T initial) {
init(cx, initial);
}
explicit PersistentRooted(JSRuntime* rt) {
init(rt);
}
PersistentRooted(JSRuntime* rt, T initial) {
init(rt, initial);
template <typename RootingContext, typename U>
PersistentRooted(const RootingContext& cx, U&& initial)
: ptr(mozilla::Forward<U>(initial))
{
registerWithRootLists(js::RootListsForRootingContext(cx));
}
PersistentRooted(const PersistentRooted& rhs)
@ -1034,22 +1051,15 @@ class PersistentRooted : public js::PersistentRootedBase<T>,
return ListBase::isInList();
}
void init(JSContext* cx) {
template <typename RootingContext>
void init(const RootingContext& cx) {
init(cx, js::GCMethods<T>::initial());
}
void init(JSContext* cx, T initial) {
ptr = initial;
registerWithRootLists(js::ContextFriendFields::get(cx)->roots);
}
void init(JSRuntime* rt) {
init(rt, js::GCMethods<T>::initial());
}
void init(JSRuntime* rt, T initial) {
ptr = initial;
registerWithRootLists(js::PerThreadDataFriendFields::getMainThread(rt)->roots);
template <typename RootingContext, typename U>
void init(const RootingContext& cx, U&& initial) {
ptr = mozilla::Forward<U>(initial);
registerWithRootLists(js::RootListsForRootingContext(cx));
}
void reset() {

View File

@ -320,17 +320,16 @@ struct PersistentRootedMarker
void
js::gc::MarkPersistentRootedChainsInLists(RootLists& roots, JSTracer* trc)
{
PersistentRootedMarker<JSFunction*>::markChain(trc, roots.functionPersistentRooteds,
"PersistentRooted<JSFunction*>");
PersistentRootedMarker<JSObject*>::markChain(trc, roots.objectPersistentRooteds,
PersistentRootedMarker<JSObject*>::markChain(trc, roots.getPersistentRootedList<JSObject*>(),
"PersistentRooted<JSObject*>");
PersistentRootedMarker<JSScript*>::markChain(trc, roots.scriptPersistentRooteds,
PersistentRootedMarker<JSScript*>::markChain(trc, roots.getPersistentRootedList<JSScript*>(),
"PersistentRooted<JSScript*>");
PersistentRootedMarker<JSString*>::markChain(trc, roots.stringPersistentRooteds,
PersistentRootedMarker<JSString*>::markChain(trc, roots.getPersistentRootedList<JSString*>(),
"PersistentRooted<JSString*>");
PersistentRootedMarker<jsid>::markChain(trc, roots.idPersistentRooteds,
PersistentRootedMarker<jsid>::markChain(trc, roots.getPersistentRootedList<jsid>(),
"PersistentRooted<jsid>");
PersistentRootedMarker<Value>::markChain(trc, roots.valuePersistentRooteds,
PersistentRootedMarker<Value>::markChain(trc, roots.getPersistentRootedList<Value>(),
"PersistentRooted<Value>");
}

View File

@ -1366,12 +1366,11 @@ FinishPersistentRootedChain(mozilla::LinkedList<PersistentRooted<T>>& list)
void
js::gc::FinishPersistentRootedChains(RootLists& roots)
{
FinishPersistentRootedChain(roots.functionPersistentRooteds);
FinishPersistentRootedChain(roots.idPersistentRooteds);
FinishPersistentRootedChain(roots.objectPersistentRooteds);
FinishPersistentRootedChain(roots.scriptPersistentRooteds);
FinishPersistentRootedChain(roots.stringPersistentRooteds);
FinishPersistentRootedChain(roots.valuePersistentRooteds);
FinishPersistentRootedChain(roots.getPersistentRootedList<JSObject*>());
FinishPersistentRootedChain(roots.getPersistentRootedList<JSScript*>());
FinishPersistentRootedChain(roots.getPersistentRootedList<JSString*>());
FinishPersistentRootedChain(roots.getPersistentRootedList<jsid>());
FinishPersistentRootedChain(roots.getPersistentRootedList<Value>());
}
void

View File

@ -2449,10 +2449,16 @@ js::SetPrototype(JSContext* cx, HandleObject obj, HandleObject proto, JS::Object
if (!extensible)
return result.fail(JSMSG_CANT_SET_PROTO);
/* ES6 9.1.2 step 6 forbids generating cyclical prototype chains. */
/*
* ES6 9.1.2 step 6 forbids generating cyclical prototype chains. But we
* have to do this comparison on the observable outer objects, not on the
* possibly-inner object we're setting the proto on.
*/
RootedObject outerObj(cx, GetOuterObject(cx, obj));
RootedObject obj2(cx);
for (obj2 = proto; obj2; ) {
if (obj2 == obj)
MOZ_ASSERT(GetOuterObject(cx, obj2) == obj2);
if (obj2 == outerObj)
return result.fail(JSMSG_CANT_SET_PROTO_CYCLE);
if (!GetPrototype(cx, obj2, &obj2))

View File

@ -345,12 +345,7 @@ class RootLists
friend void js::gc::MarkPersistentRootedChainsInLists(RootLists&, JSTracer*);
friend void js::gc::FinishPersistentRootedChains(RootLists&);
mozilla::LinkedList<JS::PersistentRootedFunction> functionPersistentRooteds;
mozilla::LinkedList<JS::PersistentRootedId> idPersistentRooteds;
mozilla::LinkedList<JS::PersistentRootedObject> objectPersistentRooteds;
mozilla::LinkedList<JS::PersistentRootedScript> scriptPersistentRooteds;
mozilla::LinkedList<JS::PersistentRootedString> stringPersistentRooteds;
mozilla::LinkedList<JS::PersistentRootedValue> valuePersistentRooteds;
mozilla::LinkedList<JS::PersistentRooted<void*>> heapRoots_[THING_ROOT_LIMIT];
/* Specializations of this return references to the appropriate list. */
template<typename Referent>
@ -358,28 +353,46 @@ class RootLists
};
template<>
inline mozilla::LinkedList<JS::PersistentRootedFunction>
&RootLists::getPersistentRootedList<JSFunction*>() { return functionPersistentRooteds; }
inline mozilla::LinkedList<JS::PersistentRootedFunction>&
RootLists::getPersistentRootedList<JSFunction*>() {
return reinterpret_cast<mozilla::LinkedList<JS::PersistentRooted<JSFunction*>>&>(
heapRoots_[THING_ROOT_OBJECT]);
}
template<>
inline mozilla::LinkedList<JS::PersistentRootedId>
&RootLists::getPersistentRootedList<jsid>() { return idPersistentRooteds; }
inline mozilla::LinkedList<JS::PersistentRootedObject>&
RootLists::getPersistentRootedList<JSObject*>() {
return reinterpret_cast<mozilla::LinkedList<JS::PersistentRooted<JSObject*>>&>(
heapRoots_[THING_ROOT_OBJECT]);
}
template<>
inline mozilla::LinkedList<JS::PersistentRootedObject>
&RootLists::getPersistentRootedList<JSObject*>() { return objectPersistentRooteds; }
inline mozilla::LinkedList<JS::PersistentRootedId>&
RootLists::getPersistentRootedList<jsid>() {
return reinterpret_cast<mozilla::LinkedList<JS::PersistentRooted<jsid>>&>(
heapRoots_[THING_ROOT_ID]);
}
template<>
inline mozilla::LinkedList<JS::PersistentRootedScript>
&RootLists::getPersistentRootedList<JSScript*>() { return scriptPersistentRooteds; }
inline mozilla::LinkedList<JS::PersistentRootedScript>&
RootLists::getPersistentRootedList<JSScript*>() {
return reinterpret_cast<mozilla::LinkedList<JS::PersistentRooted<JSScript*>>&>(
heapRoots_[THING_ROOT_SCRIPT]);
}
template<>
inline mozilla::LinkedList<JS::PersistentRootedString>
&RootLists::getPersistentRootedList<JSString*>() { return stringPersistentRooteds; }
inline mozilla::LinkedList<JS::PersistentRootedString>&
RootLists::getPersistentRootedList<JSString*>() {
return reinterpret_cast<mozilla::LinkedList<JS::PersistentRooted<JSString*>>&>(
heapRoots_[THING_ROOT_STRING]);
}
template<>
inline mozilla::LinkedList<JS::PersistentRootedValue>
&RootLists::getPersistentRootedList<JS::Value>() { return valuePersistentRooteds; }
inline mozilla::LinkedList<JS::PersistentRootedValue>&
RootLists::getPersistentRootedList<JS::Value>() {
return reinterpret_cast<mozilla::LinkedList<JS::PersistentRooted<JS::Value>>&>(
heapRoots_[THING_ROOT_VALUE]);
}
struct ContextFriendFields
{

View File

@ -96,7 +96,7 @@ struct MOZ_MUST_USE already_AddRefed
* Note that nsRefPtr is the XPCOM reference counting smart pointer class.
*/
template <typename U>
already_AddRefed(already_AddRefed<U>&& aOther) : mRawPtr(aOther.take()) {}
MOZ_IMPLICIT already_AddRefed(already_AddRefed<U>&& aOther) : mRawPtr(aOther.take()) {}
~already_AddRefed() { MOZ_ASSERT(!mRawPtr); }

View File

@ -526,7 +526,7 @@ public:
* argument is valid.
*/
template<typename U>
CheckedInt(U aValue) MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT
MOZ_IMPLICIT CheckedInt(U aValue) MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT
: mValue(T(aValue)),
mIsValid(detail::IsInRange<T>(aValue))
{

View File

@ -36,7 +36,7 @@ public:
: mCurrent(aCurrent) { }
template<typename IntType, typename EnumType>
EnumeratedIterator(const EnumeratedIterator<IntType, EnumType>& aOther)
explicit EnumeratedIterator(const EnumeratedIterator<IntType, EnumType>& aOther)
: mCurrent(aOther.mCurrent) { }
EnumTypeT operator*() const { return mCurrent; }

View File

@ -26,7 +26,7 @@ public:
: mCurrent(aCurrent) { }
template<typename IntType>
IntegerIterator(const IntegerIterator<IntType>& aOther)
explicit IntegerIterator(const IntegerIterator<IntType>& aOther)
: mCurrent(aOther.mCurrent) { }
IntTypeT operator*() const { return mCurrent; }

View File

@ -104,7 +104,7 @@ public:
/* Equivalent to RangedPtr(aArr, aArr, N). */
template<size_t N>
RangedPtr(T (&aArr)[N])
explicit RangedPtr(T (&aArr)[N])
: mPtr(aArr)
#ifdef DEBUG
, mRangeStart(aArr), mRangeEnd(aArr + N)

View File

@ -26,12 +26,12 @@ class ReentrancyGuard
public:
template<class T>
#ifdef DEBUG
ReentrancyGuard(T& aObj
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
explicit ReentrancyGuard(T& aObj
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: mEntered(aObj.mEntered)
#else
ReentrancyGuard(T&
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
explicit ReentrancyGuard(T&
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
#endif
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;

View File

@ -238,7 +238,7 @@ public:
MOZ_IMPLICIT RefPtr(T* aVal) : mPtr(ref(aVal)) {}
template<typename U>
RefPtr(const RefPtr<U>& aOther) : mPtr(ref(aOther.get())) {}
MOZ_IMPLICIT RefPtr(const RefPtr<U>& aOther) : mPtr(ref(aOther.get())) {}
~RefPtr() { unref(mPtr); }

View File

@ -126,11 +126,11 @@ public:
typedef ReverseIterator<IteratorT> const_reverse_iterator;
template<typename Iterator1, typename Iterator2>
IteratorRange(Iterator1 aIterBegin, Iterator2 aIterEnd)
MOZ_IMPLICIT IteratorRange(Iterator1 aIterBegin, Iterator2 aIterEnd)
: mIterBegin(aIterBegin), mIterEnd(aIterEnd) { }
template<typename Iterator>
IteratorRange(const IteratorRange<Iterator>& aOther)
MOZ_IMPLICIT IteratorRange(const IteratorRange<Iterator>& aOther)
: mIterBegin(aOther.mIterBegin), mIterEnd(aOther.mIterEnd) { }
iterator begin() const { return mIterBegin; }

View File

@ -238,6 +238,7 @@ public:
}
template<typename U, class E>
MOZ_IMPLICIT
UniquePtr(UniquePtr<U, E>&& aOther,
typename EnableIf<IsConvertible<typename UniquePtr<U, E>::Pointer,
Pointer>::value &&
@ -478,9 +479,9 @@ public:
MOZ_CONSTEXPR DefaultDelete() {}
template<typename U>
DefaultDelete(const DefaultDelete<U>& aOther,
typename EnableIf<mozilla::IsConvertible<U*, T*>::value,
int>::Type aDummy = 0)
MOZ_IMPLICIT DefaultDelete(const DefaultDelete<U>& aOther,
typename EnableIf<mozilla::IsConvertible<U*, T*>::value,
int>::Type aDummy = 0)
{}
void operator()(T* aPtr) const

View File

@ -309,6 +309,12 @@
</intent-filter>
</receiver>
<receiver android:name="org.mozilla.gecko.RestrictionProvider">
<intent-filter>
<action android:name="android.intent.action.GET_RESTRICTION_ENTRIES" />
</intent-filter>
</receiver>
<!-- Activity used for launching non-privileged WebApps via a URL -->
<activity android:name="org.mozilla.gecko.Webapp"
android:label="@string/webapp_generic_name"

View File

@ -473,6 +473,9 @@ public class BrowserApp extends GeckoApp
case LOCATION_CHANGE:
// fall through
case SELECTED:
if (mZoomedView != null) {
mZoomedView.stopZoomDisplay(false);
}
if (Tabs.getInstance().isSelectedTab(tab)) {
updateHomePagerForTab(tab);
}

View File

@ -65,30 +65,55 @@ public class RestrictedProfiles {
* These constants should be in sync with the ones from toolkit/components/parentalcontrols/nsIParentalControlServices.idl
*/
public enum Restriction {
DISALLOW_DOWNLOADS(1, "no_download_files"),
DISALLOW_INSTALL_EXTENSION(2, "no_install_extensions"),
DISALLOW_INSTALL_APPS(3, "no_install_apps"), // UserManager.DISALLOW_INSTALL_APPS
DISALLOW_BROWSE_FILES(4, "no_browse_files"),
DISALLOW_SHARE(5, "no_share"),
DISALLOW_BOOKMARK(6, "no_bookmark"),
DISALLOW_ADD_CONTACTS(7, "no_add_contacts"),
DISALLOW_SET_IMAGE(8, "no_set_image"),
DISALLOW_MODIFY_ACCOUNTS(9, "no_modify_accounts"), // UserManager.DISALLOW_MODIFY_ACCOUNTS
DISALLOW_REMOTE_DEBUGGING(10, "no_remote_debugging"),
DISALLOW_IMPORT_SETTINGS(11, "no_import_settings"),
DISALLOW_TOOLS_MENU(12, "no_tools_menu"),
DISALLOW_REPORT_SITE_ISSUE(13, "no_report_site_issue");
// These restrictions have no strings assigned because they are only used in guest mode and not shown in the
// restricted profiles settings UI
DISALLOW_DOWNLOADS(1, "no_download_files", 0, 0),
DISALLOW_BROWSE_FILES(4, "no_browse_files", 0, 0),
DISALLOW_SHARE(5, "no_share", 0, 0),
DISALLOW_BOOKMARK(6, "no_bookmark", 0, 0),
DISALLOW_ADD_CONTACTS(7, "no_add_contacts", 0, 0),
DISALLOW_SET_IMAGE(8, "no_set_image", 0, 0),
DISALLOW_MODIFY_ACCOUNTS(9, "no_modify_accounts", 0, 0), // UserManager.DISALLOW_MODIFY_ACCOUNTS
DISALLOW_REMOTE_DEBUGGING(10, "no_remote_debugging", 0, 0),
// These restrictions are used for restricted profiles and therefore need to have strings assigned for the profile
// settings UI.
DISALLOW_INSTALL_EXTENSION(2, "no_install_extensions", R.string.restriction_disallow_addons_title, R.string.restriction_disallow_addons_description),
DISALLOW_INSTALL_APPS(3, "no_install_apps", R.string.restriction_disallow_apps_title, R.string.restriction_disallow_apps_description), // UserManager.DISALLOW_INSTALL_APPS
DISALLOW_IMPORT_SETTINGS(11, "no_report_site_issue", R.string.restriction_disallow_import_settings_title, R.string.restriction_disallow_import_settings_description),
DISALLOW_TOOLS_MENU(12, "no_tools_menu", R.string.restriction_disallow_tools_menu_title, R.string.restriction_disallow_tools_menu_description),
DISALLOW_REPORT_SITE_ISSUE(13, "no_report_site_issue", R.string.restriction_disallow_report_site_issue_title, R.string.restriction_disallow_report_site_issue_description);
public final int id;
public final String name;
public final int titleResource;
public final int descriptionResource;
Restriction(final int id, final String name) {
Restriction(final int id, final String name, int titleResource, int descriptionResource) {
this.id = id;
this.name = name;
this.titleResource = titleResource;
this.descriptionResource = descriptionResource;
}
public String getTitle(Context context) {
if (titleResource == 0) {
return toString();
}
return context.getResources().getString(titleResource);
}
public String getDescription(Context context) {
if (descriptionResource == 0) {
return name;
}
return context.getResources().getString(descriptionResource);
}
}
private static List<Restriction> restrictionsOfGuestProfile = Arrays.asList(
static List<Restriction> GUEST_RESTRICTIONS = Arrays.asList(
Restriction.DISALLOW_DOWNLOADS,
Restriction.DISALLOW_INSTALL_EXTENSION,
Restriction.DISALLOW_INSTALL_APPS,
@ -103,7 +128,9 @@ public class RestrictedProfiles {
);
// Restricted profiles will automatically have these restrictions by default
private static List<Restriction> defaultRestrictionsOfRestrictedProfiles = Arrays.asList(
static List<Restriction> RESTRICTED_PROFILE_RESTRICTIONS = Arrays.asList(
Restriction.DISALLOW_INSTALL_EXTENSION,
Restriction.DISALLOW_INSTALL_APPS,
Restriction.DISALLOW_TOOLS_MENU,
Restriction.DISALLOW_REPORT_SITE_ISSUE,
Restriction.DISALLOW_IMPORT_SETTINGS
@ -125,6 +152,12 @@ public class RestrictedProfiles {
return mgr.getUserRestrictions();
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
private static Bundle getAppRestrictions(final Context context) {
final UserManager mgr = (UserManager) context.getSystemService(Context.USER_SERVICE);
return mgr.getApplicationRestrictions(context.getPackageName());
}
/**
* This method does the system version check for you.
*
@ -134,14 +167,18 @@ public class RestrictedProfiles {
*
* Returns true otherwise.
*/
private static boolean getRestriction(final Context context, final String name) {
private static boolean getRestriction(final Context context, final Restriction restriction) {
// Early versions don't support restrictions at all,
// so no action can be restricted.
if (Versions.preJBMR2) {
return false;
}
return getRestrictions(context).getBoolean(name, false);
if (!isUserRestricted(context)) {
return false;
}
return getAppRestrictions(context).getBoolean(restriction.name, RESTRICTED_PROFILE_RESTRICTIONS.contains(restriction));
}
private static boolean canLoadUrl(final Context context, final String url) {
@ -153,7 +190,7 @@ public class RestrictedProfiles {
try {
// If we're not in guest mode, and the system restriction isn't in place, everything is allowed.
if (!getInGuest() &&
!getRestriction(context, Restriction.DISALLOW_BROWSE_FILES.name)) {
!getRestriction(context, Restriction.DISALLOW_BROWSE_FILES)) {
return true;
}
} catch (IllegalArgumentException ex) {
@ -231,16 +268,11 @@ public class RestrictedProfiles {
return canLoadUrl(context, url);
}
return !restrictionsOfGuestProfile.contains(restriction);
}
// Hardcoded restrictions. Make restrictions configurable and read from UserManager (Bug 1180653)
if (isUserRestricted(context) && defaultRestrictionsOfRestrictedProfiles.contains(restriction)) {
return false;
return !GUEST_RESTRICTIONS.contains(restriction);
}
// NOTE: Restrictions hold the opposite intention, so we need to flip it.
return !getRestriction(context, restriction.name);
return !getRestriction(context, restriction);
}
@WrapElementForJNI

View File

@ -0,0 +1,69 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
* 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/. */
package org.mozilla.gecko;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.RestrictionEntry;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import java.util.ArrayList;
/**
* Broadcast receiver providing supported restrictions to the system.
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public class RestrictionProvider extends BroadcastReceiver {
@Override
public void onReceive(final Context context, final Intent intent) {
if (AppConstants.Versions.preJBMR2) {
// This broadcast does not make any sense prior to Jelly Bean MR2.
return;
}
final PendingResult result = goAsync();
new Thread() {
@Override
public void run() {
final Bundle oldRestrictions = intent.getBundleExtra(Intent.EXTRA_RESTRICTIONS_BUNDLE);
final Bundle extras = new Bundle();
ArrayList<RestrictionEntry> entries = initRestrictions(context, oldRestrictions);
extras.putParcelableArrayList(Intent.EXTRA_RESTRICTIONS_LIST, entries);
result.setResult(Activity.RESULT_OK, null, extras);
result.finish();
}
}.start();
}
private ArrayList<RestrictionEntry> initRestrictions(Context context, Bundle oldRestrictions) {
ArrayList<RestrictionEntry> entries = new ArrayList<RestrictionEntry>();
for (RestrictedProfiles.Restriction restriction : RestrictedProfiles.RESTRICTED_PROFILE_RESTRICTIONS) {
RestrictionEntry entry = createRestrictionEntryWithDefaultValue(context, restriction,
oldRestrictions.getBoolean(restriction.name, true));
entries.add(entry);
}
return entries;
}
private RestrictionEntry createRestrictionEntryWithDefaultValue(Context context, RestrictedProfiles.Restriction restriction, boolean defaultValue) {
RestrictionEntry entry = new RestrictionEntry(restriction.name, defaultValue);
entry.setTitle(restriction.getTitle(context));
entry.setDescription(restriction.getDescription(context));
return entry;
}
}

View File

@ -501,7 +501,7 @@ public class ZoomedView extends FrameLayout implements LayerView.OnMetricsChange
moveUsingGeckoPosition(leftFromGecko, topFromGecko);
}
private void stopZoomDisplay(boolean withAnimation) {
public void stopZoomDisplay(boolean withAnimation) {
if (getVisibility() == View.VISIBLE) {
shouldSetVisibleOnUpdate = false;
hideZoomedView(withAnimation);

View File

@ -678,3 +678,18 @@ just addresses the organization to follow, e.g. "This site is run by " -->
desktop Firefox via WebIDE), so you just need to aim this device at the QR
code. -->
<!ENTITY devtools_auth_scan_header "Scanning for the QR code displayed on your other device">
<!-- Restrictions -->
<!-- Localization note: These are restrictions the device owner (e.g. parent) can enable for
a restricted profile (e.g. child). Used inside the Android settings UI. -->
<!ENTITY restriction_disallow_tools_menu_title "Disallow Tools menu">
<!ENTITY restriction_disallow_tools_menu_description "Hide Tools menu from UI.">
<!ENTITY restriction_disallow_report_site_issue_title "Disallow \'Report site issue\'">
<!ENTITY restriction_disallow_report_site_issue_description "Hide \'Report site issue\' menu item.">
<!ENTITY restriction_disallow_import_settings_title "Disallow importing settings">
<!ENTITY restriction_disallow_import_settings_description "Do not allow to import settings from other system browsers.">
<!ENTITY restriction_disallow_addons_title "Disallow add-ons">
<!ENTITY restriction_disallow_addons_description "Disallow installation of add-ons.">
<!ENTITY restriction_disallow_apps_title "Disallow apps">
<!ENTITY restriction_disallow_apps_description "Disallow installing apps from Firefox Marketplace.">

View File

@ -433,6 +433,7 @@ gbjar.sources += [
'RemoteTabsExpandableListAdapter.java',
'Restarter.java',
'RestrictedProfiles.java',
'RestrictionProvider.java',
'ServiceNotificationClient.java',
'SessionParser.java',
'SharedPreferencesHelper.java',

View File

@ -541,6 +541,18 @@
<!-- Voice search from the Awesome Bar -->
<string name="voicesearch_prompt">&voicesearch_prompt;</string>
<!-- Restrictions -->
<string name="restriction_disallow_tools_menu_title">&restriction_disallow_tools_menu_title;</string>
<string name="restriction_disallow_tools_menu_description">&restriction_disallow_tools_menu_description;</string>
<string name="restriction_disallow_report_site_issue_title">&restriction_disallow_report_site_issue_title;</string>
<string name="restriction_disallow_report_site_issue_description">&restriction_disallow_report_site_issue_description;</string>
<string name="restriction_disallow_import_settings_title">&restriction_disallow_import_settings_title;</string>
<string name="restriction_disallow_import_settings_description">&restriction_disallow_import_settings_description;</string>
<string name="restriction_disallow_addons_title">&restriction_disallow_addons_title;</string>
<string name="restriction_disallow_addons_description">&restriction_disallow_addons_description;</string>
<string name="restriction_disallow_apps_title">&restriction_disallow_apps_title;</string>
<string name="restriction_disallow_apps_description">&restriction_disallow_apps_description;</string>
<!-- Miscellaneous -->
<string name="ellipsis">&ellipsis;</string>

View File

@ -4261,8 +4261,12 @@ pref("layers.async-pan-zoom.enabled", true);
#ifdef XP_MACOSX
pref("layers.enable-tiles", true);
pref("layers.tiled-drawtarget.enabled", true);
pref("layers.tiles.edge-padding", false);
#endif
#ifdef MOZ_WIDGET_GONK
pref("layers.tiled-drawtarget.enabled", true);
#endif
// same effect as layers.offmainthreadcomposition.enabled, but specifically for
// use with tests.

View File

@ -426,8 +426,8 @@ public:
* lower precision, usually 15.6 ms, but with very good performance benefit.
* Use it for measurements of longer times, like >200ms timeouts.
*/
static MFBT_API TimeStamp Now() { return Now(true); }
static MFBT_API TimeStamp NowLoRes() { return Now(false); }
static TimeStamp Now() { return Now(true); }
static TimeStamp NowLoRes() { return Now(false); }
/**
* Return a timestamp representing the time when the current process was

View File

@ -42,7 +42,9 @@ def visual_studio_product_to_internal_version(version, solution=False):
elif version == '2011':
return '12.00'
elif version == '2012':
return '13.00'
return '12.00'
elif version == '2013':
return '12.00'
else:
raise Exception('Unknown version seen: %s' % version)
else:
@ -52,9 +54,23 @@ def visual_studio_product_to_internal_version(version, solution=False):
return '11.00'
elif version == '2012':
return '12.00'
elif version == '2013':
return '12.00'
else:
raise Exception('Unknown version seen: %s' % version)
def visual_studio_product_to_platform_toolset_version(version):
if version == '2010':
return 'v100'
elif version == '2011':
return 'v110'
elif version == '2012':
return 'v120'
elif version == '2013':
return 'v120'
else:
raise Exception('Unknown version seen: %s' % version)
class VisualStudioBackend(CommonBackend):
"""Generate Visual Studio project files.
@ -75,8 +91,9 @@ class VisualStudioBackend(CommonBackend):
# These should eventually evolve into parameters.
self._out_dir = os.path.join(self.environment.topobjdir, 'msvc')
self._projsubdir = 'projects'
# But making this one a parameter requires testing first.
self._version = '2010'
self._version = '2013'
self._paths_to_sources = {}
self._paths_to_includes = {}
@ -141,11 +158,17 @@ class VisualStudioBackend(CommonBackend):
def consume_finished(self):
out_dir = self._out_dir
out_proj_dir = os.path.join(self._out_dir, self._projsubdir)
try:
os.makedirs(out_dir)
except OSError as e:
if e.errno != errno.EEXIST:
raise
try:
os.makedirs(out_proj_dir)
except OSError as e:
if e.errno != errno.EEXIST:
raise
projects = {}
@ -194,7 +217,7 @@ class VisualStudioBackend(CommonBackend):
defines.append('%s=%s' % (k, v))
basename = 'library_%s' % lib
project_id = self._write_vs_project(out_dir, basename, lib,
project_id = self._write_vs_project(out_proj_dir, basename, lib,
includes=includes,
forced_includes=['$(TopObjDir)\\dist\\include\\mozilla-config.h'],
defines=defines,
@ -210,7 +233,7 @@ class VisualStudioBackend(CommonBackend):
if target != 'full':
command += ' %s' % target
project_id = self._write_vs_project(out_dir, basename, target,
project_id = self._write_vs_project(out_proj_dir, basename, target,
build_command=command,
clean_command='$(SolutionDir)\\mach.bat build clean')
@ -218,14 +241,14 @@ class VisualStudioBackend(CommonBackend):
# A project that can be used to regenerate the visual studio projects.
basename = 'target_vs'
project_id = self._write_vs_project(out_dir, basename, 'visual-studio',
project_id = self._write_vs_project(out_proj_dir, basename, 'visual-studio',
build_command='$(SolutionDir)\\mach.bat build-backend -b VisualStudio')
projects[basename] = (project_id, basename, 'visual-studio')
# A project to run the main application binary.
app_name = self.environment.substs['MOZ_APP_NAME']
basename = 'binary_%s' % app_name
project_id = self._write_vs_project(out_dir, basename, app_name,
project_id = self._write_vs_project(out_proj_dir, basename, app_name,
debugger=('$(TopObjDir)\\dist\\bin\\%s.exe' % app_name,
'-no-remote'))
projects[basename] = (project_id, basename, app_name)
@ -233,12 +256,12 @@ class VisualStudioBackend(CommonBackend):
# Projects to run other common binaries.
for app in ['js', 'xpcshell']:
basename = 'binary_%s' % app
project_id = self._write_vs_project(out_dir, basename, app,
project_id = self._write_vs_project(out_proj_dir, basename, app,
debugger=('$(TopObjDir)\\dist\\bin\\%s.exe' % app, ''))
projects[basename] = (project_id, basename, app)
# Write out a shared property file with common variables.
props_path = os.path.join(out_dir, 'mozilla.props')
props_path = os.path.join(out_proj_dir, 'mozilla.props')
with open(props_path, 'wb') as fh:
self._write_props(fh)
@ -274,7 +297,7 @@ class VisualStudioBackend(CommonBackend):
# Write out entries for each project.
for key in sorted(projects):
project_id, basename, name = projects[key]
path = '%s.vcxproj' % basename
path = os.path.join(self._projsubdir, '%s.vcxproj' % basename)
fh.write('Project("{%s}") = "%s", "%s", "{%s}"\r\n' % (
project_type, name, path, project_id))
@ -446,9 +469,11 @@ class VisualStudioBackend(CommonBackend):
def _write_vs_project(self, out_dir, basename, name, **kwargs):
root = '%s.vcxproj' % basename
project_id = get_id(basename.encode('utf-8'))
with open(os.path.join(out_dir, root), 'wb') as fh:
project_id, name = VisualStudioBackend.write_vs_project(fh,
self._version, name, **kwargs)
self._version, project_id, name, **kwargs)
with open(os.path.join(out_dir, '%s.user' % root), 'w') as fh:
fh.write('<?xml version="1.0" encoding="utf-8"?>\r\n')
@ -459,13 +484,11 @@ class VisualStudioBackend(CommonBackend):
return project_id
@staticmethod
def write_vs_project(fh, version, name, includes=[],
def write_vs_project(fh, version, project_id, name, includes=[],
forced_includes=[], defines=[],
build_command=None, clean_command=None,
debugger=None, headers=[], sources=[]):
project_id = get_id(name.encode('utf-8'))
impl = getDOMImplementation()
doc = impl.createDocument(MSBUILD_NAMESPACE, 'Project', None)
@ -501,6 +524,9 @@ class VisualStudioBackend(CommonBackend):
rn = pg.appendChild(doc.createElement('RootNamespace'))
rn.appendChild(doc.createTextNode('mozilla'))
pts = pg.appendChild(doc.createElement('PlatformToolset'))
pts.appendChild(doc.createTextNode(visual_studio_product_to_platform_toolset_version(version)))
i = project.appendChild(doc.createElement('Import'))
i.setAttribute('Project', '$(VCTargetsPath)\\Microsoft.Cpp.Default.props')

View File

@ -326,7 +326,8 @@ static const char contentSandboxRules[] =
" (allow file-read*\n"
" (home-regex \"/Library/Application Support/[^/]+/Extensions/[^/]/\")\n"
" (resolving-regex \"/Library/Application Support/[^/]+/Extensions/[^/]/\")\n"
" (home-regex \"/Library/Application Support/Firefox/Profiles/[^/]+/extensions/\"))\n"
" (home-regex \"/Library/Application Support/Firefox/Profiles/[^/]+/extensions/\")\n"
" (home-regex \"/Library/Application Support/Firefox/Profiles/[^/]+/weave/\"))\n"
"\n"
"; the following rules should be removed when printing and \n"
"; opening a file from disk are brokered through the main process\n"

View File

@ -419,6 +419,10 @@ XPCOMUtils.defineLazyGetter(this, "Prefs", () => {
store.suggestTyped = prefs.get(...PREF_SUGGEST_HISTORY_ONLYTYPED);
store.suggestSearches = prefs.get(...PREF_SUGGEST_SEARCHES);
store.maxCharsForSearchSuggestions = prefs.get(...PREF_MAX_CHARS_FOR_SUGGEST);
store.keywordEnabled = true;
try {
store.keywordEnabled = Services.prefs.getBoolPref("keyword.enabled");
} catch (ex) {}
// If history is not set, onlyTyped value should be ignored.
if (!store.suggestHistory) {
@ -473,7 +477,9 @@ XPCOMUtils.defineLazyGetter(this, "Prefs", () => {
loadPrefs(subject, topic, data);
this._ignoreNotifications = false;
},
QueryInterface: XPCOMUtils.generateQI([ Ci.nsIObserver ])
QueryInterface: XPCOMUtils.generateQI([
Ci.nsIObserver,
Ci.nsISupportsWeakReference ])
};
// Synchronize suggest.* prefs with autocomplete.enabled at initialization
@ -481,6 +487,7 @@ XPCOMUtils.defineLazyGetter(this, "Prefs", () => {
loadPrefs();
prefs.observe("", store);
Services.prefs.addObserver("keyword.enabled", store, true);
return Object.seal(store);
});
@ -1174,7 +1181,9 @@ Search.prototype = {
// If the result is something that looks like a single-worded hostname
// we need to check the domain whitelist to treat it as such.
// We also want to return a "visit" if keyword.enabled is false.
if (uri.asciiHost &&
Prefs.keywordEnabled &&
REGEXP_SINGLEWORD_HOST.test(uri.asciiHost) &&
!Services.uriFixup.isDomainWhitelisted(uri.asciiHost, -1)) {
return false;

Some files were not shown because too many files have changed in this diff Show More