diff --git a/browser/components/loop/content/js/conversation.js b/browser/components/loop/content/js/conversation.js
index baa089052a82..fe0d3d3c9bf4 100644
--- a/browser/components/loop/content/js/conversation.js
+++ b/browser/components/loop/content/js/conversation.js
@@ -656,9 +656,9 @@ loop.conversation = (function(mozL10n) {
dispatcher: dispatcher,
mozLoop: navigator.mozLoop
});
- var conversationStore = new loop.store.ConversationStore({}, {
+ var conversationStore = new loop.store.ConversationStore(dispatcher, {
client: client,
- dispatcher: dispatcher,
+ mozLoop: navigator.mozLoop,
sdkDriver: sdkDriver
});
var activeRoomStore = new loop.store.ActiveRoomStore(dispatcher, {
diff --git a/browser/components/loop/content/js/conversation.jsx b/browser/components/loop/content/js/conversation.jsx
index c77966e31b83..5ce05242f0ed 100644
--- a/browser/components/loop/content/js/conversation.jsx
+++ b/browser/components/loop/content/js/conversation.jsx
@@ -656,9 +656,9 @@ loop.conversation = (function(mozL10n) {
dispatcher: dispatcher,
mozLoop: navigator.mozLoop
});
- var conversationStore = new loop.store.ConversationStore({}, {
+ var conversationStore = new loop.store.ConversationStore(dispatcher, {
client: client,
- dispatcher: dispatcher,
+ mozLoop: navigator.mozLoop,
sdkDriver: sdkDriver
});
var activeRoomStore = new loop.store.ActiveRoomStore(dispatcher, {
diff --git a/browser/components/loop/content/js/conversationViews.js b/browser/components/loop/content/js/conversationViews.js
index 6aa4603e81de..b0bae810e0a2 100644
--- a/browser/components/loop/content/js/conversationViews.js
+++ b/browser/components/loop/content/js/conversationViews.js
@@ -224,7 +224,7 @@ loop.conversationViews = (function(mozL10n) {
},
_onEmailLinkReceived: function() {
- var emailLink = this.props.store.get("emailLink");
+ var emailLink = this.props.store.getStoreState("emailLink");
var contactEmail = _getPreferredEmail(this.props.contact).value;
sharedUtils.composeCallUrlEmail(emailLink, contactEmail);
window.close();
@@ -428,7 +428,10 @@ loop.conversationViews = (function(mozL10n) {
* the different views that need displaying.
*/
var OutgoingConversationView = React.createClass({displayName: 'OutgoingConversationView',
- mixins: [sharedMixins.AudioMixin],
+ mixins: [
+ sharedMixins.AudioMixin,
+ Backbone.Events
+ ],
propTypes: {
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
@@ -438,12 +441,18 @@ loop.conversationViews = (function(mozL10n) {
},
getInitialState: function() {
- return this.props.store.attributes;
+ return this.props.store.getStoreState();
},
componentWillMount: function() {
- this.props.store.on("change", function() {
- this.setState(this.props.store.attributes);
+ this.listenTo(this.props.store, "change", function() {
+ this.setState(this.props.store.getStoreState());
+ }, this);
+ },
+
+ componentWillUnmount: function() {
+ this.stopListening(this.props.store, "change", function() {
+ this.setState(this.props.store.getStoreState());
}, this);
},
diff --git a/browser/components/loop/content/js/conversationViews.jsx b/browser/components/loop/content/js/conversationViews.jsx
index 5de7c233f617..b1b552f74e4a 100644
--- a/browser/components/loop/content/js/conversationViews.jsx
+++ b/browser/components/loop/content/js/conversationViews.jsx
@@ -224,7 +224,7 @@ loop.conversationViews = (function(mozL10n) {
},
_onEmailLinkReceived: function() {
- var emailLink = this.props.store.get("emailLink");
+ var emailLink = this.props.store.getStoreState("emailLink");
var contactEmail = _getPreferredEmail(this.props.contact).value;
sharedUtils.composeCallUrlEmail(emailLink, contactEmail);
window.close();
@@ -428,7 +428,10 @@ loop.conversationViews = (function(mozL10n) {
* the different views that need displaying.
*/
var OutgoingConversationView = React.createClass({
- mixins: [sharedMixins.AudioMixin],
+ mixins: [
+ sharedMixins.AudioMixin,
+ Backbone.Events
+ ],
propTypes: {
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
@@ -438,12 +441,18 @@ loop.conversationViews = (function(mozL10n) {
},
getInitialState: function() {
- return this.props.store.attributes;
+ return this.props.store.getStoreState();
},
componentWillMount: function() {
- this.props.store.on("change", function() {
- this.setState(this.props.store.attributes);
+ this.listenTo(this.props.store, "change", function() {
+ this.setState(this.props.store.getStoreState());
+ }, this);
+ },
+
+ componentWillUnmount: function() {
+ this.stopListening(this.props.store, "change", function() {
+ this.setState(this.props.store.getStoreState());
}, this);
},
diff --git a/browser/components/loop/content/js/roomViews.js b/browser/components/loop/content/js/roomViews.js
index d2dfa98a6e0c..65cf5f137237 100644
--- a/browser/components/loop/content/js/roomViews.js
+++ b/browser/components/loop/content/js/roomViews.js
@@ -162,15 +162,20 @@ loop.roomViews = (function(mozL10n) {
*/
window.addEventListener('orientationchange', this.updateVideoContainer);
window.addEventListener('resize', this.updateVideoContainer);
+ },
+ componentWillUpdate: function(nextProps, nextState) {
// The SDK needs to know about the configuration and the elements to use
// for display. So the best way seems to pass the information here - ideally
// the sdk wouldn't need to know this, but we can't change that.
- this.props.dispatcher.dispatch(new sharedActions.SetupStreamElements({
- publisherConfig: this._getPublisherConfig(),
- getLocalElementFunc: this._getElement.bind(this, ".local"),
- getRemoteElementFunc: this._getElement.bind(this, ".remote")
- }));
+ if (this.state.roomState !== ROOM_STATES.MEDIA_WAIT &&
+ nextState.roomState === ROOM_STATES.MEDIA_WAIT) {
+ this.props.dispatcher.dispatch(new sharedActions.SetupStreamElements({
+ publisherConfig: this._getPublisherConfig(),
+ getLocalElementFunc: this._getElement.bind(this, ".local"),
+ getRemoteElementFunc: this._getElement.bind(this, ".remote")
+ }));
+ }
},
_getPublisherConfig: function() {
diff --git a/browser/components/loop/content/js/roomViews.jsx b/browser/components/loop/content/js/roomViews.jsx
index 9aa6e08e2420..f306a408459b 100644
--- a/browser/components/loop/content/js/roomViews.jsx
+++ b/browser/components/loop/content/js/roomViews.jsx
@@ -162,15 +162,20 @@ loop.roomViews = (function(mozL10n) {
*/
window.addEventListener('orientationchange', this.updateVideoContainer);
window.addEventListener('resize', this.updateVideoContainer);
+ },
+ componentWillUpdate: function(nextProps, nextState) {
// The SDK needs to know about the configuration and the elements to use
// for display. So the best way seems to pass the information here - ideally
// the sdk wouldn't need to know this, but we can't change that.
- this.props.dispatcher.dispatch(new sharedActions.SetupStreamElements({
- publisherConfig: this._getPublisherConfig(),
- getLocalElementFunc: this._getElement.bind(this, ".local"),
- getRemoteElementFunc: this._getElement.bind(this, ".remote")
- }));
+ if (this.state.roomState !== ROOM_STATES.MEDIA_WAIT &&
+ nextState.roomState === ROOM_STATES.MEDIA_WAIT) {
+ this.props.dispatcher.dispatch(new sharedActions.SetupStreamElements({
+ publisherConfig: this._getPublisherConfig(),
+ getLocalElementFunc: this._getElement.bind(this, ".local"),
+ getRemoteElementFunc: this._getElement.bind(this, ".remote")
+ }));
+ }
},
_getPublisherConfig: function() {
diff --git a/browser/components/loop/content/shared/js/conversationStore.js b/browser/components/loop/content/shared/js/conversationStore.js
index f07b3ae3a6e6..c5eb044e97d4 100644
--- a/browser/components/loop/content/shared/js/conversationStore.js
+++ b/browser/components/loop/content/shared/js/conversationStore.js
@@ -7,7 +7,7 @@
var loop = loop || {};
loop.store = loop.store || {};
-loop.store.ConversationStore = (function() {
+(function() {
var sharedActions = loop.shared.actions;
var CALL_TYPES = loop.shared.utils.CALL_TYPES;
@@ -53,81 +53,84 @@ loop.store.ConversationStore = (function() {
TERMINATED: "cs-terminated"
};
- // XXX this needs to migrate to use loop.store.createStore
- var ConversationStore = Backbone.Model.extend({
- defaults: {
- // The id of the window. Currently used for getting the window id.
- windowId: undefined,
- // The current state of the call
- callState: CALL_STATES.INIT,
- // The reason if a call was terminated
- callStateReason: undefined,
- // The error information, if there was a failure
- error: undefined,
- // True if the call is outgoing, false if not, undefined if unknown
- outgoing: undefined,
- // The contact being called for outgoing calls
- contact: undefined,
- // The call type for the call.
- // XXX Don't hard-code, this comes from the data in bug 1072323
- callType: CALL_TYPES.AUDIO_VIDEO,
+ /**
+ * Conversation store.
+ *
+ * @param {loop.Dispatcher} dispatcher The dispatcher for dispatching actions
+ * and registering to consume actions.
+ * @param {Object} options Options object:
+ * - {client} client The client object.
+ * - {mozLoop} mozLoop The MozLoop API object.
+ * - {loop.OTSdkDriver} loop.OTSdkDriver The SDK Driver
+ */
+ loop.store.ConversationStore = loop.store.createStore({
+ // Further actions are registered in setupWindowData when
+ // we know what window type this is.
+ actions: [
+ "setupWindowData"
+ ],
- // Call Connection information
- // The call id from the loop-server
- callId: undefined,
- // The caller id of the contacting side
- callerId: undefined,
- // The connection progress url to connect the websocket
- progressURL: undefined,
- // The websocket token that allows connection to the progress url
- websocketToken: undefined,
- // SDK API key
- apiKey: undefined,
- // SDK session ID
- sessionId: undefined,
- // SDK session token
- sessionToken: undefined,
- // If the audio is muted
- audioMuted: false,
- // If the video is muted
- videoMuted: false
+ getInitialStoreState: function() {
+ return {
+ // The id of the window. Currently used for getting the window id.
+ windowId: undefined,
+ // The current state of the call
+ callState: CALL_STATES.INIT,
+ // The reason if a call was terminated
+ callStateReason: undefined,
+ // True if the call is outgoing, false if not, undefined if unknown
+ outgoing: undefined,
+ // The contact being called for outgoing calls
+ contact: undefined,
+ // The call type for the call.
+ // XXX Don't hard-code, this comes from the data in bug 1072323
+ callType: CALL_TYPES.AUDIO_VIDEO,
+ // A link for emailing once obtained from the server
+ emailLink: undefined,
+
+ // Call Connection information
+ // The call id from the loop-server
+ callId: undefined,
+ // The caller id of the contacting side
+ callerId: undefined,
+ // The connection progress url to connect the websocket
+ progressURL: undefined,
+ // The websocket token that allows connection to the progress url
+ websocketToken: undefined,
+ // SDK API key
+ apiKey: undefined,
+ // SDK session ID
+ sessionId: undefined,
+ // SDK session token
+ sessionToken: undefined,
+ // If the audio is muted
+ audioMuted: false,
+ // If the video is muted
+ videoMuted: false
+ };
},
/**
- * Constructor
+ * Handles initialisation of the store.
*
- * Options:
- * - {loop.Dispatcher} dispatcher The dispatcher for dispatching actions and
- * registering to consume actions.
- * - {Object} client A client object for communicating with the server.
- *
- * @param {Object} attributes Attributes object.
* @param {Object} options Options object.
*/
- initialize: function(attributes, options) {
+ initialize: function(options) {
options = options || {};
- if (!options.dispatcher) {
- throw new Error("Missing option dispatcher");
- }
if (!options.client) {
throw new Error("Missing option client");
}
if (!options.sdkDriver) {
throw new Error("Missing option sdkDriver");
}
+ if (!options.mozLoop) {
+ throw new Error("Missing option mozLoop");
+ }
this.client = options.client;
- this.dispatcher = options.dispatcher;
this.sdkDriver = options.sdkDriver;
-
- // XXX Further actions are registered in setupWindowData when
- // we know what window type this is. At some stage, we might want to
- // consider store mixins or some alternative which means the stores
- // would only be created when we want them.
- this.dispatcher.register(this, [
- "setupWindowData"
- ]);
+ this.mozLoop = options.mozLoop;
},
/**
@@ -138,7 +141,7 @@ loop.store.ConversationStore = (function() {
*/
connectionFailure: function(actionData) {
this._endSession();
- this.set({
+ this.setStoreState({
callState: CALL_STATES.TERMINATED,
callStateReason: actionData.reason
});
@@ -151,34 +154,35 @@ loop.store.ConversationStore = (function() {
* @param {sharedActions.ConnectionProgress} actionData The action data.
*/
connectionProgress: function(actionData) {
- var callState = this.get("callState");
+ var state = this.getStoreState();
switch(actionData.wsState) {
case WS_STATES.INIT: {
- if (callState === CALL_STATES.GATHER) {
- this.set({callState: CALL_STATES.CONNECTING});
+ if (state.callState === CALL_STATES.GATHER) {
+ this.setStoreState({callState: CALL_STATES.CONNECTING});
}
break;
}
case WS_STATES.ALERTING: {
- this.set({callState: CALL_STATES.ALERTING});
+ this.setStoreState({callState: CALL_STATES.ALERTING});
break;
}
case WS_STATES.CONNECTING: {
this.sdkDriver.connectSession({
- apiKey: this.get("apiKey"),
- sessionId: this.get("sessionId"),
- sessionToken: this.get("sessionToken")
+ apiKey: state.apiKey,
+ sessionId: state.sessionId,
+ sessionToken: state.sessionToken
});
- navigator.mozLoop.addConversationContext(this.get("windowId"),
- this.get("sessionId"),
- this.get("callId"));
- this.set({callState: CALL_STATES.ONGOING});
+ this.mozLoop.addConversationContext(
+ state.windowId,
+ state.sessionId,
+ state.callId);
+ this.setStoreState({callState: CALL_STATES.ONGOING});
break;
}
case WS_STATES.HALF_CONNECTED:
case WS_STATES.CONNECTED: {
- this.set({callState: CALL_STATES.ONGOING});
+ this.setStoreState({callState: CALL_STATES.ONGOING});
break;
}
default: {
@@ -209,7 +213,7 @@ loop.store.ConversationStore = (function() {
"fetchEmailLink"
]);
- this.set({
+ this.setStoreState({
contact: actionData.contact,
outgoing: windowType === "outgoing",
windowId: actionData.windowId,
@@ -218,7 +222,7 @@ loop.store.ConversationStore = (function() {
videoMuted: actionData.callType === CALL_TYPES.AUDIO_ONLY
});
- if (this.get("outgoing")) {
+ if (this.getStoreState("outgoing")) {
this._setupOutgoingCall();
} // XXX Else, other types aren't supported yet.
},
@@ -231,7 +235,7 @@ loop.store.ConversationStore = (function() {
* @param {sharedActions.ConnectCall} actionData The action data.
*/
connectCall: function(actionData) {
- this.set(actionData.sessionData);
+ this.setStoreState(actionData.sessionData);
this._connectWebSocket();
},
@@ -245,7 +249,7 @@ loop.store.ConversationStore = (function() {
}
this._endSession();
- this.set({callState: CALL_STATES.FINISHED});
+ this.setStoreState({callState: CALL_STATES.FINISHED});
},
/**
@@ -259,9 +263,9 @@ loop.store.ConversationStore = (function() {
// If the peer hungup, we end normally, otherwise
// we treat this as a call failure.
if (actionData.peerHungup) {
- this.set({callState: CALL_STATES.FINISHED});
+ this.setStoreState({callState: CALL_STATES.FINISHED});
} else {
- this.set({
+ this.setStoreState({
callState: CALL_STATES.TERMINATED,
callStateReason: "peerNetworkDisconnected"
});
@@ -272,7 +276,7 @@ loop.store.ConversationStore = (function() {
* Cancels a call
*/
cancelCall: function() {
- var callState = this.get("callState");
+ var callState = this.getStoreState("callState");
if (this._websocket &&
(callState === CALL_STATES.CONNECTING ||
callState === CALL_STATES.ALERTING)) {
@@ -281,21 +285,21 @@ loop.store.ConversationStore = (function() {
}
this._endSession();
- this.set({callState: CALL_STATES.CLOSE});
+ this.setStoreState({callState: CALL_STATES.CLOSE});
},
/**
* Retries a call
*/
retryCall: function() {
- var callState = this.get("callState");
+ var callState = this.getStoreState("callState");
if (callState !== CALL_STATES.TERMINATED) {
console.error("Unexpected retry in state", callState);
return;
}
- this.set({callState: CALL_STATES.GATHER});
- if (this.get("outgoing")) {
+ this.setStoreState({callState: CALL_STATES.GATHER});
+ if (this.getStoreState("outgoing")) {
this._setupOutgoingCall();
}
},
@@ -313,8 +317,9 @@ loop.store.ConversationStore = (function() {
* @param {sharedActions.setMute} actionData The mute state for the stream type.
*/
setMute: function(actionData) {
- var muteType = actionData.type + "Muted";
- this.set(muteType, !actionData.enabled);
+ var newState = {};
+ newState[actionData.type + "Muted"] = !actionData.enabled;
+ this.setStoreState(newState);
},
/**
@@ -329,7 +334,7 @@ loop.store.ConversationStore = (function() {
this.trigger("error:emailLink");
return;
}
- this.set("emailLink", callUrlData.callUrl);
+ this.setStoreState({"emailLink": callUrlData.callUrl});
}.bind(this));
},
@@ -339,9 +344,9 @@ loop.store.ConversationStore = (function() {
*/
_setupOutgoingCall: function() {
var contactAddresses = [];
- var contact = this.get("contact");
+ var contact = this.getStoreState("contact");
- navigator.mozLoop.calls.setCallInProgress(this.get("windowId"));
+ this.mozLoop.calls.setCallInProgress(this.getStoreState("windowId"));
function appendContactValues(property, strip) {
if (contact.hasOwnProperty(property)) {
@@ -362,7 +367,7 @@ loop.store.ConversationStore = (function() {
appendContactValues("tel", true);
this.client.setupOutgoingCall(contactAddresses,
- this.get("callType"),
+ this.getStoreState("callType"),
function(err, result) {
if (err) {
console.error("Failed to get outgoing call data", err);
@@ -385,9 +390,9 @@ loop.store.ConversationStore = (function() {
*/
_connectWebSocket: function() {
this._websocket = new loop.CallConnectionWebSocket({
- url: this.get("progressURL"),
- callId: this.get("callId"),
- websocketToken: this.get("websocketToken")
+ url: this.getStoreState("progressURL"),
+ callId: this.getStoreState("callId"),
+ websocketToken: this.getStoreState("websocketToken")
});
this._websocket.promiseConnect().then(
@@ -422,7 +427,8 @@ loop.store.ConversationStore = (function() {
delete this._websocket;
}
- navigator.mozLoop.calls.clearCallInProgress(this.get("windowId"));
+ this.mozLoop.calls.clearCallInProgress(
+ this.getStoreState("windowId"));
},
/**
@@ -450,6 +456,4 @@ loop.store.ConversationStore = (function() {
this.dispatcher.dispatch(action);
}
});
-
- return ConversationStore;
})();
diff --git a/browser/components/loop/standalone/content/js/standaloneRoomViews.js b/browser/components/loop/standalone/content/js/standaloneRoomViews.js
index d6a8238dcd5d..4440af4560bd 100644
--- a/browser/components/loop/standalone/content/js/standaloneRoomViews.js
+++ b/browser/components/loop/standalone/content/js/standaloneRoomViews.js
@@ -127,6 +127,10 @@ loop.standaloneRoomViews = (function(mozL10n) {
React.DOM.div({className: "room-inner-info-area"},
React.DOM.p({className: "failed-room-message"},
this._getFailureString()
+ ),
+ React.DOM.button({className: "btn btn-join btn-info",
+ onClick: this.props.joinRoom},
+ mozL10n.get("retry_call_button")
)
)
);
diff --git a/browser/components/loop/standalone/content/js/standaloneRoomViews.jsx b/browser/components/loop/standalone/content/js/standaloneRoomViews.jsx
index d128d0774095..8f235874c558 100644
--- a/browser/components/loop/standalone/content/js/standaloneRoomViews.jsx
+++ b/browser/components/loop/standalone/content/js/standaloneRoomViews.jsx
@@ -128,6 +128,10 @@ loop.standaloneRoomViews = (function(mozL10n) {
{this._getFailureString()}
+
);
}
diff --git a/browser/components/loop/test/desktop-local/conversationViews_test.js b/browser/components/loop/test/desktop-local/conversationViews_test.js
index 60a2dde9d453..2b8ba185bd20 100644
--- a/browser/components/loop/test/desktop-local/conversationViews_test.js
+++ b/browser/components/loop/test/desktop-local/conversationViews_test.js
@@ -8,6 +8,7 @@ describe("loop.conversationViews", function () {
var sharedUtils = loop.shared.utils;
var sandbox, oldTitle, view, dispatcher, contact, fakeAudioXHR;
+ var fakeMozLoop;
var CALL_STATES = loop.store.CALL_STATES;
@@ -43,7 +44,7 @@ describe("loop.conversationViews", function () {
onload: null
};
- navigator.mozLoop = {
+ fakeMozLoop = navigator.mozLoop = {
getLoopPref: sinon.stub().returns("http://fakeurl"),
composeEmail: sinon.spy(),
get appVersionInfo() {
@@ -242,9 +243,9 @@ describe("loop.conversationViews", function () {
}
beforeEach(function() {
- store = new loop.store.ConversationStore({}, {
- dispatcher: dispatcher,
+ store = new loop.store.ConversationStore(dispatcher, {
client: {},
+ mozLoop: navigator.mozLoop,
sdkDriver: {}
});
fakeAudio = {
@@ -306,7 +307,7 @@ describe("loop.conversationViews", function () {
it("should compose an email once the email link is received", function() {
var composeCallUrlEmail = sandbox.stub(sharedUtils, "composeCallUrlEmail");
view = mountTestComponent();
- store.set("emailLink", "http://fake.invalid/");
+ store.setStoreState({emailLink: "http://fake.invalid/"});
sinon.assert.calledOnce(composeCallUrlEmail);
sinon.assert.calledWithExactly(composeCallUrlEmail,
@@ -318,7 +319,7 @@ describe("loop.conversationViews", function () {
sandbox.stub(window, "close");
view = mountTestComponent();
- store.set("emailLink", "http://fake.invalid/");
+ store.setStoreState({emailLink: "http://fake.invalid/"});
sinon.assert.calledOnce(window.close);
});
@@ -457,9 +458,9 @@ describe("loop.conversationViews", function () {
}
beforeEach(function() {
- store = new loop.store.ConversationStore({}, {
- dispatcher: dispatcher,
+ store = new loop.store.ConversationStore(dispatcher, {
client: {},
+ mozLoop: fakeMozLoop,
sdkDriver: {}
});
feedbackStore = new loop.store.FeedbackStore(dispatcher, {
@@ -469,7 +470,7 @@ describe("loop.conversationViews", function () {
it("should render the CallFailedView when the call state is 'terminated'",
function() {
- store.set({callState: CALL_STATES.TERMINATED});
+ store.setStoreState({callState: CALL_STATES.TERMINATED});
view = mountTestComponent();
@@ -479,7 +480,7 @@ describe("loop.conversationViews", function () {
it("should render the PendingConversationView when the call state is 'gather'",
function() {
- store.set({
+ store.setStoreState({
callState: CALL_STATES.GATHER,
contact: contact
});
@@ -492,7 +493,7 @@ describe("loop.conversationViews", function () {
it("should render the OngoingConversationView when the call state is 'ongoing'",
function() {
- store.set({callState: CALL_STATES.ONGOING});
+ store.setStoreState({callState: CALL_STATES.ONGOING});
view = mountTestComponent();
@@ -502,7 +503,7 @@ describe("loop.conversationViews", function () {
it("should render the FeedbackView when the call state is 'finished'",
function() {
- store.set({callState: CALL_STATES.FINISHED});
+ store.setStoreState({callState: CALL_STATES.FINISHED});
view = mountTestComponent();
@@ -519,7 +520,7 @@ describe("loop.conversationViews", function () {
};
sandbox.stub(window, "Audio").returns(fakeAudio);
- store.set({callState: CALL_STATES.FINISHED});
+ store.setStoreState({callState: CALL_STATES.FINISHED});
view = mountTestComponent();
@@ -528,7 +529,7 @@ describe("loop.conversationViews", function () {
it("should update the rendered views when the state is changed.",
function() {
- store.set({
+ store.setStoreState({
callState: CALL_STATES.GATHER,
contact: contact
});
@@ -538,7 +539,7 @@ describe("loop.conversationViews", function () {
TestUtils.findRenderedComponentWithType(view,
loop.conversationViews.PendingConversationView);
- store.set({callState: CALL_STATES.TERMINATED});
+ store.setStoreState({callState: CALL_STATES.TERMINATED});
TestUtils.findRenderedComponentWithType(view,
loop.conversationViews.CallFailedView);
diff --git a/browser/components/loop/test/desktop-local/conversation_test.js b/browser/components/loop/test/desktop-local/conversation_test.js
index 524a657afc25..a150e664cd62 100644
--- a/browser/components/loop/test/desktop-local/conversation_test.js
+++ b/browser/components/loop/test/desktop-local/conversation_test.js
@@ -160,20 +160,22 @@ describe("loop.conversation", function() {
sdk: {}
});
dispatcher = new loop.Dispatcher();
- conversationStore = new loop.store.ConversationStore({
- contact: {
- name: [ "Mr Smith" ],
- email: [{
- type: "home",
- value: "fakeEmail",
- pref: true
- }]
- }
- }, {
- client: client,
- dispatcher: dispatcher,
- sdkDriver: {}
- });
+ conversationStore = new loop.store.ConversationStore(
+ dispatcher, {
+ client: client,
+ mozLoop: navigator.mozLoop,
+ sdkDriver: {}
+ });
+
+ conversationStore.setStoreState({contact: {
+ name: [ "Mr Smith" ],
+ email: [{
+ type: "home",
+ value: "fakeEmail",
+ pref: true
+ }]
+ }});
+
roomStore = new loop.store.RoomStore(dispatcher, {
mozLoop: navigator.mozLoop,
});
diff --git a/browser/components/loop/test/desktop-local/index.html b/browser/components/loop/test/desktop-local/index.html
index f3a2039bcdf0..0aecad67b92a 100644
--- a/browser/components/loop/test/desktop-local/index.html
+++ b/browser/components/loop/test/desktop-local/index.html
@@ -41,7 +41,6 @@
-
@@ -51,6 +50,7 @@
+
diff --git a/browser/components/loop/test/desktop-local/roomViews_test.js b/browser/components/loop/test/desktop-local/roomViews_test.js
index 11a6706fa4bb..e4d0e00ca17e 100644
--- a/browser/components/loop/test/desktop-local/roomViews_test.js
+++ b/browser/components/loop/test/desktop-local/roomViews_test.js
@@ -206,15 +206,6 @@ describe("loop.roomViews", function () {
}));
}
- it("should dispatch a setupStreamElements action when the view is created",
- function() {
- view = mountTestComponent();
-
- sinon.assert.calledOnce(dispatcher.dispatch);
- sinon.assert.calledWithMatch(dispatcher.dispatch,
- sinon.match.hasOwn("name", "setupStreamElements"));
- });
-
it("should dispatch a setMute action when the audio mute button is pressed",
function() {
view = mountTestComponent();
@@ -271,6 +262,44 @@ describe("loop.roomViews", function () {
expect(muteBtn.classList.contains("muted")).eql(true);
});
+ describe("#componentWillUpdate", function() {
+ function expectActionDispatched(view) {
+ sinon.assert.calledOnce(dispatcher.dispatch);
+ sinon.assert.calledWithExactly(dispatcher.dispatch,
+ sinon.match.instanceOf(sharedActions.SetupStreamElements));
+ sinon.assert.calledWithExactly(dispatcher.dispatch,
+ sinon.match(function(value) {
+ return value.getLocalElementFunc() ===
+ view.getDOMNode().querySelector(".local");
+ }));
+ sinon.assert.calledWithExactly(dispatcher.dispatch,
+ sinon.match(function(value) {
+ return value.getRemoteElementFunc() ===
+ view.getDOMNode().querySelector(".remote");
+ }));
+ }
+
+ it("should dispatch a `SetupStreamElements` action when the MEDIA_WAIT state " +
+ "is entered", function() {
+ activeRoomStore.setStoreState({roomState: ROOM_STATES.READY});
+ var view = mountTestComponent();
+
+ activeRoomStore.setStoreState({roomState: ROOM_STATES.MEDIA_WAIT});
+
+ expectActionDispatched(view);
+ });
+
+ it("should dispatch a `SetupStreamElements` action on MEDIA_WAIT state is " +
+ "re-entered", function() {
+ activeRoomStore.setStoreState({roomState: ROOM_STATES.ENDED});
+ var view = mountTestComponent();
+
+ activeRoomStore.setStoreState({roomState: ROOM_STATES.MEDIA_WAIT});
+
+ expectActionDispatched(view);
+ });
+ });
+
describe("#render", function() {
it("should set document.title to store.serverData.roomName", function() {
mountTestComponent();
diff --git a/browser/components/loop/test/shared/conversationStore_test.js b/browser/components/loop/test/shared/conversationStore_test.js
index 2ca796a9bcc2..d75d3fc7e8bc 100644
--- a/browser/components/loop/test/shared/conversationStore_test.js
+++ b/browser/components/loop/test/shared/conversationStore_test.js
@@ -11,7 +11,7 @@ describe("loop.store.ConversationStore", function () {
var sharedActions = loop.shared.actions;
var sharedUtils = loop.shared.utils;
var sandbox, dispatcher, client, store, fakeSessionData, sdkDriver;
- var contact;
+ var contact, fakeMozLoop;
var connectPromise, resolveConnectPromise, rejectConnectPromise;
var wsCancelSpy, wsCloseSpy, wsMediaUpSpy, fakeWebsocket;
@@ -36,7 +36,7 @@ describe("loop.store.ConversationStore", function () {
}]
};
- navigator.mozLoop = {
+ fakeMozLoop = {
getLoopPref: sandbox.stub(),
addConversationContext: sandbox.stub(),
calls: {
@@ -65,9 +65,9 @@ describe("loop.store.ConversationStore", function () {
mediaUp: wsMediaUpSpy
};
- store = new loop.store.ConversationStore({}, {
+ store = new loop.store.ConversationStore(dispatcher, {
client: client,
- dispatcher: dispatcher,
+ mozLoop: fakeMozLoop,
sdkDriver: sdkDriver
});
fakeSessionData = {
@@ -99,19 +99,9 @@ describe("loop.store.ConversationStore", function () {
});
describe("#initialize", function() {
- it("should throw an error if the dispatcher is missing", function() {
- expect(function() {
- new loop.store.ConversationStore({}, {
- client: client,
- sdkDriver: sdkDriver
- });
- }).to.Throw(/dispatcher/);
- });
-
it("should throw an error if the client is missing", function() {
expect(function() {
- new loop.store.ConversationStore({}, {
- dispatcher: dispatcher,
+ new loop.store.ConversationStore(dispatcher, {
sdkDriver: sdkDriver
});
}).to.Throw(/client/);
@@ -119,18 +109,26 @@ describe("loop.store.ConversationStore", function () {
it("should throw an error if the sdkDriver is missing", function() {
expect(function() {
- new loop.store.ConversationStore({}, {
- client: client,
- dispatcher: dispatcher
+ new loop.store.ConversationStore(dispatcher, {
+ client: client
});
}).to.Throw(/sdkDriver/);
});
+
+ it("should throw an error if mozLoop is missing", function() {
+ expect(function() {
+ new loop.store.ConversationStore(dispatcher, {
+ sdkDriver: sdkDriver,
+ client: client
+ });
+ }).to.Throw(/mozLoop/);
+ });
});
describe("#connectionFailure", function() {
beforeEach(function() {
store._websocket = fakeWebsocket;
- store.set({windowId: "42"});
+ store.setStoreState({windowId: "42"});
});
it("should disconnect the session", function() {
@@ -148,71 +146,71 @@ describe("loop.store.ConversationStore", function () {
});
it("should set the state to 'terminated'", function() {
- store.set({callState: CALL_STATES.ALERTING});
+ store.setStoreState({callState: CALL_STATES.ALERTING});
store.connectionFailure(
new sharedActions.ConnectionFailure({reason: "fake"}));
- expect(store.get("callState")).eql(CALL_STATES.TERMINATED);
- expect(store.get("callStateReason")).eql("fake");
+ expect(store.getStoreState("callState")).eql(CALL_STATES.TERMINATED);
+ expect(store.getStoreState("callStateReason")).eql("fake");
});
it("should release mozLoop callsData", function() {
store.connectionFailure(
new sharedActions.ConnectionFailure({reason: "fake"}));
- sinon.assert.calledOnce(navigator.mozLoop.calls.clearCallInProgress);
+ sinon.assert.calledOnce(fakeMozLoop.calls.clearCallInProgress);
sinon.assert.calledWithExactly(
- navigator.mozLoop.calls.clearCallInProgress, "42");
+ fakeMozLoop.calls.clearCallInProgress, "42");
});
});
describe("#connectionProgress", function() {
describe("progress: init", function() {
it("should change the state from 'gather' to 'connecting'", function() {
- store.set({callState: CALL_STATES.GATHER});
+ store.setStoreState({callState: CALL_STATES.GATHER});
store.connectionProgress(
new sharedActions.ConnectionProgress({wsState: WS_STATES.INIT}));
- expect(store.get("callState")).eql(CALL_STATES.CONNECTING);
+ expect(store.getStoreState("callState")).eql(CALL_STATES.CONNECTING);
});
});
describe("progress: alerting", function() {
it("should change the state from 'gather' to 'alerting'", function() {
- store.set({callState: CALL_STATES.GATHER});
+ store.setStoreState({callState: CALL_STATES.GATHER});
store.connectionProgress(
new sharedActions.ConnectionProgress({wsState: WS_STATES.ALERTING}));
- expect(store.get("callState")).eql(CALL_STATES.ALERTING);
+ expect(store.getStoreState("callState")).eql(CALL_STATES.ALERTING);
});
it("should change the state from 'init' to 'alerting'", function() {
- store.set({callState: CALL_STATES.INIT});
+ store.setStoreState({callState: CALL_STATES.INIT});
store.connectionProgress(
new sharedActions.ConnectionProgress({wsState: WS_STATES.ALERTING}));
- expect(store.get("callState")).eql(CALL_STATES.ALERTING);
+ expect(store.getStoreState("callState")).eql(CALL_STATES.ALERTING);
});
});
describe("progress: connecting", function() {
beforeEach(function() {
- store.set({callState: CALL_STATES.ALERTING});
+ store.setStoreState({callState: CALL_STATES.ALERTING});
});
it("should change the state to 'ongoing'", function() {
store.connectionProgress(
new sharedActions.ConnectionProgress({wsState: WS_STATES.CONNECTING}));
- expect(store.get("callState")).eql(CALL_STATES.ONGOING);
+ expect(store.getStoreState("callState")).eql(CALL_STATES.ONGOING);
});
it("should connect the session", function() {
- store.set(fakeSessionData);
+ store.setStoreState(fakeSessionData);
store.connectionProgress(
new sharedActions.ConnectionProgress({wsState: WS_STATES.CONNECTING}));
@@ -226,13 +224,13 @@ describe("loop.store.ConversationStore", function () {
});
it("should call mozLoop.addConversationContext", function() {
- store.set(fakeSessionData);
+ store.setStoreState(fakeSessionData);
store.connectionProgress(
new sharedActions.ConnectionProgress({wsState: WS_STATES.CONNECTING}));
- sinon.assert.calledOnce(navigator.mozLoop.addConversationContext);
- sinon.assert.calledWithExactly(navigator.mozLoop.addConversationContext,
+ sinon.assert.calledOnce(fakeMozLoop.addConversationContext);
+ sinon.assert.calledWithExactly(fakeMozLoop.addConversationContext,
"28", "321456", "142536");
});
});
@@ -242,7 +240,7 @@ describe("loop.store.ConversationStore", function () {
var fakeSetupWindowData;
beforeEach(function() {
- store.set({callState: CALL_STATES.INIT});
+ store.setStoreState({callState: CALL_STATES.INIT});
fakeSetupWindowData = {
windowId: "123456",
type: "outgoing",
@@ -255,23 +253,24 @@ describe("loop.store.ConversationStore", function () {
dispatcher.dispatch(
new sharedActions.SetupWindowData(fakeSetupWindowData));
- expect(store.get("callState")).eql(CALL_STATES.GATHER);
+ expect(store.getStoreState("callState")).eql(CALL_STATES.GATHER);
});
it("should save the basic call information", function() {
dispatcher.dispatch(
new sharedActions.SetupWindowData(fakeSetupWindowData));
- expect(store.get("windowId")).eql("123456");
- expect(store.get("outgoing")).eql(true);
+ expect(store.getStoreState("windowId")).eql("123456");
+ expect(store.getStoreState("outgoing")).eql(true);
});
it("should save the basic information from the mozLoop api", function() {
dispatcher.dispatch(
new sharedActions.SetupWindowData(fakeSetupWindowData));
- expect(store.get("contact")).eql(contact);
- expect(store.get("callType")).eql(sharedUtils.CALL_TYPES.AUDIO_VIDEO);
+ expect(store.getStoreState("contact")).eql(contact);
+ expect(store.getStoreState("callType"))
+ .eql(sharedUtils.CALL_TYPES.AUDIO_VIDEO);
});
describe("outgoing calls", function() {
@@ -402,12 +401,12 @@ describe("loop.store.ConversationStore", function () {
store.connectCall(
new sharedActions.ConnectCall({sessionData: fakeSessionData}));
- expect(store.get("apiKey")).eql("fakeKey");
- expect(store.get("callId")).eql("142536");
- expect(store.get("sessionId")).eql("321456");
- expect(store.get("sessionToken")).eql("341256");
- expect(store.get("websocketToken")).eql("543216");
- expect(store.get("progressURL")).eql("fakeURL");
+ expect(store.getStoreState("apiKey")).eql("fakeKey");
+ expect(store.getStoreState("callId")).eql("142536");
+ expect(store.getStoreState("sessionId")).eql("321456");
+ expect(store.getStoreState("sessionToken")).eql("341256");
+ expect(store.getStoreState("websocketToken")).eql("543216");
+ expect(store.getStoreState("progressURL")).eql("fakeURL");
});
it("should initialize the websocket", function() {
@@ -488,8 +487,8 @@ describe("loop.store.ConversationStore", function () {
mediaFail: wsMediaFailSpy,
close: wsCloseSpy
};
- store.set({callState: CALL_STATES.ONGOING});
- store.set({windowId: "42"});
+ store.setStoreState({callState: CALL_STATES.ONGOING});
+ store.setStoreState({windowId: "42"});
});
it("should disconnect the session", function() {
@@ -513,15 +512,15 @@ describe("loop.store.ConversationStore", function () {
it("should set the callState to finished", function() {
store.hangupCall(new sharedActions.HangupCall());
- expect(store.get("callState")).eql(CALL_STATES.FINISHED);
+ expect(store.getStoreState("callState")).eql(CALL_STATES.FINISHED);
});
it("should release mozLoop callsData", function() {
store.hangupCall(new sharedActions.HangupCall());
- sinon.assert.calledOnce(navigator.mozLoop.calls.clearCallInProgress);
+ sinon.assert.calledOnce(fakeMozLoop.calls.clearCallInProgress);
sinon.assert.calledWithExactly(
- navigator.mozLoop.calls.clearCallInProgress, "42");
+ fakeMozLoop.calls.clearCallInProgress, "42");
});
});
@@ -535,8 +534,8 @@ describe("loop.store.ConversationStore", function () {
mediaFail: wsMediaFailSpy,
close: wsCloseSpy
};
- store.set({callState: CALL_STATES.ONGOING});
- store.set({windowId: "42"});
+ store.setStoreState({callState: CALL_STATES.ONGOING});
+ store.setStoreState({windowId: "42"});
});
it("should disconnect the session", function() {
@@ -560,9 +559,9 @@ describe("loop.store.ConversationStore", function () {
peerHungup: true
}));
- sinon.assert.calledOnce(navigator.mozLoop.calls.clearCallInProgress);
+ sinon.assert.calledOnce(fakeMozLoop.calls.clearCallInProgress);
sinon.assert.calledWithExactly(
- navigator.mozLoop.calls.clearCallInProgress, "42");
+ fakeMozLoop.calls.clearCallInProgress, "42");
});
it("should set the callState to finished if the peer hungup", function() {
@@ -570,7 +569,7 @@ describe("loop.store.ConversationStore", function () {
peerHungup: true
}));
- expect(store.get("callState")).eql(CALL_STATES.FINISHED);
+ expect(store.getStoreState("callState")).eql(CALL_STATES.FINISHED);
});
it("should set the callState to terminated if the peer was disconnected" +
@@ -579,7 +578,7 @@ describe("loop.store.ConversationStore", function () {
peerHungup: false
}));
- expect(store.get("callState")).eql(CALL_STATES.TERMINATED);
+ expect(store.getStoreState("callState")).eql(CALL_STATES.TERMINATED);
});
it("should set the reason to peerNetworkDisconnected if the peer was" +
@@ -588,7 +587,8 @@ describe("loop.store.ConversationStore", function () {
peerHungup: false
}));
- expect(store.get("callStateReason")).eql("peerNetworkDisconnected");
+ expect(store.getStoreState("callStateReason"))
+ .eql("peerNetworkDisconnected");
});
});
@@ -596,8 +596,8 @@ describe("loop.store.ConversationStore", function () {
beforeEach(function() {
store._websocket = fakeWebsocket;
- store.set({callState: CALL_STATES.CONNECTING});
- store.set({windowId: "42"});
+ store.setStoreState({callState: CALL_STATES.CONNECTING});
+ store.setStoreState({windowId: "42"});
});
it("should disconnect the session", function() {
@@ -621,37 +621,38 @@ describe("loop.store.ConversationStore", function () {
it("should set the state to close if the call is connecting", function() {
store.cancelCall(new sharedActions.CancelCall());
- expect(store.get("callState")).eql(CALL_STATES.CLOSE);
+ expect(store.getStoreState("callState")).eql(CALL_STATES.CLOSE);
});
it("should set the state to close if the call has terminated already", function() {
- store.set({callState: CALL_STATES.TERMINATED});
+ store.setStoreState({callState: CALL_STATES.TERMINATED});
store.cancelCall(new sharedActions.CancelCall());
- expect(store.get("callState")).eql(CALL_STATES.CLOSE);
+ expect(store.getStoreState("callState")).eql(CALL_STATES.CLOSE);
});
it("should release mozLoop callsData", function() {
store.cancelCall(new sharedActions.CancelCall());
- sinon.assert.calledOnce(navigator.mozLoop.calls.clearCallInProgress);
+ sinon.assert.calledOnce(fakeMozLoop.calls.clearCallInProgress);
sinon.assert.calledWithExactly(
- navigator.mozLoop.calls.clearCallInProgress, "42");
+ fakeMozLoop.calls.clearCallInProgress, "42");
});
});
describe("#retryCall", function() {
it("should set the state to gather", function() {
- store.set({callState: CALL_STATES.TERMINATED});
+ store.setStoreState({callState: CALL_STATES.TERMINATED});
store.retryCall(new sharedActions.RetryCall());
- expect(store.get("callState")).eql(CALL_STATES.GATHER);
+ expect(store.getStoreState("callState"))
+ .eql(CALL_STATES.GATHER);
});
it("should request the outgoing call data", function() {
- store.set({
+ store.setStoreState({
callState: CALL_STATES.TERMINATED,
outgoing: true,
callType: sharedUtils.CALL_TYPES.AUDIO_VIDEO,
@@ -678,25 +679,25 @@ describe("loop.store.ConversationStore", function () {
describe("#setMute", function() {
it("should save the mute state for the audio stream", function() {
- store.set({"audioMuted": false});
+ store.setStoreState({"audioMuted": false});
dispatcher.dispatch(new sharedActions.SetMute({
type: "audio",
enabled: true
}));
- expect(store.get("audioMuted")).eql(false);
+ expect(store.getStoreState("audioMuted")).eql(false);
});
it("should save the mute state for the video stream", function() {
- store.set({"videoMuted": true});
+ store.setStoreState({"videoMuted": true});
dispatcher.dispatch(new sharedActions.SetMute({
type: "video",
enabled: false
}));
- expect(store.get("videoMuted")).eql(true);
+ expect(store.getStoreState("videoMuted")).eql(true);
});
});
@@ -715,7 +716,7 @@ describe("loop.store.ConversationStore", function () {
};
store.fetchEmailLink(new sharedActions.FetchEmailLink());
- expect(store.get("emailLink")).eql("http://fake.invalid/");
+ expect(store.getStoreState("emailLink")).eql("http://fake.invalid/");
});
it("should trigger an error:emailLink event in case of failure",
diff --git a/browser/components/loop/test/standalone/standaloneRoomViews_test.js b/browser/components/loop/test/standalone/standaloneRoomViews_test.js
index fbdbc653eee4..d93b0ceb7ca2 100644
--- a/browser/components/loop/test/standalone/standaloneRoomViews_test.js
+++ b/browser/components/loop/test/standalone/standaloneRoomViews_test.js
@@ -203,6 +203,14 @@ describe("loop.standaloneRoomViews", function() {
expect(view.getDOMNode().querySelector(".failed-room-message"))
.not.eql(null);
});
+
+ it("should display a retry button",
+ function() {
+ activeRoomStore.setStoreState({roomState: ROOM_STATES.FAILED});
+
+ expect(view.getDOMNode().querySelector(".btn-info"))
+ .not.eql(null);
+ });
});
describe("Join button", function() {
diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp
index c3b02f5dfa2a..09d4b057aee2 100644
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -8333,9 +8333,6 @@ Parser::accumulateTelemetry()
JSContext* cx = context->maybeJSContext();
if (!cx)
return;
- JSAccumulateTelemetryDataCallback cb = cx->runtime()->telemetryCallback;
- if (!cb)
- return;
const char* filename = getFilename();
if (!filename)
return;
@@ -8361,17 +8358,17 @@ Parser::accumulateTelemetry()
// Call back into Firefox's Telemetry reporter.
if (sawDeprecatedForEach)
- (*cb)(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedForEach);
+ cx->runtime()->addTelemetry(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedForEach);
if (sawDeprecatedDestructuringForIn)
- (*cb)(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedDestructuringForIn);
+ cx->runtime()->addTelemetry(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedDestructuringForIn);
if (sawDeprecatedLegacyGenerator)
- (*cb)(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedLegacyGenerator);
+ cx->runtime()->addTelemetry(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedLegacyGenerator);
if (sawDeprecatedExpressionClosure)
- (*cb)(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedExpressionClosure);
+ cx->runtime()->addTelemetry(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedExpressionClosure);
if (sawDeprecatedLetBlock)
- (*cb)(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedLetBlock);
+ cx->runtime()->addTelemetry(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedLetBlock);
if (sawDeprecatedLetExpression)
- (*cb)(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedLetExpression);
+ cx->runtime()->addTelemetry(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedLetExpression);
}
template class Parser;
diff --git a/js/src/gc/Statistics.cpp b/js/src/gc/Statistics.cpp
index 56f8153ef623..da56309c4e40 100644
--- a/js/src/gc/Statistics.cpp
+++ b/js/src/gc/Statistics.cpp
@@ -749,28 +749,26 @@ Statistics::endGC()
for (int i = 0; i < PHASE_LIMIT; i++)
phaseTotals[i] += phaseTimes[i];
- if (JSAccumulateTelemetryDataCallback cb = runtime->telemetryCallback) {
- int64_t total, longest;
- gcDuration(&total, &longest);
+ int64_t total, longest;
+ gcDuration(&total, &longest);
- int64_t sccTotal, sccLongest;
- sccDurations(&sccTotal, &sccLongest);
+ int64_t sccTotal, sccLongest;
+ sccDurations(&sccTotal, &sccLongest);
- (*cb)(JS_TELEMETRY_GC_IS_COMPARTMENTAL, !zoneStats.isCollectingAllZones());
- (*cb)(JS_TELEMETRY_GC_MS, t(total));
- (*cb)(JS_TELEMETRY_GC_MAX_PAUSE_MS, t(longest));
- (*cb)(JS_TELEMETRY_GC_MARK_MS, t(phaseTimes[PHASE_MARK]));
- (*cb)(JS_TELEMETRY_GC_SWEEP_MS, t(phaseTimes[PHASE_SWEEP]));
- (*cb)(JS_TELEMETRY_GC_MARK_ROOTS_MS, t(phaseTimes[PHASE_MARK_ROOTS]));
- (*cb)(JS_TELEMETRY_GC_MARK_GRAY_MS, t(phaseTimes[PHASE_SWEEP_MARK_GRAY]));
- (*cb)(JS_TELEMETRY_GC_NON_INCREMENTAL, !!nonincrementalReason);
- (*cb)(JS_TELEMETRY_GC_INCREMENTAL_DISABLED, !runtime->gc.isIncrementalGCAllowed());
- (*cb)(JS_TELEMETRY_GC_SCC_SWEEP_TOTAL_MS, t(sccTotal));
- (*cb)(JS_TELEMETRY_GC_SCC_SWEEP_MAX_PAUSE_MS, t(sccLongest));
-
- double mmu50 = computeMMU(50 * PRMJ_USEC_PER_MSEC);
- (*cb)(JS_TELEMETRY_GC_MMU_50, mmu50 * 100);
- }
+ runtime->addTelemetry(JS_TELEMETRY_GC_IS_COMPARTMENTAL, !zoneStats.isCollectingAllZones());
+ runtime->addTelemetry(JS_TELEMETRY_GC_MS, t(total));
+ runtime->addTelemetry(JS_TELEMETRY_GC_MAX_PAUSE_MS, t(longest));
+ runtime->addTelemetry(JS_TELEMETRY_GC_MARK_MS, t(phaseTimes[PHASE_MARK]));
+ runtime->addTelemetry(JS_TELEMETRY_GC_SWEEP_MS, t(phaseTimes[PHASE_SWEEP]));
+ runtime->addTelemetry(JS_TELEMETRY_GC_MARK_ROOTS_MS, t(phaseTimes[PHASE_MARK_ROOTS]));
+ runtime->addTelemetry(JS_TELEMETRY_GC_MARK_GRAY_MS, t(phaseTimes[PHASE_SWEEP_MARK_GRAY]));
+ runtime->addTelemetry(JS_TELEMETRY_GC_NON_INCREMENTAL, !!nonincrementalReason);
+ runtime->addTelemetry(JS_TELEMETRY_GC_INCREMENTAL_DISABLED, !runtime->gc.isIncrementalGCAllowed());
+ runtime->addTelemetry(JS_TELEMETRY_GC_SCC_SWEEP_TOTAL_MS, t(sccTotal));
+ runtime->addTelemetry(JS_TELEMETRY_GC_SCC_SWEEP_MAX_PAUSE_MS, t(sccLongest));
+
+ double mmu50 = computeMMU(50 * PRMJ_USEC_PER_MSEC);
+ runtime->addTelemetry(JS_TELEMETRY_GC_MMU_50, mmu50 * 100);
if (fp)
printStats();
@@ -795,8 +793,7 @@ Statistics::beginSlice(const ZoneGCStats &zoneStats, JSGCInvocationKind gckind,
if (!slices.append(data))
CrashAtUnhandlableOOM("Failed to allocate statistics slice.");
- if (JSAccumulateTelemetryDataCallback cb = runtime->telemetryCallback)
- (*cb)(JS_TELEMETRY_GC_REASON, reason);
+ runtime->addTelemetry(JS_TELEMETRY_GC_REASON, reason);
// Slice callbacks should only fire for the outermost level
if (++gcDepth == 1) {
@@ -813,10 +810,8 @@ Statistics::endSlice()
slices.back().end = PRMJ_Now();
slices.back().endFaults = GetPageFaultCount();
- if (JSAccumulateTelemetryDataCallback cb = runtime->telemetryCallback) {
- (*cb)(JS_TELEMETRY_GC_SLICE_MS, t(slices.back().end - slices.back().start));
- (*cb)(JS_TELEMETRY_GC_RESET, !!slices.back().resetReason);
- }
+ runtime->addTelemetry(JS_TELEMETRY_GC_SLICE_MS, t(slices.back().end - slices.back().start));
+ runtime->addTelemetry(JS_TELEMETRY_GC_RESET, !!slices.back().resetReason);
bool last = runtime->gc.state() == gc::NO_INCREMENTAL;
if (last)
diff --git a/js/src/jsexn.cpp b/js/src/jsexn.cpp
index c6ea97105fe6..7bb75548c911 100644
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -20,6 +20,7 @@
#include "jsfun.h"
#include "jsnum.h"
#include "jsobj.h"
+#include "jsprf.h"
#include "jsscript.h"
#include "jstypes.h"
#include "jsutil.h"
@@ -713,8 +714,31 @@ ErrorReport::init(JSContext *cx, HandleValue exn)
if (exn.isObject()) {
exnObject = &exn.toObject();
reportp = js_ErrorFromException(cx, exnObject);
- }
+ JSCompartment *comp = exnObject->compartment();
+ JSAddonId *addonId = comp->addonId;
+ if (addonId) {
+ UniqueChars addonIdChars(JS_EncodeString(cx, addonId));
+
+ const char *filename = nullptr;
+
+ if (reportp && reportp->filename) {
+ filename = strrchr(reportp->filename, '/');
+ if (filename)
+ filename++;
+ }
+ if (!filename) {
+ filename = "FILE_NOT_FOUND";
+ }
+ char histogramKey[64];
+ JS_snprintf(histogramKey, sizeof(histogramKey),
+ "%s %s %u",
+ addonIdChars.get(),
+ filename,
+ (reportp ? reportp->lineno : 0) );
+ cx->runtime()->addTelemetry(JS_TELEMETRY_ADDON_EXCEPTIONS, 1, histogramKey);
+ }
+ }
// Be careful not to invoke ToString if we've already successfully extracted
// an error report, since the exception might be wrapped in a security
// wrapper, and ToString-ing it might throw.
diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp
index 230676e8718f..9d9d45adfb1a 100644
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -681,7 +681,7 @@ js::StringToLinearStringSlow(JSContext *cx, JSString *str)
JS_FRIEND_API(void)
JS_SetAccumulateTelemetryCallback(JSRuntime *rt, JSAccumulateTelemetryDataCallback callback)
{
- rt->telemetryCallback = callback;
+ rt->setTelemetryCallback(rt, callback);
}
JS_FRIEND_API(JSObject *)
diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h
index 78112e6e3dca..e9a7a0ff67e9 100644
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -110,11 +110,12 @@ enum {
JS_TELEMETRY_GC_NON_INCREMENTAL,
JS_TELEMETRY_GC_SCC_SWEEP_TOTAL_MS,
JS_TELEMETRY_GC_SCC_SWEEP_MAX_PAUSE_MS,
- JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT
+ JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT,
+ JS_TELEMETRY_ADDON_EXCEPTIONS
};
typedef void
-(* JSAccumulateTelemetryDataCallback)(int id, uint32_t sample);
+(*JSAccumulateTelemetryDataCallback)(int id, uint32_t sample, const char *key);
extern JS_FRIEND_API(void)
JS_SetAccumulateTelemetryCallback(JSRuntime *rt, JSAccumulateTelemetryDataCallback callback);
diff --git a/js/src/vm/Runtime.cpp b/js/src/vm/Runtime.cpp
index fa1167bb3864..e79390adf035 100644
--- a/js/src/vm/Runtime.cpp
+++ b/js/src/vm/Runtime.cpp
@@ -139,6 +139,7 @@ JSRuntime::JSRuntime(JSRuntime *parentRuntime)
parentRuntime(parentRuntime),
interrupt_(false),
interruptPar_(false),
+ telemetryCallback(nullptr),
handlingSignal(false),
interruptCallback(nullptr),
exclusiveAccessLock(nullptr),
@@ -196,7 +197,6 @@ JSRuntime::JSRuntime(JSRuntime *parentRuntime)
DOMcallbacks(nullptr),
destroyPrincipals(nullptr),
structuredCloneCallbacks(nullptr),
- telemetryCallback(nullptr),
errorReporter(nullptr),
linkedAsmJSModules(nullptr),
propertyRemovals(0),
@@ -458,6 +458,19 @@ JSRuntime::~JSRuntime()
#endif
}
+void
+JSRuntime::addTelemetry(int id, uint32_t sample, const char *key)
+{
+ if (telemetryCallback)
+ (*telemetryCallback)(id, sample, key);
+}
+
+void
+JSRuntime::setTelemetryCallback(JSRuntime *rt, JSAccumulateTelemetryDataCallback callback)
+{
+ rt->telemetryCallback = callback;
+}
+
void
NewObjectCache::clearNurseryObjects(JSRuntime *rt)
{
diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h
index 55c040be182a..cb62d03d600b 100644
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -707,7 +707,16 @@ struct JSRuntime : public JS::shadow::Runtime,
private:
mozilla::Atomic interrupt_;
mozilla::Atomic interruptPar_;
+
+ /* Call this to accumulate telemetry data. */
+ JSAccumulateTelemetryDataCallback telemetryCallback;
public:
+ // Accumulates data for Firefox telemetry. |id| is the ID of a JS_TELEMETRY_*
+ // histogram. |key| provides an additional key to identify the histogram.
+ // |sample| is the data to add to the histogram.
+ void addTelemetry(int id, uint32_t sample, const char *key = nullptr);
+
+ void setTelemetryCallback(JSRuntime *rt, JSAccumulateTelemetryDataCallback callback);
enum InterruptMode {
RequestInterruptUrgent,
@@ -1090,9 +1099,6 @@ struct JSRuntime : public JS::shadow::Runtime,
/* Structured data callbacks are runtime-wide. */
const JSStructuredCloneCallbacks *structuredCloneCallbacks;
- /* Call this to accumulate telemetry data. */
- JSAccumulateTelemetryDataCallback telemetryCallback;
-
/* Optional error reporter. */
JSErrorReporter errorReporter;
diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp
index e85a181e1be2..7f917322a0fb 100644
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -2963,7 +2963,7 @@ DiagnosticMemoryCallback(void *ptr, size_t size)
#endif
static void
-AccumulateTelemetryCallback(int id, uint32_t sample)
+AccumulateTelemetryCallback(int id, uint32_t sample, const char *key)
{
switch (id) {
case JS_TELEMETRY_GC_REASON:
@@ -3015,6 +3015,9 @@ AccumulateTelemetryCallback(int id, uint32_t sample)
MOZ_ASSERT(sample <= 5);
Telemetry::Accumulate(Telemetry::JS_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, sample);
break;
+ case JS_TELEMETRY_ADDON_EXCEPTIONS:
+ Telemetry::Accumulate(Telemetry::JS_TELEMETRY_ADDON_EXCEPTIONS, nsDependentCString(key), sample);
+ break;
default:
MOZ_ASSERT_UNREACHABLE("Unexpected JS_TELEMETRY id");
}
diff --git a/mobile/android/base/db/BrowserContract.java b/mobile/android/base/db/BrowserContract.java
index f5d40b003da8..4f9922933115 100644
--- a/mobile/android/base/db/BrowserContract.java
+++ b/mobile/android/base/db/BrowserContract.java
@@ -157,7 +157,6 @@ public class BrowserContract {
public static final String TAGS_FOLDER_GUID = "tags";
public static final String TOOLBAR_FOLDER_GUID = "toolbar";
public static final String UNFILED_FOLDER_GUID = "unfiled";
- public static final String READING_LIST_FOLDER_GUID = "readinglist";
public static final String FAKE_DESKTOP_FOLDER_GUID = "desktop";
public static final String PINNED_FOLDER_GUID = "pinned";
@@ -342,53 +341,6 @@ public class BrowserContract {
new String[] { _ID, DATASET_ID, URL, TITLE, DESCRIPTION, IMAGE_URL, FILTER };
}
- /*
- * Contains names and schema definitions for tables and views
- * no longer being used by current ContentProviders. These values are used
- * to make incremental updates to the schema during a database upgrade. Will be
- * removed with bug 947018.
- */
- static final class Obsolete {
- public static final String TABLE_IMAGES = "images";
- public static final String VIEW_BOOKMARKS_WITH_IMAGES = "bookmarks_with_images";
- public static final String VIEW_HISTORY_WITH_IMAGES = "history_with_images";
- public static final String VIEW_COMBINED_WITH_IMAGES = "combined_with_images";
-
- public static final class Images implements CommonColumns, SyncColumns {
- private Images() {}
-
- public static final String URL = "url_key";
- public static final String FAVICON_URL = "favicon_url";
- public static final String FAVICON = "favicon";
- public static final String THUMBNAIL = "thumbnail";
- public static final String _ID = "_id";
- public static final String GUID = "guid";
- public static final String DATE_CREATED = "created";
- public static final String DATE_MODIFIED = "modified";
- public static final String IS_DELETED = "deleted";
- }
-
- public static final class Combined {
- private Combined() {}
-
- public static final String THUMBNAIL = "thumbnail";
- public static final String DISPLAY = "display";
-
- public static final int DISPLAY_NORMAL = 0;
- public static final int DISPLAY_READER = 1;
- }
-
- static final String TABLE_BOOKMARKS_JOIN_IMAGES = Bookmarks.TABLE_NAME + " LEFT OUTER JOIN " +
- Obsolete.TABLE_IMAGES + " ON " + Bookmarks.TABLE_NAME + "." + Bookmarks.URL + " = " +
- Obsolete.TABLE_IMAGES + "." + Obsolete.Images.URL;
-
- static final String TABLE_HISTORY_JOIN_IMAGES = History.TABLE_NAME + " LEFT OUTER JOIN " +
- Obsolete.TABLE_IMAGES + " ON " + Bookmarks.TABLE_NAME + "." + History.URL + " = " +
- Obsolete.TABLE_IMAGES + "." + Obsolete.Images.URL;
-
- static final String FAVICON_DB = "favicon_urls.db";
- }
-
@RobocopTarget
public static final class ReadingListItems implements CommonColumns, URLColumns, SyncColumns {
private ReadingListItems() {}
diff --git a/mobile/android/base/db/BrowserDatabaseHelper.java b/mobile/android/base/db/BrowserDatabaseHelper.java
index e77c32d7deed..7505fca68d9e 100644
--- a/mobile/android/base/db/BrowserDatabaseHelper.java
+++ b/mobile/android/base/db/BrowserDatabaseHelper.java
@@ -11,14 +11,12 @@ import java.util.List;
import org.mozilla.gecko.R;
import org.mozilla.gecko.db.BrowserContract.Bookmarks;
import org.mozilla.gecko.db.BrowserContract.Combined;
-import org.mozilla.gecko.db.BrowserContract.FaviconColumns;
import org.mozilla.gecko.db.BrowserContract.Favicons;
import org.mozilla.gecko.db.BrowserContract.History;
-import org.mozilla.gecko.db.BrowserContract.Obsolete;
import org.mozilla.gecko.db.BrowserContract.ReadingListItems;
import org.mozilla.gecko.db.BrowserContract.SearchHistory;
import org.mozilla.gecko.db.BrowserContract.Thumbnails;
-import org.mozilla.gecko.sync.Utils;
+import static org.mozilla.gecko.db.DBUtils.qualifyColumn;
import android.content.ContentValues;
import android.content.Context;
@@ -61,7 +59,6 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
static final String TABLE_BOOKMARKS_TMP = TABLE_BOOKMARKS + "_tmp";
static final String TABLE_HISTORY_TMP = TABLE_HISTORY + "_tmp";
- static final String TABLE_IMAGES_TMP = Obsolete.TABLE_IMAGES + "_tmp";
private static final String[] mobileIdColumns = new String[] { Bookmarks._ID };
private static final String[] mobileIdSelectionArgs = new String[] { Bookmarks.MOBILE_FOLDER_GUID };
@@ -74,37 +71,6 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
private void createBookmarksTable(SQLiteDatabase db) {
debug("Creating " + TABLE_BOOKMARKS + " table");
- db.execSQL("CREATE TABLE " + TABLE_BOOKMARKS + "(" +
- Bookmarks._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
- Bookmarks.TITLE + " TEXT," +
- Bookmarks.URL + " TEXT," +
- Bookmarks.TYPE + " INTEGER NOT NULL DEFAULT " + Bookmarks.TYPE_BOOKMARK + "," +
- Bookmarks.PARENT + " INTEGER," +
- Bookmarks.POSITION + " INTEGER NOT NULL," +
- Bookmarks.KEYWORD + " TEXT," +
- Bookmarks.DESCRIPTION + " TEXT," +
- Bookmarks.TAGS + " TEXT," +
- Bookmarks.DATE_CREATED + " INTEGER," +
- Bookmarks.DATE_MODIFIED + " INTEGER," +
- Bookmarks.GUID + " TEXT NOT NULL," +
- Bookmarks.IS_DELETED + " INTEGER NOT NULL DEFAULT 0, " +
- "FOREIGN KEY (" + Bookmarks.PARENT + ") REFERENCES " +
- TABLE_BOOKMARKS + "(" + Bookmarks._ID + ")" +
- ");");
-
- db.execSQL("CREATE INDEX bookmarks_url_index ON " + TABLE_BOOKMARKS + "("
- + Bookmarks.URL + ")");
- db.execSQL("CREATE INDEX bookmarks_type_deleted_index ON " + TABLE_BOOKMARKS + "("
- + Bookmarks.TYPE + ", " + Bookmarks.IS_DELETED + ")");
- db.execSQL("CREATE UNIQUE INDEX bookmarks_guid_index ON " + TABLE_BOOKMARKS + "("
- + Bookmarks.GUID + ")");
- db.execSQL("CREATE INDEX bookmarks_modified_index ON " + TABLE_BOOKMARKS + "("
- + Bookmarks.DATE_MODIFIED + ")");
- }
-
- private void createBookmarksTableOn13(SQLiteDatabase db) {
- debug("Creating " + TABLE_BOOKMARKS + " table");
-
db.execSQL("CREATE TABLE " + TABLE_BOOKMARKS + "(" +
Bookmarks._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
Bookmarks.TITLE + " TEXT," +
@@ -135,30 +101,6 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
}
private void createHistoryTable(SQLiteDatabase db) {
- debug("Creating " + TABLE_HISTORY + " table");
- db.execSQL("CREATE TABLE " + TABLE_HISTORY + "(" +
- History._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
- History.TITLE + " TEXT," +
- History.URL + " TEXT NOT NULL," +
- History.VISITS + " INTEGER NOT NULL DEFAULT 0," +
- History.DATE_LAST_VISITED + " INTEGER," +
- History.DATE_CREATED + " INTEGER," +
- History.DATE_MODIFIED + " INTEGER," +
- History.GUID + " TEXT NOT NULL," +
- History.IS_DELETED + " INTEGER NOT NULL DEFAULT 0" +
- ");");
-
- db.execSQL("CREATE INDEX history_url_index ON " + TABLE_HISTORY + "("
- + History.URL + ")");
- db.execSQL("CREATE UNIQUE INDEX history_guid_index ON " + TABLE_HISTORY + "("
- + History.GUID + ")");
- db.execSQL("CREATE INDEX history_modified_index ON " + TABLE_HISTORY + "("
- + History.DATE_MODIFIED + ")");
- db.execSQL("CREATE INDEX history_visited_index ON " + TABLE_HISTORY + "("
- + History.DATE_LAST_VISITED + ")");
- }
-
- private void createHistoryTableOn13(SQLiteDatabase db) {
debug("Creating " + TABLE_HISTORY + " table");
db.execSQL("CREATE TABLE " + TABLE_HISTORY + "(" +
History._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
@@ -173,36 +115,14 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
History.IS_DELETED + " INTEGER NOT NULL DEFAULT 0" +
");");
- db.execSQL("CREATE INDEX history_url_index ON " + TABLE_HISTORY + "("
- + History.URL + ")");
- db.execSQL("CREATE UNIQUE INDEX history_guid_index ON " + TABLE_HISTORY + "("
- + History.GUID + ")");
- db.execSQL("CREATE INDEX history_modified_index ON " + TABLE_HISTORY + "("
- + History.DATE_MODIFIED + ")");
- db.execSQL("CREATE INDEX history_visited_index ON " + TABLE_HISTORY + "("
- + History.DATE_LAST_VISITED + ")");
- }
-
- private void createImagesTable(SQLiteDatabase db) {
- debug("Creating " + Obsolete.TABLE_IMAGES + " table");
- db.execSQL("CREATE TABLE " + Obsolete.TABLE_IMAGES + " (" +
- Obsolete.Images._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
- Obsolete.Images.URL + " TEXT UNIQUE NOT NULL," +
- Obsolete.Images.FAVICON + " BLOB," +
- Obsolete.Images.FAVICON_URL + " TEXT," +
- Obsolete.Images.THUMBNAIL + " BLOB," +
- Obsolete.Images.DATE_CREATED + " INTEGER," +
- Obsolete.Images.DATE_MODIFIED + " INTEGER," +
- Obsolete.Images.GUID + " TEXT NOT NULL," +
- Obsolete.Images.IS_DELETED + " INTEGER NOT NULL DEFAULT 0" +
- ");");
-
- db.execSQL("CREATE INDEX images_url_index ON " + Obsolete.TABLE_IMAGES + "("
- + Obsolete.Images.URL + ")");
- db.execSQL("CREATE UNIQUE INDEX images_guid_index ON " + Obsolete.TABLE_IMAGES + "("
- + Obsolete.Images.GUID + ")");
- db.execSQL("CREATE INDEX images_modified_index ON " + Obsolete.TABLE_IMAGES + "("
- + Obsolete.Images.DATE_MODIFIED + ")");
+ db.execSQL("CREATE INDEX history_url_index ON " + TABLE_HISTORY + '('
+ + History.URL + ')');
+ db.execSQL("CREATE UNIQUE INDEX history_guid_index ON " + TABLE_HISTORY + '('
+ + History.GUID + ')');
+ db.execSQL("CREATE INDEX history_modified_index ON " + TABLE_HISTORY + '('
+ + History.DATE_MODIFIED + ')');
+ db.execSQL("CREATE INDEX history_visited_index ON " + TABLE_HISTORY + '('
+ + History.DATE_LAST_VISITED + ')');
}
private void createFaviconsTable(SQLiteDatabase db) {
@@ -233,15 +153,6 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
+ Thumbnails.URL + ")");
}
- private void createBookmarksWithImagesView(SQLiteDatabase db) {
- debug("Creating " + Obsolete.VIEW_BOOKMARKS_WITH_IMAGES + " view");
-
- db.execSQL("CREATE VIEW IF NOT EXISTS " + Obsolete.VIEW_BOOKMARKS_WITH_IMAGES + " AS " +
- "SELECT " + qualifyColumn(TABLE_BOOKMARKS, "*") +
- ", " + Obsolete.Images.FAVICON + ", " + Obsolete.Images.THUMBNAIL + " FROM " +
- Obsolete.TABLE_BOOKMARKS_JOIN_IMAGES);
- }
-
private void createBookmarksWithFaviconsView(SQLiteDatabase db) {
debug("Creating " + VIEW_BOOKMARKS_WITH_FAVICONS + " view");
@@ -252,15 +163,6 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
" FROM " + TABLE_BOOKMARKS_JOIN_FAVICONS);
}
- private void createHistoryWithImagesView(SQLiteDatabase db) {
- debug("Creating " + Obsolete.VIEW_HISTORY_WITH_IMAGES + " view");
-
- db.execSQL("CREATE VIEW IF NOT EXISTS " + Obsolete.VIEW_HISTORY_WITH_IMAGES + " AS " +
- "SELECT " + qualifyColumn(TABLE_HISTORY, "*") +
- ", " + Obsolete.Images.FAVICON + ", " + Obsolete.Images.THUMBNAIL + " FROM " +
- Obsolete.TABLE_HISTORY_JOIN_IMAGES);
- }
-
private void createHistoryWithFaviconsView(SQLiteDatabase db) {
debug("Creating " + VIEW_HISTORY_WITH_FAVICONS + " view");
@@ -271,363 +173,6 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
" FROM " + TABLE_HISTORY_JOIN_FAVICONS);
}
- private void createCombinedWithImagesView(SQLiteDatabase db) {
- debug("Creating " + Obsolete.VIEW_COMBINED_WITH_IMAGES + " view");
-
- db.execSQL("CREATE VIEW IF NOT EXISTS " + Obsolete.VIEW_COMBINED_WITH_IMAGES + " AS" +
- " SELECT " + Combined.BOOKMARK_ID + ", " +
- Combined.HISTORY_ID + ", " +
- // We need to return an _id column because CursorAdapter requires it for its
- // default implementation for the getItemId() method. However, since
- // we're not using this feature in the parts of the UI using this view,
- // we can just use 0 for all rows.
- "0 AS " + Combined._ID + ", " +
- Combined.URL + ", " +
- Combined.TITLE + ", " +
- Combined.VISITS + ", " +
- Combined.DATE_LAST_VISITED + ", " +
- qualifyColumn(Obsolete.TABLE_IMAGES, Obsolete.Images.FAVICON) + " AS " + Combined.FAVICON + ", " +
- qualifyColumn(Obsolete.TABLE_IMAGES, Obsolete.Images.THUMBNAIL) + " AS " + Obsolete.Combined.THUMBNAIL +
- " FROM (" +
- // Bookmarks without history.
- " SELECT " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks._ID) + " AS " + Combined.BOOKMARK_ID + ", " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.URL) + " AS " + Combined.URL + ", " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TITLE) + " AS " + Combined.TITLE + ", " +
- "-1 AS " + Combined.HISTORY_ID + ", " +
- "-1 AS " + Combined.VISITS + ", " +
- "-1 AS " + Combined.DATE_LAST_VISITED +
- " FROM " + TABLE_BOOKMARKS +
- " WHERE " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TYPE) + " = " + Bookmarks.TYPE_BOOKMARK + " AND " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.IS_DELETED) + " = 0 AND " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.URL) +
- " NOT IN (SELECT " + History.URL + " FROM " + TABLE_HISTORY + ")" +
- " UNION ALL" +
- // History with and without bookmark.
- " SELECT " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks._ID) + " AS " + Combined.BOOKMARK_ID + ", " +
- qualifyColumn(TABLE_HISTORY, History.URL) + " AS " + Combined.URL + ", " +
- // Prioritize bookmark titles over history titles, since the user may have
- // customized the title for a bookmark.
- "COALESCE(" + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TITLE) + ", " +
- qualifyColumn(TABLE_HISTORY, History.TITLE) +")" + " AS " + Combined.TITLE + ", " +
- qualifyColumn(TABLE_HISTORY, History._ID) + " AS " + Combined.HISTORY_ID + ", " +
- qualifyColumn(TABLE_HISTORY, History.VISITS) + " AS " + Combined.VISITS + ", " +
- qualifyColumn(TABLE_HISTORY, History.DATE_LAST_VISITED) + " AS " + Combined.DATE_LAST_VISITED +
- " FROM " + TABLE_HISTORY + " LEFT OUTER JOIN " + TABLE_BOOKMARKS +
- " ON " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.URL) + " = " + qualifyColumn(TABLE_HISTORY, History.URL) +
- " WHERE " + qualifyColumn(TABLE_HISTORY, History.URL) + " IS NOT NULL AND " +
- qualifyColumn(TABLE_HISTORY, History.IS_DELETED) + " = 0 AND (" +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TYPE) + " IS NULL OR " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TYPE) + " = " + Bookmarks.TYPE_BOOKMARK + ")" +
- ") LEFT OUTER JOIN " + Obsolete.TABLE_IMAGES +
- " ON " + Combined.URL + " = " + qualifyColumn(Obsolete.TABLE_IMAGES, Obsolete.Images.URL));
- }
-
- private void createCombinedWithImagesViewOn9(SQLiteDatabase db) {
- debug("Creating " + Obsolete.VIEW_COMBINED_WITH_IMAGES + " view");
-
- db.execSQL("CREATE VIEW IF NOT EXISTS " + Obsolete.VIEW_COMBINED_WITH_IMAGES + " AS" +
- " SELECT " + Combined.BOOKMARK_ID + ", " +
- Combined.HISTORY_ID + ", " +
- // We need to return an _id column because CursorAdapter requires it for its
- // default implementation for the getItemId() method. However, since
- // we're not using this feature in the parts of the UI using this view,
- // we can just use 0 for all rows.
- "0 AS " + Combined._ID + ", " +
- Combined.URL + ", " +
- Combined.TITLE + ", " +
- Combined.VISITS + ", " +
- Obsolete.Combined.DISPLAY + ", " +
- Combined.DATE_LAST_VISITED + ", " +
- qualifyColumn(Obsolete.TABLE_IMAGES, Obsolete.Images.FAVICON) + " AS " + Combined.FAVICON + ", " +
- qualifyColumn(Obsolete.TABLE_IMAGES, Obsolete.Images.THUMBNAIL) + " AS " + Obsolete.Combined.THUMBNAIL +
- " FROM (" +
- // Bookmarks without history.
- " SELECT " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks._ID) + " AS " + Combined.BOOKMARK_ID + ", " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.URL) + " AS " + Combined.URL + ", " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TITLE) + " AS " + Combined.TITLE + ", " +
- "CASE " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.PARENT) + " WHEN " +
- Bookmarks.FIXED_READING_LIST_ID + " THEN " + Obsolete.Combined.DISPLAY_READER + " ELSE " +
- Obsolete.Combined.DISPLAY_NORMAL + " END AS " + Obsolete.Combined.DISPLAY + ", " +
- "-1 AS " + Combined.HISTORY_ID + ", " +
- "-1 AS " + Combined.VISITS + ", " +
- "-1 AS " + Combined.DATE_LAST_VISITED +
- " FROM " + TABLE_BOOKMARKS +
- " WHERE " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TYPE) + " = " + Bookmarks.TYPE_BOOKMARK + " AND " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.IS_DELETED) + " = 0 AND " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.URL) +
- " NOT IN (SELECT " + History.URL + " FROM " + TABLE_HISTORY + ")" +
- " UNION ALL" +
- // History with and without bookmark.
- " SELECT " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks._ID) + " AS " + Combined.BOOKMARK_ID + ", " +
- qualifyColumn(TABLE_HISTORY, History.URL) + " AS " + Combined.URL + ", " +
- // Prioritize bookmark titles over history titles, since the user may have
- // customized the title for a bookmark.
- "COALESCE(" + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TITLE) + ", " +
- qualifyColumn(TABLE_HISTORY, History.TITLE) +")" + " AS " + Combined.TITLE + ", " +
- "CASE " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.PARENT) + " WHEN " +
- Bookmarks.FIXED_READING_LIST_ID + " THEN " + Obsolete.Combined.DISPLAY_READER + " ELSE " +
- Obsolete.Combined.DISPLAY_NORMAL + " END AS " + Obsolete.Combined.DISPLAY + ", " +
- qualifyColumn(TABLE_HISTORY, History._ID) + " AS " + Combined.HISTORY_ID + ", " +
- qualifyColumn(TABLE_HISTORY, History.VISITS) + " AS " + Combined.VISITS + ", " +
- qualifyColumn(TABLE_HISTORY, History.DATE_LAST_VISITED) + " AS " + Combined.DATE_LAST_VISITED +
- " FROM " + TABLE_HISTORY + " LEFT OUTER JOIN " + TABLE_BOOKMARKS +
- " ON " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.URL) + " = " + qualifyColumn(TABLE_HISTORY, History.URL) +
- " WHERE " + qualifyColumn(TABLE_HISTORY, History.URL) + " IS NOT NULL AND " +
- qualifyColumn(TABLE_HISTORY, History.IS_DELETED) + " = 0 AND (" +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TYPE) + " IS NULL OR " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TYPE) + " = " + Bookmarks.TYPE_BOOKMARK + ")" +
- ") LEFT OUTER JOIN " + Obsolete.TABLE_IMAGES +
- " ON " + Combined.URL + " = " + qualifyColumn(Obsolete.TABLE_IMAGES, Obsolete.Images.URL));
- }
-
- private void createCombinedWithImagesViewOn10(SQLiteDatabase db) {
- debug("Creating " + Obsolete.VIEW_COMBINED_WITH_IMAGES + " view");
-
- db.execSQL("CREATE VIEW IF NOT EXISTS " + Obsolete.VIEW_COMBINED_WITH_IMAGES + " AS" +
- " SELECT " + Combined.BOOKMARK_ID + ", " +
- Combined.HISTORY_ID + ", " +
- // We need to return an _id column because CursorAdapter requires it for its
- // default implementation for the getItemId() method. However, since
- // we're not using this feature in the parts of the UI using this view,
- // we can just use 0 for all rows.
- "0 AS " + Combined._ID + ", " +
- Combined.URL + ", " +
- Combined.TITLE + ", " +
- Combined.VISITS + ", " +
- Obsolete.Combined.DISPLAY + ", " +
- Combined.DATE_LAST_VISITED + ", " +
- qualifyColumn(Obsolete.TABLE_IMAGES, Obsolete.Images.FAVICON) + " AS " + Combined.FAVICON + ", " +
- qualifyColumn(Obsolete.TABLE_IMAGES, Obsolete.Images.THUMBNAIL) + " AS " + Obsolete.Combined.THUMBNAIL +
- " FROM (" +
- // Bookmarks without history.
- " SELECT " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks._ID) + " AS " + Combined.BOOKMARK_ID + ", " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.URL) + " AS " + Combined.URL + ", " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TITLE) + " AS " + Combined.TITLE + ", " +
- "CASE " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.PARENT) + " WHEN " +
- Bookmarks.FIXED_READING_LIST_ID + " THEN " + Obsolete.Combined.DISPLAY_READER + " ELSE " +
- Obsolete.Combined.DISPLAY_NORMAL + " END AS " + Obsolete.Combined.DISPLAY + ", " +
- "-1 AS " + Combined.HISTORY_ID + ", " +
- "-1 AS " + Combined.VISITS + ", " +
- "-1 AS " + Combined.DATE_LAST_VISITED +
- " FROM " + TABLE_BOOKMARKS +
- " WHERE " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TYPE) + " = " + Bookmarks.TYPE_BOOKMARK + " AND " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.IS_DELETED) + " = 0 AND " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.URL) +
- " NOT IN (SELECT " + History.URL + " FROM " + TABLE_HISTORY + ")" +
- " UNION ALL" +
- // History with and without bookmark.
- " SELECT " + "CASE " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.IS_DELETED) + " WHEN 0 THEN " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks._ID) + " ELSE NULL END AS " + Combined.BOOKMARK_ID + ", " +
- qualifyColumn(TABLE_HISTORY, History.URL) + " AS " + Combined.URL + ", " +
- // Prioritize bookmark titles over history titles, since the user may have
- // customized the title for a bookmark.
- "COALESCE(" + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TITLE) + ", " +
- qualifyColumn(TABLE_HISTORY, History.TITLE) +")" + " AS " + Combined.TITLE + ", " +
- "CASE " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.PARENT) + " WHEN " +
- Bookmarks.FIXED_READING_LIST_ID + " THEN " + Obsolete.Combined.DISPLAY_READER + " ELSE " +
- Obsolete.Combined.DISPLAY_NORMAL + " END AS " + Obsolete.Combined.DISPLAY + ", " +
- qualifyColumn(TABLE_HISTORY, History._ID) + " AS " + Combined.HISTORY_ID + ", " +
- qualifyColumn(TABLE_HISTORY, History.VISITS) + " AS " + Combined.VISITS + ", " +
- qualifyColumn(TABLE_HISTORY, History.DATE_LAST_VISITED) + " AS " + Combined.DATE_LAST_VISITED +
- " FROM " + TABLE_HISTORY + " LEFT OUTER JOIN " + TABLE_BOOKMARKS +
- " ON " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.URL) + " = " + qualifyColumn(TABLE_HISTORY, History.URL) +
- " WHERE " + qualifyColumn(TABLE_HISTORY, History.URL) + " IS NOT NULL AND " +
- qualifyColumn(TABLE_HISTORY, History.IS_DELETED) + " = 0 AND (" +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TYPE) + " IS NULL OR " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TYPE) + " = " + Bookmarks.TYPE_BOOKMARK + ")" +
- ") LEFT OUTER JOIN " + Obsolete.TABLE_IMAGES +
- " ON " + Combined.URL + " = " + qualifyColumn(Obsolete.TABLE_IMAGES, Obsolete.Images.URL));
- }
-
- private void createCombinedWithImagesViewOn11(SQLiteDatabase db) {
- debug("Creating " + Obsolete.VIEW_COMBINED_WITH_IMAGES + " view");
-
- db.execSQL("CREATE VIEW IF NOT EXISTS " + Obsolete.VIEW_COMBINED_WITH_IMAGES + " AS" +
- " SELECT " + Combined.BOOKMARK_ID + ", " +
- Combined.HISTORY_ID + ", " +
- // We need to return an _id column because CursorAdapter requires it for its
- // default implementation for the getItemId() method. However, since
- // we're not using this feature in the parts of the UI using this view,
- // we can just use 0 for all rows.
- "0 AS " + Combined._ID + ", " +
- Combined.URL + ", " +
- Combined.TITLE + ", " +
- Combined.VISITS + ", " +
- Obsolete.Combined.DISPLAY + ", " +
- Combined.DATE_LAST_VISITED + ", " +
- qualifyColumn(Obsolete.TABLE_IMAGES, Obsolete.Images.FAVICON) + " AS " + Combined.FAVICON + ", " +
- qualifyColumn(Obsolete.TABLE_IMAGES, Obsolete.Images.THUMBNAIL) + " AS " + Obsolete.Combined.THUMBNAIL +
- " FROM (" +
- // Bookmarks without history.
- " SELECT " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks._ID) + " AS " + Combined.BOOKMARK_ID + ", " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.URL) + " AS " + Combined.URL + ", " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TITLE) + " AS " + Combined.TITLE + ", " +
- "CASE " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.PARENT) + " WHEN " +
- Bookmarks.FIXED_READING_LIST_ID + " THEN " + Obsolete.Combined.DISPLAY_READER + " ELSE " +
- Obsolete.Combined.DISPLAY_NORMAL + " END AS " + Obsolete.Combined.DISPLAY + ", " +
- "-1 AS " + Combined.HISTORY_ID + ", " +
- "-1 AS " + Combined.VISITS + ", " +
- "-1 AS " + Combined.DATE_LAST_VISITED +
- " FROM " + TABLE_BOOKMARKS +
- " WHERE " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TYPE) + " = " + Bookmarks.TYPE_BOOKMARK + " AND " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.IS_DELETED) + " = 0 AND " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.URL) +
- " NOT IN (SELECT " + History.URL + " FROM " + TABLE_HISTORY + ")" +
- " UNION ALL" +
- // History with and without bookmark.
- " SELECT " + "CASE " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.IS_DELETED) + " WHEN 0 THEN " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks._ID) + " ELSE NULL END AS " + Combined.BOOKMARK_ID + ", " +
- qualifyColumn(TABLE_HISTORY, History.URL) + " AS " + Combined.URL + ", " +
- // Prioritize bookmark titles over history titles, since the user may have
- // customized the title for a bookmark.
- "COALESCE(" + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TITLE) + ", " +
- qualifyColumn(TABLE_HISTORY, History.TITLE) +")" + " AS " + Combined.TITLE + ", " +
- qualifyColumn(TABLE_HISTORY, History._ID) + " AS " + Combined.HISTORY_ID + ", " +
- qualifyColumn(TABLE_HISTORY, History.VISITS) + " AS " + Combined.VISITS + ", " +
- qualifyColumn(TABLE_HISTORY, History.DATE_LAST_VISITED) + " AS " + Combined.DATE_LAST_VISITED +
- " FROM " + TABLE_HISTORY + " LEFT OUTER JOIN " + TABLE_BOOKMARKS +
- " ON " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.URL) + " = " + qualifyColumn(TABLE_HISTORY, History.URL) +
- " WHERE " + qualifyColumn(TABLE_HISTORY, History.URL) + " IS NOT NULL AND " +
- qualifyColumn(TABLE_HISTORY, History.IS_DELETED) + " = 0 AND (" +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TYPE) + " IS NULL OR " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TYPE) + " = " + Bookmarks.TYPE_BOOKMARK + ") " +
- ") LEFT OUTER JOIN " + Obsolete.TABLE_IMAGES +
- " ON " + Combined.URL + " = " + qualifyColumn(Obsolete.TABLE_IMAGES, Obsolete.Images.URL));
- }
-
- private void createCombinedViewOn12(SQLiteDatabase db) {
- debug("Creating " + VIEW_COMBINED + " view");
-
- db.execSQL("CREATE VIEW IF NOT EXISTS " + VIEW_COMBINED + " AS" +
- " SELECT " + Combined.BOOKMARK_ID + ", " +
- Combined.HISTORY_ID + ", " +
- // We need to return an _id column because CursorAdapter requires it for its
- // default implementation for the getItemId() method. However, since
- // we're not using this feature in the parts of the UI using this view,
- // we can just use 0 for all rows.
- "0 AS " + Combined._ID + ", " +
- Combined.URL + ", " +
- Combined.TITLE + ", " +
- Combined.VISITS + ", " +
- Obsolete.Combined.DISPLAY + ", " +
- Combined.DATE_LAST_VISITED +
- " FROM (" +
- // Bookmarks without history.
- " SELECT " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks._ID) + " AS " + Combined.BOOKMARK_ID + ", " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.URL) + " AS " + Combined.URL + ", " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TITLE) + " AS " + Combined.TITLE + ", " +
- "CASE " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.PARENT) + " WHEN " +
- Bookmarks.FIXED_READING_LIST_ID + " THEN " + Obsolete.Combined.DISPLAY_READER + " ELSE " +
- Obsolete.Combined.DISPLAY_NORMAL + " END AS " + Obsolete.Combined.DISPLAY + ", " +
- "-1 AS " + Combined.HISTORY_ID + ", " +
- "-1 AS " + Combined.VISITS + ", " +
- "-1 AS " + Combined.DATE_LAST_VISITED +
- " FROM " + TABLE_BOOKMARKS +
- " WHERE " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TYPE) + " = " + Bookmarks.TYPE_BOOKMARK + " AND " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.IS_DELETED) + " = 0 AND " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.URL) +
- " NOT IN (SELECT " + History.URL + " FROM " + TABLE_HISTORY + ")" +
- " UNION ALL" +
- // History with and without bookmark.
- " SELECT " + "CASE " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.IS_DELETED) + " WHEN 0 THEN " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks._ID) + " ELSE NULL END AS " + Combined.BOOKMARK_ID + ", " +
- qualifyColumn(TABLE_HISTORY, History.URL) + " AS " + Combined.URL + ", " +
- // Prioritize bookmark titles over history titles, since the user may have
- // customized the title for a bookmark.
- "COALESCE(" + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TITLE) + ", " +
- qualifyColumn(TABLE_HISTORY, History.TITLE) +")" + " AS " + Combined.TITLE + ", " +
- qualifyColumn(TABLE_HISTORY, History._ID) + " AS " + Combined.HISTORY_ID + ", " +
- qualifyColumn(TABLE_HISTORY, History.VISITS) + " AS " + Combined.VISITS + ", " +
- qualifyColumn(TABLE_HISTORY, History.DATE_LAST_VISITED) + " AS " + Combined.DATE_LAST_VISITED +
- " FROM " + TABLE_HISTORY + " LEFT OUTER JOIN " + TABLE_BOOKMARKS +
- " ON " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.URL) + " = " + qualifyColumn(TABLE_HISTORY, History.URL) +
- " WHERE " + qualifyColumn(TABLE_HISTORY, History.URL) + " IS NOT NULL AND " +
- qualifyColumn(TABLE_HISTORY, History.IS_DELETED) + " = 0 AND (" +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TYPE) + " IS NULL OR " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TYPE) + " = " + Bookmarks.TYPE_BOOKMARK + ") " +
- ")");
-
- debug("Creating " + Obsolete.VIEW_COMBINED_WITH_IMAGES + " view");
-
- db.execSQL("CREATE VIEW IF NOT EXISTS " + Obsolete.VIEW_COMBINED_WITH_IMAGES + " AS" +
- " SELECT *, " +
- qualifyColumn(Obsolete.TABLE_IMAGES, Obsolete.Images.FAVICON) + " AS " + Combined.FAVICON + ", " +
- qualifyColumn(Obsolete.TABLE_IMAGES, Obsolete.Images.THUMBNAIL) + " AS " + Obsolete.Combined.THUMBNAIL +
- " FROM " + VIEW_COMBINED + " LEFT OUTER JOIN " + Obsolete.TABLE_IMAGES +
- " ON " + Combined.URL + " = " + qualifyColumn(Obsolete.TABLE_IMAGES, Obsolete.Images.URL));
- }
-
- private void createCombinedViewOn13(SQLiteDatabase db) {
- debug("Creating " + VIEW_COMBINED + " view");
-
- db.execSQL("CREATE VIEW IF NOT EXISTS " + VIEW_COMBINED + " AS" +
- " SELECT " + Combined.BOOKMARK_ID + ", " +
- Combined.HISTORY_ID + ", " +
- // We need to return an _id column because CursorAdapter requires it for its
- // default implementation for the getItemId() method. However, since
- // we're not using this feature in the parts of the UI using this view,
- // we can just use 0 for all rows.
- "0 AS " + Combined._ID + ", " +
- Combined.URL + ", " +
- Combined.TITLE + ", " +
- Combined.VISITS + ", " +
- Obsolete.Combined.DISPLAY + ", " +
- Combined.DATE_LAST_VISITED + ", " +
- Combined.FAVICON_ID +
- " FROM (" +
- // Bookmarks without history.
- " SELECT " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks._ID) + " AS " + Combined.BOOKMARK_ID + ", " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.URL) + " AS " + Combined.URL + ", " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TITLE) + " AS " + Combined.TITLE + ", " +
- "CASE " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.PARENT) + " WHEN " +
- Bookmarks.FIXED_READING_LIST_ID + " THEN " + Obsolete.Combined.DISPLAY_READER + " ELSE " +
- Obsolete.Combined.DISPLAY_NORMAL + " END AS " + Obsolete.Combined.DISPLAY + ", " +
- "-1 AS " + Combined.HISTORY_ID + ", " +
- "-1 AS " + Combined.VISITS + ", " +
- "-1 AS " + Combined.DATE_LAST_VISITED + ", " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.FAVICON_ID) + " AS " + Combined.FAVICON_ID +
- " FROM " + TABLE_BOOKMARKS +
- " WHERE " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TYPE) + " = " + Bookmarks.TYPE_BOOKMARK + " AND " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.IS_DELETED) + " = 0 AND " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.URL) +
- " NOT IN (SELECT " + History.URL + " FROM " + TABLE_HISTORY + ")" +
- " UNION ALL" +
- // History with and without bookmark.
- " SELECT " + "CASE " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.IS_DELETED) + " WHEN 0 THEN " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks._ID) + " ELSE NULL END AS " + Combined.BOOKMARK_ID + ", " +
- qualifyColumn(TABLE_HISTORY, History.URL) + " AS " + Combined.URL + ", " +
- // Prioritize bookmark titles over history titles, since the user may have
- // customized the title for a bookmark.
- "COALESCE(" + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TITLE) + ", " +
- qualifyColumn(TABLE_HISTORY, History.TITLE) +")" + " AS " + Combined.TITLE + ", " +
- // Only use DISPLAY_READER if the matching bookmark entry inside reading
- // list folder is not marked as deleted.
- "CASE " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.IS_DELETED) + " WHEN 0 THEN CASE " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.PARENT) + " WHEN " + Bookmarks.FIXED_READING_LIST_ID +
- " THEN " + Obsolete.Combined.DISPLAY_READER + " ELSE " + Obsolete.Combined.DISPLAY_NORMAL + " END ELSE " +
- Obsolete.Combined.DISPLAY_NORMAL + " END AS " + Obsolete.Combined.DISPLAY + ", " +
- qualifyColumn(TABLE_HISTORY, History._ID) + " AS " + Combined.HISTORY_ID + ", " +
- qualifyColumn(TABLE_HISTORY, History.VISITS) + " AS " + Combined.VISITS + ", " +
- qualifyColumn(TABLE_HISTORY, History.DATE_LAST_VISITED) + " AS " + Combined.DATE_LAST_VISITED + ", " +
- qualifyColumn(TABLE_HISTORY, History.FAVICON_ID) + " AS " + Combined.FAVICON_ID +
- " FROM " + TABLE_HISTORY + " LEFT OUTER JOIN " + TABLE_BOOKMARKS +
- " ON " + qualifyColumn(TABLE_BOOKMARKS, Bookmarks.URL) + " = " + qualifyColumn(TABLE_HISTORY, History.URL) +
- " WHERE " + qualifyColumn(TABLE_HISTORY, History.URL) + " IS NOT NULL AND " +
- qualifyColumn(TABLE_HISTORY, History.IS_DELETED) + " = 0 AND (" +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TYPE) + " IS NULL OR " +
- qualifyColumn(TABLE_BOOKMARKS, Bookmarks.TYPE) + " = " + Bookmarks.TYPE_BOOKMARK + ") " +
- ")");
-
- debug("Creating " + VIEW_COMBINED_WITH_FAVICONS + " view");
-
- db.execSQL("CREATE VIEW IF NOT EXISTS " + VIEW_COMBINED_WITH_FAVICONS + " AS" +
- " SELECT " + qualifyColumn(VIEW_COMBINED, "*") + ", " +
- qualifyColumn(TABLE_FAVICONS, Favicons.URL) + " AS " + Combined.FAVICON_URL + ", " +
- qualifyColumn(TABLE_FAVICONS, Favicons.DATA) + " AS " + Combined.FAVICON +
- " FROM " + VIEW_COMBINED + " LEFT OUTER JOIN " + TABLE_FAVICONS +
- " ON " + Combined.FAVICON_ID + " = " + qualifyColumn(TABLE_FAVICONS, Favicons._ID));
- }
-
private void createCombinedViewOn19(SQLiteDatabase db) {
/*
The v19 combined view removes the redundant subquery from the v16
@@ -725,6 +270,7 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
qualifyColumn(TABLE_FAVICONS, Favicons.DATA) + " AS " + Combined.FAVICON +
" FROM " + VIEW_COMBINED + " LEFT OUTER JOIN " + TABLE_FAVICONS +
" ON " + Combined.FAVICON_ID + " = " + qualifyColumn(TABLE_FAVICONS, Favicons._ID));
+
}
@Override
@@ -735,8 +281,8 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
table.onCreate(db);
}
- createBookmarksTableOn13(db);
- createHistoryTableOn13(db);
+ createBookmarksTable(db);
+ createHistoryTable(db);
createFaviconsTable(db);
createThumbnailsTable(db);
@@ -777,7 +323,7 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
ReadingListItems.IS_DELETED + " TINYINT DEFAULT 0, " +
ReadingListItems.GUID + " TEXT UNIQUE NOT NULL, " +
ReadingListItems.DATE_MODIFIED + " INTEGER NOT NULL, " +
- ReadingListItems.DATE_CREATED + " INTEGER NOT NULL, " +
+ ReadingListItems.DATE_CREATED + " INTEGER NOT NULL, " +
ReadingListItems.LENGTH + " INTEGER DEFAULT 0 ); ");
db.execSQL("CREATE INDEX reading_list_url ON " + TABLE_READING_LIST + "("
@@ -797,10 +343,8 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
R.string.bookmarks_folder_tags, 3);
createOrUpdateSpecialFolder(db, Bookmarks.UNFILED_FOLDER_GUID,
R.string.bookmarks_folder_unfiled, 4);
- createOrUpdateSpecialFolder(db, Bookmarks.READING_LIST_FOLDER_GUID,
- R.string.bookmarks_folder_reading_list, 5);
createOrUpdateSpecialFolder(db, Bookmarks.PINNED_FOLDER_GUID,
- R.string.bookmarks_folder_pinned, 6);
+ R.string.bookmarks_folder_pinned, 5);
}
private void createOrUpdateSpecialFolder(SQLiteDatabase db,
@@ -810,12 +354,11 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
values.put(Bookmarks.TYPE, Bookmarks.TYPE_FOLDER);
values.put(Bookmarks.POSITION, position);
- if (guid.equals(Bookmarks.PLACES_FOLDER_GUID))
+ if (guid.equals(Bookmarks.PLACES_FOLDER_GUID)) {
values.put(Bookmarks._ID, Bookmarks.FIXED_ROOT_ID);
- else if (guid.equals(Bookmarks.READING_LIST_FOLDER_GUID))
- values.put(Bookmarks._ID, Bookmarks.FIXED_READING_LIST_ID);
- else if (guid.equals(Bookmarks.PINNED_FOLDER_GUID))
+ } else if (guid.equals(Bookmarks.PINNED_FOLDER_GUID)) {
values.put(Bookmarks._ID, Bookmarks.FIXED_PINNED_LIST_ID);
+ }
// Set the parent to 0, which sync assumes is the root
values.put(Bookmarks.PARENT, Bookmarks.FIXED_ROOT_ID);
@@ -841,8 +384,9 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
private boolean isSpecialFolder(ContentValues values) {
String guid = values.getAsString(Bookmarks.GUID);
- if (guid == null)
+ if (guid == null) {
return false;
+ }
return guid.equals(Bookmarks.MOBILE_FOLDER_GUID) ||
guid.equals(Bookmarks.MENU_FOLDER_GUID) ||
@@ -958,7 +502,6 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
" RENAME TO " + TABLE_BOOKMARKS_TMP);
debug("Dropping views and indexes related to " + TABLE_BOOKMARKS);
- db.execSQL("DROP VIEW IF EXISTS " + Obsolete.VIEW_BOOKMARKS_WITH_IMAGES);
db.execSQL("DROP INDEX IF EXISTS bookmarks_url_index");
db.execSQL("DROP INDEX IF EXISTS bookmarks_type_deleted_index");
@@ -966,7 +509,6 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
db.execSQL("DROP INDEX IF EXISTS bookmarks_modified_index");
createBookmarksTable(db);
- createBookmarksWithImagesView(db);
createOrUpdateSpecialFolder(db, Bookmarks.PLACES_FOLDER_GUID,
R.string.bookmarks_folder_places, 0);
@@ -981,15 +523,16 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_BOOKMARKS_TMP);
}
-
+ /**
+ * Migrate a history table from some old version to the newest one by creating the new table and
+ * copying all the data over.
+ */
private void migrateHistoryTable(SQLiteDatabase db) {
debug("Renaming history table to " + TABLE_HISTORY_TMP);
db.execSQL("ALTER TABLE " + TABLE_HISTORY +
" RENAME TO " + TABLE_HISTORY_TMP);
debug("Dropping views and indexes related to " + TABLE_HISTORY);
- db.execSQL("DROP VIEW IF EXISTS " + Obsolete.VIEW_HISTORY_WITH_IMAGES);
- db.execSQL("DROP VIEW IF EXISTS " + Obsolete.VIEW_COMBINED_WITH_IMAGES);
db.execSQL("DROP INDEX IF EXISTS history_url_index");
db.execSQL("DROP INDEX IF EXISTS history_guid_index");
@@ -997,8 +540,6 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
db.execSQL("DROP INDEX IF EXISTS history_visited_index");
createHistoryTable(db);
- createHistoryWithImagesView(db);
- createCombinedWithImagesView(db);
db.execSQL("INSERT INTO " + TABLE_HISTORY + " SELECT * FROM " + TABLE_HISTORY_TMP);
@@ -1006,86 +547,16 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_HISTORY_TMP);
}
- private void migrateImagesTable(SQLiteDatabase db) {
- debug("Renaming images table to " + TABLE_IMAGES_TMP);
- db.execSQL("ALTER TABLE " + Obsolete.TABLE_IMAGES +
- " RENAME TO " + TABLE_IMAGES_TMP);
-
- debug("Dropping views and indexes related to " + Obsolete.TABLE_IMAGES);
- db.execSQL("DROP VIEW IF EXISTS " + Obsolete.VIEW_HISTORY_WITH_IMAGES);
- db.execSQL("DROP VIEW IF EXISTS " + Obsolete.VIEW_COMBINED_WITH_IMAGES);
-
- db.execSQL("DROP INDEX IF EXISTS images_url_index");
- db.execSQL("DROP INDEX IF EXISTS images_guid_index");
- db.execSQL("DROP INDEX IF EXISTS images_modified_index");
-
- createImagesTable(db);
- createHistoryWithImagesView(db);
- createCombinedWithImagesView(db);
-
- db.execSQL("INSERT INTO " + Obsolete.TABLE_IMAGES + " SELECT * FROM " + TABLE_IMAGES_TMP);
-
- debug("Dropping images temporary table");
- db.execSQL("DROP TABLE IF EXISTS " + TABLE_IMAGES_TMP);
- }
-
- private void upgradeDatabaseFrom1to2(SQLiteDatabase db) {
- migrateBookmarksTable(db);
- }
-
- private void upgradeDatabaseFrom2to3(SQLiteDatabase db) {
- debug("Dropping view: " + Obsolete.VIEW_BOOKMARKS_WITH_IMAGES);
- db.execSQL("DROP VIEW IF EXISTS " + Obsolete.VIEW_BOOKMARKS_WITH_IMAGES);
-
- createBookmarksWithImagesView(db);
-
- debug("Dropping view: " + Obsolete.VIEW_HISTORY_WITH_IMAGES);
- db.execSQL("DROP VIEW IF EXISTS " + Obsolete.VIEW_HISTORY_WITH_IMAGES);
-
- createHistoryWithImagesView(db);
- }
-
private void upgradeDatabaseFrom3to4(SQLiteDatabase db) {
migrateBookmarksTable(db, new BookmarkMigrator3to4());
}
- private void upgradeDatabaseFrom4to5(SQLiteDatabase db) {
- createCombinedWithImagesView(db);
- }
-
- private void upgradeDatabaseFrom5to6(SQLiteDatabase db) {
- debug("Dropping view: " + Obsolete.VIEW_COMBINED_WITH_IMAGES);
- db.execSQL("DROP VIEW IF EXISTS " + Obsolete.VIEW_COMBINED_WITH_IMAGES);
-
- createCombinedWithImagesView(db);
- }
-
private void upgradeDatabaseFrom6to7(SQLiteDatabase db) {
debug("Removing history visits with NULL GUIDs");
db.execSQL("DELETE FROM " + TABLE_HISTORY + " WHERE " + History.GUID + " IS NULL");
- debug("Update images with NULL GUIDs");
- String[] columns = new String[] { Obsolete.Images._ID };
- Cursor cursor = null;
- try {
- cursor = db.query(Obsolete.TABLE_IMAGES, columns, Obsolete.Images.GUID + " IS NULL", null, null ,null, null, null);
- ContentValues values = new ContentValues();
- if (cursor.moveToFirst()) {
- do {
- values.put(Obsolete.Images.GUID, Utils.generateGuid());
- db.update(Obsolete.TABLE_IMAGES, values, Obsolete.Images._ID + " = ?", new String[] {
- cursor.getString(cursor.getColumnIndexOrThrow(Obsolete.Images._ID))
- });
- } while (cursor.moveToNext());
- }
- } finally {
- if (cursor != null)
- cursor.close();
- }
-
migrateBookmarksTable(db);
migrateHistoryTable(db);
- migrateImagesTable(db);
}
private void upgradeDatabaseFrom7to8(SQLiteDatabase db) {
@@ -1122,157 +593,38 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
db.execSQL("DROP TABLE " + TABLE_DUPES);
}
- private void upgradeDatabaseFrom8to9(SQLiteDatabase db) {
- createOrUpdateSpecialFolder(db, Bookmarks.READING_LIST_FOLDER_GUID,
- R.string.bookmarks_folder_reading_list, 5);
-
- debug("Dropping view: " + Obsolete.VIEW_COMBINED_WITH_IMAGES);
- db.execSQL("DROP VIEW IF EXISTS " + Obsolete.VIEW_COMBINED_WITH_IMAGES);
-
- createCombinedWithImagesViewOn9(db);
- }
-
- private void upgradeDatabaseFrom9to10(SQLiteDatabase db) {
- debug("Dropping view: " + Obsolete.VIEW_COMBINED_WITH_IMAGES);
- db.execSQL("DROP VIEW IF EXISTS " + Obsolete.VIEW_COMBINED_WITH_IMAGES);
-
- createCombinedWithImagesViewOn10(db);
- }
-
private void upgradeDatabaseFrom10to11(SQLiteDatabase db) {
- debug("Dropping view: " + Obsolete.VIEW_COMBINED_WITH_IMAGES);
- db.execSQL("DROP VIEW IF EXISTS " + Obsolete.VIEW_COMBINED_WITH_IMAGES);
-
db.execSQL("CREATE INDEX bookmarks_type_deleted_index ON " + TABLE_BOOKMARKS + "("
+ Bookmarks.TYPE + ", " + Bookmarks.IS_DELETED + ")");
-
- createCombinedWithImagesViewOn11(db);
- }
-
- private void upgradeDatabaseFrom11to12(SQLiteDatabase db) {
- debug("Dropping view: " + Obsolete.VIEW_COMBINED_WITH_IMAGES);
- db.execSQL("DROP VIEW IF EXISTS " + Obsolete.VIEW_COMBINED_WITH_IMAGES);
-
- createCombinedViewOn12(db);
}
private void upgradeDatabaseFrom12to13(SQLiteDatabase db) {
- // Update images table with favicon URLs
- SQLiteDatabase faviconsDb = null;
- Cursor c = null;
- try {
- final String FAVICON_TABLE = "favicon_urls";
- final String FAVICON_URL = "favicon_url";
- final String FAVICON_PAGE = "page_url";
-
- String dbPath = mContext.getDatabasePath(Obsolete.FAVICON_DB).getPath();
- faviconsDb = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READONLY);
- String[] columns = new String[] { FAVICON_URL, FAVICON_PAGE };
- c = faviconsDb.query(FAVICON_TABLE, columns, null, null, null, null, null, null);
- int faviconIndex = c.getColumnIndexOrThrow(FAVICON_URL);
- int pageIndex = c.getColumnIndexOrThrow(FAVICON_PAGE);
- while (c.moveToNext()) {
- ContentValues values = new ContentValues(1);
- String faviconUrl = c.getString(faviconIndex);
- String pageUrl = c.getString(pageIndex);
- values.put(FAVICON_URL, faviconUrl);
- db.update(Obsolete.TABLE_IMAGES, values, Obsolete.Images.URL + " = ?", new String[] { pageUrl });
- }
- } catch (SQLException e) {
- // If we can't read from the database for some reason, we won't
- // be able to import the favicon URLs. This isn't a fatal
- // error, so continue the upgrade.
- Log.e(LOGTAG, "Exception importing from " + Obsolete.FAVICON_DB, e);
- } finally {
- if (c != null)
- c.close();
- if (faviconsDb != null)
- faviconsDb.close();
- }
-
createFaviconsTable(db);
- // Import favicons into the favicons table
- db.execSQL("ALTER TABLE " + TABLE_HISTORY
- + " ADD COLUMN " + History.FAVICON_ID + " INTEGER");
- db.execSQL("ALTER TABLE " + TABLE_BOOKMARKS
- + " ADD COLUMN " + Bookmarks.FAVICON_ID + " INTEGER");
-
+ // Add favicon_id column to the history/bookmarks tables. We wrap this in a try-catch
+ // because the column *may* already exist at this point (depending on how many upgrade
+ // steps have been performed in this operation). In which case these queries will throw,
+ // but we don't care.
try {
- c = db.query(Obsolete.TABLE_IMAGES,
- new String[] {
- Obsolete.Images.URL,
- Obsolete.Images.FAVICON_URL,
- Obsolete.Images.FAVICON,
- Obsolete.Images.DATE_MODIFIED,
- Obsolete.Images.DATE_CREATED
- },
- Obsolete.Images.FAVICON + " IS NOT NULL",
- null, null, null, null);
-
- while (c.moveToNext()) {
- long faviconId = -1;
- int faviconUrlIndex = c.getColumnIndexOrThrow(Obsolete.Images.FAVICON_URL);
- String faviconUrl = null;
- if (!c.isNull(faviconUrlIndex)) {
- faviconUrl = c.getString(faviconUrlIndex);
- Cursor c2 = null;
- try {
- c2 = db.query(TABLE_FAVICONS,
- new String[] { Favicons._ID },
- Favicons.URL + " = ?",
- new String[] { faviconUrl },
- null, null, null);
- if (c2.moveToFirst()) {
- faviconId = c2.getLong(c2.getColumnIndexOrThrow(Favicons._ID));
- }
- } finally {
- if (c2 != null)
- c2.close();
- }
- }
-
- if (faviconId == -1) {
- ContentValues values = new ContentValues(4);
- values.put(Favicons.URL, faviconUrl);
- values.put(Favicons.DATA, c.getBlob(c.getColumnIndexOrThrow(Obsolete.Images.FAVICON)));
- values.put(Favicons.DATE_MODIFIED, c.getLong(c.getColumnIndexOrThrow(Obsolete.Images.DATE_MODIFIED)));
- values.put(Favicons.DATE_CREATED, c.getLong(c.getColumnIndexOrThrow(Obsolete.Images.DATE_CREATED)));
- faviconId = db.insert(TABLE_FAVICONS, null, values);
- }
-
- ContentValues values = new ContentValues(1);
- values.put(FaviconColumns.FAVICON_ID, faviconId);
- db.update(TABLE_HISTORY, values, History.URL + " = ?",
- new String[] { c.getString(c.getColumnIndexOrThrow(Obsolete.Images.URL)) });
- db.update(TABLE_BOOKMARKS, values, Bookmarks.URL + " = ?",
- new String[] { c.getString(c.getColumnIndexOrThrow(Obsolete.Images.URL)) });
- }
- } finally {
- if (c != null)
- c.close();
+ db.execSQL("ALTER TABLE " + TABLE_HISTORY +
+ " ADD COLUMN " + History.FAVICON_ID + " INTEGER");
+ db.execSQL("ALTER TABLE " + TABLE_BOOKMARKS +
+ " ADD COLUMN " + Bookmarks.FAVICON_ID + " INTEGER");
+ } catch (SQLException e) {
+ // Don't care.
+ debug("Exception adding favicon_id column. We're probably fine." + e);
}
createThumbnailsTable(db);
- // Import thumbnails into the thumbnails table
- db.execSQL("INSERT INTO " + TABLE_THUMBNAILS + " ("
- + Thumbnails.URL + ", "
- + Thumbnails.DATA + ") "
- + "SELECT " + Obsolete.Images.URL + ", " + Obsolete.Images.THUMBNAIL
- + " FROM " + Obsolete.TABLE_IMAGES
- + " WHERE " + Obsolete.Images.THUMBNAIL + " IS NOT NULL");
-
- db.execSQL("DROP VIEW IF EXISTS " + Obsolete.VIEW_BOOKMARKS_WITH_IMAGES);
- db.execSQL("DROP VIEW IF EXISTS " + Obsolete.VIEW_HISTORY_WITH_IMAGES);
- db.execSQL("DROP VIEW IF EXISTS " + Obsolete.VIEW_COMBINED_WITH_IMAGES);
- db.execSQL("DROP VIEW IF EXISTS " + VIEW_COMBINED);
+ db.execSQL("DROP VIEW IF EXISTS bookmarks_with_images");
+ db.execSQL("DROP VIEW IF EXISTS history_with_images");
+ db.execSQL("DROP VIEW IF EXISTS combined_with_images");
createBookmarksWithFaviconsView(db);
createHistoryWithFaviconsView(db);
- createCombinedViewOn13(db);
- db.execSQL("DROP TABLE IF EXISTS " + Obsolete.TABLE_IMAGES);
+ db.execSQL("DROP TABLE IF EXISTS images");
}
private void upgradeDatabaseFrom13to14(SQLiteDatabase db) {
@@ -1425,26 +777,10 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
// database schema version.
for (int v = oldVersion + 1; v <= newVersion; v++) {
switch(v) {
- case 2:
- upgradeDatabaseFrom1to2(db);
- break;
-
- case 3:
- upgradeDatabaseFrom2to3(db);
- break;
-
case 4:
upgradeDatabaseFrom3to4(db);
break;
- case 5:
- upgradeDatabaseFrom4to5(db);
- break;
-
- case 6:
- upgradeDatabaseFrom5to6(db);
- break;
-
case 7:
upgradeDatabaseFrom6to7(db);
break;
@@ -1453,22 +789,10 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
upgradeDatabaseFrom7to8(db);
break;
- case 9:
- upgradeDatabaseFrom8to9(db);
- break;
-
- case 10:
- upgradeDatabaseFrom9to10(db);
- break;
-
case 11:
upgradeDatabaseFrom10to11(db);
break;
- case 12:
- upgradeDatabaseFrom11to12(db);
- break;
-
case 13:
upgradeDatabaseFrom12to13(db);
break;
@@ -1507,14 +831,12 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
table.onUpgrade(db, oldVersion, newVersion);
}
- // If an upgrade after 12->13 fails, the entire upgrade is rolled
- // back, but we can't undo the deletion of favicon_urls.db if we
- // delete this in step 13; therefore, we wait until all steps are
- // complete before removing it.
- if (oldVersion < 13 && newVersion >= 13
- && mContext.getDatabasePath(Obsolete.FAVICON_DB).exists()
- && !mContext.deleteDatabase(Obsolete.FAVICON_DB)) {
- throw new SQLException("Could not delete " + Obsolete.FAVICON_DB);
+ // Delete the obsolete favicon database after all other upgrades complete.
+ // This can probably equivalently be moved into upgradeDatabaseFrom12to13.
+ if (oldVersion < 13 && newVersion >= 13) {
+ if (mContext.getDatabasePath("favicon_urls.db").exists()) {
+ mContext.deleteDatabase("favicon_urls.db");
+ }
}
}
@@ -1559,10 +881,6 @@ final class BrowserDatabaseHelper extends SQLiteOpenHelper {
}
}
- private static final String qualifyColumn(String table, String column) {
- return DBUtils.qualifyColumn(table, column);
- }
-
// Calculate these once, at initialization. isLoggable is too expensive to
// have in-line in each log call.
private static final boolean logDebug = Log.isLoggable(LOGTAG, Log.DEBUG);
diff --git a/mobile/android/base/sync/repositories/android/AndroidBrowserBookmarksDataAccessor.java b/mobile/android/base/sync/repositories/android/AndroidBrowserBookmarksDataAccessor.java
index 7bb4e2b65a5e..fd3c35da0131 100644
--- a/mobile/android/base/sync/repositories/android/AndroidBrowserBookmarksDataAccessor.java
+++ b/mobile/android/base/sync/repositories/android/AndroidBrowserBookmarksDataAccessor.java
@@ -37,7 +37,6 @@ public class AndroidBrowserBookmarksDataAccessor extends AndroidBrowserRepositor
private static final String GUID_SHOULD_TRACK = BrowserContract.SyncColumns.GUID + " NOT IN ('" +
BrowserContract.Bookmarks.TAGS_FOLDER_GUID + "', '" +
BrowserContract.Bookmarks.PLACES_FOLDER_GUID + "', '" +
- BrowserContract.Bookmarks.READING_LIST_FOLDER_GUID + "', '" +
BrowserContract.Bookmarks.PINNED_FOLDER_GUID + "')";
private static final String EXCLUDE_SPECIAL_GUIDS_WHERE_CLAUSE;
diff --git a/mobile/android/base/sync/repositories/android/AndroidBrowserBookmarksRepositorySession.java b/mobile/android/base/sync/repositories/android/AndroidBrowserBookmarksRepositorySession.java
index 0127b06ccb0d..fb79901a144c 100644
--- a/mobile/android/base/sync/repositories/android/AndroidBrowserBookmarksRepositorySession.java
+++ b/mobile/android/base/sync/repositories/android/AndroidBrowserBookmarksRepositorySession.java
@@ -203,8 +203,6 @@ public class AndroidBrowserBookmarksRepositorySession extends AndroidBrowserRepo
*/
public static boolean forbiddenGUID(final String recordGUID) {
return recordGUID == null ||
- // Temporarily exclude reading list items (Bug 762118; re-enable in Bug 762109.)
- BrowserContract.Bookmarks.READING_LIST_FOLDER_GUID.equals(recordGUID) ||
BrowserContract.Bookmarks.PINNED_FOLDER_GUID.equals(recordGUID) ||
BrowserContract.Bookmarks.PLACES_FOLDER_GUID.equals(recordGUID) ||
BrowserContract.Bookmarks.TAGS_FOLDER_GUID.equals(recordGUID);
@@ -221,8 +219,6 @@ public class AndroidBrowserBookmarksRepositorySession extends AndroidBrowserRepo
*/
public static boolean forbiddenParent(final String parentGUID) {
return parentGUID == null ||
- // Temporarily exclude reading list items (Bug 762118; re-enable in Bug 762109.)
- BrowserContract.Bookmarks.READING_LIST_FOLDER_GUID.equals(parentGUID) ||
BrowserContract.Bookmarks.PINNED_FOLDER_GUID.equals(parentGUID);
}
diff --git a/mobile/android/base/tests/testBrowserProvider.java b/mobile/android/base/tests/testBrowserProvider.java
index 610eb6f44075..2d3d7061d440 100644
--- a/mobile/android/base/tests/testBrowserProvider.java
+++ b/mobile/android/base/tests/testBrowserProvider.java
@@ -40,7 +40,7 @@ public class testBrowserProvider extends ContentProviderTest {
}
private void ensureEmptyDatabase() throws Exception {
- Cursor c = null;
+ Cursor c;
String guid = BrowserContract.Bookmarks.GUID;
@@ -50,18 +50,16 @@ public class testBrowserProvider extends ContentProviderTest {
guid + " != ? AND " +
guid + " != ? AND " +
guid + " != ? AND " +
- guid + " != ? AND " +
guid + " != ?",
new String[] { BrowserContract.Bookmarks.PLACES_FOLDER_GUID,
BrowserContract.Bookmarks.MOBILE_FOLDER_GUID,
BrowserContract.Bookmarks.MENU_FOLDER_GUID,
BrowserContract.Bookmarks.TAGS_FOLDER_GUID,
BrowserContract.Bookmarks.TOOLBAR_FOLDER_GUID,
- BrowserContract.Bookmarks.UNFILED_FOLDER_GUID,
- BrowserContract.Bookmarks.READING_LIST_FOLDER_GUID });
+ BrowserContract.Bookmarks.UNFILED_FOLDER_GUID });
c = mProvider.query(appendUriParam(BrowserContract.Bookmarks.CONTENT_URI, BrowserContract.PARAM_SHOW_DELETED, "1"), null, null, null, null);
- assertCountIsAndClose(c, 7, "All non-special bookmarks and folders were deleted");
+ assertCountIsAndClose(c, 6, "All non-special bookmarks and folders were deleted");
mProvider.delete(appendUriParam(BrowserContract.History.CONTENT_URI, BrowserContract.PARAM_IS_SYNC, "1"), null, null);
c = mProvider.query(appendUriParam(BrowserContract.History.CONTENT_URI, BrowserContract.PARAM_SHOW_DELETED, "1"), null, null, null, null);
diff --git a/mobile/android/tests/background/junit3/src/db/TestBookmarks.java b/mobile/android/tests/background/junit3/src/db/TestBookmarks.java
index f3a0dec165d6..783aea1ff848 100644
--- a/mobile/android/tests/background/junit3/src/db/TestBookmarks.java
+++ b/mobile/android/tests/background/junit3/src/db/TestBookmarks.java
@@ -50,7 +50,7 @@ public class TestBookmarks extends AndroidSyncTestCase {
protected static final String LOG_TAG = "BookmarksTest";
/**
- * Trivial test that forbidden records (reading list prior to Bug 762109, pinned items…)
+ * Trivial test that forbidden records such as pinned items
* will be ignored if processed.
*/
public void testForbiddenItemsAreIgnored() {
@@ -58,32 +58,25 @@ public class TestBookmarks extends AndroidSyncTestCase {
final long now = System.currentTimeMillis();
final String bookmarksCollection = "bookmarks";
- final BookmarkRecord toRead = new BookmarkRecord("daaaaaaaaaaa", "bookmarks", now - 1, false);
final BookmarkRecord pinned = new BookmarkRecord("pinpinpinpin", "bookmarks", now - 1, false);
final BookmarkRecord normal = new BookmarkRecord("baaaaaaaaaaa", "bookmarks", now - 2, false);
- final BookmarkRecord readingList = new BookmarkRecord(Bookmarks.READING_LIST_FOLDER_GUID,
- bookmarksCollection, now - 3, false);
final BookmarkRecord pinnedItems = new BookmarkRecord(Bookmarks.PINNED_FOLDER_GUID,
bookmarksCollection, now - 4, false);
- toRead.type = normal.type = pinned.type = "bookmark";
- readingList.type = "folder";
+ normal.type = "bookmark";
+ pinned.type = "bookmark";
pinnedItems.type = "folder";
- toRead.parentID = Bookmarks.READING_LIST_FOLDER_GUID;
pinned.parentID = Bookmarks.PINNED_FOLDER_GUID;
normal.parentID = Bookmarks.TOOLBAR_FOLDER_GUID;
- readingList.parentID = Bookmarks.PLACES_FOLDER_GUID;
pinnedItems.parentID = Bookmarks.PLACES_FOLDER_GUID;
inBegunSession(repo, new SimpleSuccessBeginDelegate() {
@Override
public void onBeginSucceeded(RepositorySession session) {
- assertTrue(((AndroidBrowserBookmarksRepositorySession) session).shouldIgnore(toRead));
assertTrue(((AndroidBrowserBookmarksRepositorySession) session).shouldIgnore(pinned));
- assertTrue(((AndroidBrowserBookmarksRepositorySession) session).shouldIgnore(readingList));
assertTrue(((AndroidBrowserBookmarksRepositorySession) session).shouldIgnore(pinnedItems));
assertFalse(((AndroidBrowserBookmarksRepositorySession) session).shouldIgnore(normal));
finishAndNotify(session);
@@ -115,24 +108,6 @@ public class TestBookmarks extends AndroidSyncTestCase {
assertFalse(guids.contains("dapinneditem"));
}
- /**
- * Trivial test that reading list records will be skipped if present in the DB.
- */
- public void testReadingListIsNotRetrieved() {
- final AndroidBrowserBookmarksRepository repo = new AndroidBrowserBookmarksRepository();
-
- // Ensure that it exists.
- setUpFennecReadingListRecord();
-
- // It's there in the DB…
- final ArrayList roots = fetchChildrenDirect(BrowserContract.Bookmarks.FIXED_ROOT_ID);
- Logger.info(LOG_TAG, "Roots: " + roots);
- assertTrue(roots.contains(Bookmarks.READING_LIST_FOLDER_GUID));
-
- // … but not when we fetch.
- assertFalse(fetchGUIDs(repo).contains(Bookmarks.READING_LIST_FOLDER_GUID));
- }
-
public void testRetrieveFolderHasAccurateChildren() {
AndroidBrowserBookmarksRepository repo = new AndroidBrowserBookmarksRepository();
@@ -864,17 +839,6 @@ public class TestBookmarks extends AndroidSyncTestCase {
return values;
}
- protected ContentValues fennecReadingListRecord() {
- final ContentValues values = specialFolder();
- final String title = getApplicationContext().getResources().getString(R.string.bookmarks_folder_reading_list);
-
- values.put(BrowserContract.SyncColumns.GUID, Bookmarks.READING_LIST_FOLDER_GUID);
- values.put(Bookmarks._ID, Bookmarks.FIXED_READING_LIST_ID);
- values.put(Bookmarks.PARENT, Bookmarks.FIXED_ROOT_ID);
- values.put(Bookmarks.TITLE, title);
- return values;
- }
-
protected long setUpFennecMobileRecordWithoutTitle() {
ContentResolver cr = getApplicationContext().getContentResolver();
ContentValues values = fennecMobileRecordWithoutTitle();
@@ -897,10 +861,6 @@ public class TestBookmarks extends AndroidSyncTestCase {
insertRow(fennecPinnedChildItemRecord());
}
- protected void setUpFennecReadingListRecord() {
- insertRow(fennecReadingListRecord());
- }
-
//
// Fennec fake layer.
//
diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json
index 257a9a754ada..28ffc944d0ed 100644
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -4509,6 +4509,12 @@
"n_values": 100,
"description": "Security UI Telemetry"
},
+ "JS_TELEMETRY_ADDON_EXCEPTIONS" : {
+ "expires_in_version" : "never",
+ "kind": "count",
+ "keyed" : true,
+ "description" : "Exceptions thrown by add-ons"
+ },
"SEARCH_COUNTS": {
"expires_in_version": "never",
"kind": "count",
diff --git a/toolkit/devtools/server/actors/script.js b/toolkit/devtools/server/actors/script.js
index cf3ecb722ca2..1a95a77f8d8c 100644
--- a/toolkit/devtools/server/actors/script.js
+++ b/toolkit/devtools/server/actors/script.js
@@ -107,7 +107,7 @@ BreakpointStore.prototype = {
* @returns Object aBreakpoint
* The new or existing breakpoint.
*/
- addBreakpoint: function (aBreakpoint) {
+ addBreakpoint: function (aBreakpoint, aActor) {
let { source: { actor }, line, column } = aBreakpoint;
if (column != null) {
@@ -119,7 +119,7 @@ BreakpointStore.prototype = {
}
if (!this._breakpoints[actor][line][column]) {
- this._breakpoints[actor][line][column] = aBreakpoint;
+ this._breakpoints[actor][line][column] = aActor;
this._size++;
}
return this._breakpoints[actor][line][column];
@@ -130,7 +130,7 @@ BreakpointStore.prototype = {
}
if (!this._wholeLineBreakpoints[actor][line]) {
- this._wholeLineBreakpoints[actor][line] = aBreakpoint;
+ this._wholeLineBreakpoints[actor][line] = aActor;
this._size++;
}
return this._wholeLineBreakpoints[actor][line];
@@ -178,53 +178,6 @@ BreakpointStore.prototype = {
}
},
- /**
- * Move the breakpoint to the new location.
- *
- * @param Object aBreakpoint
- * The breakpoint being moved. See `addBreakpoint` for a description of
- * its expected properties.
- * @param Object aNewLocation
- * The location to move the breakpoint to. Properties:
- * - line
- * - column (optional; omission implies whole line breakpoint)
- */
- moveBreakpoint: function (aBreakpoint, aNewLocation) {
- const existingBreakpoint = this.getBreakpoint(aBreakpoint);
- this.removeBreakpoint(existingBreakpoint);
-
- const { line, column } = aNewLocation;
- existingBreakpoint.line = line;
- existingBreakpoint.column = column;
- this.addBreakpoint(existingBreakpoint);
- },
-
- /**
- * Get a breakpoint from the breakpoint store. Will throw an error if the
- * breakpoint is not found.
- *
- * @param Object aLocation
- * The location of the breakpoint you are retrieving. It is an object
- * with the following properties:
- * - source
- * - line
- * - column (optional)
- */
- getBreakpoint: function (aLocation) {
- let { source: { actor, url }, line, column } = aLocation;
- dbg_assert(actor != null);
- dbg_assert(line != null);
-
- var foundBreakpoint = this.hasBreakpoint(aLocation);
- if (foundBreakpoint == null) {
- throw new Error("No breakpoint at = " + (url || actor)
- + ", line = " + line
- + ", column = " + column);
- }
-
- return foundBreakpoint;
- },
-
/**
* Checks if the breakpoint store has a requested breakpoint.
*
@@ -236,16 +189,16 @@ BreakpointStore.prototype = {
* - column (optional)
* @returns The stored breakpoint if it exists, null otherwise.
*/
- hasBreakpoint: function (aLocation) {
+ getBreakpoint: function (aLocation) {
let { source: { actor }, line, column } = aLocation;
dbg_assert(actor != null);
dbg_assert(line != null);
- for (let bp of this.findBreakpoints(aLocation)) {
+ for (let actor of this.findBreakpoints(aLocation)) {
// We will get whole line breakpoints before individual columns, so just
// return the first one and if they didn't specify a column then they will
// get the whole line breakpoint, and otherwise we will find the correct
// one.
- return bp;
+ return actor;
}
return null;
@@ -275,7 +228,7 @@ BreakpointStore.prototype = {
for (let actor of this._iterActors(actor)) {
for (let line of this._iterLines(actor, aSearchParams.line)) {
// Always yield whole line breakpoints first. See comment in
- // |BreakpointStore.prototype.hasBreakpoint|.
+ // |BreakpointStore.prototype.getBreakpoint|.
if (aSearchParams.column == null
&& this._wholeLineBreakpoints[actor]
&& this._wholeLineBreakpoints[actor][line]) {
@@ -1330,18 +1283,16 @@ ThreadActor.prototype = {
for (let line = 0, n = offsets.length; line < n; line++) {
if (offsets[line]) {
let location = { line: line };
- let resp = sourceActor.createAndStoreBreakpoint(location);
+ let resp = sourceActor._setBreakpoint(location);
dbg_assert(!resp.actualLocation, "No actualLocation should be returned");
if (resp.error) {
reportError(new Error("Unable to set breakpoint on event listener"));
return;
}
- let bp = this.breakpointStore.getBreakpoint({
+ let bpActor = this.breakpointStore.getBreakpoint({
source: sourceActor.form(),
line: location.line
});
- let bpActor = bp.actor;
- dbg_assert(bp, "Breakpoint must exist");
dbg_assert(bpActor, "Breakpoint actor must be created");
this._hiddenBreakpoints.set(bpActor.actorID, bpActor);
break;
@@ -1496,10 +1447,8 @@ ThreadActor.prototype = {
* caches won't hold on to the Debugger.Script objects leaking memory.
*/
disableAllBreakpoints: function () {
- for (let bp of this.breakpointStore.findBreakpoints()) {
- if (bp.actor) {
- bp.actor.removeScripts();
- }
+ for (let bpActor of this.breakpointStore.findBreakpoints()) {
+ bpActor.removeScripts();
}
},
@@ -2153,11 +2102,11 @@ ThreadActor.prototype = {
let endLine = aScript.startLine + aScript.lineCount - 1;
let source = this.sources.source({ source: aScript.source });
- for (let bp of this.breakpointStore.findBreakpoints(source.form())) {
+ for (let bpActor of this.breakpointStore.findBreakpoints({ source: source.form() })) {
// Limit the search to the line numbers contained in the new script.
- if (bp.line >= aScript.startLine
- && bp.line <= endLine) {
- source._setBreakpoint(bp, aScript);
+ if (bpActor.location.line >= aScript.startLine
+ && bpActor.location.line <= endLine) {
+ source._setBreakpoint(bpActor.location, aScript);
}
}
@@ -2841,7 +2790,7 @@ SourceActor.prototype = {
_createBreakpoint: function(loc, originalLoc, condition) {
return resolve(null).then(() => {
- return this.createAndStoreBreakpoint({
+ return this._setBreakpoint({
line: loc.line,
column: loc.column,
condition: condition
@@ -2904,23 +2853,6 @@ SourceActor.prototype = {
});
},
- /**
- * Create a breakpoint at the specified location and store it in the
- * cache. Takes ownership of `aRequest`. This is the
- * generated location if this source is sourcemapped.
- * Used by the XPCShell test harness to set breakpoints in a script before
- * it has loaded.
- *
- * @param Object aRequest
- * An object of the form { line[, column, condition] }. The
- * location is in the generated source, if sourcemapped.
- */
- createAndStoreBreakpoint: function (aRequest) {
- let bp = update({}, aRequest, { source: this.form() });
- this.breakpointStore.addBreakpoint(bp);
- return this._setBreakpoint(aRequest);
- },
-
/** Get or create the BreakpointActor for the breakpoint at the given location.
*
* NB: This will override a pre-existing BreakpointActor's condition with
@@ -2932,22 +2864,20 @@ SourceActor.prototype = {
* @returns BreakpointActor
*/
_getOrCreateBreakpointActor: function (location) {
- let actor;
- const storedBp = this.breakpointStore.getBreakpoint(location);
-
- if (storedBp.actor) {
- actor = storedBp.actor;
- actor.condition = location.condition;
+ let actor = this.breakpointStore.getBreakpoint(location);
+ if (!actor) {
+ actor = new BreakpointActor(this.threadActor, {
+ sourceActor: this,
+ line: location.line,
+ column: location.column,
+ condition: location.condition
+ });
+ this.threadActor.threadLifetimePool.addActor(actor);
+ this.breakpointStore.addBreakpoint(location, actor);
return actor;
}
- storedBp.actor = actor = new BreakpointActor(this.threadActor, {
- sourceActor: this,
- line: location.line,
- column: location.column,
- condition: location.condition
- });
- this.threadActor.threadLifetimePool.addActor(actor);
+ actor.condition = location.condition;
return actor;
},
@@ -3112,12 +3042,12 @@ SourceActor.prototype = {
// above is redundant and must be destroyed. If we do not have an existing
// actor, we need to update the breakpoint store with the new location.
- const existingBreakpoint = this.breakpointStore.hasBreakpoint(actualLocation);
- if (existingBreakpoint && existingBreakpoint.actor) {
+ let existingActor = this.breakpointStore.getBreakpoint(actualLocation);
+ if (existingActor) {
actor.onDelete();
this.breakpointStore.removeBreakpoint(location);
return {
- actor: existingBreakpoint.actor.actorID,
+ actor: existingActor.actorID,
actualLocation
};
} else {
@@ -3126,7 +3056,8 @@ SourceActor.prototype = {
sourceActor: this,
line: actualLocation.line
};
- this.breakpointStore.moveBreakpoint(location, actualLocation);
+ this.breakpointStore.removeBreakpoint(location);
+ this.breakpointStore.addBreakpoint(actualLocation, actor);
}
}
diff --git a/toolkit/devtools/server/tests/unit/test_breakpointstore.js b/toolkit/devtools/server/tests/unit/test_breakpointstore.js
index 1e4ed102e17a..40eeb7e5000b 100644
--- a/toolkit/devtools/server/tests/unit/test_breakpointstore.js
+++ b/toolkit/devtools/server/tests/unit/test_breakpointstore.js
@@ -11,15 +11,14 @@ function run_test()
Cu.import("resource://gre/modules/jsdebugger.jsm");
addDebuggerToGlobal(this);
- test_has_breakpoint();
+ test_get_breakpoint();
test_add_breakpoint();
test_remove_breakpoint();
test_find_breakpoints();
test_duplicate_breakpoints();
- test_move_breakpoint();
}
-function test_has_breakpoint() {
+function test_get_breakpoint() {
let bpStore = new BreakpointStore();
let location = {
source: { actor: 'actor1' },
@@ -32,27 +31,27 @@ function test_has_breakpoint() {
};
// Shouldn't have breakpoint
- do_check_eq(null, bpStore.hasBreakpoint(location),
+ do_check_eq(null, bpStore.getBreakpoint(location),
"Breakpoint not added and shouldn't exist.");
- bpStore.addBreakpoint(location);
- do_check_true(!!bpStore.hasBreakpoint(location),
+ bpStore.addBreakpoint(location, {});
+ do_check_true(!!bpStore.getBreakpoint(location),
"Breakpoint added but not found in Breakpoint Store.");
bpStore.removeBreakpoint(location);
- do_check_eq(null, bpStore.hasBreakpoint(location),
+ do_check_eq(null, bpStore.getBreakpoint(location),
"Breakpoint removed but still exists.");
// Same checks for breakpoint with a column
- do_check_eq(null, bpStore.hasBreakpoint(columnLocation),
+ do_check_eq(null, bpStore.getBreakpoint(columnLocation),
"Breakpoint with column not added and shouldn't exist.");
- bpStore.addBreakpoint(columnLocation);
- do_check_true(!!bpStore.hasBreakpoint(columnLocation),
+ bpStore.addBreakpoint(columnLocation, {});
+ do_check_true(!!bpStore.getBreakpoint(columnLocation),
"Breakpoint with column added but not found in Breakpoint Store.");
bpStore.removeBreakpoint(columnLocation);
- do_check_eq(null, bpStore.hasBreakpoint(columnLocation),
+ do_check_eq(null, bpStore.getBreakpoint(columnLocation),
"Breakpoint with column removed but still exists in Breakpoint Store.");
}
@@ -64,8 +63,8 @@ function test_add_breakpoint() {
line: 10,
column: 9
};
- bpStore.addBreakpoint(location);
- do_check_true(!!bpStore.hasBreakpoint(location),
+ bpStore.addBreakpoint(location, {});
+ do_check_true(!!bpStore.getBreakpoint(location),
"We should have the column breakpoint we just added");
// Breakpoint without column (whole line breakpoint)
@@ -73,8 +72,8 @@ function test_add_breakpoint() {
source: { actor: 'actor2' },
line: 103
};
- bpStore.addBreakpoint(location);
- do_check_true(!!bpStore.hasBreakpoint(location),
+ bpStore.addBreakpoint(location, {});
+ do_check_true(!!bpStore.getBreakpoint(location),
"We should have the whole line breakpoint we just added");
}
@@ -86,9 +85,9 @@ function test_remove_breakpoint() {
line: 10,
column: 9
};
- bpStore.addBreakpoint(location);
+ bpStore.addBreakpoint(location, {});
bpStore.removeBreakpoint(location);
- do_check_eq(bpStore.hasBreakpoint(location), null,
+ do_check_eq(bpStore.getBreakpoint(location), null,
"We should not have the column breakpoint anymore");
// Breakpoint without column (whole line breakpoint)
@@ -96,9 +95,9 @@ function test_remove_breakpoint() {
source: { actor: 'actor2' },
line: 103
};
- bpStore.addBreakpoint(location);
+ bpStore.addBreakpoint(location, {});
bpStore.removeBreakpoint(location);
- do_check_eq(bpStore.hasBreakpoint(location), null,
+ do_check_eq(bpStore.getBreakpoint(location), null,
"We should not have the whole line breakpoint anymore");
}
@@ -117,7 +116,7 @@ function test_find_breakpoints() {
let bpStore = new BreakpointStore();
for (let bp of bps) {
- bpStore.addBreakpoint(bp);
+ bpStore.addBreakpoint(bp, bp);
}
// All breakpoints
@@ -166,8 +165,8 @@ function test_duplicate_breakpoints() {
line: 10,
column: 9
};
- bpStore.addBreakpoint(location);
- bpStore.addBreakpoint(location);
+ bpStore.addBreakpoint(location, {});
+ bpStore.addBreakpoint(location, {});
do_check_eq(bpStore.size, 1, "We should have only 1 column breakpoint");
bpStore.removeBreakpoint(location);
@@ -176,36 +175,8 @@ function test_duplicate_breakpoints() {
source: { actor: "foo-actor" },
line: 15
};
- bpStore.addBreakpoint(location);
- bpStore.addBreakpoint(location);
+ bpStore.addBreakpoint(location, {});
+ bpStore.addBreakpoint(location, {});
do_check_eq(bpStore.size, 1, "We should have only 1 whole line breakpoint");
bpStore.removeBreakpoint(location);
}
-
-function test_move_breakpoint() {
- let bpStore = new BreakpointStore();
-
- let oldLocation = {
- source: { actor: "foo-actor" },
- line: 10
- };
-
- let newLocation = {
- source: { actor: "foo-actor" },
- line: 12
- };
-
- bpStore.addBreakpoint(oldLocation);
- bpStore.moveBreakpoint(oldLocation, newLocation);
-
- equal(bpStore.size, 1, "Moving a breakpoint maintains the correct size.");
-
- let bp = bpStore.getBreakpoint(newLocation);
- ok(bp, "We should be able to get a breakpoint at the new location.");
- equal(bp.line, newLocation.line,
- "We should get the moved line.");
-
- equal(bpStore.hasBreakpoint({ source: { actor: "foo-actor" }, line: 10 }),
- null,
- "And we shouldn't be able to get any BP at the old location.");
-}
diff --git a/uriloader/exthandler/tests/mochitest/handlerApps.js b/uriloader/exthandler/tests/mochitest/handlerApps.js
index cbfbcca6acb7..379f04120ba9 100644
--- a/uriloader/exthandler/tests/mochitest/handlerApps.js
+++ b/uriloader/exthandler/tests/mochitest/handlerApps.js
@@ -37,7 +37,7 @@ function test() {
getInterface(SpecialPowers.Ci.nsIWebNavigation).
QueryInterface(SpecialPowers.Ci.nsIDocShell);
- webHandler.launchWithURI(uri, windowContext);
+ webHandler.launchWithURI(uri, windowContext);
// if we get this far without an exception, we've at least partly passed
// (remaining check in handlerApp.xhtml)