diff --git a/CLOBBER b/CLOBBER index 07be57e6865e..537e3880f198 100644 --- a/CLOBBER +++ b/CLOBBER @@ -22,4 +22,8 @@ # changes to stick? As of bug 928195, this shouldn't be necessary! Please # don't change CLOBBER for WebIDL changes any more. +<<<<<<< local +Bug 1092813 needs a CLOBBER +======= Bug 1056337 - Change the default compiler on B2G ICS to gcc 4.8. +>>>>>>> other diff --git a/accessible/atk/moz.build b/accessible/atk/moz.build index 557ca5d47b23..cfd826711040 100644 --- a/accessible/atk/moz.build +++ b/accessible/atk/moz.build @@ -50,4 +50,4 @@ if CONFIG['MOZ_ENABLE_GTK']: if CONFIG['MOZ_ENABLE_DBUS']: CXXFLAGS += CONFIG['MOZ_DBUS_CFLAGS'] - include('/ipc/chromium/chromium-config.mozbuild') +include('/ipc/chromium/chromium-config.mozbuild') diff --git a/browser/app/macbuild/Contents/MacOS-files.in b/browser/app/macbuild/Contents/MacOS-files.in index 32ebf105f3ee..849336bc9be6 100644 --- a/browser/app/macbuild/Contents/MacOS-files.in +++ b/browser/app/macbuild/Contents/MacOS-files.in @@ -5,6 +5,5 @@ /gtest/*** /pk12util /ssltunnel -/webapprt-stub /xpcshell /XUL diff --git a/browser/components/loop/LoopRooms.jsm b/browser/components/loop/LoopRooms.jsm index 92718ffd0659..0dbc67587bee 100644 --- a/browser/components/loop/LoopRooms.jsm +++ b/browser/components/loop/LoopRooms.jsm @@ -106,6 +106,11 @@ const checkForParticipantsUpdate = function(room, updatedRoom) { let LoopRoomsInternal = { rooms: new Map(), + get sessionType() { + return MozLoopService.userProfile ? LOOP_SESSION_TYPE.FXA : + LOOP_SESSION_TYPE.GUEST; + }, + /** * Fetch a list of rooms that the currently registered user is a member of. * @@ -131,10 +136,8 @@ let LoopRoomsInternal = { } // Fetch the rooms from the server. - let sessionType = MozLoopService.userProfile ? LOOP_SESSION_TYPE.FXA : - LOOP_SESSION_TYPE.GUEST; let url = "/rooms" + (version ? "?version=" + encodeURIComponent(version) : ""); - let response = yield MozLoopService.hawkRequest(sessionType, url, "GET"); + let response = yield MozLoopService.hawkRequest(this.sessionType, url, "GET"); let roomsList = JSON.parse(response.body); if (!Array.isArray(roomsList)) { throw new Error("Missing array of rooms in response."); @@ -188,9 +191,7 @@ let LoopRoomsInternal = { return; } - let sessionType = MozLoopService.userProfile ? LOOP_SESSION_TYPE.FXA : - LOOP_SESSION_TYPE.GUEST; - MozLoopService.hawkRequest(sessionType, "/rooms/" + encodeURIComponent(roomToken), "GET") + MozLoopService.hawkRequest(this.sessionType, "/rooms/" + encodeURIComponent(roomToken), "GET") .then(response => { let data = JSON.parse(response.body); @@ -227,10 +228,7 @@ let LoopRoomsInternal = { return; } - let sessionType = MozLoopService.userProfile ? LOOP_SESSION_TYPE.FXA : - LOOP_SESSION_TYPE.GUEST; - - MozLoopService.hawkRequest(sessionType, "/rooms", "POST", room) + MozLoopService.hawkRequest(this.sessionType, "/rooms", "POST", room) .then(response => { let data = JSON.parse(response.body); extend(room, data); @@ -252,6 +250,28 @@ let LoopRoomsInternal = { MozLoopService.openChatWindow(windowData); }, + /** + * Deletes a room. + * + * @param {String} roomToken The room token. + * @param {Function} callback Function that will be invoked once the operation + * finished. The first argument passed will be an + * `Error` object or `null`. + */ + delete: function(roomToken, callback) { + // XXX bug 1092954: Before deleting a room, the client should check room + // membership and forceDisconnect() all current participants. + let room = this.rooms.get(roomToken); + let url = "/rooms/" + encodeURIComponent(roomToken); + MozLoopService.hawkRequest(this.sessionType, url, "DELETE") + .then(response => { + this.rooms.delete(roomToken); + eventEmitter.emit("delete", room); + callback(null, room); + }, error => callback(error)).catch(error => callback(error)); + }, + + /** * Callback used to indicate changes to rooms data on the LoopServer. * @@ -273,7 +293,7 @@ Object.freeze(LoopRoomsInternal); * At this point the following events may be subscribed to: * - 'add[:{room-id}]': A new room object was successfully added to the data * store. - * - 'remove[:{room-id}]': A room was successfully removed from the data store. + * - 'delete[:{room-id}]': A room was successfully removed from the data store. * - 'update[:{room-id}]': A room object was successfully updated with changed * properties in the data store. * - 'joined[:{room-id}]': A participant joined a room. @@ -298,6 +318,10 @@ this.LoopRooms = { return LoopRoomsInternal.open(roomToken); }, + delete: function(roomToken, callback) { + return LoopRoomsInternal.delete(roomToken, callback); + }, + promise: function(method, ...params) { return new Promise((resolve, reject) => { this[method](...params, (error, result) => { diff --git a/browser/components/loop/content/js/panel.js b/browser/components/loop/content/js/panel.js index 0bdd248ffdef..82542501d73d 100644 --- a/browser/components/loop/content/js/panel.js +++ b/browser/components/loop/content/js/panel.js @@ -467,8 +467,8 @@ loop.panel = (function(_, mozL10n) { */ var RoomEntry = React.createClass({displayName: 'RoomEntry', propTypes: { - openRoom: React.PropTypes.func.isRequired, - room: React.PropTypes.instanceOf(loop.store.Room).isRequired + dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired, + room: React.PropTypes.instanceOf(loop.store.Room).isRequired }, getInitialState: function() { @@ -480,9 +480,11 @@ loop.panel = (function(_, mozL10n) { (nextState.urlCopied !== this.state.urlCopied); }, - handleClickRoom: function(event) { + handleClickRoomUrl: function(event) { event.preventDefault(); - this.props.openRoom(this.props.room); + this.props.dispatcher.dispatch(new sharedActions.OpenRoom({ + roomToken: this.props.room.roomToken + })); }, handleCopyButtonClick: function(event) { @@ -491,6 +493,14 @@ loop.panel = (function(_, mozL10n) { this.setState({urlCopied: true}); }, + handleDeleteButtonClick: function(event) { + event.preventDefault(); + // XXX We should prompt end user for confirmation; see bug 1092953. + this.props.dispatcher.dispatch(new sharedActions.DeleteRoom({ + roomToken: this.props.room.roomToken + })); + }, + handleMouseLeave: function(event) { this.setState({urlCopied: false}); }, @@ -507,20 +517,22 @@ loop.panel = (function(_, mozL10n) { "room-active": this._isActive() }); var copyButtonClasses = React.addons.classSet({ - 'copy-link': true, - 'checked': this.state.urlCopied + "copy-link": true, + "checked": this.state.urlCopied }); return ( React.DOM.div({className: roomClasses, onMouseLeave: this.handleMouseLeave}, React.DOM.h2(null, React.DOM.span({className: "room-notification"}), - room.roomName, + room.roomName, React.DOM.button({className: copyButtonClasses, - onClick: this.handleCopyButtonClick}) + onClick: this.handleCopyButtonClick}), + React.DOM.button({className: "delete-link", + onClick: this.handleDeleteButtonClick}) ), React.DOM.p(null, - React.DOM.a({ref: "room", href: "#", onClick: this.handleClickRoom}, + React.DOM.a({href: "#", onClick: this.handleClickRoomUrl}, room.roomUrl ) ) @@ -581,12 +593,6 @@ loop.panel = (function(_, mozL10n) { })); }, - openRoom: function(room) { - this.props.dispatcher.dispatch(new sharedActions.OpenRoom({ - roomToken: room.roomToken - })); - }, - render: function() { if (this.state.error) { // XXX Better end user reporting of errors. @@ -598,7 +604,11 @@ loop.panel = (function(_, mozL10n) { React.DOM.h1(null, this._getListHeading()), React.DOM.div({className: "room-list"}, this.state.rooms.map(function(room, i) { - return RoomEntry({key: i, room: room, openRoom: this.openRoom}); + return RoomEntry({ + key: room.roomToken, + dispatcher: this.props.dispatcher, + room: room} + ); }, this) ), React.DOM.p(null, diff --git a/browser/components/loop/content/js/panel.jsx b/browser/components/loop/content/js/panel.jsx index 956ed9c182f9..5143fc5b5e18 100644 --- a/browser/components/loop/content/js/panel.jsx +++ b/browser/components/loop/content/js/panel.jsx @@ -467,8 +467,8 @@ loop.panel = (function(_, mozL10n) { */ var RoomEntry = React.createClass({ propTypes: { - openRoom: React.PropTypes.func.isRequired, - room: React.PropTypes.instanceOf(loop.store.Room).isRequired + dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired, + room: React.PropTypes.instanceOf(loop.store.Room).isRequired }, getInitialState: function() { @@ -480,9 +480,11 @@ loop.panel = (function(_, mozL10n) { (nextState.urlCopied !== this.state.urlCopied); }, - handleClickRoom: function(event) { + handleClickRoomUrl: function(event) { event.preventDefault(); - this.props.openRoom(this.props.room); + this.props.dispatcher.dispatch(new sharedActions.OpenRoom({ + roomToken: this.props.room.roomToken + })); }, handleCopyButtonClick: function(event) { @@ -491,6 +493,14 @@ loop.panel = (function(_, mozL10n) { this.setState({urlCopied: true}); }, + handleDeleteButtonClick: function(event) { + event.preventDefault(); + // XXX We should prompt end user for confirmation; see bug 1092953. + this.props.dispatcher.dispatch(new sharedActions.DeleteRoom({ + roomToken: this.props.room.roomToken + })); + }, + handleMouseLeave: function(event) { this.setState({urlCopied: false}); }, @@ -507,20 +517,22 @@ loop.panel = (function(_, mozL10n) { "room-active": this._isActive() }); var copyButtonClasses = React.addons.classSet({ - 'copy-link': true, - 'checked': this.state.urlCopied + "copy-link": true, + "checked": this.state.urlCopied }); return (

- {room.roomName} + {room.roomName}

- + {room.roomUrl}

@@ -581,12 +593,6 @@ loop.panel = (function(_, mozL10n) { })); }, - openRoom: function(room) { - this.props.dispatcher.dispatch(new sharedActions.OpenRoom({ - roomToken: room.roomToken - })); - }, - render: function() { if (this.state.error) { // XXX Better end user reporting of errors. @@ -598,7 +604,11 @@ loop.panel = (function(_, mozL10n) {

{this._getListHeading()}

{ this.state.rooms.map(function(room, i) { - return ; + return ; }, this) }

diff --git a/browser/components/loop/content/shared/css/panel.css b/browser/components/loop/content/shared/css/panel.css index 4654bb6b303d..9c87f11793a5 100644 --- a/browser/components/loop/content/shared/css/panel.css +++ b/browser/components/loop/content/shared/css/panel.css @@ -222,37 +222,48 @@ body { text-decoration: underline; } -.room-list > .room-entry > h2 > .copy-link { +@keyframes drop-and-fade-in { + 0% {opacity: 0; top: -15px;} + 25% {opacity: 0; top: -15px;} + 100% {opacity: 1; top: 0px;} +} + +.room-list > .room-entry > h2 > button { display: inline-block; + position: relative; width: 24px; height: 24px; border: none; - margin: .1em .5em; /* relative to _this_ line's font, not the document's */ + margin: .1em .1em .1em .5em; /* relative to _this_ line's font, not the document's */ background-color: transparent; /* override browser default for button tags */ + top: -15px; } -@keyframes drop-and-fade-in { - from { opacity: 0; transform: translateY(-10px); } - to { opacity: 100; transform: translateY(0); } +.room-list > .room-entry:hover > h2 > button { + animation: drop-and-fade-in 0.250s; + animation-fill-mode: forwards; + cursor: pointer; } .room-list > .room-entry:hover > h2 > .copy-link { - background: transparent url(../img/svg/copy-16x16.svg); - cursor: pointer; - animation: drop-and-fade-in 0.4s; - animation-fill-mode: forwards; + background-image: url(../img/icons-16x16.svg#copy); +} + +.room-list > .room-entry:hover > h2 > .delete-link { + background-image: url(../img/icons-16x16.svg#trash); } /* scale this up to 1.1x and then back to the original size */ @keyframes pulse { 0%, 100% { transform: scale(1.0); } - 50% { transform: scale(1.1); } + 50% { transform: scale(1.1); } } .room-list > .room-entry > h2 > .copy-link.checked { - background: transparent url(../img/svg/checkmark-16x16.svg); - animation: pulse .250s; + background: transparent url(../img/icons-16x16.svg#checkmark); + animation: pulse .150s; animation-timing-function: ease-in-out; + top: 0px; } .room-list > .room-entry > h2 { diff --git a/browser/components/loop/content/shared/img/icons-16x16.svg b/browser/components/loop/content/shared/img/icons-16x16.svg index d62e062dd013..3d508fa36bfe 100644 --- a/browser/components/loop/content/shared/img/icons-16x16.svg +++ b/browser/components/loop/content/shared/img/icons-16x16.svg @@ -87,6 +87,37 @@ use[id$="-red"] { + + + + + + + + + + + + + + + + + @@ -98,6 +129,8 @@ use[id$="-red"] { + + @@ -113,6 +146,7 @@ use[id$="-red"] { + diff --git a/browser/components/loop/content/shared/img/svg/checkmark-16x16.svg b/browser/components/loop/content/shared/img/svg/checkmark-16x16.svg deleted file mode 100644 index 2ac67b1da317..000000000000 --- a/browser/components/loop/content/shared/img/svg/checkmark-16x16.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/browser/components/loop/content/shared/img/svg/copy-16x16.svg b/browser/components/loop/content/shared/img/svg/copy-16x16.svg deleted file mode 100644 index 2b68a345bf5b..000000000000 --- a/browser/components/loop/content/shared/img/svg/copy-16x16.svg +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/browser/components/loop/content/shared/js/actions.js b/browser/components/loop/content/shared/js/actions.js index c444b8b461ed..52f1d2866baf 100644 --- a/browser/components/loop/content/shared/js/actions.js +++ b/browser/components/loop/content/shared/js/actions.js @@ -158,6 +158,22 @@ loop.shared.actions = (function() { error: Error }), + /** + * Deletes a room. + * XXX: should move to some roomActions module - refs bug 1079284 + */ + DeleteRoom: Action.define("deleteRoom", { + roomToken: String + }), + + /** + * Room deletion error. + * XXX: should move to some roomActions module - refs bug 1079284 + */ + DeleteRoomError: Action.define("deleteRoomError", { + error: Error + }), + /** * Retrieves room list. * XXX: should move to some roomActions module - refs bug 1079284 diff --git a/browser/components/loop/content/shared/js/roomListStore.js b/browser/components/loop/content/shared/js/roomListStore.js index 5c366121edc5..f281e304f913 100644 --- a/browser/components/loop/content/shared/js/roomListStore.js +++ b/browser/components/loop/content/shared/js/roomListStore.js @@ -71,6 +71,8 @@ loop.store = loop.store || {}; this._dispatcher.register(this, [ "createRoom", "createRoomError", + "deleteRoom", + "deleteRoomError", "getAllRooms", "getAllRoomsError", "openRoom", @@ -139,7 +141,7 @@ loop.store = loop.store || {}; // Rooms event registration this._mozLoop.rooms.on("add", this._onRoomAdded.bind(this)); this._mozLoop.rooms.on("update", this._onRoomUpdated.bind(this)); - this._mozLoop.rooms.on("remove", this._onRoomRemoved.bind(this)); + this._mozLoop.rooms.on("delete", this._onRoomRemoved.bind(this)); }, /** @@ -181,7 +183,7 @@ loop.store = loop.store || {}; }, /** - * Executed when a room is removed. + * Executed when a room is deleted. * * @param {String} eventName The event name (unused). * @param {Object} removedRoomData The removed room data. @@ -194,7 +196,6 @@ loop.store = loop.store || {}; })); }, - /** * Maps and sorts the raw room list received from the mozLoop API. * @@ -267,7 +268,7 @@ loop.store = loop.store || {}; this._mozLoop.rooms.create(roomCreationData, function(err) { this.setStoreState({pendingCreation: false}); if (err) { - this._dispatchAction(new sharedActions.CreateRoomError({error: err})); + this._dispatchAction(new sharedActions.CreateRoomError({error: err})); } }.bind(this)); }, @@ -284,6 +285,28 @@ loop.store = loop.store || {}; }); }, + /** + * Creates a new room. + * + * @param {sharedActions.DeleteRoom} actionData The action data. + */ + deleteRoom: function(actionData) { + this._mozLoop.rooms.delete(actionData.roomToken, function(err) { + if (err) { + this._dispatchAction(new sharedActions.DeleteRoomError({error: err})); + } + }.bind(this)); + }, + + /** + * Executed when a room deletion error occurs. + * + * @param {sharedActions.DeleteRoomError} actionData The action data. + */ + deleteRoomError: function(actionData) { + this.setStoreState({error: actionData.error}); + }, + /** * Gather the list of all available rooms from the MozLoop API. */ diff --git a/browser/components/loop/jar.mn b/browser/components/loop/jar.mn index 8e70b628b27d..d7b8046428c2 100644 --- a/browser/components/loop/jar.mn +++ b/browser/components/loop/jar.mn @@ -49,8 +49,6 @@ browser.jar: content/browser/loop/shared/img/svg/glyph-account-16x16.svg (content/shared/img/svg/glyph-account-16x16.svg) content/browser/loop/shared/img/svg/glyph-signin-16x16.svg (content/shared/img/svg/glyph-signin-16x16.svg) content/browser/loop/shared/img/svg/glyph-signout-16x16.svg (content/shared/img/svg/glyph-signout-16x16.svg) - content/browser/loop/shared/img/svg/copy-16x16.svg (content/shared/img/svg/copy-16x16.svg) - content/browser/loop/shared/img/svg/checkmark-16x16.svg (content/shared/img/svg/checkmark-16x16.svg) content/browser/loop/shared/img/audio-call-avatar.svg (content/shared/img/audio-call-avatar.svg) content/browser/loop/shared/img/beta-ribbon.svg (content/shared/img/beta-ribbon.svg) content/browser/loop/shared/img/icons-10x10.svg (content/shared/img/icons-10x10.svg) diff --git a/browser/components/loop/test/desktop-local/panel_test.js b/browser/components/loop/test/desktop-local/panel_test.js index 134cea6954eb..007a373c3625 100644 --- a/browser/components/loop/test/desktop-local/panel_test.js +++ b/browser/components/loop/test/desktop-local/panel_test.js @@ -639,7 +639,7 @@ describe("loop.panel", function() { }); describe("loop.panel.RoomEntry", function() { - var buttonNode, roomData, roomEntry, roomStore, dispatcher; + var dispatcher, roomData; beforeEach(function() { dispatcher = new loop.Dispatcher(); @@ -656,52 +656,104 @@ describe("loop.panel", function() { ], ctime: 1405517418 }; - roomStore = new loop.store.Room(roomData); - roomEntry = mountRoomEntry(); - buttonNode = roomEntry.getDOMNode().querySelector("button.copy-link"); }); - function mountRoomEntry() { - return TestUtils.renderIntoDocument(loop.panel.RoomEntry({ - openRoom: sandbox.stub(), - room: roomStore - })); + function mountRoomEntry(props) { + return TestUtils.renderIntoDocument(loop.panel.RoomEntry(props)); } - it("should not display copy-link button by default", function() { - expect(buttonNode).to.not.equal(null); - }); + describe("Copy button", function() { + var roomEntry, copyButton; - it("should copy the URL when the click event fires", function() { - TestUtils.Simulate.click(buttonNode); - - sinon.assert.calledOnce(navigator.mozLoop.copyString); - sinon.assert.calledWithExactly(navigator.mozLoop.copyString, - roomData.roomUrl); - }); - - it("should set state.urlCopied when the click event fires", function() { - TestUtils.Simulate.click(buttonNode); - - expect(roomEntry.state.urlCopied).to.equal(true); - }); - - it("should switch to displaying a check icon when the URL has been copied", - function() { - TestUtils.Simulate.click(buttonNode); - - expect(buttonNode.classList.contains("checked")).eql(true); + beforeEach(function() { + roomEntry = mountRoomEntry({ + dispatcher: dispatcher, + deleteRoom: sandbox.stub(), + room: new loop.store.Room(roomData) + }); + copyButton = roomEntry.getDOMNode().querySelector("button.copy-link"); }); - it("should not display a check icon after mouse leaves the entry", - function() { - var roomNode = roomEntry.getDOMNode(); - TestUtils.Simulate.click(buttonNode); - - TestUtils.SimulateNative.mouseOut(roomNode); - - expect(buttonNode.classList.contains("checked")).eql(false); + it("should not display a copy button by default", function() { + expect(copyButton).to.not.equal(null); }); + + it("should copy the URL when the click event fires", function() { + TestUtils.Simulate.click(copyButton); + + sinon.assert.calledOnce(navigator.mozLoop.copyString); + sinon.assert.calledWithExactly(navigator.mozLoop.copyString, + roomData.roomUrl); + }); + + it("should set state.urlCopied when the click event fires", function() { + TestUtils.Simulate.click(copyButton); + + expect(roomEntry.state.urlCopied).to.equal(true); + }); + + it("should switch to displaying a check icon when the URL has been copied", + function() { + TestUtils.Simulate.click(copyButton); + + expect(copyButton.classList.contains("checked")).eql(true); + }); + + it("should not display a check icon after mouse leaves the entry", + function() { + var roomNode = roomEntry.getDOMNode(); + TestUtils.Simulate.click(copyButton); + + TestUtils.SimulateNative.mouseOut(roomNode); + + expect(copyButton.classList.contains("checked")).eql(false); + }); + }); + + describe("Delete button click", function() { + var roomEntry, deleteButton; + + beforeEach(function() { + roomEntry = mountRoomEntry({ + dispatcher: dispatcher, + room: new loop.store.Room(roomData) + }); + deleteButton = roomEntry.getDOMNode().querySelector("button.delete-link"); + }); + + it("should not display a delete button by default", function() { + expect(deleteButton).to.not.equal(null); + }); + + it("should call the delete function when clicked", function() { + sandbox.stub(dispatcher, "dispatch"); + + TestUtils.Simulate.click(deleteButton); + + sinon.assert.calledOnce(dispatcher.dispatch); + sinon.assert.calledWithExactly(dispatcher.dispatch, + new sharedActions.DeleteRoom({roomToken: roomData.roomToken})); + }); + }); + + describe("Room URL click", function() { + var roomEntry; + + it("should dispatch an OpenRoom action", function() { + sandbox.stub(dispatcher, "dispatch"); + roomEntry = mountRoomEntry({ + dispatcher: dispatcher, + room: new loop.store.Room(roomData) + }); + var urlLink = roomEntry.getDOMNode().querySelector("p > a"); + + TestUtils.Simulate.click(urlLink); + + sinon.assert.calledOnce(dispatcher.dispatch); + sinon.assert.calledWithExactly(dispatcher.dispatch, + new sharedActions.OpenRoom({roomToken: roomData.roomToken})); + }); + }); }); describe("loop.panel.RoomList", function() { @@ -775,20 +827,6 @@ describe("loop.panel", function() { var buttonNode = view.getDOMNode().querySelector("button[disabled]"); expect(buttonNode).to.not.equal(null); }); - - describe("#openRoom", function() { - it("should dispatch an OpenRoom action", function() { - var view = createTestComponent(); - var dispatch = sandbox.stub(dispatcher, "dispatch"); - - view.openRoom({roomToken: "42cba"}); - - sinon.assert.calledOnce(dispatch); - sinon.assert.calledWithExactly(dispatch, new sharedActions.OpenRoom({ - roomToken: "42cba" - })); - }); - }); }); describe('loop.panel.ToSView', function() { diff --git a/browser/components/loop/test/shared/roomListStore_test.js b/browser/components/loop/test/shared/roomListStore_test.js index 9d3db3005b16..a5a9fb690ce5 100644 --- a/browser/components/loop/test/shared/roomListStore_test.js +++ b/browser/components/loop/test/shared/roomListStore_test.js @@ -135,9 +135,9 @@ describe("loop.store.RoomListStore", function () { }); }); - describe("remove", function() { - it("should remove a room from the list", function() { - fakeMozLoop.rooms.trigger("remove", "remove", { + describe("delete", function() { + it("should delete a room from the list", function() { + fakeMozLoop.rooms.trigger("delete", "delete", { roomToken: "_nxD4V4FflQ" }); diff --git a/browser/components/loop/test/xpcshell/test_looprooms.js b/browser/components/loop/test/xpcshell/test_looprooms.js index de3003af5110..f221595b4305 100644 --- a/browser/components/loop/test/xpcshell/test_looprooms.js +++ b/browser/components/loop/test/xpcshell/test_looprooms.js @@ -262,6 +262,15 @@ add_task(function* test_createRoom() { compareRooms(room, kCreateRoomProps); }); +// Test if deleting a room works as expected. +add_task(function* test_deleteRoom() { + let roomToken = "QzBbvGmIZWU"; + let deletedRoom = yield LoopRooms.promise("delete", roomToken); + Assert.equal(deletedRoom.roomToken, roomToken); + let rooms = yield LoopRooms.promise("getAll"); + Assert.ok(!rooms.some((room) => room.roomToken == roomToken)); +}); + // Test if opening a new room window works correctly. add_task(function* test_openRoom() { let openedUrl; diff --git a/browser/components/loop/ui/ui-showcase.css b/browser/components/loop/ui/ui-showcase.css index 5d8abffa09a2..5f4a0ec1484b 100644 --- a/browser/components/loop/ui/ui-showcase.css +++ b/browser/components/loop/ui/ui-showcase.css @@ -162,3 +162,24 @@ /* Removes the fake video image for ended conversations */ background: none; } + +/* SVG icons showcase */ + +.svg-icon-entry { + width: 180px; + float: left; +} + +.svg-icon-entry > p { + float: left; + margin-right: .5rem; +} + +.svg-icon { + display: inline-block; + width: 16px; + height: 16px; + background-repeat: no-repeat; + background-size: 16px 16px; + background-position: center; +} diff --git a/browser/components/loop/ui/ui-showcase.js b/browser/components/loop/ui/ui-showcase.js index d3094b981f8e..d0cd1dfd11cc 100644 --- a/browser/components/loop/ui/ui-showcase.js +++ b/browser/components/loop/ui/ui-showcase.js @@ -101,6 +101,41 @@ detailsButtonLabel: "Retry", }); + var SVGIcon = React.createClass({displayName: 'SVGIcon', + render: function() { + return ( + React.DOM.span({className: "svg-icon", style: { + "background-image": "url(/content/shared/img/icons-16x16.svg#" + this.props.shapeId + ")" + }}) + ); + } + }); + + var SVGIcons = React.createClass({displayName: 'SVGIcons', + shapes: [ + "audio", "audio-hover", "audio-active", "block", + "block-red", "block-hover", "block-active", "contacts", "contacts-hover", + "contacts-active", "copy", "checkmark", "google", "google-hover", + "google-active", "history", "history-hover", "history-active", + "precall", "precall-hover", "precall-active", "settings", "settings-hover", + "settings-active", "tag", "tag-hover", "tag-active", "trash", "unblock", + "unblock-hover", "unblock-active", "video", "video-hover", "video-active" + ], + + render: function() { + return ( + React.DOM.div({className: "svg-icon-list"}, + this.shapes.map(function(shapeId, i) { + return React.DOM.div({className: "svg-icon-entry"}, + React.DOM.p(null, SVGIcon({key: i, shapeId: shapeId})), + React.DOM.p(null, shapeId) + ); + }, this) + ) + ); + } + }); + var Example = React.createClass({displayName: 'Example', makeId: function(prefix) { return (prefix || "") + this.props.summary.toLowerCase().replace(/\s/g, "-"); @@ -490,6 +525,12 @@ UnsupportedDeviceView(null) ) ) + ), + + Section({name: "SVG icons preview"}, + Example({summary: "16x16"}, + SVGIcons(null) + ) ) ) diff --git a/browser/components/loop/ui/ui-showcase.jsx b/browser/components/loop/ui/ui-showcase.jsx index 6fda09c81c14..030254c4e0b3 100644 --- a/browser/components/loop/ui/ui-showcase.jsx +++ b/browser/components/loop/ui/ui-showcase.jsx @@ -101,6 +101,41 @@ detailsButtonLabel: "Retry", }); + var SVGIcon = React.createClass({ + render: function() { + return ( + + ); + } + }); + + var SVGIcons = React.createClass({ + shapes: [ + "audio", "audio-hover", "audio-active", "block", + "block-red", "block-hover", "block-active", "contacts", "contacts-hover", + "contacts-active", "copy", "checkmark", "google", "google-hover", + "google-active", "history", "history-hover", "history-active", + "precall", "precall-hover", "precall-active", "settings", "settings-hover", + "settings-active", "tag", "tag-hover", "tag-active", "trash", "unblock", + "unblock-hover", "unblock-active", "video", "video-hover", "video-active" + ], + + render: function() { + return ( +

{ + this.shapes.map(function(shapeId, i) { + return
+

+

{shapeId}

+
; + }, this) + }
+ ); + } + }); + var Example = React.createClass({ makeId: function(prefix) { return (prefix || "") + this.props.summary.toLowerCase().replace(/\s/g, "-"); @@ -492,6 +527,12 @@ +
+ + + +
+ ); } diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index 7cbeb3b8c7df..125354ff90a7 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -856,11 +856,7 @@ bin/libfreebl_32int64_3.so #ifdef XP_WIN @BINPATH@/webapp-uninstaller@BIN_SUFFIX@ #endif -#ifdef XP_MACOSX -@APPNAME@/Contents/MacOS/webapprt-stub@BIN_SUFFIX@ -#else @BINPATH@/webapprt-stub@BIN_SUFFIX@ -#endif @BINPATH@/webapprt/webapprt.ini @BINPATH@/webapprt/chrome.manifest @BINPATH@/webapprt/chrome/webapprt@JAREXT@ diff --git a/build/win32/mozconfig.vs2013-win64 b/build/win32/mozconfig.vs2013-win64 index d62635f3e973..0adf6cc05e67 100644 --- a/build/win32/mozconfig.vs2013-win64 +++ b/build/win32/mozconfig.vs2013-win64 @@ -4,18 +4,18 @@ export WIN32_REDIST_DIR=${_VSPATH}/VC/redist/x86/Microsoft.VC120.CRT ## moz tools location for 64-bit builders ## export MOZ_TOOLS=C:/mozilla-build/moztools -## includes: win8 sdk includes, winrt headers for metro, msvc std library, directx sdk for d3d9 ## -export INCLUDE=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/shared:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/um:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt/wrl:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt/wrl/wrappers:${_VSPATH}/vc/include:${_VSPATH}/vc/atlmfc/include:/c/tools/sdks/dx10/include +## includes: win8.1 sdk includes, winrt headers for metro, msvc std library, directx sdk for d3d9 ## +export INCLUDE=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/shared:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/um:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/winrt:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/winrt/wrl:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/winrt/wrl/wrappers:${_VSPATH}/vc/include:${_VSPATH}/vc/atlmfc/include:/c/tools/sdks/dx10/include -## libs: win8 sdk x86 (32-bit) libs, msvc (32-bit) std library, msvc atl libs, directx sdk (32-bit) for d3d9 ## -export LIBPATH=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x86:${_VSPATH}/vc/lib:${_VSPATH}/vc/atlmfc/lib:/c/tools/sdks/dx10/lib -export LIB=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x86:${_VSPATH}/vc/lib:${_VSPATH}/vc/atlmfc/lib:/c/tools/sdks/dx10/lib +## libs: win8.1 sdk x86 (32-bit) libs, msvc (32-bit) std library, msvc atl libs, directx sdk (32-bit) for d3d9 ## +export LIBPATH=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/Lib/winv6.3/um/x86:${_VSPATH}/vc/lib:${_VSPATH}/vc/atlmfc/lib:/c/tools/sdks/dx10/lib +export LIB=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/Lib/winv6.3/um/x86:${_VSPATH}/vc/lib:${_VSPATH}/vc/atlmfc/lib:/c/tools/sdks/dx10/lib -## paths: win8 sdk x86 (32-bit) tools, msvc (64-bit compiling 32-bit) build toolchain, moz tools ## -export PATH="/c/Program Files (x86)/Windows Kits/8.0/bin/x86:${_VSPATH}/Common7/IDE:${_VSPATH}/VC/BIN/amd64_x86:${_VSPATH}/VC/BIN/amd64:${_VSPATH}/Common7/Tools:${_VSPATH}/VC/VCPackages:/c/mozilla-build/moztools:${PATH}" +## paths: win8.1 sdk x86 (32-bit) tools, msvc (64-bit compiling 32-bit) build toolchain, moz tools ## +export PATH="/c/Program Files (x86)/Windows Kits/8.1/bin/x86:${_VSPATH}/Common7/IDE:${_VSPATH}/VC/BIN/amd64_x86:${_VSPATH}/VC/BIN/amd64:${_VSPATH}/Common7/Tools:${_VSPATH}/VC/VCPackages:/c/mozilla-build/moztools:${PATH}" ## WindowsSDKDir ## -export WINDOWSSDKDIR="/c/Program Files (x86)/Windows Kits/8.0/" +export WINDOWSSDKDIR="/c/Program Files (x86)/Windows Kits/8.1/" . $topsrcdir/build/mozconfig.vs-common diff --git a/build/win64/mozconfig.vs2013 b/build/win64/mozconfig.vs2013 index f4d48fc81674..52fa311b0497 100644 --- a/build/win64/mozconfig.vs2013 +++ b/build/win64/mozconfig.vs2013 @@ -1,18 +1,18 @@ _VSPATH="/c/tools/vs2013" export WIN32_REDIST_DIR=${_VSPATH}/VC/redist/x64/Microsoft.VC120.CRT -## includes: win8 sdk includes, winrt headers for metro, msvc 10 std library, directx sdk for d3d9 ## -export INCLUDE=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/shared:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/um:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt/wrl:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt/wrl/wrappers:${_VSPATH}/vc/include:${_VSPATH}/vc/atlmfc/include:/c/tools/sdks/dx10/include +## includes: win8.1 sdk includes, winrt headers for metro, msvc std library, directx sdk for d3d9 ## +export INCLUDE=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/shared:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/um:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/winrt:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/winrt/wrl:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/winrt/wrl/wrappers:${_VSPATH}/vc/include:${_VSPATH}/vc/atlmfc/include:/c/tools/sdks/dx10/include -## libs: win8 sdk x64 (64-bit) libs, msvc 10 (64-bit) std library, msvc 10 atl libs, directx sdk (64-bit) for d3d9 ## -export LIBPATH=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x64:${_VSPATH}/vc/lib/amd64:${_VSPATH}/vc/atlmfc/lib/amd64:/c/tools/sdks/dx10/lib/x64 -export LIB=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x64:${_VSPATH}/vc/lib/amd64:${_VSPATH}/vc/atlmfc/lib/amd64:/c/tools/sdks/dx10/lib/x64 +## libs: win8.1 sdk x64 (64-bit) libs, msvc (64-bit) std library, msvc atl libs, directx sdk (64-bit) for d3d9 ## +export LIBPATH=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/Lib/winv6.3/um/x64:${_VSPATH}/vc/lib/amd64:${_VSPATH}/vc/atlmfc/lib/amd64:/c/tools/sdks/dx10/lib/x64 +export LIB=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/Lib/winv6.3/um/x64:${_VSPATH}/vc/lib/amd64:${_VSPATH}/vc/atlmfc/lib/amd64:/c/tools/sdks/dx10/lib/x64 -## paths: win8 sdk x64 (64-bit) tools, msvc 10 (64-bit) build toolchain, moz tools ## -export PATH="/c/Program Files (x86)/Windows Kits/8.0/bin/x64:${_VSPATH}/Common7/IDE:${_VSPATH}/VC/BIN/amd64:${_VSPATH}/VC/BIN/x86_amd64:${_VSPATH}/VC/BIN:${_VSPATH}/Common7/Tools:${_VSPATH}/VC/VCPackages:${PATH}" +## paths: win8.1 sdk x64 (64-bit) tools, msvc (64-bit) build toolchain, moz tools ## +export PATH="/c/Program Files (x86)/Windows Kits/8.1/bin/x64:${_VSPATH}/Common7/IDE:${_VSPATH}/VC/BIN/amd64:${_VSPATH}/VC/BIN/x86_amd64:${_VSPATH}/VC/BIN:${_VSPATH}/Common7/Tools:${_VSPATH}/VC/VCPackages:${PATH}" ## WindowsSDKDir ## -export WINDOWSSDKDIR="/c/Program Files (x86)/Windows Kits/8.0/" +export WINDOWSSDKDIR="/c/Program Files (x86)/Windows Kits/8.1/" . $topsrcdir/build/mozconfig.vs-common diff --git a/docshell/test/navigation/mochitest.ini b/docshell/test/navigation/mochitest.ini index b7514ba66cbe..ad906f146aae 100644 --- a/docshell/test/navigation/mochitest.ini +++ b/docshell/test/navigation/mochitest.ini @@ -44,7 +44,7 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop spec [test_popup-navigates-children.html] skip-if = buildapp == 'b2g' # b2g(Needs multiple window.open support, also uses docshelltreenode) b2g-debug(Needs multiple window.open support, also uses docshelltreenode) b2g-desktop(Needs multiple window.open support, also uses docshelltreenode) [test_reserved.html] -skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) +skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) || android_version == '10' #too slow on Android 2.3 aws only; bug 1030403 [test_sessionhistory.html] skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) || toolkit == 'android' #RANDOM # b2g-debug(Perma-orange on debug emulator builds) b2g-desktop(Bug 931116, b2g desktop specific, initial triage) [test_sibling-matching-parent.html] diff --git a/dom/canvas/test/webgl-mochitest.ini b/dom/canvas/test/webgl-mochitest.ini index ece220bbd5ef..a48356ab0a69 100644 --- a/dom/canvas/test/webgl-mochitest.ini +++ b/dom/canvas/test/webgl-mochitest.ini @@ -11,6 +11,7 @@ support-files = [webgl-mochitest/test_fb_param_crash.html] [webgl-mochitest/test_highp_fs.html] [webgl-mochitest/test_no_arr_points.html] +skip-if = android_version == '10' #Android 2.3 aws only; bug 1030942 [webgl-mochitest/test_noprog_draw.html] [webgl-mochitest/test_privileged_exts.html] [webgl-mochitest/test_texsubimage_float.html] diff --git a/dom/html/test/mochitest.ini b/dom/html/test/mochitest.ini index 69c55e93fe7d..4384aaec9ae1 100644 --- a/dom/html/test/mochitest.ini +++ b/dom/html/test/mochitest.ini @@ -395,7 +395,7 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop spec [test_bug658746.html] [test_bug659596.html] [test_bug659743.xml] -skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage +skip-if = (buildapp == 'b2g' && toolkit != 'gonk') || android_version == '10' #Bug 931116, b2g desktop specific, initial triage #Android 2.3 aws only; bug 1031103 [test_bug660663.html] [test_bug660959-1.html] [test_bug660959-2.html] diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index bf7e4cd900ca..40990de58979 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -1907,6 +1907,17 @@ ContentChild::RecvGeolocationUpdate(const GeoPosition& somewhere) return true; } +bool +ContentChild::RecvGeolocationError(const uint16_t& errorCode) +{ + nsCOMPtr gs = do_GetService("@mozilla.org/geolocation/service;1"); + if (!gs) { + return true; + } + gs->NotifyError(errorCode); + return true; +} + bool ContentChild::RecvUpdateDictionaryList(const InfallibleTArray& aDictionaries) { diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index 60ec6598ea77..20a5d3e279aa 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -305,6 +305,8 @@ public: virtual bool RecvGeolocationUpdate(const GeoPosition& somewhere) MOZ_OVERRIDE; + virtual bool RecvGeolocationError(const uint16_t& errorCode) MOZ_OVERRIDE; + virtual bool RecvUpdateDictionaryList(const InfallibleTArray& aDictionaries) MOZ_OVERRIDE; virtual bool RecvAddPermission(const IPC::Permission& permission) MOZ_OVERRIDE; diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 128cfe9dd20d..8050f60c8545 100755 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -93,6 +93,7 @@ #include "nsICycleCollectorListener.h" #include "nsIDocument.h" #include "nsIDOMGeoGeolocation.h" +#include "nsIDOMGeoPositionError.h" #include "mozilla/dom/WakeLock.h" #include "nsIDOMWindow.h" #include "nsIExternalProtocolService.h" @@ -2590,6 +2591,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ContentParent) NS_INTERFACE_MAP_ENTRY(nsIContentParent) NS_INTERFACE_MAP_ENTRY(nsIObserver) NS_INTERFACE_MAP_ENTRY(nsIDOMGeoPositionCallback) + NS_INTERFACE_MAP_ENTRY(nsIDOMGeoPositionErrorCallback) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver) NS_INTERFACE_MAP_END @@ -3689,7 +3691,7 @@ ContentParent::RecvFilePathUpdateNotify(const nsString& aType, } static int32_t -AddGeolocationListener(nsIDOMGeoPositionCallback* watcher, bool highAccuracy) +AddGeolocationListener(nsIDOMGeoPositionCallback* watcher, nsIDOMGeoPositionErrorCallback* errorCallBack, bool highAccuracy) { nsCOMPtr geo = do_GetService("@mozilla.org/geolocation;1"); if (!geo) { @@ -3701,7 +3703,7 @@ AddGeolocationListener(nsIDOMGeoPositionCallback* watcher, bool highAccuracy) options->mMaximumAge = 0; options->mEnableHighAccuracy = highAccuracy; int32_t retval = 1; - geo->WatchPosition(watcher, nullptr, options, &retval); + geo->WatchPosition(watcher, errorCallBack, options, &retval); return retval; } @@ -3722,7 +3724,7 @@ ContentParent::RecvAddGeolocationListener(const IPC::Principal& aPrincipal, // To ensure no geolocation updates are skipped, we always force the // creation of a new listener. RecvRemoveGeolocationListener(); - mGeolocationWatchID = AddGeolocationListener(this, aHighAccuracy); + mGeolocationWatchID = AddGeolocationListener(this, this, aHighAccuracy); return true; } @@ -3747,7 +3749,7 @@ ContentParent::RecvSetGeolocationHigherAccuracy(const bool& aEnable) // so this check allows us to forgo securing privileges. if (mGeolocationWatchID != -1) { RecvRemoveGeolocationListener(); - mGeolocationWatchID = AddGeolocationListener(this, aEnable); + mGeolocationWatchID = AddGeolocationListener(this, this, aEnable); } return true; } @@ -3759,6 +3761,17 @@ ContentParent::HandleEvent(nsIDOMGeoPosition* postion) return NS_OK; } +NS_IMETHODIMP +ContentParent::HandleEvent(nsIDOMGeoPositionError* postionError) +{ + int16_t errorCode; + nsresult rv; + rv = postionError->GetCode(&errorCode); + NS_ENSURE_SUCCESS(rv,rv); + unused << SendGeolocationError(errorCode); + return NS_OK; +} + nsConsoleService * ContentParent::GetConsoleService() { diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index fc96b196fc07..5ab32d06ffe6 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -22,6 +22,7 @@ #include "nsIObserver.h" #include "nsIThreadInternal.h" #include "nsIDOMGeoPositionCallback.h" +#include "nsIDOMGeoPositionErrorCallback.h" #include "PermissionMessageUtils.h" #define CHILD_PROCESS_SHUTDOWN_MESSAGE NS_LITERAL_STRING("child-process-shutdown") @@ -68,6 +69,7 @@ class ContentParent MOZ_FINAL : public PContentParent , public nsIContentParent , public nsIObserver , public nsIDOMGeoPositionCallback + , public nsIDOMGeoPositionErrorCallback , public mozilla::LinkedListElement { typedef mozilla::ipc::GeckoChildProcessHost GeckoChildProcessHost; @@ -160,6 +162,7 @@ public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_NSIOBSERVER NS_DECL_NSIDOMGEOPOSITIONCALLBACK + NS_DECL_NSIDOMGEOPOSITIONERRORCALLBACK /** * MessageManagerCallback methods that we override. diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index ed1ada4546d6..e9945b39cdb6 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -449,6 +449,8 @@ child: GeolocationUpdate(GeoPosition somewhere); + GeolocationError(uint16_t errorCode); + UpdateDictionaryList(nsString[] dictionaries); // nsIPermissionManager messages diff --git a/dom/media/tests/mochitest/mochitest.ini b/dom/media/tests/mochitest/mochitest.ini index 09870566e1a0..0cc509376c34 100644 --- a/dom/media/tests/mochitest/mochitest.ini +++ b/dom/media/tests/mochitest/mochitest.ini @@ -1,5 +1,5 @@ [DEFAULT] -skip-if = (os == 'win' && contentSandbox != 'off') # contentSandbox(Bug 1042735) +skip-if = (os == 'win' && contentSandbox != 'off') || android_version == '10' # contentSandbox(Bug 1042735) #Android 2.3 only; bug 981881 support-files = head.js constraints.js diff --git a/dom/permission/tests/mochitest-bt.ini b/dom/permission/tests/mochitest-bt.ini index a4b6389d370c..f0a61bf2cace 100644 --- a/dom/permission/tests/mochitest-bt.ini +++ b/dom/permission/tests/mochitest-bt.ini @@ -1 +1,2 @@ [test_bluetooth.html] +skip-if = (toolkit == 'gonk' && debug) # bug 1093079 diff --git a/dom/tests/unit/test_geolocation_position_unavailable.js b/dom/tests/unit/test_geolocation_position_unavailable.js new file mode 100644 index 000000000000..77c1d4717202 --- /dev/null +++ b/dom/tests/unit/test_geolocation_position_unavailable.js @@ -0,0 +1,36 @@ +const Cc = Components.classes; +const Ci = Components.interfaces; +const Cu = Components.utils; +const Cr = Components.results; + + +function successCallback() { + do_check_true(false); + do_test_finished(); +} + +function errorCallback(err) { + do_check_eq(Ci.nsIDOMGeoPositionError.POSITION_UNAVAILABLE, err.code); + do_test_finished(); +} + +function run_test() +{ + do_test_pending(); + + if (Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime) + .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT) { + // XPCShell does not get a profile by default. The geolocation service + // depends on the settings service which uses IndexedDB and IndexedDB + // needs a place where it can store databases. + do_get_profile(); + + var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); + prefs.setBoolPref("geo.wifi.scan", false); + prefs.setCharPref("geo.wifi.uri", "UrlNotUsedHere:"); + prefs.setBoolPref("dom.testing.ignore_ipc_principal", true); + } + + geolocation = Cc["@mozilla.org/geolocation;1"].getService(Ci.nsISupports); + geolocation.getCurrentPosition(successCallback, errorCallback); +} diff --git a/dom/tests/unit/test_geolocation_position_unavailable_wrap.js b/dom/tests/unit/test_geolocation_position_unavailable_wrap.js new file mode 100644 index 000000000000..585c7511a791 --- /dev/null +++ b/dom/tests/unit/test_geolocation_position_unavailable_wrap.js @@ -0,0 +1,13 @@ +const Cc = Components.classes; +const Ci = Components.interfaces; +const Cu = Components.utils; + + +function run_test() { + var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); + prefs.setBoolPref("geo.wifi.scan", false); + + prefs.setCharPref("geo.wifi.uri", "UrlNotUsedHere"); + prefs.setBoolPref("dom.testing.ignore_ipc_principal", true); + run_test_in_child("./test_geolocation_position_unavailable.js"); +} diff --git a/dom/tests/unit/xpcshell.ini b/dom/tests/unit/xpcshell.ini index 4db9a9eb71b3..5eed85620e63 100644 --- a/dom/tests/unit/xpcshell.ini +++ b/dom/tests/unit/xpcshell.ini @@ -18,4 +18,8 @@ skip-if = os == "mac" || os == "android" skip-if = os == "android" [test_geolocation_reset_accuracy_wrap.js] skip-if = os == "mac" || os == "android" +[test_geolocation_position_unavailable.js] +skip-if = os == "android" +[test_geolocation_position_unavailable_wrap.js] +skip-if = os == "mac" || os == "android" [test_PromiseDebugging.js] diff --git a/ipc/glue/MessageChannel.cpp b/ipc/glue/MessageChannel.cpp index 2703f8411626..579a1809489c 100644 --- a/ipc/glue/MessageChannel.cpp +++ b/ipc/glue/MessageChannel.cpp @@ -747,7 +747,7 @@ MessageChannel::SendAndWait(Message* aMsg, Message* aReply) MOZ_ASSERT(mRecvd->type() == replyType, "wrong reply type"); MOZ_ASSERT(mRecvd->seqno() == replySeqno); - *aReply = *mRecvd; + *aReply = Move(*mRecvd); mRecvd = nullptr; return true; } @@ -838,10 +838,10 @@ MessageChannel::Call(Message* aMsg, Message* aReply) if ((it = mOutOfTurnReplies.find(mInterruptStack.top().seqno())) != mOutOfTurnReplies.end()) { - recvd = it->second; + recvd = Move(it->second); mOutOfTurnReplies.erase(it); } else if (!mPending.empty()) { - recvd = mPending.front(); + recvd = Move(mPending.front()); mPending.pop_front(); } else { // because of subtleties with nested event loops, it's possible @@ -882,7 +882,7 @@ MessageChannel::Call(Message* aMsg, Message* aReply) if ((mSide == ChildSide && recvd.seqno() > outcall.seqno()) || (mSide != ChildSide && recvd.seqno() < outcall.seqno())) { - mOutOfTurnReplies[recvd.seqno()] = recvd; + mOutOfTurnReplies[recvd.seqno()] = Move(recvd); continue; } @@ -896,8 +896,9 @@ MessageChannel::Call(Message* aMsg, Message* aReply) // this frame and return the reply. mInterruptStack.pop(); - if (!recvd.is_reply_error()) { - *aReply = recvd; + bool is_reply_error = recvd.is_reply_error(); + if (!is_reply_error) { + *aReply = Move(recvd); } // If we have no more pending out calls waiting on replies, then @@ -906,7 +907,7 @@ MessageChannel::Call(Message* aMsg, Message* aReply) "still have pending replies with no pending out-calls", true); - return !recvd.is_reply_error(); + return !is_reply_error; } // Dispatch an Interrupt in-call. Snapshot the current stack depth while we @@ -1017,7 +1018,7 @@ MessageChannel::OnMaybeDequeueOne() if (IsOnCxxStack() && recvd.is_interrupt() && recvd.is_reply()) { // We probably just received a reply in a nested loop for an // Interrupt call sent before entering that loop. - mOutOfTurnReplies[recvd.seqno()] = recvd; + mOutOfTurnReplies[recvd.seqno()] = Move(recvd); return false; } diff --git a/layout/style/test/mochitest.ini b/layout/style/test/mochitest.ini index 50d950977216..8d669e1ed44f 100644 --- a/layout/style/test/mochitest.ini +++ b/layout/style/test/mochitest.ini @@ -157,7 +157,7 @@ skip-if = toolkit == 'android' [test_initial_storage.html] [test_keyframes_rules.html] [test_media_queries.html] -skip-if = (toolkit == 'gonk' && debug) #debug-only failure; timed out +skip-if = (toolkit == 'gonk' && debug) || android_version == '10' #debug-only failure; timed out #Android 2.3 aws only; bug 1030419 [test_media_queries_dynamic.html] [test_media_queries_dynamic_xbl.html] [test_media_query_list.html] @@ -170,7 +170,6 @@ skip-if = (toolkit == 'gonk' && debug) #debug-only failure; timed out [test_parse_url.html] [test_parser_diagnostics_unprintables.html] [test_pixel_lengths.html] -skip-if = true # bug 891840 - intermittent crashes [test_pointer-events.html] [test_position_sticky.html] support-files = file_position_sticky.html @@ -201,6 +200,7 @@ skip-if = (toolkit == 'gonk' && debug) || toolkit == 'android' #bug 775227 #debu [test_transitions_and_restyles.html] [test_transitions_and_zoom.html] [test_transitions_cancel_near_end.html] +skip-if = android_version == '10' #Android 2.3 aws only; bug 1030432 [test_transitions_computed_values.html] [test_transitions_computed_value_combinations.html] [test_transitions_events.html] diff --git a/security/pkix/lib/pkixcert.cpp b/security/pkix/lib/pkixcert.cpp index 1ce0dbf595f7..73a7eca99715 100644 --- a/security/pkix/lib/pkixcert.cpp +++ b/security/pkix/lib/pkixcert.cpp @@ -222,6 +222,10 @@ BackCert::RememberExtension(Reader& extnID, const Input& extnValue, static const uint8_t id_pe_authorityInfoAccess[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01 }; + // python DottedOIDToCode.py id-pkix-ocsp-nocheck 1.3.6.1.5.5.7.48.1.5 + static const uint8_t id_pkix_ocsp_nocheck[] = { + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x05 + }; // python DottedOIDToCode.py Netscape-certificate-type 2.16.840.1.113730.1.1 static const uint8_t Netscape_certificate_type[] = { 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01 @@ -237,6 +241,17 @@ BackCert::RememberExtension(Reader& extnID, const Input& extnValue, // ignore the extension. Input dummyPolicyConstraints; + // We don't need to save the contents of this extension if it is present. We + // just need to handle its presence (it is essentially ignored right now). + Input dummyOCSPNocheck; + + // For compatibility reasons, for some extensions we have to allow empty + // extension values. This would normally interfere with our duplicate + // extension checking code. However, as long as the extensions we allow to + // have empty values are also the ones we implicitly allow duplicates of, + // this will work fine. + bool emptyValueAllowed = false; + // RFC says "Conforming CAs MUST mark this extension as non-critical" for // both authorityKeyIdentifier and subjectKeyIdentifier, and we do not use // them for anything, so we totally ignore them here. @@ -259,6 +274,17 @@ BackCert::RememberExtension(Reader& extnID, const Input& extnValue, out = &inhibitAnyPolicy; } else if (extnID.MatchRest(id_pe_authorityInfoAccess)) { out = &authorityInfoAccess; + } else if (extnID.MatchRest(id_pkix_ocsp_nocheck) && critical) { + // We need to make sure we don't reject delegated OCSP response signing + // certificates that contain the id-pkix-ocsp-nocheck extension marked as + // critical when validating OCSP responses. Without this, an application + // that implements soft-fail OCSP might ignore a valid Revoked or Unknown + // response, and an application that implements hard-fail OCSP might fail + // to connect to a server given a valid Good response. + out = &dummyOCSPNocheck; + // We allow this extension to have an empty value. + // See http://comments.gmane.org/gmane.ietf.x509/30947 + emptyValueAllowed = true; } else if (extnID.MatchRest(Netscape_certificate_type) && critical) { out = &criticalNetscapeCertificateType; } @@ -266,7 +292,7 @@ BackCert::RememberExtension(Reader& extnID, const Input& extnValue, if (out) { // Don't allow an empty value for any extension we understand. This way, we // can test out->GetLength() != 0 or out->Init() to check for duplicates. - if (extnValue.GetLength() == 0) { + if (extnValue.GetLength() == 0 && !emptyValueAllowed) { return Result::ERROR_EXTENSION_VALUE_INVALID; } if (out->Init(extnValue) != Success) { diff --git a/security/pkix/test/gtest/pkixcert_extension_tests.cpp b/security/pkix/test/gtest/pkixcert_extension_tests.cpp index c32f584cb79e..ae3632021858 100644 --- a/security/pkix/test/gtest/pkixcert_extension_tests.cpp +++ b/security/pkix/test/gtest/pkixcert_extension_tests.cpp @@ -23,6 +23,7 @@ */ #include "pkix/pkix.h" +#include "pkixder.h" #include "pkixgtest.h" #include "pkixtestutil.h" @@ -107,7 +108,144 @@ private: } }; -class pkixcert_extension : public ::testing::Test +// python DottedOIDToCode.py --tlv unknownExtensionOID 1.3.6.1.4.1.13769.666.666.666.1.500.9.3 +static const uint8_t tlv_unknownExtensionOID[] = { + 0x06, 0x12, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xeb, 0x49, 0x85, 0x1a, 0x85, 0x1a, + 0x85, 0x1a, 0x01, 0x83, 0x74, 0x09, 0x03 +}; + +// python DottedOIDToCode.py --tlv id-pe-authorityInformationAccess 1.3.6.1.5.5.7.1.1 +static const uint8_t tlv_id_pe_authorityInformationAccess[] = { + 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01 +}; + +// python DottedOIDToCode.py --tlv wrongExtensionOID 1.3.6.6.1.5.5.7.1.1 +// (there is an extra "6" that shouldn't be in this OID) +static const uint8_t tlv_wrongExtensionOID[] = { + 0x06, 0x09, 0x2b, 0x06, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01 +}; + +// python DottedOIDToCode.py --tlv id-ce-unknown 2.5.29.55 +// (this is a made-up OID for testing "id-ce"-prefixed OIDs that mozilla::pkix +// doesn't handle) +static const uint8_t tlv_id_ce_unknown[] = { + 0x06, 0x03, 0x55, 0x1d, 0x37 +}; + +// python DottedOIDToCode.py --tlv id-ce-inhibitAnyPolicy 2.5.29.54 +static const uint8_t tlv_id_ce_inhibitAnyPolicy[] = { + 0x06, 0x03, 0x55, 0x1d, 0x36 +}; + +// python DottedOIDToCode.py --tlv id-pkix-ocsp-nocheck 1.3.6.1.5.5.7.48.1.5 +static const uint8_t tlv_id_pkix_ocsp_nocheck[] = { + 0x06, 0x09, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x05 +}; + +template +inline ByteString +BytesToByteString(const uint8_t (&bytes)[L]) +{ + return ByteString(bytes, L); +} + +struct ExtensionTestcase +{ + ByteString extension; + Result expectedResult; +}; + +static const ExtensionTestcase EXTENSION_TESTCASES[] = +{ + // Tests that a non-critical extension not in the id-ce or id-pe arcs (which + // is thus unknown to us) verifies successfully even if empty (extensions we + // know about aren't normally allowed to be empty). + { TLV(der::SEQUENCE, + BytesToByteString(tlv_unknownExtensionOID) + + TLV(der::OCTET_STRING, ByteString())), + Success + }, + + // Tests that a critical extension not in the id-ce or id-pe arcs (which is + // thus unknown to us) is detected and that verification fails with the + // appropriate error. + { TLV(der::SEQUENCE, + BytesToByteString(tlv_unknownExtensionOID) + + Boolean(true) + + TLV(der::OCTET_STRING, ByteString())), + Result::ERROR_UNKNOWN_CRITICAL_EXTENSION + }, + + // Tests that a id-pe-authorityInformationAccess critical extension + // is detected and that verification succeeds. + // XXX: According to RFC 5280 an AIA that consists of an empty sequence is + // not legal, but we accept it and that is not what we're testing here. + { TLV(der::SEQUENCE, + BytesToByteString(tlv_id_pe_authorityInformationAccess) + + Boolean(true) + + TLV(der::OCTET_STRING, TLV(der::SEQUENCE, ByteString()))), + Success + }, + + // Tests that an incorrect OID for id-pe-authorityInformationAccess + // (when marked critical) is detected and that verification fails. + // (Until bug 1020993 was fixed, this wrong value was used for + // id-pe-authorityInformationAccess.) + { TLV(der::SEQUENCE, + BytesToByteString(tlv_wrongExtensionOID) + + Boolean(true) + + TLV(der::OCTET_STRING, ByteString())), + Result::ERROR_UNKNOWN_CRITICAL_EXTENSION + }, + + // We know about some id-ce extensions (OID arc 2.5.29), but not all of them. + // Tests that an unknown id-ce extension is detected and that verification + // fails. + { TLV(der::SEQUENCE, + BytesToByteString(tlv_id_ce_unknown) + + Boolean(true) + + TLV(der::OCTET_STRING, ByteString())), + Result::ERROR_UNKNOWN_CRITICAL_EXTENSION + }, + + // Tests that a certificate with a known critical id-ce extension (in this + // case, OID 2.5.29.54, which is id-ce-inhibitAnyPolicy), verifies + // successfully. + { TLV(der::SEQUENCE, + BytesToByteString(tlv_id_ce_inhibitAnyPolicy) + + Boolean(true) + + TLV(der::OCTET_STRING, Integer(0))), + Success + }, + + // Tests that a certificate with the id-pkix-ocsp-nocheck extension (marked + // critical) verifies successfully. + // RFC 6960: + // ext-ocsp-nocheck EXTENSION ::= { SYNTAX NULL IDENTIFIED + // BY id-pkix-ocsp-nocheck } + { TLV(der::SEQUENCE, + BytesToByteString(tlv_id_pkix_ocsp_nocheck) + + Boolean(true) + + TLV(der::OCTET_STRING, TLV(der::NULLTag, ByteString()))), + Success + }, + + // Tests that a certificate with another representation of the + // id-pkix-ocsp-nocheck extension (marked critical) verifies successfully. + // According to http://comments.gmane.org/gmane.ietf.x509/30947, + // some code creates certificates where value of the extension is + // an empty OCTET STRING. + { TLV(der::SEQUENCE, + BytesToByteString(tlv_id_pkix_ocsp_nocheck) + + Boolean(true) + + TLV(der::OCTET_STRING, ByteString())), + Success + }, +}; + +class pkixcert_extension + : public ::testing::Test + , public ::testing::WithParamInterface { protected: static TrustEverythingTrustDomain trustDomain; @@ -115,29 +253,15 @@ protected: /*static*/ TrustEverythingTrustDomain pkixcert_extension::trustDomain; -// Tests that a critical extension not in the id-ce or id-pe arcs (which is -// thus unknown to us) is detected and that verification fails with the -// appropriate error. -TEST_F(pkixcert_extension, UnknownCriticalExtension) +TEST_P(pkixcert_extension, ExtensionHandledProperly) { - static const uint8_t unknownCriticalExtensionBytes[] = { - 0x30, 0x19, // SEQUENCE (length = 25) - 0x06, 0x12, // OID (length = 18) - // 1.3.6.1.4.1.13769.666.666.666.1.500.9.3 - 0x2b, 0x06, 0x01, 0x04, 0x01, 0xeb, 0x49, 0x85, 0x1a, - 0x85, 0x1a, 0x85, 0x1a, 0x01, 0x83, 0x74, 0x09, 0x03, - 0x01, 0x01, 0xff, // BOOLEAN (length = 1) TRUE - 0x04, 0x00 // OCTET STRING (length = 0) - }; - static const ByteString - unknownCriticalExtension(unknownCriticalExtensionBytes, - sizeof(unknownCriticalExtensionBytes)); - const char* certCN = "Cert With Unknown Critical Extension"; - ByteString cert(CreateCertWithOneExtension(certCN, unknownCriticalExtension)); + const ExtensionTestcase& testcase(GetParam()); + const char* cn = "Cert Extension Test"; + ByteString cert(CreateCertWithOneExtension(cn, testcase.extension)); ASSERT_FALSE(ENCODING_FAILED(cert)); Input certInput; ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length())); - ASSERT_EQ(Result::ERROR_UNKNOWN_CRITICAL_EXTENSION, + ASSERT_EQ(testcase.expectedResult, BuildCertChain(trustDomain, certInput, Now(), EndEntityOrCA::MustBeEndEntity, KeyUsage::noParticularKeyUsageRequired, @@ -146,172 +270,24 @@ TEST_F(pkixcert_extension, UnknownCriticalExtension) nullptr/*stapledOCSPResponse*/)); } -// Tests that a non-critical extension not in the id-ce or id-pe arcs (which is -// thus unknown to us) verifies successfully. -TEST_F(pkixcert_extension, UnknownNonCriticalExtension) -{ - static const uint8_t unknownNonCriticalExtensionBytes[] = { - 0x30, 0x16, // SEQUENCE (length = 22) - 0x06, 0x12, // OID (length = 18) - // 1.3.6.1.4.1.13769.666.666.666.1.500.9.3 - 0x2b, 0x06, 0x01, 0x04, 0x01, 0xeb, 0x49, 0x85, 0x1a, - 0x85, 0x1a, 0x85, 0x1a, 0x01, 0x83, 0x74, 0x09, 0x03, - 0x04, 0x00 // OCTET STRING (length = 0) - }; - static const ByteString - unknownNonCriticalExtension(unknownNonCriticalExtensionBytes, - sizeof(unknownNonCriticalExtensionBytes)); - const char* certCN = "Cert With Unknown NonCritical Extension"; - ByteString cert(CreateCertWithOneExtension(certCN, - unknownNonCriticalExtension)); - ASSERT_FALSE(ENCODING_FAILED(cert)); - Input certInput; - ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length())); - ASSERT_EQ(Success, - BuildCertChain(trustDomain, certInput, Now(), - EndEntityOrCA::MustBeEndEntity, - KeyUsage::noParticularKeyUsageRequired, - KeyPurposeId::anyExtendedKeyUsage, - CertPolicyId::anyPolicy, - nullptr/*stapledOCSPResponse*/)); -} - -// Tests that an incorrect OID for id-pe-authorityInformationAccess -// (when marked critical) is detected and that verification fails. -// (Until bug 1020993 was fixed, the code checked for this OID.) -TEST_F(pkixcert_extension, WrongOIDCriticalExtension) -{ - static const uint8_t wrongOIDCriticalExtensionBytes[] = { - 0x30, 0x10, // SEQUENCE (length = 16) - 0x06, 0x09, // OID (length = 9) - // 1.3.6.6.1.5.5.7.1.1 (there is an extra "6" that shouldn't be there) - 0x2b, 0x06, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, - 0x01, 0x01, 0xff, // BOOLEAN (length = 1) TRUE - 0x04, 0x00 // OCTET STRING (length = 0) - }; - static const ByteString - wrongOIDCriticalExtension(wrongOIDCriticalExtensionBytes, - sizeof(wrongOIDCriticalExtensionBytes)); - const char* certCN = "Cert With Critical Wrong OID Extension"; - ByteString cert(CreateCertWithOneExtension(certCN, - wrongOIDCriticalExtension)); - ASSERT_FALSE(ENCODING_FAILED(cert)); - Input certInput; - ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length())); - ASSERT_EQ(Result::ERROR_UNKNOWN_CRITICAL_EXTENSION, - BuildCertChain(trustDomain, certInput, Now(), - EndEntityOrCA::MustBeEndEntity, - KeyUsage::noParticularKeyUsageRequired, - KeyPurposeId::anyExtendedKeyUsage, - CertPolicyId::anyPolicy, - nullptr/*stapledOCSPResponse*/)); -} - -// Tests that a id-pe-authorityInformationAccess critical extension -// is detected and that verification succeeds. -TEST_F(pkixcert_extension, CriticalAIAExtension) -{ - // XXX: According to RFC 5280 an AIA that consists of an empty sequence is - // not legal, but we accept it and that is not what we're testing here. - static const uint8_t criticalAIAExtensionBytes[] = { - 0x30, 0x11, // SEQUENCE (length = 17) - 0x06, 0x08, // OID (length = 8) - // 1.3.6.1.5.5.7.1.1 - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, - 0x01, 0x01, 0xff, // BOOLEAN (length = 1) TRUE - 0x04, 0x02, // OCTET STRING (length = 2) - 0x30, 0x00, // SEQUENCE (length = 0) - }; - static const ByteString - criticalAIAExtension(criticalAIAExtensionBytes, - sizeof(criticalAIAExtensionBytes)); - const char* certCN = "Cert With Critical AIA Extension"; - ByteString cert(CreateCertWithOneExtension(certCN, criticalAIAExtension)); - ASSERT_FALSE(ENCODING_FAILED(cert)); - Input certInput; - ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length())); - ASSERT_EQ(Success, - BuildCertChain(trustDomain, certInput, Now(), - EndEntityOrCA::MustBeEndEntity, - KeyUsage::noParticularKeyUsageRequired, - KeyPurposeId::anyExtendedKeyUsage, - CertPolicyId::anyPolicy, - nullptr/*stapledOCSPResponse*/)); -} - -// We know about some id-ce extensions (OID arc 2.5.29), but not all of them. -// Tests that an unknown id-ce extension is detected and that verification -// fails. -TEST_F(pkixcert_extension, UnknownCriticalCEExtension) -{ - static const uint8_t unknownCriticalCEExtensionBytes[] = { - 0x30, 0x0a, // SEQUENCE (length = 10) - 0x06, 0x03, // OID (length = 3) - 0x55, 0x1d, 0x37, // 2.5.29.55 - 0x01, 0x01, 0xff, // BOOLEAN (length = 1) TRUE - 0x04, 0x00 // OCTET STRING (length = 0) - }; - static const ByteString - unknownCriticalCEExtension(unknownCriticalCEExtensionBytes, - sizeof(unknownCriticalCEExtensionBytes)); - const char* certCN = "Cert With Unknown Critical id-ce Extension"; - ByteString cert(CreateCertWithOneExtension(certCN, - unknownCriticalCEExtension)); - ASSERT_FALSE(ENCODING_FAILED(cert)); - Input certInput; - ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length())); - ASSERT_EQ(Result::ERROR_UNKNOWN_CRITICAL_EXTENSION, - BuildCertChain(trustDomain, certInput, Now(), - EndEntityOrCA::MustBeEndEntity, - KeyUsage::noParticularKeyUsageRequired, - KeyPurposeId::anyExtendedKeyUsage, - CertPolicyId::anyPolicy, - nullptr/*stapledOCSPResponse*/)); -} - -// Tests that a certificate with a known critical id-ce extension (in this case, -// OID 2.5.29.54, which is id-ce-inhibitAnyPolicy), verifies successfully. -TEST_F(pkixcert_extension, KnownCriticalCEExtension) -{ - static const uint8_t criticalCEExtensionBytes[] = { - 0x30, 0x0d, // SEQUENCE (length = 13) - 0x06, 0x03, // OID (length = 3) - 0x55, 0x1d, 0x36, // 2.5.29.54 (id-ce-inhibitAnyPolicy) - 0x01, 0x01, 0xff, // BOOLEAN (length = 1) TRUE - 0x04, 0x03, // OCTET STRING (length = 3) - 0x02, 0x01, 0x00, // INTEGER (length = 1, value = 0) - }; - static const ByteString - criticalCEExtension(criticalCEExtensionBytes, - sizeof(criticalCEExtensionBytes)); - const char* certCN = "Cert With Known Critical id-ce Extension"; - ByteString cert(CreateCertWithOneExtension(certCN, criticalCEExtension)); - ASSERT_FALSE(ENCODING_FAILED(cert)); - Input certInput; - ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length())); - ASSERT_EQ(Success, - BuildCertChain(trustDomain, certInput, Now(), - EndEntityOrCA::MustBeEndEntity, - KeyUsage::noParticularKeyUsageRequired, - KeyPurposeId::anyExtendedKeyUsage, - CertPolicyId::anyPolicy, - nullptr/*stapledOCSPResponse*/)); -} +INSTANTIATE_TEST_CASE_P(pkixcert_extension, + pkixcert_extension, + testing::ValuesIn(EXTENSION_TESTCASES)); // Two subjectAltNames must result in an error. TEST_F(pkixcert_extension, DuplicateSubjectAltName) { - static const uint8_t DER_BYTES[] = { - 0x30, 22, // SEQUENCE (length = 22) - 0x06, 3, // OID (length = 3) - 0x55, 0x1d, 0x11, // 2.5.29.17 - 0x04, 15, // OCTET STRING (length = 15) - 0x30, 13, // GeneralNames (SEQUENCE) (length = 13) - 0x82, 11, // [2] (dNSName) (length = 11) - 'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm' + // python DottedOIDToCode.py --tlv id-ce-subjectAltName 2.5.29.17 + static const uint8_t tlv_id_ce_subjectAltName[] = { + 0x06, 0x03, 0x55, 0x1d, 0x11 }; - static const ByteString DER(DER_BYTES, sizeof(DER_BYTES)); - static const ByteString extensions[] = { DER, DER, ByteString() }; + + ByteString subjectAltName( + TLV(der::SEQUENCE, + BytesToByteString(tlv_id_ce_subjectAltName) + + TLV(der::OCTET_STRING, TLV(der::SEQUENCE, DNSName("example.com"))))); + static const ByteString extensions[] = { subjectAltName, subjectAltName, + ByteString() }; static const char* certCN = "Cert With Duplicate subjectAltName"; ByteString cert(CreateCertWithExtensions(certCN, extensions)); ASSERT_FALSE(ENCODING_FAILED(cert)); diff --git a/security/pkix/test/lib/pkixtestutil.cpp b/security/pkix/test/lib/pkixtestutil.cpp index d722cd9076be..27f0c0b52a69 100644 --- a/security/pkix/test/lib/pkixtestutil.cpp +++ b/security/pkix/test/lib/pkixtestutil.cpp @@ -183,7 +183,7 @@ BitString(const ByteString& rawBytes, bool corrupt) return TLV(der::BIT_STRING, prefixed); } -static ByteString +ByteString Boolean(bool value) { ByteString encodedValue; @@ -191,7 +191,7 @@ Boolean(bool value) return TLV(der::BOOLEAN, encodedValue); } -static ByteString +ByteString Integer(long value) { if (value < 0 || value > 127) { diff --git a/security/pkix/test/lib/pkixtestutil.h b/security/pkix/test/lib/pkixtestutil.h index 71b68ad3c06a..50bf48e51255 100644 --- a/security/pkix/test/lib/pkixtestutil.h +++ b/security/pkix/test/lib/pkixtestutil.h @@ -111,6 +111,8 @@ mozilla::pkix::Time YMDHMS(int16_t year, int16_t month, int16_t day, int16_t hour, int16_t minutes, int16_t seconds); ByteString TLV(uint8_t tag, const ByteString& value); +ByteString Boolean(bool value); +ByteString Integer(long value); ByteString CN(const ByteString&, uint8_t encodingTag = 0x0c /*UTF8String*/); diff --git a/testing/config/mozharness/android_arm_config.py b/testing/config/mozharness/android_arm_config.py index 053a1904d761..19b42a031cce 100644 --- a/testing/config/mozharness/android_arm_config.py +++ b/testing/config/mozharness/android_arm_config.py @@ -33,6 +33,7 @@ config = { "--apk=%(installer_path)s", "--no-logfiles", "--symbols-path=%(symbols_path)s", "--manifest=tests/xpcshell.ini", + "--log-raw=%(raw_log_file)s", ], }, }, # end suite_definitions diff --git a/testing/config/mozharness/android_panda_config.py b/testing/config/mozharness/android_panda_config.py index ef57e90d40b4..8b6523062ecd 100644 --- a/testing/config/mozharness/android_panda_config.py +++ b/testing/config/mozharness/android_panda_config.py @@ -61,7 +61,8 @@ config = { "--local-lib-dir=../fennec", "--apk=../%(apk_name)s", "--no-logfiles", - "--symbols-path=%(symbols_path)s" + "--symbols-path=%(symbols_path)s", + "--log-raw=%(raw_log_file)s", ], "jittest_options": [ "bin/js", diff --git a/testing/config/mozharness/android_x86_config.py b/testing/config/mozharness/android_x86_config.py index 68d0b03d704a..7c0477026f4b 100644 --- a/testing/config/mozharness/android_x86_config.py +++ b/testing/config/mozharness/android_x86_config.py @@ -33,6 +33,7 @@ config = { "--apk=%(installer_path)s", "--no-logfiles", "--symbols-path=%(symbols_path)s", "--manifest=tests/xpcshell.ini", + "--log-raw=%(raw_log_file)s", ], }, }, # end suite_definitions diff --git a/testing/config/mozharness/b2g_emulator_config.py b/testing/config/mozharness/b2g_emulator_config.py index 04d7feb19384..91b6cf13bfba 100644 --- a/testing/config/mozharness/b2g_emulator_config.py +++ b/testing/config/mozharness/b2g_emulator_config.py @@ -47,6 +47,7 @@ config = { "--logdir=%(logcat_dir)s", "--manifest=tests/xpcshell.ini", "--use-device-libs", "--testing-modules-dir=%(modules_dir)s", "--symbols-path=%(symbols_path)s", "--busybox=%(busybox)s", "--total-chunks=%(total_chunks)s", "--this-chunk=%(this_chunk)s", + "--log-raw=%(raw_log_file)s", ], "cppunittest_options": [ diff --git a/testing/config/mozharness/linux_config.py b/testing/config/mozharness/linux_config.py index f799918a4c4d..c47b5e62f5b1 100644 --- a/testing/config/mozharness/linux_config.py +++ b/testing/config/mozharness/linux_config.py @@ -24,7 +24,8 @@ config = { ], "xpcshell_options": [ "--symbols-path=%(symbols_path)s", - "--test-plugin-path=%(test_plugin_path)s" + "--test-plugin-path=%(test_plugin_path)s", + "--log-raw=%(raw_log_file)s", ], "cppunittest_options": [ "--symbols-path=%(symbols_path)s", diff --git a/testing/config/mozharness/mac_config.py b/testing/config/mozharness/mac_config.py index 483159ae5de4..2c44f6bca806 100644 --- a/testing/config/mozharness/mac_config.py +++ b/testing/config/mozharness/mac_config.py @@ -23,7 +23,8 @@ config = { ], "xpcshell_options": [ "--symbols-path=%(symbols_path)s", - "--test-plugin-path=%(test_plugin_path)s" + "--test-plugin-path=%(test_plugin_path)s", + "--log-raw=%(raw_log_file)s", ], "cppunittest_options": [ "--symbols-path=%(symbols_path)s", diff --git a/testing/config/mozharness/windows_config.py b/testing/config/mozharness/windows_config.py index 483159ae5de4..2c44f6bca806 100644 --- a/testing/config/mozharness/windows_config.py +++ b/testing/config/mozharness/windows_config.py @@ -23,7 +23,8 @@ config = { ], "xpcshell_options": [ "--symbols-path=%(symbols_path)s", - "--test-plugin-path=%(test_plugin_path)s" + "--test-plugin-path=%(test_plugin_path)s", + "--log-raw=%(raw_log_file)s", ], "cppunittest_options": [ "--symbols-path=%(symbols_path)s", diff --git a/testing/mochitest/android23.json b/testing/mochitest/android23.json index b6b788b5f1c3..d2c9122d77fc 100644 --- a/testing/mochitest/android23.json +++ b/testing/mochitest/android23.json @@ -1,12 +1,6 @@ { "runtests": {}, "excludetests": { - "dom/html/test/test_bug659743.xml": "Android 2.3 aws only; bug 1031103", - "docshell/test/navigation/test_reserved.html": "too slow on Android 2.3 aws only; bug 1030403", - "dom/canvas/test/webgl-conformance": "bug 865443 - separate suite -- mochitest-gl", - "dom/canvas/test/webgl-mochitest/test_no_arr_points.html": "Android 2.3 aws only; bug 1030942", - "dom/media/tests/mochitest": "Android 2.3 only; bug 981881", - "layout/style/test/test_media_queries.html": "Android 2.3 aws only; bug 1030419", - "layout/style/test/test_transitions_cancel_near_end.html": "Android 2.3 aws only; bug 1030432" + "dom/canvas/test/webgl-conformance": "bug 865443 - separate suite -- mochitest-gl" } } diff --git a/testing/mochitest/mach_commands.py b/testing/mochitest/mach_commands.py index f3851448ac68..581323a03b67 100644 --- a/testing/mochitest/mach_commands.py +++ b/testing/mochitest/mach_commands.py @@ -92,7 +92,7 @@ class MochitestRunner(MozbuildObject): appname = 'webapprt-stub' + mozinfo.info.get('bin_suffix', '') if sys.platform.startswith('darwin'): appname = os.path.join(self.distdir, self.substs['MOZ_MACBUNDLE_NAME'], - 'Contents', 'MacOS', appname) + 'Contents', 'Resources', appname) else: appname = os.path.join(self.distdir, 'bin', appname) return appname diff --git a/testing/mozbase/mozdevice/mozdevice/adb.py b/testing/mozbase/mozdevice/mozdevice/adb.py index e69244947e3a..8070c699b5dc 100644 --- a/testing/mozbase/mozdevice/mozdevice/adb.py +++ b/testing/mozbase/mozdevice/mozdevice/adb.py @@ -114,7 +114,7 @@ class ADBCommand(object): from mozdevice import ADBCommand try: - adbcommand = ADBCommand(...) + adbcommand = ADBCommand() except NotImplementedError: print "ADBCommand can not be instantiated." @@ -280,7 +280,7 @@ class ADBHost(ADBCommand): from mozdevice import ADBHost - adbhost = ADBHost(...) + adbhost = ADBHost() adbhost.start_server() """ @@ -442,7 +442,7 @@ class ADBDevice(ADBCommand): from mozdevice import ADBDevice - adbdevice = ADBDevice(...) + adbdevice = ADBDevice() print adbdevice.list_files("/mnt/sdcard") if adbdevice.process_exist("org.mozilla.fennec"): print "Fennec is running" diff --git a/testing/mozharness/README.txt b/testing/mozharness/README.txt deleted file mode 100644 index a4b534a419d3..000000000000 --- a/testing/mozharness/README.txt +++ /dev/null @@ -1,2 +0,0 @@ -mozharness.json is a manifest file that is currently only used on try. -It allows you to lock mozharness to a repository and a revision. diff --git a/testing/mozharness/mozharness.json b/testing/mozharness/mozharness.json deleted file mode 100644 index 0908d77c9e3e..000000000000 --- a/testing/mozharness/mozharness.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "repo": "http://hg.mozilla.org/build/mozharness", - "revision": "production" -} diff --git a/testing/mozharness/repository_from_code.py b/testing/mozharness/repository_from_code.py deleted file mode 100644 index addfe69fd29a..000000000000 --- a/testing/mozharness/repository_from_code.py +++ /dev/null @@ -1,121 +0,0 @@ -#! /usr/bin/env python -# 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/. - -# -# Script name: repository_manifest.py -# Purpose: Reads from a json file a repository and revision to use. -# If none is found we fall back to the default values. -# Author(s): Zambrano Gasparnian, Armen -# Target: Python 2.7.x -# -from optparse import OptionParser -import json -import re -import urllib2 -import urlparse -import sys -import os - -def main(): - ''' - Determine which repository and revision mozharness.json indicates. - If none is found we fall back to the default repository - ''' - parser = OptionParser() - parser.add_option("--repository-manifest-url", dest="repository_manifest_url", type="string", - help="It indicates from where to download the talos.json file.") - (options, args) = parser.parse_args() - - # 1) check that the url was passed - if options.repository_manifest_url == None: - print "You need to specify --repository-manifest-url." - sys.exit(1) - - # 2) try to download the talos.json file - try: - jsonFilename = download_file(options.talos_json_url) - except Exception, e: - print "ERROR: We tried to download the talos.json file but something failed." - print "ERROR: %s" % str(e) - sys.exit(1) - - # 3) download the necessary files - print "INFO: talos.json URL: %s" % options.talos_json_url - try: - key = 'talos.zip' - entity = get_value(jsonFilename, key) - if passesRestrictions(options.talos_json_url, entity["url"]): - # the key is at the same time the filename e.g. talos.zip - print "INFO: Downloading %s as %s" % (entity["url"], os.path.join(entity["path"], key)) - download_file(entity["url"], entity["path"], key) - else: - print "ERROR: You have tried to download a file " + \ - "from: %s " % entity["url"] + \ - "which is a location different than http://talos-bundles.pvt.build.mozilla.org/" - print "ERROR: This is only allowed for the certain branches." - sys.exit(1) - except Exception, e: - print "ERROR: %s" % str(e) - sys.exit(1) - -def passesRestrictions(talosJsonUrl, fileUrl): - ''' - Only certain branches are exempted from having to host their downloadable files - in talos-bundles.pvt.build.mozilla.org - ''' - if talosJsonUrl.startswith("http://hg.mozilla.org/try/") or \ - talosJsonUrl.startswith("https://hg.mozilla.org/try/") or \ - talosJsonUrl.startswith("http://hg.mozilla.org/projects/pine/") or \ - talosJsonUrl.startswith("https://hg.mozilla.org/projects/pine/") or \ - talosJsonUrl.startswith("http://hg.mozilla.org/projects/ash/") or \ - talosJsonUrl.startswith("https://hg.mozilla.org/projects/ash/"): - return True - else: - p = re.compile('^http://talos-bundles.pvt.build.mozilla.org/') - m = p.match(fileUrl) - if m == None: - return False - return True - -def get_filename_from_url(url): - ''' - This returns the filename of the file we're trying to download - ''' - parsed = urlparse.urlsplit(url.rstrip('/')) - if parsed.path != '': - return parsed.path.rsplit('/', 1)[-1] - else: - print "ERROR: We were trying to download a file from %s " + \ - "but the URL seems to be incorrect." - sys.exit(1) - -def download_file(url, path="", saveAs=None): - ''' - It downloads a file from URL to the indicated path - ''' - req = urllib2.Request(url) - f = urllib2.urlopen(req) - if path != "" and not os.path.isdir(path): - try: - os.makedirs(path) - print "INFO: directory %s created" % path - except Exception, e: - print "ERROR: %s" % str(e) - sys.exit(1) - filename = saveAs if saveAs else get_filename_from_url(url) - local_file = open(os.path.join(path, filename), 'wb') - local_file.write(f.read()) - local_file.close() - return filename - -def get_value(json_filename, key): - ''' - It loads up a JSON file and returns the value for the given string - ''' - f = open(json_filename, 'r') - return json.load(f)[key] - -if __name__ == '__main__': - main() diff --git a/testing/testsuite-targets.mk b/testing/testsuite-targets.mk index 2143ed000956..a1b0b3af2e8d 100644 --- a/testing/testsuite-targets.mk +++ b/testing/testsuite-targets.mk @@ -169,7 +169,7 @@ endif $(CHECK_TEST_ERROR) ifeq ($(OS_ARCH),Darwin) -webapprt_stub_path = $(TARGET_DIST)/$(MOZ_MACBUNDLE_NAME)/Contents/MacOS/webapprt-stub$(BIN_SUFFIX) +webapprt_stub_path = $(TARGET_DIST)/$(MOZ_MACBUNDLE_NAME)/Contents/Resources/webapprt-stub$(BIN_SUFFIX) endif ifeq ($(OS_ARCH),WINNT) webapprt_stub_path = $(TARGET_DIST)/bin/webapprt-stub$(BIN_SUFFIX) diff --git a/toolkit/webapps/MacNativeApp.js b/toolkit/webapps/MacNativeApp.js index 0e12503f5985..dadd6c43ed45 100644 --- a/toolkit/webapps/MacNativeApp.js +++ b/toolkit/webapps/MacNativeApp.js @@ -222,7 +222,8 @@ NativeApp.prototype = { _copyPrebuiltFiles: function(aDir) { let destDir = getFile(aDir, this.macOSDir); - let stub = getFile(this.runtimeFolder, "webapprt-stub"); + let stub = getFile(OS.Path.join(OS.Path.dirname(this.runtimeFolder), + "Resources"), "webapprt-stub"); stub.copyTo(destDir, "webapprt"); }, diff --git a/toolkit/webapps/tests/test_webapp_runtime_executable_update.xul b/toolkit/webapps/tests/test_webapp_runtime_executable_update.xul index 9886fc061311..1400a262d84d 100644 --- a/toolkit/webapps/tests/test_webapp_runtime_executable_update.xul +++ b/toolkit/webapps/tests/test_webapp_runtime_executable_update.xul @@ -94,7 +94,7 @@ let runTest = Task.async(function*() { let fakeInstallDir; if (MAC) { - fakeInstallDir = getFile(testAppInfo.installPath, "Contents", "MacOS"); + fakeInstallDir = getFile(testAppInfo.installPath, "Contents", "Resources"); } else { fakeInstallDir = getFile(OS.Constants.Path.profileDir, "fakeInstallDir"); fakeInstallDir.createUnique(Ci.nsIFile.DIRECTORY_TYPE, 0o755); diff --git a/webapprt/mac/webapprt.mm b/webapprt/mac/webapprt.mm index dea620e4d44c..4e2299ad207b 100644 --- a/webapprt/mac/webapprt.mm +++ b/webapprt/mac/webapprt.mm @@ -166,7 +166,7 @@ main(int argc, char **argv) //we know the firefox path, so copy the new webapprt here NSString *newWebRTPath = - [NSString stringWithFormat: @"%@%s%s", firefoxPath, APP_MACOS_PATH, + [NSString stringWithFormat: @"%@%s%s", firefoxPath, APP_RESOURCES_PATH, WEBAPPRT_EXECUTABLE]; NSLog(@"### Firefox webapprt path: %@", newWebRTPath); if (![fileClerk fileExistsAtPath:newWebRTPath]) {